找回密码
 注册
搜索
热搜: 回贴

乱乱的Softwrap脱壳总结,脱壳,脱壳技术

2010-1-30 18:22| 发布者: admin| 查看: 75| 评论: 0|原作者: 回梦游仙


乱乱的Softwrap脱壳总结,脱壳,脱壳技术
2008年06月23日 星期一 下午 06:06
本文中的程序:http://www.fractalpc.com/resources/SetupFractalPC30.exe

取得完整的输入表:

断点:GetModuleHandleA,普通断点要下在函数末尾,否则会被检测到,当堆栈出现如下内容时,返回:

0012FF98 00459CF5 返回到 FractalP.00459CF5

0012FF9C 00000000

0012FFA0 00B20000

0012FFA4 0012FFE0 指向下一个 SEH 记录的指针

壳会检测单步执行,如果能避开检测的话,会来到这里:

0045B7F6 F6C3 02 test bl, 2

0045B7F9 74 21 je short 0045B81C 这里决定是否把函数代码抽走,改成jmp

0045B7FB FFB5 DF1C0000 push dword ptr [ebp 1CDF]

0045B801 6A 10 push 10

0045B803 50 push eax

0045B804 FFB5 DF1C0000 push dword ptr [ebp 1CDF]

下面是循环的底部:

0045B827 C1E2 02 shl edx, 2

0045B82A 83C6 04 add esi, 4

0045B82D 57 push edi

0045B82E 51 push ecx

0045B82F 6A 03 push 3 push 3,所以每个函数会储存3次

0045B831 59 pop ecx

0045B832 8D7E F4 lea edi, dword ptr [esi-C]

0045B835 F3:AB rep stos dword ptr es:[edi] 这里储存需要用到的函数,数据窗口定位在edi上

0045B837 59 pop ecx

0045B838 5F pop edi

0045B839 35 BB82506D xor eax, 6D5082BB

0045B83E 890413 mov dword ptr [ebx edx], eax

0045B841 ^ E9 58FFFFFF jmp 0045B79E

0045B846 41 inc ecx

0045B847 ^ E9 94FEFFFF jmp 0045B6E0

0045B84C FFB5 E31C0000 push dword ptr [ebp 1CE3] 在这里下断,运行,数据窗口会看见函数列表,复制出来.



然后,找到oep,在oep处中断,把复制出来的输入函数列表挪到原来的输入表的位置,记住每个函数只复制一次就行了,不同的dll中间需要用一行00000000隔开,以利于区分.



壳没有抽取代码,其主要表现形式有三种:

第一种:

CALL [004XXXXX] 变成 CALL [00XXXXXX] 的形式,当然这个形式里面的 00XXXXXX 表现为不同的地址,这里的00XXXXXX是壳里的地址,由于我们跳开了抽取函数代码,所以最后会返回到函数的地址,修复的方法是找到所有这样的地址,然后跟踪一下

进入一个这样的call:

首先传递一些参数:

0045C013 6A 00 push 0

0045C015 9C pushfd

0045C016 50 push eax

0045C017 53 push ebx

0045C018 8B5C24 10 mov ebx, dword ptr [esp 10]

0045C01C 53 push ebx

0045C01D 83EB 06 sub ebx, 6

0045C020 68 E9260000 push 26E9

0045C025 68 0000B300 push 0B30000 变形call

0045C02A C3 retn

来到00B30000,这里通过堆栈,利用产生的另外几个区段的数据计算出函数地址:

00B30000 55 push ebp

00B30001 56 push esi

00B30002 57 push edi

00B30003 51 push ecx

00B30004 52 push edx

00B30005 50 push eax

00B30006 BD 1A994500 mov ebp, 45991A

00B3000B 016C24 18 add dword ptr [esp 18], ebp

00B3000F 2B9D 962A0000 sub ebx, dword ptr [ebp 2A96]

00B30015 8BBD DE2A0000 mov edi, dword ptr [ebp 2ADE]

00B3001B 8B8D DA2A0000 mov ecx, dword ptr [ebp 2ADA]

00B30021 8BC3 mov eax, ebx

00B30023 2B85 D22A0000 sub eax, dword ptr [ebp 2AD2]

00B30029 D3E8 shr eax, cl

00B3002B 8B0487 mov eax, dword ptr [edi eax*4]

00B3002E 8BF0 mov esi, eax

00B30030 81E6 FFFF0000 and esi, 0FFFF

00B30036 C1E8 10 shr eax, 10

00B30039 8BF8 mov edi, eax

00B3003B 8D043E lea eax, dword ptr [esi edi]

00B3003E BA 06639227 mov edx, 27926306

00B30043 D1E8 shr eax, 1

00B30045 8BC8 mov ecx, eax

00B30047 69C9 8466DA44 imul ecx, ecx, 44DA6684

00B3004D 2BD1 sub edx, ecx

00B3004F 8B8D FA2A0000 mov ecx, dword ptr [ebp 2AFA]

00B30055 51 push ecx

00B30056 8B0CC1 mov ecx, dword ptr [ecx eax*8]

00B30059 33CA xor ecx, edx

00B3005B 3BCB cmp ecx, ebx

00B3005D 59 pop ecx

00B3005E 74 0C je short 00B3006C

00B30060 77 05 ja short 00B30067

00B30062 8D78 01 lea edi, dword ptr [eax 1]

00B30065 ^ EB D4 jmp short 00B3003B

00B30067 8D70 FF lea esi, dword ptr [eax-1]

00B3006A ^ EB CF jmp short 00B3003B

00B3006C 8B5C24 1C mov ebx, dword ptr [esp 1C]

00B30070 3354C1 04 xor edx, dword ptr [ecx eax*8 4]

00B30074 0FB61B movzx ebx, byte ptr [ebx]

00B30077 2BD3 sub edx, ebx

00B30079 8BB5 EA2A0000 mov esi, dword ptr [ebp 2AEA]

00B3007F 8B0496 mov eax, dword ptr [esi edx*4]

00B30082 35 67B6BDD0 xor eax, D0BDB667

00B30087 50 push eax

00B30088 8A00 mov al, byte ptr [eax]

00B3008A 04 0F add al, 0F

00B3008C 74 11 je short 00B3009F

00B3008E F6D8 neg al

00B30090 2C 23 sub al, 23

00B30092 74 0B je short 00B3009F

00B30094 FEC8 dec al

00B30096 74 07 je short 00B3009F

00B30098 FEC8 dec al

00B3009A 74 03 je short 00B3009F

00B3009C F8 clc

00B3009D EB 1E jmp short 00B300BD

00B3009F 8B0424 mov eax, dword ptr [esp]

00B300A2 8B00 mov eax, dword ptr [eax]

00B300A4 330424 xor eax, dword ptr [esp]

00B300A7 C1E8 18 shr eax, 18

00B300AA 84C0 test al, al

00B300AC ^ 74 EE je short 00B3009C

00B300AE 8B0424 mov eax, dword ptr [esp]

00B300B1 8A40 01 mov al, byte ptr [eax 1]

00B300B4 34 C3 xor al, 0C3

00B300B6 ^ 74 E4 je short 00B3009C

00B300B8 83C4 04 add esp, 4

00B300BB 50 push eax

00B300BC F9 stc

00B300BD 58 pop eax

00B300BE 73 02 jnb short 00B300C2

00B300C0 33C0 xor eax, eax

00B300C2 50 push eax

00B300C3 5B pop ebx

00B300C4 58 pop eax

00B300C5 5A pop edx

00B300C6 59 pop ecx

00B300C7 5F pop edi

00B300C8 5E pop esi

00B300C9 5D pop ebp

00B300CA 830424 08 add dword ptr [esp], 8

00B300CE C2 0400 retn 4

返回到这里:

0045C00F 5B pop ebx

0045C010 58 pop eax

0045C011 9D popfd

0045C012 C3 retn



这只是其中一种00XXXXXX地址 的 CALL [00XXXXXX] 的返回地址,如果里面的00XXXXXX 不同的话返回地址是不同的,跟一下就知道了,由于已经制造好了一个输入表,因此可以在这里比较输入表和这里的esp的值即产生的函数地址,相同的话,就把这句代码修复好.

比如:401000 call [00XXXXXX] 得到 esp 值是 74142545 而输入表 中 402000的地址也是 74142545 ,那就改成:401000 call [402000],具体操作可以通过path一段代码来自动完成. 第二种情况:

MOV EXX [004XXXXX] 变成 一个call

比如:mov eax, dword ptr [402000] mov EDX, dword ptr [402000] 会变成:call 00XXXXXX ,当然这里的00XXXXXX 也不是唯一的。不过在运行中的表现是一样的。



跟进这个call:

同样先传递一些参数:

0045924A /E9 19270000 jmp 0045B968



0045B968 9C pushfd

0045B969 60 pushad

0045B96A 8B5C24 24 mov ebx, dword ptr [esp 24]

0045B96E 43 inc ebx

0045B96F 53 push ebx

0045B970 83EB 06 sub ebx, 6

0045B973 8BD3 mov edx, ebx

0045B975 68 76200000 push 2076

0045B97A 68 0000B300 push 0B30000 这里同样是变形的call

0045B97F C3 retn



不同的是从这个变形的call返回后来到这样的地址:

此时,ebx是运算得到的函数地址,而edx则决定了MOV EXX [004XXXXX] 中的EXX 是EAX还是EBX或者EDX、EDI、ESI、EPB。



从上到下的顺序是按照寄存器的顺序生成的

EAX 7FFDF000

ECX 0012FA04

EDX 00009164

EBX 00000000

ESP 0012F9E8

EBP 0045991A FractalP.0045991A

ESI 00B300D1

EDI 0012FD6C



0045B9AC 5A pop edx

0045B9AD 8D9402 0A000000 lea edx, dword ptr [edx eax A]

0045B9B4 FFE2 jmp edx

0045B9B6 895C24 1C mov dword ptr [esp 1C], ebx

0045B9BA EB 27 jmp short 0045B9E3

0045B9BC 895C24 18 mov dword ptr [esp 18], ebx

0045B9C0 EB 21 jmp short 0045B9E3

0045B9C2 895C24 14 mov dword ptr [esp 14], ebx

0045B9C6 EB 1B jmp short 0045B9E3

0045B9C8 895C24 10 mov dword ptr [esp 10], ebx

0045B9CC EB 15 jmp short 0045B9E3

0045B9CE 895C24 0C mov dword ptr [esp C], ebx

0045B9D2 EB 0F jmp short 0045B9E3

0045B9D4 895C24 08 mov dword ptr [esp 8], ebx

0045B9D8 EB 09 jmp short 0045B9E3

0045B9DA 895C24 04 mov dword ptr [esp 4], ebx

0045B9DE EB 03 jmp short 0045B9E3

0045B9E0 891C24 mov dword ptr [esp], ebx

0045B9E3 61 popad

0045B9E4 FF4424 04 inc dword ptr [esp 4]

0045B9E8 9D popfd



现在可以在0045B9B4 FFE2 jmp edx 下断点然后根据edx和ebx的值来修复了,或者改成jmp 008D0010到代码处,自动的修复:

例子代码如下:

008D0000 A1 FC018D00 mov eax, dword ptr [8D01FC]

这里的8D01FC处的地址为存放所有存在这种变形call的地址的第一个地址-4

008D0005 83C0 04 add eax, 4

008D0008 A3 FC018D00 mov dword ptr [8D01FC], eax

008D000D FF20 jmp dword ptr [eax]

008D000F 90 nop

008D0010 B9 00500310 mov ecx, 10035000 这里10035000是IAT起始地址,不是前面说的程序的

008D0015 8B01 mov eax, dword ptr [ecx]

008D0017 3BC3 cmp eax, ebx

008D0019 90 nop

008D001A 74 0C je short 008D0028

008D001C 83C1 04 add ecx, 4

008D001F 81F9 B8530310 cmp ecx, 100353B8 这里100353B8是IAT结束地址 4,不是前面说的程序的

008D0025 ^ 75 EE jnz short 008D0015

008D0027 90 nop 这里下断,防止壳产生IAT里没有的函数,不过不会用到。

下面开始根据edx的值判断mov EXX 的修复,其中的值是另外程序的,不是前面的地址,可以根据顺序改过来。

008D0028 81FA 9C250B10 cmp edx, 100B259C

008D002E 75 0F jnz short 008D003F

008D0030 A1 FC018D00 mov eax, dword ptr [8D01FC]

008D0035 8B00 mov eax, dword ptr [eax]

008D0037 C600 A1 mov byte ptr [eax], 0A1

008D003A 8948 01 mov dword ptr [eax 1], ecx

008D003D ^ EB C1 jmp short 008D0000

008D003F 81FA A2250B10 cmp edx, 100B25A2

008D0045 75 11 jnz short 008D0058

008D0047 A1 FC018D00 mov eax, dword ptr [8D01FC]

008D004C 8B00 mov eax, dword ptr [eax]

008D004E 66:C700 8B0D mov word ptr [eax], 0D8B

008D0053 8948 02 mov dword ptr [eax 2], ecx

008D0056 ^ EB A8 jmp short 008D0000

008D0058 81FA A8250B10 cmp edx, 100B25A8

008D005E 75 11 jnz short 008D0071

008D0060 A1 FC018D00 mov eax, dword ptr [8D01FC]

008D0065 8B00 mov eax, dword ptr [eax]

008D0067 66:C700 8B15 mov word ptr [eax], 158B

008D006C 8948 02 mov dword ptr [eax 2], ecx

008D006F ^ EB 8F jmp short 008D0000

008D0071 81FA AE250B10 cmp edx, 100B25AE

008D0077 75 11 jnz short 008D008A

008D0079 A1 FC018D00 mov eax, dword ptr [8D01FC]

008D007E 8B00 mov eax, dword ptr [eax]

008D0080 66:C700 8B1D mov word ptr [eax], 1D8B

008D0085 8948 02 mov dword ptr [eax 2], ecx

008D0088 ^ EB E5 jmp short 008D006F

008D008A 81FA B4250B10 cmp edx, 100B25B4

008D0090 75 11 jnz short 008D00A3

008D0092 A1 FC018D00 mov eax, dword ptr [8D01FC]

008D0097 8B00 mov eax, dword ptr [eax]

008D0099 66:C700 8B25 mov word ptr [eax], 258B

008D009E 8948 02 mov dword ptr [eax 2], ecx

008D00A1 ^ EB E5 jmp short 008D0088

008D00A3 81FA BA250B10 cmp edx, 100B25BA

008D00A9 75 11 jnz short 008D00BC

008D00AB A1 FC018D00 mov eax, dword ptr [8D01FC]

008D00B0 8B00 mov eax, dword ptr [eax]

008D00B2 66:C700 8B2D mov word ptr [eax], 2D8B

008D00B7 8948 02 mov dword ptr [eax 2], ecx

008D00BA ^ EB E5 jmp short 008D00A1

008D00BC 81FA C0250B10 cmp edx, 100B25C0

008D00C2 75 11 jnz short 008D00D5

008D00C4 A1 FC018D00 mov eax, dword ptr [8D01FC]

008D00C9 8B00 mov eax, dword ptr [eax]

008D00CB 66:C700 8B35 mov word ptr [eax], 358B

008D00D0 8948 02 mov dword ptr [eax 2], ecx

008D00D3 ^ EB E5 jmp short 008D00BA

008D00D5 81FA C6250B10 cmp edx, 100B25C6

008D00DB 75 11 jnz short 008D00EE

008D00DD A1 FC018D00 mov eax, dword ptr [8D01FC]

008D00E2 8B00 mov eax, dword ptr [eax]

008D00E4 66:C700 8B3D mov word ptr [eax], 3D8B

008D00E9 8948 02 mov dword ptr [eax 2], ecx

008D00EC ^ EB E5 jmp short 008D00D3

008D00EE - EB FE jmp short 008D00EE 如果没有成功会跳到这里死掉。

运行后,程序可能暂时运行无相应,另外这段代码里没有判断是否读取完所有的变形的call的地址,所以直接用到最后会提示0000000无法读取。



第三种:



call到壳里的某个地址,其地址和第二种的接近,但是不可执行,应该是中间CCCCCCCCC代码的变形,不用理它。



如果程序过期,无法运行并脱壳,可以在这里跳开:

0045BB9B F3:AB rep stos dword ptr es:[edi]

0045BB9D 53 push ebx

0045BB9E 57 push edi

0045BB9F 56 push esi

0045BBA0 FF73 08 push dword ptr [ebx 8]

0045BBA3 56 push esi

0045BBA4 50 push eax

0045BBA5 FFD2 call edx 进入这里

0045BBA7 83C4 0C add esp, 0C

0045BBAA 8985 E9220000 mov dword ptr [ebp 22E9], eax

0045BBB0 5E pop esi

0045BBB1 5F pop edi

0045BBB2 5B pop ebx



10001934 > 55 push ebp ; FractalP.0045991A

10001935 8BEC mov ebp, esp

10001937 83EC 10 sub esp, 10

1000193A 8B45 10 mov eax, dword ptr [ebp 10]

1000193D FF05 E88B0410 inc dword ptr [10048BE8]

10001943 833D E88B0410 0>cmp dword ptr [10048BE8], 2

1000194A 53 push ebx

1000194B 56 push esi

1000194C 57 push edi

1000194D A3 90B50410 mov dword ptr [1004B590], eax

10001952 7C 56 jl short 100019AA

上面NOP掉,没有任何提示,程序就运行了,壳的注册功能已经被废掉了

10001954 E8 286A0200 call 10028381

10001959 8BF0 mov esi, eax



比较乱套,凑合着看吧。辛苦了。


最新评论

QQ|小黑屋|最新主题|手机版|微赢网络技术论坛 ( 苏ICP备08020429号 )

GMT+8, 2024-9-29 21:26 , Processed in 0.266216 second(s), 12 queries , Gzip On, MemCache On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

返回顶部