导语:不知道你有没有这样的感觉,有时候你只是一个只知道如何从StackOverflow扒各种源码的Shit?
不知道你有没有这样的感觉,有时候你只是一个只知道如何从StackOverflow扒各种源码的Shit?
这种感觉挑战着我去学习新的东西,找到新的方法来测试我的大脑,开始把玩逆向工程是一个正确的事情,我再次感觉到自己像一个有点牛逼的开发人员了(也可能只是一个有点不同的shit!)。
下面是我学习新事物的秘诀:
感觉自己像一坨shit。 做了一些“很酷”的东西。 过了15分钟,继续转到了第1点(不要在源代码中使用gotos ;)
好的,当你有了好的心情,那就让我们开始本文的主题吧。
最近,我们遇到了一个使用VB.NET编写的加密器,但是源码被混淆过了。我们的主要目的是找出加密的逻辑和方法。我认为玩逆向最难的部分之一是确定代码逻辑,而不仅仅是编写补丁或者是从程序中找出了一个密钥。
本文将会重点讲述下面两个部分:
移除各种反逆向保护。 反编译程序并运行。
在对一个巨大的文本尝试了多个反混淆器后,依旧没有结果。这真是一个连没有运气都没有的非常完美的地方,让我们跳过这一步,先试试手。 (用右手是最有效的,这样能感觉好点)。
让我们使用dnSpy加载程序集。然后,让我们看看我们的模块和类,我们注意到的,在程序集中定义的方法没有反编译成功。
这意味着我们要寻找的方法加密到了一些隐藏的节中(不在IL节),当程序运行时,会解密这些方法并把它们放在正确的位置。 为了确认,让我们用CFF资源管理器打开我们的程序集并导航到PE节。
是的,我们想的是对的。 现在我们必须在源代码中找到函数解密和修复发生的地方。 经过一些观察,发现该过程发生在<Module> .ctor。 此构造函数在应用程序的主入口点之前调用。 这意味着它是实施这些工作的完美点。
重新打开dnSpy,然后右击程序集 – >转到.cctor。
由于在<Module>类中有一些没有被很好的反编译的函数,所以,我们得出的结论是,在第一次调用期间必须会发生方法的修改,so,让我们继续深挖一下。
这里我们看到程序导入了kernel32.dll 的VirtualProtect函数的调用。 此功能用于设置存储器块的访问属性。 好吧,这给了我们这一信息:程序获取了方法真正存放的地址并在这个地址上设置了PAGE_EXECUTE属性,对于其他的信息,我们不需要知道了。 我们找到了修复方法的确切地址,没错,就是它。
让我们在调用之后设置一个断点,然后从内存中导出程序集。
保存并使用dnSpy打开新保存的程序模块。 现在我们看到我们要找的方法已经被反编译了,感觉很好。 我们做到了!
但仍然有一个问题,我们的.exe是有问题的,因为我们忘记删除掉“方法修复函数”。 程序运行后仍然会执行修复的方法(但方法已经被我们固化了),这是一件完全混乱的事情。
现在让我们删除该函数并再次保存程序集。
然后单击模块,然后单击文件 – >保存模块。 不要忘记设置MD Writer选项,如:
好的,现在我们就有了一个用反编译的方法操作过的可运行的可执行文件。