0%

手脱AsPack壳

​ 首先需要找到OEP,我们按照之前说的ESP定律来找,看到PUSHAD后按F7,各个寄存器的初始值被压入到堆栈中了,这里我们可以对这些初始值设置内存或者硬件访问断点,当解密例程读取这些初始值的时候就会断下来,断下来处基本上就在OEP附近了。

​ 在寄存器ESP处右键Follow in Dump,然后将第一个字节或前四个字节设置硬件访问断点,右键breakpoint-Hardware,on access-Dword,然后按F9

image-20211220140915458

​ 发现断在了POPAD指令的下一行,当壳的解密例程读取该值的时候断了下来,紧接着下面就是跳往OEP处

image-20211220141025695

​ 继续按F7单步,就到了OEP处,OD代码解析有误,将代码解析成了数据,右键Analysis-Remove analysis from module,删除掉OD的分析结果,这样就能正常解析了。

image-20211220141338534

解析还不够彻底,再次Analysis-analysis code

image-20211220142249513

​ 然后dump,保险起见我们使用imprec重构输入表

image-20211220142411426

​ 代码中直接有一个GetModuleHandle函数,右键Follow,我们可以看到直接来到了GetModuleHandleA的入口点处,并没有间接跳转(并不是所有的程序调用API函数都是通过间接跳转来实现的)。

​ 这里是通过一个间接CALL来调用API函数的。

​ 显然,4011F4是IAT其中的一项,该内存单元中保存了GetModuleHandleA的入口地址。

image-20211220144406702

image-20211220144622020

​ 如上图,Follow出来的跳转表和之间看到的有所出入,我们直接看M按钮

image-20211220150021566

接着我们在数据窗口中定位到IAT,第二个图是最后一个Dll的IAT项,地址是771xxxxx,现在我们知道了IAT的结束地址是401218,再来看看起始地址

image-20211220150352948

image-20211220150432901

​ 上图中标注起来的颜色前有一部分是10xx或者11xx的地址,明显不属于任何一个DLL,而且这些数值比当前进程空间中分配内存单元中的最小地址(M窗口中现实了最小地址为00010000)还要小。所以这些数值不属于任何一个DLL,也不属于任何一个区段,有可能是壳存放的一些垃圾数据,我们继续往下拉。

​ 我们可以看到一共调用了三个Dll,其余还有一些dll估计是被壳调用的,

image-20211220153539586

​ 我们看一下ntdll的调用,看到这一项的地址为401200,和Kernel32.dll的IAT项混在了一起。我们看看这个Dump窗口中的地址可以看到,kernel32.dll的地址是最靠前的,ntdll是最靠后的,往前拉可以看到,我们的IAT起始地址确实是40119c,与上图一致。

image-20211220153736685

image-20211220154448259

好了,现在我们有了以下三条数据:

OEP = 4000 (RVA)

IAT的起始地址 = 119C (RVA)

IAT的大小 = 401218 - 40119C = 7C。

image-20211220154632198

中间的是垃圾数据,不知道为什么和之前一样第一个userdll也显示No,但是点开+号里面的数据又是对的。

image-20211220154903219

​ 可以看到这里ntdll.dll中分配内存空间的两个函数用kernel32.dll中两个类似的函数HeapAlloc,HeapFree替换掉了。这里日志信息中也提示说这两个函数跟ntdll.dll中的RtlAllocateHeap,RtlFreeHeap完成的功能类似,壳也可以对这些IAT项进行修改和混淆。

image-20211220155159007

​ 现在我们需要剔除掉垃圾数据,即valid显示为NO的项(无效数据),我们单击左边的+号将其展开。

img

单击Show Invalid,显示无效的数据,然后单击鼠标右键选择-Cut thunk(s)(剪切掉)。

img

image-20211220155402523