第十五章的15.3介绍了upx壳的四个循环及其作用,接下来我们一个一个的看一下:
循环1
通过代码我们能知道,ecx为循环次数,循环的内容是从edx中读取一个字节放入edi中,这个字节就是节区(upx0)
0042D6FD > /8A02 mov al,byte ptr ds:[edx] ; 将edx放入al
0042D6FF . |42 inc edx ; edx自加
0042D700 . |8807 mov byte ptr ds:[edi],al ; al放入edi
0042D702 . |47 inc edi ; edi自加
0042D703 . |49 dec ecx ; ecx自减
0042D704 .^75 F7 jnz short add_upx.0042D6FD
循环2
循环二就是一个解码循环。当我们运行到0x0042D71D时,可以看在数据窗口处看到压缩后的数据。(前面一部分的乱码)
循环4
0042D746 > /8A07 mov al,byte ptr ds:[edi] ; 循环4
0042D748 . |47 inc edi ; add_upx.0042C008
0042D749 . |08C0 or al,al
0042D74B .^|74 DC je short add_upx.0042D729
0042D74D . |89F9 mov ecx,edi ; add_upx.0042C008
0042D74F . |57 push edi ; add_upx.0042C008
0042D750 . |48 dec eax
0042D751 . |F2:AE repne scas byte ptr es:[edi]
0042D753 . |55 push ebp ; kernel32.7DD60000
0042D754 . |FF96 2CD00200 call dword ptr ds:[esi+0x2D02C] ; kernel32.GetProcAddress
0042D75A . |09C0 or eax,eax
0042D75C . |74 07 je short add_upx.0042D765
0042D75E . |8903 mov dword ptr ds:[ebx],eax
0042D760 . |83C3 04 add ebx,0x4
0042D763 .^EB E1 jmp short add_upx.0042D746
当UPX压缩文件时,它会分析文件的IAT表,然后提出API,形成API列表。
而当UPX解压的时候,会调用GetProcAddress()函数,重新获得API的起始地址,再重新复原IAT表。
所以我们可以看到,UPX存放的文件函数:
至于第三个循环,在《逆向工程核心原理》中,作者写道第三个循环是还原文件原本的call/jmp指令,但在我的upx压缩文件中,我并没有找到第三个循环,我猜测可能是因为UPX版本不同的原因,我的这个UPX的版本是3.04
当以后系统接触到壳的时候,我会再去寻找其中的原因,在这里就先跳过