Acprotect学习笔记
垃圾前言
这个壳早就已经被各位大牛肢解了,而 且也不更新了,现在的软件基本上不会用它来加壳了吧。我写这篇文章只是来过下手瘾
其实Acprotect以前就分析过 了(主要是分析IAT处理),现在写篇文章来作个记录吧。
同样来给 MM.exe加个壳吧,这里我用的是1.41版的来加壳。
好吧,运行一下,MM1.exe能运 行。OD载入。跟一下,发现全是花指令
既然它这么多花指令,那我们就不具体 F7了。我们直接我们的目标,IAT处理分析
忽略所有异常访问,SOD全选
1.1找OEP+修复
先到 OEP去吧.怎么到OEP?
方法很多哈.理解了原理,用哪种方法 看大家的爱好,
这里我用两次内存断点法。在.rsrc 段下内存访问断点.f9运行,断下
现在代码段应该解码了吧
到 00401000去看下
Boolean都出来了,证明已经解 码了
那么接下来程序要到OEP就应该会到 代码段去执行代码了吧
在代码段00401000下内存访问 断点,F9。断下。
咦这里是Delphi程序的笫一个 Call吧。为什么不是断在OEP,看看堆栈
返回到 004A3071 , 这 个004A3071是在哪里呢看看区段信息
原来是在壳段中,那么为什么不会断下 OEP应该知道了吧。
它把程序的OEP移动到壳段而且进行 了变形。我们不管它的变形,我们主要分析它的IAT哈
既然找到了笫一个call那就在 004A306B这里下个硬件执行断点吧。然后重载程序。F9。断下。
我们来修复下OEP,
找个未回味加壳的delphi程序
下面就直接patch代码来修复 OEP
eax的值看下断下后的 eax的值就行了
004A3060新建EIP。取消两 个nop的修改。
OEP修复完毕
1.2,修复IAT
现在跟进去笫一个CALL
004A3060 55 push ebp
004A3061 8BEC mov ebp, esp
004A3063 83C4 F0 add esp, -10
004A3066 B8 4C2B4600 mov eax, 462B4C
004A306B FF15 B5D84800 call dword ptr [48D8B5] ; F7跟进
004A3071 A1 E8484600 mov eax, dword ptr [4648E8]
-----------------------------------------------------------------------------
00405C34 53 push ebx ;到这,
00405C35 8BD8 mov ebx, eax
00405C37 33C0 xor eax, eax
00405C39 A3 9C304600 mov dword ptr [46309C], eax
00405C3E 6A 00 push 0
00405C40 E8 2BFFFFFF call 00405B70 ; 继续F7跟进
00405C45 A3 64564600 mov dword ptr [465664], eax
00405C4A A1 64564600 mov eax, dword ptr [465664]
------------------------------------------------------------------------------
到这里 就是iat 重定向了吧,都定向到壳段去了
先数据窗口中跟随内存地址
00466110 00000000
00466114 00000000
00466118 0048D010 MM1.0048D010
0046611C 0048D01D MM1.0048D01D
00466120 0048D02A MM1.0048D02A
00466124 0048D037 MM1.0048D037
00466128 0048D044 MM1.0048D044
0046612C 0048D051 MM1.0048D051
00466130 0048D05E MM1.0048D05E
00466134 0048D06B MM1.0048D06B
00466138 0048D078 MM1.0048D078
0046613C 0048D085 MM1.0048D085
00466140 0048D092 MM1.0048D092
00466144 0048D09F MM1.0048D09F
00466148 0048D0AC MM1.0048D0AC
0046614C 0048D0B9 MM1.0048D0B9
00466150 0048D0C6 MM1.0048D0C6
00466154 0048D0D3 MM1.0048D0D3
00466158 0048D0E0 MM1.0048D0E0
0046615C 0048D0ED MM1.0048D0ED
00466160 0048D0FA MM1.0048D0FA
00466164 0048D107 MM1.0048D107
00466168 0048D114 MM1.0048D114
0046616C 0048D121 MM1.0048D121
00466170 0048D12E MM1.0048D12E
00466174 0048D13B MM1.0048D13B
00466178 0048D148 MM1.0048D148
0046617C 0048D155 MM1.0048D155
00466180 0048D162 MM1.0048D162
00466184 0048D16F MM1.0048D16F
00466188 0048D17C MM1.0048D17C
0046618C 0048D189 MM1.0048D189
00466190 0048D196 MM1.0048D196
00466194 0048D1A3 MM1.0048D1A3
00466198 0048D1B0 MM1.0048D1B0
0046619C 0048D1BD MM1.0048D1BD
004661A0 00000000
004661A4 0048D1CA MM1.0048D1CA
004661A8 0048D1D7 MM1.0048D1D7
004661AC 0048D1E4 MM1.0048D1E4
004661B0 0048D1F1 MM1.0048D1F1
004661B4 00000000
004661B8 77DA7ABB advapi32.RegQueryValueExA
004661BC 77DA7852 advapi32.RegOpenKeyExA
004661C0 77DA6C27 advapi32.RegCloseKey
004661C4 00000000
004661C8 770F4880 oleaut32.SysFreeString
004661CC 770FA3EC oleaut32.SysReAllocStringLen
004661D0 770F4B39 oleaut32.SysAllocStringLen
004661D4 00000000
004661D8 0048D1FE MM1.0048D1FE
004661DC 0048D20B MM1.0048D20B
这就是被处理后的IAT的,看到有一 些函数被处理了,有一些函数没被处理。
我们跟一个看看吧。这里选择笫一个 0048D010。到0048D010去新建个EIP
看到这是是一段重复的差 不多的代码
我们F7单步走
当我们走到 0048D01C这里的时候我们发现栈顶中出现了真实的API地址
它这里是先push了一个值支栈顶, 然后把这个值和另外一个值进行异或不得到了真实函数的地址.
我们再跟一个函数看下是不是也是这 样,我们就跟笫二个0048D01D,吧,在0048D01D新建EIP,然后跟
发现当走到retn的时候又出现了真 实API的函数地址。
那么我们只要每个函数都这个跟一下到 retn的时候再把栈顶的真实地址写回IAT里,这样就能得找正确的IAT了。
这样手动一个个跟估计我 会xx掉,那 么我们就用脚本来帮我人来完成这个工作
