iy0507 发表于 2010-4-27 16:10

UPX+未知RCData资源压缩壳 脱壳逆向

本帖最后由 iy0507 于 2010-5-11 16:03 编辑

UPX+未知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:
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:,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:,AL
00401011    C087 45D9C086 5>ROL BYTE PTR DS:,55
00401018    99            CDQ
00401019    C083 03B8ACF5 2>ROL BYTE PTR DS:,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:,AL
00401011    C087 45D9C086 5>ROL BYTE PTR DS:,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:,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:,EAX
0056C8EA    B8 DAC7C42A   MOV EAX,2AC4C7DA
0056C8EF    8946 04         MOV DWORD PTR DS:,EAX
0056C8F2    B8 B6ACE324   MOV EAX,24E3ACB6
0056C8F7    8946 08         MOV DWORD PTR DS:,EAX
0056C8FA    B8 B7C18645   MOV EAX,4586C1B7
0056C8FF    8946 0C         MOV DWORD PTR DS:,EAX
0056C902    B8 D9C08745   MOV EAX,4587C0D9
0056C907    8946 10         MOV DWORD PTR DS:,EAX
0056C90A    B8 D9C08655   MOV EAX,5586C0D9
0056C90F    8946 14         MOV DWORD PTR DS:,EAX
0056C912    B8 99C08303   MOV EAX,383C099
0056C917    8946 18         MOV DWORD PTR DS:,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:,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:,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:
004C4ED9    8B00            MOV EAX,DWORD PTR DS:
004C4EDB    E8 CCABF9FF   CALL 0045FAAC
004C4EE0    A1 F86D4C00   MOV EAX,DWORD PTR DS:
004C4EE5    8B00            MOV EAX,DWORD PTR DS:
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++语言特有的。
                                                                            2010年4月26日17:27:45
                                                                           by:Howlet

作者回复了,是他调试软件时修改日期后忘记修改回来
然后直接使用搜狗输入日期,才造成错误日期,呵呵

CHHSun 发表于 2010-4-27 21:01

2010年5月26日17:27:45
                                                                           by:Howlet

你这超前的文在哪找的,准不?
页: [1]
查看完整版本: UPX+未知RCData资源压缩壳 脱壳逆向