1.申请ID:xiaoshitou
2.个人邮箱:747209181@qq.com
3.原创技术文章:未知RCData资源压缩壳 脱壳逆向
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~配置:
操作系统: Windows XP SP2
逆向程序:OptimumJPEG 英文版
逆向工具:OD(OllyDbg),LordPE,ImpREC,PEID,ResHacker,FreeRes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
本人逆向经验不足,有任何披漏请各位指点
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OptimumJPEG是图像像素压缩程序,因为是英文的不习惯,因此想将其汉化
Peid查壳:UPX 0.89.6 - 1.02 / 1.05 - 1.24 -> Markus & Laszlo
OD载入程序,忽略所有异常~
主窗口(CPU窗口)
0056FA90 > 60 PUSHAD ;1、UPX的EP
0056FA91 BE 00904E00 MOV ESI,004E9000 ;2、壳压入一个地址,到时候就得抛出,直接Ctrl+F搜索 popad
0056FA96 8DBE 0080F1FF LEA EDI,DWORD PTR DS:[ESI+FFF18000]
0056FA9C 57 PUSH EDI ; ntdll.7C930738
0056FA9D 83CD FF OR EBP,FFFFFFFF
0056FAA0 EB 10 JMP SHORT 0056FAB2
ESP定律就是压帐与出帐,因此ESP定律也可以
主窗口
0056FBF2 61 POPAD ;3、搜索到这里
0056FBF3 - E9 0814E9FF JMP 00401000 ;4、F2下断,Shift+F9运行到这里 ,F8到OEP(正常时候是到OEP)(或者直接F4)
0056FBF8 10FC ADC AH,BH
0056FBFA 56 PUSH ESI
0056FBFB 0020 ADD BYTE PTR DS:[EAX],AH
主窗口:
00401000 - E9 FBB71600 JMP 0056C800 ;5、程序中断在这里,显然这里不是OEP,不过UPX应该已脱壳了,脱壳看看
00401005 25 A95FB6AC AND EAX,ACB65FA9 ;6、逆向一般做法是:不到OEP不脱壳~
0040100A E3 24 JECXZ SHORT 00401030
0040100C B7 C1 MOV BH,0C1
0040100E 8645 D9 XCHG BYTE PTR SS:[EBP-27],AL
00401011 C087 45D9C086 5>ROL BYTE PTR DS:[EDI+86C0D945],55
00401018 99 CDQ
00401019 C083 03B8ACF5 2>ROL BYTE PTR DS:[EBX+F5ACB803],20
00401020 DD94F4 30BC4DC6 FST QWORD PTR SS:[ESP+ESI*8+C64DBC30>
00401027 45 INC EBP
00401028 F5 CMC
LordPE脱壳,脱壳后程序不能运行!!
使用ImpREC修复吧~
程序基址是00400000,里面OEP就是00401000-00400000=1000
OEP处输入1000,然后点击中断查找IAT,ImpREC提示“无法获取IAT!”
直接运行OptimumJPEG,然后ImpREC选择该程序的进程即可修复
修复后程序可以运行~~到此加载壳程序的OD可以关闭了(不关闭也可以)
Peid查壳:yoda's Protector v1.02 (.dll,.ocx) -> Ashkbiz Danehkar (h) *
是yp壳??不是,从程序PE区段和EP入口(即00401000处开始的代码)指令判断不可能是yp壳,
一般没有脱干净也会出现Peid查壳为yp壳~,点击Peid上的“额外信息”(一般Peid是“>>”)按钮看是那部分没有解码
发现是“熵值”没有解码,即资源被压缩了,使用ResHacker(资源编辑器)看看判断是否正确,
查看字符串程序提示“资源被压缩”,判断还是正确的O(∩_∩)O~。
大家可以使用 freeRes 来释放资源,不过咱们还是来玩玩看程序是怎么解码资源的
OD载入脱壳后可以运行的程序,忽略所有异常
主窗口:
00401000 - E9 FBB71600 JMP 0056C800 ;1、这个JMP向上跳 F8去看看
00401005 25 A95FB6AC AND EAX,ACB65FA9
0040100A E3 24 JECXZ SHORT 00401030
0040100C B7 C1 MOV BH,0C1
0040100E 8645 D9 XCHG BYTE PTR SS:[EBP-27],AL
00401011 C087 45D9C086 5>ROL BYTE PTR DS:[EDI+86C0D945],55
00401018 99 CDQ
主窗口:
0056C800 66:83CD 00 OR BP,0 ;2、到这里,是被加密过的代码,应该开始解码资源了吧?
0056C804 83CF 00 OR EDI,0 ;3、F8跟踪该段代码
0056C807 66:83CC 00 OR SP,0
0056C80B 90 NOP
0056C80C 90 NOP
0056C80D FC CLD
0056C80E 90 NOP
0056C80F E8 25000000 CALL 0056C839
0056C814 53 PUSH EBX
~~~~忽略代码~~~~~
0056C8CD F6C5 01 TEST CH,1
0056C8D0 - 75 FE JNZ SHORT 0056C8D0
0056C8D2 59 POP ECX ; kernel32.7C816FD7
0056C8D3 FC CLD
0056C8D4 90 NOP
0056C8D5 85C9 TEST ECX,ECX
0056C8D7 ^ 0F85 C6FFFFFF JNZ 0056C8A3 ;4、F8到这里,发现这里进行循环解码
0056C8DD C7 ??? ;5、在这里F4,运行到这里,让壳进行完全解码
0056C8DE 19A7 B7E7A71F SBB DWORD PTR DS:[EDI+1FA7E7B7],ESP
0056C8E4 7A 77 JPE SHORT 0056C95D
主窗口
0056C8D0 - 75 FE JNZ SHORT 0056C8D0
0056C8D2 59 POP ECX ; kernel32.7C816FD7
0056C8D3 FC CLD
0056C8D4 90 NOP
0056C8D5 85C9 TEST ECX,ECX
0056C8D7 ^ 0F85 C6FFFFFF JNZ 0056C8A3 ;解码跳
0056C8DD 60 PUSHAD ;6、解码后的代码,压入地址,直接Ctrl+F搜索 popad
0056C8DE BE 00104000 MOV ESI,00401000
0056C8E3 B8 DDD0C645 MOV EAX,45C6D0DD
0056C8E8 8906 MOV DWORD PTR DS:[ESI],EAX
0056C8EA B8 DAC7C42A MOV EAX,2AC4C7DA
0056C8EF 8946 04 MOV DWORD PTR DS:[ESI+4],EAX
0056C8F2 B8 B6ACE324 MOV EAX,24E3ACB6
0056C8F7 8946 08 MOV DWORD PTR DS:[ESI+8],EAX
0056C8FA B8 B7C18645 MOV EAX,4586C1B7
0056C8FF 8946 0C MOV DWORD PTR DS:[ESI+C],EAX
0056C902 B8 D9C08745 MOV EAX,4587C0D9
0056C907 8946 10 MOV DWORD PTR DS:[ESI+10],EAX
0056C90A B8 D9C08655 MOV EAX,5586C0D9
0056C90F 8946 14 MOV DWORD PTR DS:[ESI+14],EAX
0056C912 B8 99C08303 MOV EAX,383C099
0056C917 8946 18 MOV DWORD PTR DS:[ESI+18],EAX
0056C91A 61 POPAD ;7、这里抛出地址
0056C91B E8 00000000 CALL 0056C920 ;8、进去就是OEP?? F7进去
0056C920 5D POP EBP ;9、晕是他下面的代码,这里也不是OEP
0056C921 81ED 05104000 SUB EBP,00401005 ;10、继续F8跟踪
0056C927 8CC9 MOV CX,CS
~~~~~~~~忽略代码~~~~~~~~
0056C975 8618 XCHG BYTE PTR DS:[EAX],BL ;11、F8到这里程序开始跑飞??可能是线程时间检测~?
0056C977 ^ EB FA JMP SHORT 0056C973
推断~:0056C8DD开始后的代码应该是检测代码,咱们碰碰运气,在他返回指令中断,看程序是否跑飞。
如果跑飞并运行程序,说明咱们找OEP的关键在0056C8DD到返回指令(Ret)间。
如果没有跑飞,而且中断在返回指令(Ret)说明咱们就离OEP不远了。
Ctrl+F2重新载入程序,照前面的步伐到 0056C8DD (程序解码后!)然后慢慢向下找返回指令(Ret)~
(或者是Ctrl+F2重新载入程序,Ctrl+D 命令行下命令 HE 0056C8DD (HE:硬件执行断点) Shift+F9中断在0056C8DD,然后慢慢向下找返回指令(Ret)~)
主窗口
0056C8DD 60 PUSHAD ;12、重新运行到这里
0056C8DE BE 00104000 MOV ESI,00401000 ;13、向下查找返回指令(Ret)
0056C8E3 B8 DDD0C645 MOV EAX,45C6D0DD
0056C8E8 8906 MOV DWORD PTR DS:[ESI],EAX
0056C8EA B8 DAC7C42A MOV EAX,2AC4C7DA
~~~~~~忽略代码~~~~~~
0056C9FB ^\E2 FA LOOPD SHORT 0056C9F7
0056C9FD 9D POPFD
0056C9FE 61 POPAD
0056C9FF BF C44E4C00 MOV EDI,004C4EC4
0056CA04 57 PUSH EDI
0056CA05 C3 RET ;14、F2下断 Shift+F9运行中断在这里(直接F4也可以)
;15、程序中断下来了,F8走
主窗口:
004C4EC4 55 PUSH EBP ;16、返回到这里
004C4EC5 8BEC MOV EBP,ESP ;17、根据指令,确认这里是Delphi的OEP
004C4EC7 83C4 F0 ADD ESP,-10
004C4ECA B8 5C4B4C00 MOV EAX,004C4B5C
004C4ECF E8 D01BF4FF CALL 00406AA4
004C4ED4 A1 F86D4C00 MOV EAX,DWORD PTR DS:[4C6DF8]
004C4ED9 8B00 MOV EAX,DWORD PTR DS:[EAX]
004C4EDB E8 CCABF9FF CALL 0045FAAC
004C4EE0 A1 F86D4C00 MOV EAX,DWORD PTR DS:[4C6DF8]
004C4EE5 8B00 MOV EAX,DWORD PTR DS:[EAX]
004C4EE7 BA 3C4F4C00 MOV EDX,004C4F3C ; ASCII "Optimal Jpeg Reduction Module"
004C4EEC E8 A3A7F9FF CALL 0045F694
OK,脱壳吧~~
脱壳修复后,咱们Peid查壳看看:Borland Delphi 6.0 - 7.0
使用ResHacker(资源编辑器)看看资源是否正确解压缩,
查看字符串程序提示“资源被压缩”,晕死了!没办法了,只能使用 freeRes 来释放资源。
freeRes载入脱壳后的程序,Alt+G 选择“释放压缩资源(R)”然后再选“建立可编辑资源(B)”
软件资源完全释放了,想怎么改就怎么改O(∩_∩)O~。
后记
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
经过比较第一次脱壳和第二次脱壳程序确定UPX里面的壳应该是一个压缩Borland公司RCData资源的壳。
第一次脱壳后使用直接使用freeRes来释放资源,在使用ResHacker编辑资源时,发现部分RCData资源无法识别(是主窗口的资源无法识别).
第二次脱壳后使用使用freeRes来释放资源,在使用ResHacker编辑资源时,没有发现RCData资源无法识别的问题。
因此推断UPX里面的壳压缩了RCData资源。RCData资源是Borland公司旗下Delphi和BC++语言特有的。 |