-
-
[旧帖] [转帖]初涉脱壳之upx 0.00雪花
-
发表于: 2009-6-30 01:25 1148
-
转自http://hi.baidu.com/lovelygfj/blog/item/048e0e3cdd928fe93d6d97e7.html
初涉脱壳,
UPX算是比较简单的。
最简单的拖法是ESP定律,
说一下ESP定律的用法,
1,OD载入,报错时不继续。来到最初的代码:
0040E8C0 > 60 pushad
0040E8C1 BE 15B04000 mov esi, 0040B015
0040E8C6 8DBE EB5FFFFF lea edi, dword ptr [esi+FFFF5FEB]
0040E8CC 57 push edi
2,F8单步一次,执行 pushad,这时会发现ESP堆栈内出现 0012FFA4 这个地址。
3,在ESP对堆栈内点右键=》数据窗口中跟随=》在数据窗口0012FFA4 这里选4个字节的数据,08 02 93 7C,右键=》断点=》硬件访问=》word
4,F9运行程序,断在:
0040EA0F - E9 B826FFFF jmp 004010CC 《= 断在这里
0040EA14 0000 add byte ptr [eax], al
5,F8单步执行,跳到:
004010CC 55 push ebp
004010CD 8BEC mov ebp, esp
因为我用的是记事本程序加壳,所以入口点为004010CC,在此脱壳,脱壳后用Import Rec修复输入表。
注:在使用Import Rec修复时,需先运行未脱壳的源程序,入口点输入10CC,为什么输入10CC呢?因为00400000是基址,故004010CC-00400000=10CC。
修复后程序可运行,脱壳成功。
----------------------------------------------------
方法2:
Peid直接脱壳
Peid是一款查壳软件,但可以增加插件,插件中就有脱壳插件。
我的Peid是0.95带脱壳插件的,故用Peid载入加壳记事本文件。
显示为UPX 0.89.6 - 1.02 / 1.05 - 2.90 -> Markus & Laszlo
点插件=》Generic Unpacker=》让Peid自动找OEP入口点,找到004010CC=》点Unpack=》选择存放地址=》程序询问是否用Imprt Rec插件修复输入表=》选是。
ok,脱壳完成。使用import rec插件对简单的壳都有效,不过有些壳仍需手动重建输入表。
--------------------------------------------------------
方法3 手动跟踪
脱壳一般来说是使程序向前走,不让其向回跳转。
本着这个原则,遇到回跳时,需选择跳转的下一句,按F4执行到次。
遇到大跳,若未实现时,可手动让其实现,方法为:遇到未实现的跳转,按回车进入,再按F4使程序运行至此。
0040E8C0 > 60 pushad ; 程序开始
0040E8C1 BE 15B04000 mov esi, 0040B015
0040E8C6 8DBE EB5FFFFF lea edi, dword ptr [esi+FFFF5FEB]
0040E8CC 57 push edi
0040E8CD 83CD FF or ebp, FFFFFFFF
0040E8D0 EB 10 jmp short 0040E8E2 ; 跳转成功
来到
0040E8E2 8B1E mov ebx, dword ptr [esi]
0040E8E4 83EE FC sub esi, -4
0040E8E7 11DB adc ebx, ebx
0040E8E9 ^ 72 ED jb short 0040E8D8 ; 回跳,不能跳
0040E8EB B8 01000000 mov eax, 1 ; 选这里,按F4
0040E8F0 01DB add ebx, ebx
0040E8F2 75 07 jnz short 0040E8FB ; 跳转成功
来到
0040E8E2 8B1E mov ebx, dword ptr [esi]
0040E8E4 83EE FC sub esi, -4
0040E8E7 11DB adc ebx, ebx
0040E8E9 ^ 72 ED jb short 0040E8D8 ; 回跳,不能跳
0040E8EB B8 01000000 mov eax, 1 ; 选这里,按F4
0040E8F0 01DB add ebx, ebx
0040E8F2 75 07 jnz short 0040E8FB ; 跳转成功
0040E8F4 8B1E mov ebx, dword ptr [esi]
0040E8F6 83EE FC sub esi, -4
0040E8F9 11DB adc ebx, ebx
0040E8FB 11C0 adc eax, eax
0040E8FD 01DB add ebx, ebx
0040E8FF ^ 73 EF jnb short 0040E8F0 ; 回跳,但未实现,忽略
0040E901 75 09 jnz short 0040E90C ; 跳转成功
0040E903 8B1E mov ebx, dword ptr [esi]
0040E905 83EE FC sub esi, -4
0040E908 11DB adc ebx, ebx
0040E90A ^ 73 E4 jnb short 0040E8F0
0040E90C 31C9 xor ecx, ecx ; 跳到这里
0040E90E 83E8 03 sub eax, 3
0040E911 72 0D jb short 0040E920 ; 向下跳
0040E913 C1E0 08 shl eax, 8
0040E916 8A06 mov al, byte ptr [esi]
0040E918 46 inc esi
0040E919 83F0 FF xor eax, FFFFFFFF
0040E91C 74 74 je short 0040E992
0040E91E 89C5 mov ebp, eax
0040E920 01DB add ebx, ebx ; 到这里
0040E922 75 07 jnz short 0040E92B ; 向下跳
来到
0040E92B 11C9 adc ecx, ecx ; 跳到这里
0040E92D 01DB add ebx, ebx
0040E92F 75 07 jnz short 0040E938 ; 向下跳
0040E931 8B1E mov ebx, dword ptr [esi]
0040E933 83EE FC sub esi, -4
0040E936 11DB adc ebx, ebx
0040E938 11C9 adc ecx, ecx ; 到这里
0040E93A 75 20 jnz short 0040E95C ; 向下跳
来到
0040E95C 81FD 00F3FFFF cmp ebp, -0D00 ; 到这里
0040E962 83D1 01 adc ecx, 1
0040E965 8D142F lea edx, dword ptr [edi+ebp]
0040E968 83FD FC cmp ebp, -4
0040E96B 76 0F jbe short 0040E97C ; 向下跳未实现,让其实现
0040E96D 8A02 mov al, byte ptr [edx]
0040E96F 42 inc edx
0040E970 8807 mov byte ptr [edi], al
0040E972 47 inc edi
0040E973 49 dec ecx
0040E974 ^ 75 F7 jnz short 0040E96D
0040E976 ^ E9 63FFFFFF jmp 0040E8DE
0040E97B 90 nop
0040E97C 8B02 mov eax, dword ptr [edx] ; 到这里,让其实现因为中间跨过了两个回跳
0040E97E 83C2 04 add edx, 4
0040E981 8907 mov dword ptr [edi], eax
0040E983 83C7 04 add edi, 4
0040E986 83E9 04 sub ecx, 4
0040E989 ^ 77 F1 ja short 0040E97C ; 未成功,忽略
0040E98B 01CF add edi, ecx
0040E98D ^ E9 4CFFFFFF jmp 0040E8DE ; 回跳,运行到下一行
0040E992 5E pop esi ; 到这里
继续
0040E993 89F7 mov edi, esi
0040E995 B9 DD000000 mov ecx, 0DD
0040E99A 8A07 mov al, byte ptr [edi]
0040E99C 47 inc edi
0040E99D 2C E8 sub al, 0E8
0040E99F 3C 01 cmp al, 1
0040E9A1 ^ 77 F7 ja short 0040E99A ; 又是回跳
0040E9A3 803F 00 cmp byte ptr [edi], 0
0040E9A6 ^ 75 F2 jnz short 0040E99A ; 还是回跳
0040E9A8 8B07 mov eax, dword ptr [edi]
0040E9AA 8A5F 04 mov bl, byte ptr [edi+4]
0040E9AD 66:C1E8 08 shr ax, 8
0040E9B1 C1C0 10 rol eax, 10
0040E9B4 86C4 xchg ah, al
0040E9B6 29F8 sub eax, edi
0040E9B8 80EB E8 sub bl, 0E8
0040E9BB 01F0 add eax, esi
0040E9BD 8907 mov dword ptr [edi], eax
0040E9BF 83C7 05 add edi, 5
0040E9C2 89D8 mov eax, ebx
0040E9C4 ^ E2 D9 loopd short 0040E99F ; 继续回跳
0040E9C6 8DBE 00C00000 lea edi, dword ptr [esi+C000]
0040E9CC 8B07 mov eax, dword ptr [edi]
0040E9CE 09C0 or eax, eax
0040E9D0 74 3C je short 0040EA0E ; 大跳,未实现,让其实现
跳到
0040EA0E 61 popad ; 看到这儿了吗
0040EA0F - E9 B826FFFF jmp 004010CC ; 跳回程序入口点
OK至此为止找到程序入口了。。。
单步F8到004010CC,脱壳,修复输入表。
完成。
-----------------------------------------------
UPX属于基本壳,还是十分简单的,本着一条路走到黑不回头的原则,很容易就能找到壳的出口,进而找到OEP(程序入口)。
初涉脱壳,
UPX算是比较简单的。
最简单的拖法是ESP定律,
说一下ESP定律的用法,
1,OD载入,报错时不继续。来到最初的代码:
0040E8C0 > 60 pushad
0040E8C1 BE 15B04000 mov esi, 0040B015
0040E8C6 8DBE EB5FFFFF lea edi, dword ptr [esi+FFFF5FEB]
0040E8CC 57 push edi
2,F8单步一次,执行 pushad,这时会发现ESP堆栈内出现 0012FFA4 这个地址。
3,在ESP对堆栈内点右键=》数据窗口中跟随=》在数据窗口0012FFA4 这里选4个字节的数据,08 02 93 7C,右键=》断点=》硬件访问=》word
4,F9运行程序,断在:
0040EA0F - E9 B826FFFF jmp 004010CC 《= 断在这里
0040EA14 0000 add byte ptr [eax], al
5,F8单步执行,跳到:
004010CC 55 push ebp
004010CD 8BEC mov ebp, esp
因为我用的是记事本程序加壳,所以入口点为004010CC,在此脱壳,脱壳后用Import Rec修复输入表。
注:在使用Import Rec修复时,需先运行未脱壳的源程序,入口点输入10CC,为什么输入10CC呢?因为00400000是基址,故004010CC-00400000=10CC。
修复后程序可运行,脱壳成功。
----------------------------------------------------
方法2:
Peid直接脱壳
Peid是一款查壳软件,但可以增加插件,插件中就有脱壳插件。
我的Peid是0.95带脱壳插件的,故用Peid载入加壳记事本文件。
显示为UPX 0.89.6 - 1.02 / 1.05 - 2.90 -> Markus & Laszlo
点插件=》Generic Unpacker=》让Peid自动找OEP入口点,找到004010CC=》点Unpack=》选择存放地址=》程序询问是否用Imprt Rec插件修复输入表=》选是。
ok,脱壳完成。使用import rec插件对简单的壳都有效,不过有些壳仍需手动重建输入表。
--------------------------------------------------------
方法3 手动跟踪
脱壳一般来说是使程序向前走,不让其向回跳转。
本着这个原则,遇到回跳时,需选择跳转的下一句,按F4执行到次。
遇到大跳,若未实现时,可手动让其实现,方法为:遇到未实现的跳转,按回车进入,再按F4使程序运行至此。
0040E8C0 > 60 pushad ; 程序开始
0040E8C1 BE 15B04000 mov esi, 0040B015
0040E8C6 8DBE EB5FFFFF lea edi, dword ptr [esi+FFFF5FEB]
0040E8CC 57 push edi
0040E8CD 83CD FF or ebp, FFFFFFFF
0040E8D0 EB 10 jmp short 0040E8E2 ; 跳转成功
来到
0040E8E2 8B1E mov ebx, dword ptr [esi]
0040E8E4 83EE FC sub esi, -4
0040E8E7 11DB adc ebx, ebx
0040E8E9 ^ 72 ED jb short 0040E8D8 ; 回跳,不能跳
0040E8EB B8 01000000 mov eax, 1 ; 选这里,按F4
0040E8F0 01DB add ebx, ebx
0040E8F2 75 07 jnz short 0040E8FB ; 跳转成功
来到
0040E8E2 8B1E mov ebx, dword ptr [esi]
0040E8E4 83EE FC sub esi, -4
0040E8E7 11DB adc ebx, ebx
0040E8E9 ^ 72 ED jb short 0040E8D8 ; 回跳,不能跳
0040E8EB B8 01000000 mov eax, 1 ; 选这里,按F4
0040E8F0 01DB add ebx, ebx
0040E8F2 75 07 jnz short 0040E8FB ; 跳转成功
0040E8F4 8B1E mov ebx, dword ptr [esi]
0040E8F6 83EE FC sub esi, -4
0040E8F9 11DB adc ebx, ebx
0040E8FB 11C0 adc eax, eax
0040E8FD 01DB add ebx, ebx
0040E8FF ^ 73 EF jnb short 0040E8F0 ; 回跳,但未实现,忽略
0040E901 75 09 jnz short 0040E90C ; 跳转成功
0040E903 8B1E mov ebx, dword ptr [esi]
0040E905 83EE FC sub esi, -4
0040E908 11DB adc ebx, ebx
0040E90A ^ 73 E4 jnb short 0040E8F0
0040E90C 31C9 xor ecx, ecx ; 跳到这里
0040E90E 83E8 03 sub eax, 3
0040E911 72 0D jb short 0040E920 ; 向下跳
0040E913 C1E0 08 shl eax, 8
0040E916 8A06 mov al, byte ptr [esi]
0040E918 46 inc esi
0040E919 83F0 FF xor eax, FFFFFFFF
0040E91C 74 74 je short 0040E992
0040E91E 89C5 mov ebp, eax
0040E920 01DB add ebx, ebx ; 到这里
0040E922 75 07 jnz short 0040E92B ; 向下跳
来到
0040E92B 11C9 adc ecx, ecx ; 跳到这里
0040E92D 01DB add ebx, ebx
0040E92F 75 07 jnz short 0040E938 ; 向下跳
0040E931 8B1E mov ebx, dword ptr [esi]
0040E933 83EE FC sub esi, -4
0040E936 11DB adc ebx, ebx
0040E938 11C9 adc ecx, ecx ; 到这里
0040E93A 75 20 jnz short 0040E95C ; 向下跳
来到
0040E95C 81FD 00F3FFFF cmp ebp, -0D00 ; 到这里
0040E962 83D1 01 adc ecx, 1
0040E965 8D142F lea edx, dword ptr [edi+ebp]
0040E968 83FD FC cmp ebp, -4
0040E96B 76 0F jbe short 0040E97C ; 向下跳未实现,让其实现
0040E96D 8A02 mov al, byte ptr [edx]
0040E96F 42 inc edx
0040E970 8807 mov byte ptr [edi], al
0040E972 47 inc edi
0040E973 49 dec ecx
0040E974 ^ 75 F7 jnz short 0040E96D
0040E976 ^ E9 63FFFFFF jmp 0040E8DE
0040E97B 90 nop
0040E97C 8B02 mov eax, dword ptr [edx] ; 到这里,让其实现因为中间跨过了两个回跳
0040E97E 83C2 04 add edx, 4
0040E981 8907 mov dword ptr [edi], eax
0040E983 83C7 04 add edi, 4
0040E986 83E9 04 sub ecx, 4
0040E989 ^ 77 F1 ja short 0040E97C ; 未成功,忽略
0040E98B 01CF add edi, ecx
0040E98D ^ E9 4CFFFFFF jmp 0040E8DE ; 回跳,运行到下一行
0040E992 5E pop esi ; 到这里
继续
0040E993 89F7 mov edi, esi
0040E995 B9 DD000000 mov ecx, 0DD
0040E99A 8A07 mov al, byte ptr [edi]
0040E99C 47 inc edi
0040E99D 2C E8 sub al, 0E8
0040E99F 3C 01 cmp al, 1
0040E9A1 ^ 77 F7 ja short 0040E99A ; 又是回跳
0040E9A3 803F 00 cmp byte ptr [edi], 0
0040E9A6 ^ 75 F2 jnz short 0040E99A ; 还是回跳
0040E9A8 8B07 mov eax, dword ptr [edi]
0040E9AA 8A5F 04 mov bl, byte ptr [edi+4]
0040E9AD 66:C1E8 08 shr ax, 8
0040E9B1 C1C0 10 rol eax, 10
0040E9B4 86C4 xchg ah, al
0040E9B6 29F8 sub eax, edi
0040E9B8 80EB E8 sub bl, 0E8
0040E9BB 01F0 add eax, esi
0040E9BD 8907 mov dword ptr [edi], eax
0040E9BF 83C7 05 add edi, 5
0040E9C2 89D8 mov eax, ebx
0040E9C4 ^ E2 D9 loopd short 0040E99F ; 继续回跳
0040E9C6 8DBE 00C00000 lea edi, dword ptr [esi+C000]
0040E9CC 8B07 mov eax, dword ptr [edi]
0040E9CE 09C0 or eax, eax
0040E9D0 74 3C je short 0040EA0E ; 大跳,未实现,让其实现
跳到
0040EA0E 61 popad ; 看到这儿了吗
0040EA0F - E9 B826FFFF jmp 004010CC ; 跳回程序入口点
OK至此为止找到程序入口了。。。
单步F8到004010CC,脱壳,修复输入表。
完成。
-----------------------------------------------
UPX属于基本壳,还是十分简单的,本着一条路走到黑不回头的原则,很容易就能找到壳的出口,进而找到OEP(程序入口)。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
他的文章
看原图
赞赏
雪币:
留言: