UPX脱壳详细分析

UPX脱壳详细分析文章标题】:UPX脱壳详细分析【文章作者】:index09【使用工具】:UPX+OD+Stud_PE+ImportREC——————————————————————————–【详细过程】又被R公司鄙视了,每次都被相同的理由鄙视。哭……于是决定好好学一下逆向了。首先做个幼儿级的脱壳练习,当做开始吧。网上有很多类似文章,基本只写了找OEP的过程,这里稍加分

大家好,又见面了,我是你们的朋友全栈君。

文章标题】: UPX脱壳详细分析
【文章作者】: index09
【使用工具】: UPX + OD + Stud_PE + Import REC
——————————————————————————–
【详细过程】
又被R公司鄙视了,每次都被相同的理由鄙视。哭……
于是决定好好学一下逆向了。
首先做个幼儿级的脱壳练习,当做开始吧。
网上有很多类似文章,基本只写了找OEP的过程,这里稍加分析,高手莫笑。

用UPX加密记事本,简单用Stud_PE查看一下节表信息。
No | Name      | VSize      | VOffset    | RSize      | ROffset    | Charact.   |
01 | UPX0      | 0000F000   | 00001000   | 00000000   | 00000400   | E0000080   |
02 | UPX1      | 00005000   | 00010000   | 00004600   | 00000400   | E0000040   |
03 | .rsrc     | 00008000   | 00015000   | 00007200   | 00004A00   | C0000040   |
看样子没有加密资源

OD载入后如下
01014241   . BE 00000101   MOV ESI,NOTEPAD.01010000                 ; esi = sec upx1
01014246   . 8DBE 0010FFFF LEA EDI,DWORD PTR DS:[ESI+FFFF1000]      ; edi = sec upx0
0101424C   . 57            PUSH EDI
0101424D   . 83CD FF       OR EBP,FFFFFFFF
01014250   . EB 10         JMP SHORT NOTEPAD.01014262
分别把 UPX1和UPX0节的首地址放入了esi和edi
上面看到UPX0段的RSize为0,猜想是释放解压数据的空间。而UPX1段应该就是加密的程序代码了。

继续向下看
01014258   > /8A06          MOV AL,BYTE PTR DS:[ESI]                 ; //
0101425A   . |46            INC ESI
0101425B   . |8807          MOV BYTE PTR DS:[EDI],AL
0101425D   . |47            INC EDI
0101425E   > |01DB          ADD EBX,EBX
01014260   . |75 07         JNZ SHORT NOTEPAD.01014269               ; express data in sec upx1 to sec upx0
01014262   > |8B1E          MOV EBX,DWORD PTR DS:[ESI]
01014264   . |83EE FC       SUB ESI,-4
01014267   . |11DB          ADC EBX,EBX
01014269   >^/72 ED         JB SHORT NOTEPAD.01014258
0101426B   . B8 01000000   MOV EAX,1
01014270   > 01DB          ADD EBX,EBX
01014272   . 75 07         JNZ SHORT NOTEPAD.0101427B
01014274   . 8B1E          MOV EBX,DWORD PTR DS:[ESI]
01014276   . 83EE FC       SUB ESI,-4
01014279   . 11DB          ADC EBX,EBX

…….

0101431A   > /8A07          MOV AL,BYTE PTR DS:[EDI]                 ; /
0101431C   . |47            INC EDI
0101431D   . |2C E8         SUB AL,0E8                               ; find [edi] <= 0xE9 && [edi+1] == 1
0101431F   > |3C 01         CMP AL,1
01014321   .^ 77 F7         JA SHORT NOTEPAD.0101431A
01014323   . |803F 01       CMP BYTE PTR DS:[EDI],1
01014326   .^/75 F2         JNZ SHORT NOTEPAD.0101431A               ; …………………….
01014328   . 8B07          MOV EAX,DWORD PTR DS:[EDI]
0101432A   . 8A5F 04       MOV BL,BYTE PTR DS:[EDI+4]
0101432D   . 66:C1E8 08    SHR AX,8
01014331   . C1C0 10       ROL EAX,10                               ; edi = A B C D
01014334   . 86C4          XCHG AH,AL                               ; eax = 0 C B A
01014336   . 29F8          SUB EAX,EDI
01014338   . 80EB E8       SUB BL,0E8
0101433B   . 01F0          ADD EAX,ESI                              ; eax = edi offset to sec upx0 + eax
0101433D   . 8907          MOV DWORD PTR DS:[EDI],EAX
0101433F   . 83C7 05       ADD EDI,5
01014342   . 88D8          MOV AL,BL
01014344   .^ E2 D9         LOOPD SHORT NOTEPAD.0101431F             ; …………………………………….
一大堆都是从UPX1中读取数据,做一些处理,并且放入UPX0中。
应该是UPX的解压算法。具体算法比较复杂没有详细的分析。
里面的EBX控制了每一步解压应该做的操作,十分好奇这个数是怎么出来的。改天看看UPX的源代码,看看它神奇的压缩算法。
看雪上有一篇对算法的分析,有兴趣请自行搜索。

然后来到了这里
01014346   . 8DBE 00200100 LEA EDI,DWORD PTR DS:[ESI+12000]         ; //IAT
0101434C   > 8B07          MOV EAX,DWORD PTR DS:[EDI]               ; edi = upx import table??
0101434E   . 09C0          OR EAX,EAX
01014350   . 74 3C         JE SHORT NOTEPAD.0101438E                ; jmp out
01014352   . 8B5F 04       MOV EBX,DWORD PTR DS:[EDI+4]
01014355   . 8D8430 24AE01>LEA EAX,DWORD PTR DS:[EAX+ESI+1AE24]     ; eax = lib name
0101435C   . 01F3          ADD EBX,ESI                              ; ebx = esi + 4-7 (ori IAT??)
0101435E   . 50            PUSH EAX
0101435F   . 83C7 08       ADD EDI,8
01014362   . FF96 ECAE0100 CALL DWORD PTR DS:[ESI+1AEEC]            ; loadlibrary
01014368   . 95            XCHG EAX,EBP                             ; ebp = lib handle
01014369   > 8A07          MOV AL,BYTE PTR DS:[EDI]
0101436B   . 47            INC EDI
0101436C   . 08C0          OR AL,AL
0101436E   .^ 74 DC         JE SHORT NOTEPAD.0101434C
01014370   . 89F9          MOV ECX,EDI
01014372   . 57            PUSH EDI                                 ; proc name
01014373   . 48            DEC EAX
01014374   . F2:AE         REPNE SCAS BYTE PTR ES:[EDI]
01014376   . 55            PUSH EBP                                 ; lib handle
01014377   . FF96 F0AE0100 CALL DWORD PTR DS:[ESI+1AEF0]            ; getprocaddress
0101437D   . 09C0          OR EAX,EAX
0101437F   . 74 07         JE SHORT NOTEPAD.01014388
01014381   . 8903          MOV DWORD PTR DS:[EBX],EAX
01014383   . 83C3 04       ADD EBX,4
01014386   .^ EB E1         JMP SHORT NOTEPAD.01014369               ; ……………………………………..
这里有两重循环,分别从UPX1中读取dll名称,使用LoadLibrary加载入内存。
获得句柄后,再从UPX1中读取相应函数名,使用GetProcAddress获得函数地址。
01014381   . 8903          MOV DWORD PTR DS:[EBX],EAX
这一句将函数地址填入了源程序的IAT,完成了IAT的填充。
从这段代码中可以获得IAT的RVA,为0x10000。记下来留着以后修复IAT时使用。

继续往下
0101438E   > /8BAE F4AE0100 MOV EBP,DWORD PTR DS:[ESI+1AEF4]
01014394   . 8DBE 00F0FFFF LEA EDI,DWORD PTR DS:[ESI-1000]
0101439A   . BB 00100000   MOV EBX,1000
0101439F   . 50            PUSH EAX
010143A0   . 54            PUSH ESP
010143A1   . 6A 04         PUSH 4                                   ; PAGE_EXECUTE_READWRITE
010143A3   . 53            PUSH EBX
010143A4   . 57            PUSH EDI                                 ; set file header to PAGE_EXECUTE_READWRITE
010143A5   . FFD5          CALL EBP                                 ; virtualprotect
010143A7   . 8D87 FF010000 LEA EAX,DWORD PTR DS:[EDI+1FF]
010143AD   . 8020 7F       AND BYTE PTR DS:[EAX],7F                 ; remove sec UPX0 UNINITIALIZED_DATA character
010143B0   . 8060 28 7F    AND BYTE PTR DS:[EAX+28],7F              ; remove sec UPX1 UNINITIALIZED_DATA character
010143B4   . 58            POP EAX
010143B5   . 50            PUSH EAX
010143B6   . 54            PUSH ESP
010143B7   . 50            PUSH EAX
010143B8   . 53            PUSH EBX                                 ; set to old protect
010143B9   . 57            PUSH EDI
010143BA   . FFD5          CALL EBP                                 ; virtualprotect
这里首先使用VirtualProtect把文件头设置为PAGE_EXECUTE_READWRITE,获得文件头的写权限。
然后
010143AD   . 8020 7F       AND BYTE PTR DS:[EAX],7F                 ; remove sec UPX0 UNINITIALIZED_DATA character
010143B0   . 8060 28 7F    AND BYTE PTR DS:[EAX+28],7F              ; remove sec UPX1 UNINITIALIZED_DATA character
去除了节表中UPX0和UPX1段的UNINITIALIZED_DATA属性,完成了节表的初始化。有些版本UPX并没有这段代码。
最后又用VirtualProtect恢复文件头属性。

再往下看是一个大大的JMP
010143CB   .- E9 CD2FFFFF   JMP NOTEPAD.0100739D                     ; jmp to OEP
跳转到OEP

记下OEP的RAV为739D。
使用LoadPE在OEP处Dump出镜像文件。

使用ImportREC修复一下IAT
IAT的起始地址为刚才记下的0x10000,通过观察那段内存得到IAT大小为0x344
在ImportREC的IAT Infos Needed中填入我们获得的信息,便可以成功修复。

测试一下脱出来的镜像,可以正确运行。

当然你可以在找到OEP时直接用OllyDump插件直接脱壳和修复IAT。这里只是为了练手小小的绕了个弯。
有兴趣的同学欢迎交流。

——————————————————————————–

                                                       2009年08月30日 15:59:39

为了您的安全,请只打开来源可靠的网址

打开网站    取消

来自:
http://hi.baidu.com/index09/blog/item/caf196228dc9eefad6cae211.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/161694.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • ASP.Net MVC视图间的跳转

    ASP.Net MVC视图间的跳转发现一个贼坑的地方,比如添加Home控制器,然后在views的home文件夹里添加Index视图和Second视图,在Index视图里想要通过超链接跳转到Second视图,需要这样写:<ahref=”/Home/second”>点击跳转1</a>@*这么写ok*@成功注意!!!!这样写就不行<ahref=”~/Views/Home/second.csh…

    2022年7月21日
    11
  • 河北对口计算机录取分数线_河北对口计算机专科院校名单

    河北对口计算机录取分数线_河北对口计算机专科院校名单技校网专门为您推荐的类似问题答案问题1:2009年河北对口计算机高考分数线360问题2:谁能告诉我湖南职高计算机专业对口升学本科和专科分数线湖南省2010年普通高校职高对口招生录取控制分数线代码专业门类本科专科71师范44820072种植54473养殖52374机电56675电子电工50676计算机55877建筑48278旅游48981…

    2025年11月9日
    4
  • 超声波倒车雷达原理[通俗易懂]

    超声波倒车雷达原理[通俗易懂]汽车倒车中使用的倒车雷达防撞报警系统即是俗称的倒车雷达,在汽车倒车时,超声波倒车雷采用超声波测距原理探测汽车尾部离障碍物的距离,是汽车泊车辅助装置。倒车时,当汽车尾部探测到障碍物时,倒车雷达就实时动态显示离障碍物的距离,达到设定的安全警告值时,倒车雷达立即发出报警声,以警示驾驶员,辅助驾驶员安全倒车。现在大多数都配置有倒车雷达。倒车雷达电路种类较多,本文介绍基于单片机控制的倒车雷达系统,该系统采用…

    2025年10月30日
    3
  • 织梦自定义表单 在线报名 在线预约听语音

    织梦自定义表单 在线报名 在线预约听语音

    2021年9月25日
    52
  • 【重点】kubernetes 排错办法(修改k8s配置,修改docker container)

    【重点】kubernetes 排错办法(修改k8s配置,修改docker container)

    2021年5月13日
    134
  • nginx指令详解_考试说明全解

    nginx指令详解_考试说明全解常见的命令有:nginx-sreopen#重启Nginxnginx-sreload#重新加载Nginx配置文件,然后以优雅的方式重启Nginxnginx-sstop#强制停止Nginx服务nginx-squit#优雅地停止Nginx服务(即处理完所有请求后再停止服务)nginx-t#检测配置文件是否有语法错误,然后退出nginx-?,-h#打开帮助信息nginx-v#显示版本信息并退出nginx-V#显示版本和配置选项信息,然后退出

    2025年5月25日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号