本文摘要
原作者:CodeCracker
翻译及补充:慕若曦
工具:
-
CFF Explorer(Link:https://down.52pojie.cn/Tools/PEtools/CFF_Explorer.zip)
-
main.exe(Link:https://muruoxi.lanzouq.com/ilXYSt9hp2h)
-
RE-Sign-sn工具包(Link:https://muruoxi.lanzouq.com/i2G1Cziwugb)
在本节课中,CodeCracker为我们介绍了对有强名称保护的程序如何进行分析,本文针对CodeCracker提供的main.exe作为案例,为了方便新手学习,我补充了部分配图,并对部分令新手较难上手的操作补充了图文说明,但遗憾的是我并不是专业的程序员,所以部分术语翻译可能有误,如果您有更好的术语翻译,欢迎告知我。
怎样判断程序集是否被签名(强名称)
-
在CFF Explorer中加载要分析的程序
-
转到.NET Directory -> MetaData Streams -> #~ -> MetaData Tables (或者Tables) -> Assembly
-
选中要分析的程序集(图中只有一个程序集DemoApplication)
-
观察右侧的PublicKey的值,如果为0,证明这个程序集没有被签名
如果PublicKey的值不为0,说明程序集是受到强名称保护的。
此时这个值应该是Blob的索引号,我们需要复制它,然后进入#Blob部分,在右键菜单里选择Go to Offset(部分汉化版的CFF翻译为跳转偏移),即可跳转到对应的PublicKey。
需要注意的是,这里跳转到的是 PublicKey,而不是PublicKeyToken,这是两个不同的属性!
对抗强名称保护的方法
方法1:对程序集重新签名
步骤:
-
使用sn.exe来创建密钥对(key pair),对应的命令为:sn –k keypair.snk
-
使用RE-Sign工具,用生成的秘钥对对程序集进行签名
为让新手更容易的上手,方法1的流程已经帮你写好了批处理,在RE-Sign-sn工具包里你能找到一个名为genkeypair.bat的批处理文件,运行它即可得到两个文件,keypair.snk是用来给程序签名的秘钥文件,对应的token存放在newpktoken.txt这个文档中,然后使用RE-Sign进行签名即可。
需要强调的是,RE-Sign这个工具过于古老而且没有人维护,在Win10上运行会出现部分Bug,比如界面异常,我在翻译这篇教程的时候尝试修复了它,重命名为RE-Sign_Fix.exe,你可以根据需要去选择使用。
方法2:使用 CFF Explorer 自动删除强名称保护
在CFF Explorer中加载被强名称保护的文件,在Rebuilder选项里,我们只勾选Remove Strong Name Signature,然后点击Rebuild即可。
方法3:使用 CFF Explorer 手动删除强名称保护
这个方法是方法2的手动实现,具体的步骤如下:
-
在CFF Explorer中加载被强名称保护的文件
-
在.NET Directory中有一个Flag标志,这就是dotNet的CLI Header Assembly flags,点击我箭头标注的位置,取消对Strong name signed的勾选
-
在.NET Directory中,有StrongNameSignature RVA 和 StrongNameSignature Size两个标记,将它们的值设置为0,小提示,双击对应的值去修改,八位数值
-
转到.NET Directory -> MetaData Streams -> #~ -> MetaData Tables (或者Tables) -> Assembly,把PublicKey设置为0000
-
然后在Flag里去掉对PublicKey的勾选
感谢
致谢:原作者CodeCracker
附原文内容以供参考:
I. Defeat strong name protection from assemblies which doesn’t have any reference from other assemblies (the main exe for example)
How can I see if an assembly is signed?
Load the desired assembly under CFF Explorer and go at .NET Directory->MetaData Streams->#~->MetaData Tables (Tables)->Assembly and select the current assembly.
You will see a member named PublicKey. If has the value 0 means that our assembly is not strong named!
If is different from 0 it means that is strong named and the value will be an Index under Blob. We simply copy the value and we go under “#Blob” section. We choose “Go to Offset”, we enter the copied value and you will lead to the PublicKey (not the PublicKeyToken - take care!).
We have some options for defeating strong name protection:
Option A: Resign the assembly whit our own key using re-sign tools:
Steps:
-
Use sn.exe to create a key pair using the command:
sn –k keypair.snk
-
Use RE-Sign tools to resign the assembly whit the generate snk file keypair.snk
Option B: Automatic Strong Name Protection Remove using CFF Explorer:
Load the file under CFF Explorer VII, we go to Rebuilder, we mark only Remove Strong Name Signature and we click Rebuild
Option C: Manual Strong Name Protection Remove using CFF Explorer (the same thing as under B but manual):
-
In CFF Explorer in .NET Directory we have the member Flags (CLI Header Assembly flags) – unmark “Strong name signed”.
-
In CFF Explorer in .NET Directory we have 2 members: StrongNameSignature RVA and StrongNameSignature Size – set value of these to zero.
-
In CFF Explorer in .NET Directory->MetaData Streams->#~->MetaData Tables (Tables) ->Assembly:
The member PublicKey (the index) in Assembly Table must be 0000