- 帖子
- 49
- 积分
- 182
- 威望
- 270
- 金钱
- 196
- 在线时间
- 1 小时
|
RELOC的深入利用
大家知道RELOC是改壳的利器,使用方法是输入入口点、文件偏移、区段零区域位置、零区域偏移及一个偏移量作为参数。图片教程里说明前四个参数都是使用PEID找到,但所谓“偏移量”却写得相当笼统,只给出了UPX壳的“偏移量”为6
今天,我们就来揭开RELOC的运行机理及“偏移量”的确定方法
使用的例子为UPXSHELL,本身已经加了UPX,我电脑上的UPX全加不了,就用这个吧
入口点A1210 入口点RVA 37610 零区域位置A13C7 文件偏移377C7
004A1210 > 60 pushad
004A1211 BE 00A04600 mov esi,UPXShell.0046A000
004A1216 8DBE 0070F9FF lea edi,dword ptr ds:[esi+FFF97000] ——跳回的地方
004A121C C787 0CF70700 4>mov dword ptr ds:[edi+7F70C],F427AB44
004A1226 57 push edi
004A1227 83CD FF or ebp,FFFFFFFF
004A122A EB 0E jmp short UPXShell.004A123A
004A122C 90 nop
004A122D 90 nop
004A122E 90 nop
004A122F 90 nop
004A1230 8A06 mov al,byte ptr ds:[esi]
004A1232 46 inc esi
004A1233 8807 mov byte ptr ds:[edi],al
004A1235 47 inc edi
004A1236 01DB add ebx,ebx
004A1238 75 07 jnz short UPXShell.004A1241
004A123A 8B1E mov ebx,dword ptr ds:[esi]
004A123C 83EE FC sub esi,-4
004A123F 11DB adc ebx,ebx
004A1241 ^ 72 ED jb short UPXShell.004A1230
这是本身入口处的汇编代码
使用RELOC后的如下
004A1210 > /E9 B2010000 jmp RELOC过d.004A13C7
004A1215 |90 nop
004A1216 |8DBE 0070F9FF lea edi,dword ptr ds:[esi+FFF97000]
004A121C |C787 0CF70700 4>mov dword ptr ds:[edi+7F70C],F427AB44
004A1226 |57 push edi
004A1227 |83CD FF or ebp,FFFFFFFF
这里会跳到
004A13C7 60 pushad
004A13C8 BE 00A04600 mov esi,RELOC过d.0046A000
004A13CD ^ E9 44FEFFFF jmp RELOC过d.004A1216
再跳到
004A1216 8DBE 0070F9FF lea edi,dword ptr ds:[esi+FFF97000] ——跳回的地方
004A121C C787 0CF70700 4>mov dword ptr ds:[edi+7F70C],F427AB44
004A1226 57 push edi
004A1227 83CD FF or ebp,FFFFFFFF
004A122A EB 0E jmp short RELOC过d.004A123A
004A122C 90 nop
004A122D 90 nop
004A122E 90 nop
004A122F 90 nop
004A1230 8A06 mov al,byte ptr ds:[esi]
004A1232 46 inc esi
004A1233 8807 mov byte ptr ds:[edi],al
004A1235 47 inc edi
004A1236 01DB add ebx,ebx
004A1238 75 07 jnz short RELOC过d.004A1241
004A123A 8B1E mov ebx,dword ptr ds:[esi]
004A123C 83EE FC sub esi,-4
004A123F 11DB adc ebx,ebx
004A1241 ^ 72 ED jb short RELOC过d.004A1230
可以得出RELOC改写了原入口点的代码,一个跳转跳到零区域(400000+A13C7=4A13C7)
再在零区域中执行了一部分指令后跳回入口点附近,执行余下应该执行的语句
大家仔细看,在零区域执行了是
004A13C7 60 pushad
004A13C8 BE 00A04600 mov esi,RELOC过d.0046A000
两句指令,一共是1+5=6字节!!
$ ==> > 60 pushad
$+1 > BE 00A04600 mov esi,RELOC过d.0046A000
$+6 前两句指令大小之和 >^ E9 44FEFFFF jmp RELOC过d.004A1216
然后跳回的区域和RELOC处理之前的地址是完全相同的
现在可以判断出RELOC的工作机理为:修改入口处为绝对跳转,跳到你原来设定的零区域,然后把从入口点向下数你所填写的“偏移量”的大小的 数据 移到零区域执行,再跳回剩下的指令
为什么的得出的是移动一定长度“数据”的结论,因为它没有对语句的完整性作检测。比如换了一款壳,还是使用偏移量6进行处理,那么原来的一句语句很可能会被拆成两句,那执行自然会出错,免杀失败了。
接下来来实际操作,先把UPX的壳脱掉(用工具或手脱都可),然后用ASPROTECT这款猛壳压缩一下(大家免杀中使用得比较多,所以以它为例)压缩好了,OD载入,开头几句指令为
00401000 > 68 01604A00 push unpacked.004A6001
00401005 E8 01000000 call unpacked.0040100B
0040100A C3 retn
0040100B C3 retn
0040100C 9A 7FCE2B84 A45>call far 58A4:842BCE7F
语句长度为
$ ==> > 68 01604A00 push unpacked.004A6001
$+5 > E8 01000000 call unpacked.0040100B
$+A > C3 retn
$+B > C3 retn
$+C > 9A 7FCE2B84 A45>call far 58A4:842BCE7F
可以看到
push unpacked.004A6001
call unpacked.0040100B
这两句后是两个连续得RET,不宜改动,可以只移动push unpacked.004A6001一句或两句都移
push unpacked.004A6001一句为5字节
加壳后的程序入口点1000 入口点RVA 1000 零区域位置A33F8 文件偏移3B7F8 偏移量使用5
处理结束后执行,是成功运行的,再OD载入看看
00401000 >- E9 F3230A00 jmp server.004A33F8
00401005 E8 01000000 call server.0040100B
0040100A C3 retn
0040100B C3 retn
第一句是跳转了吧?
好,再试试偏移量A,转换为十进制是10
发现出错了,那就还是使用上一种吧,现在可以得出ASPROTECT壳的偏移量使用5
本人得出的心得是偏移量一般在3-9个字节为宜,不然出错的几率很大
大家确定偏移量只要注意不要把汇编指令误拆分开来,一般都能成功的 |
|