[作者]aki
[文章题目]SVKP 1.3x -> Pavol Cerven脱壳
[破解过程]
od载入,停在入口
00453000 > 60 pushad
00453001 E8 00000000 call bczp.00453006
00453006 5D pop ebp
00453007 81ED 06000000 sub ebp,6
0045300D EB 05 jmp short bczp.00453014
0045300F B8 49DCCA05 mov eax,5CADC49
00453014 64:A0 23000000 mov al,byte ptr fs:[23]
0045301A EB 03 jmp short bczp.0045301F
插件隐藏od,忽略所以异常,f9运行,停在典型异常处
0012E3B6 6285 1E220000 bound eax,qword ptr ss:[ebp+221E]
0012E3BC EB 02 jmp short 0012E3C0
0012E3BE 0FE88B D1EB02CD psubsb mm1,qword ptr ds:[ebx+CD02EBD1]
0012E3C5 208B C2EB02CD and byte ptr ds:[ebx+CD02EBC2],cl
0012E3CB 208B 8A401600 and byte ptr ds:[ebx+16408A],cl
0012E3D1 008B 89740100 add byte ptr ds:[ebx+17489],cl
因为程序的主文件和一个主dll都加了相同的壳,所以shift+f9后又来到典型异常处,不过这次是dll的异常
0012BD42 6285 1E220000 bound eax,qword ptr ss:[ebp+221E]
0012BD48 EB 02 jmp short 0012BD4C
0012BD4A 0FE88B D1EB02CD psubsb mm1,qword ptr ds:[ebx+CD02EBD1]
0012BD51 208B C2EB02CD and byte ptr ds:[ebx+CD02EBC2],cl
0012BD57 208B 8A401600 and byte ptr ds:[ebx+16408A],cl
再一次shift+f9就运行了。
重新来过,第一次典型异常后下
bp GetModuleHandleA+5
shift+f9断下,取消断点,ctrl+f9返回主程序。
ctrl+f搜索特征码
cmp dword ptr ds:[ebx],2D66B1C5
来到特殊api处理处
071C5784 813B C5B1662D cmp dword ptr ds:[ebx],2D66B1C5
071C578A 0F84 62180000 je 071C6FF2 //jmp 071C57E4跳过特殊处理
071C5790 813B 9404B2D9 cmp dword ptr ds:[ebx],D9B20494
071C5796 0F84 AA1C0000 je 071C7446
071C579C 813B A41A86D0 cmp dword ptr ds:[ebx],D0861AA4
071C57A2 0F84 58210000 je 071C7900
071C57A8 813B 706586B1 cmp dword ptr ds:[ebx],B1866570
071C57AE 0F84 C1240000 je 071C7C75
071C57B4 813B 0E46769B cmp dword ptr ds:[ebx],9B76460E
071C57BA 0F84 36280000 je 071C7FF6
071C57C0 813B DB0793E6 cmp dword ptr ds:[ebx],E69307DB
071C57C6 0F84 76280000 je 071C8042
071C57CC 813B 627B6CA5 cmp dword ptr ds:[ebx],A56C7B62
071C57D2 0F84 BA280000 je 071C8092
071C57D8 813B 664E96BB cmp dword ptr ds:[ebx],BB964E66
071C57DE 0F84 00290000 je 071C80E4
071C57E4 813B 4506D75B cmp dword ptr ds:[ebx],5BD70645 //壳验证函数
071C57EA 0F84 43290000 je 071C8133
071C57F0 813B 0DE0FC1D cmp dword ptr ds:[ebx],1DFCE00D //壳验证函数
071C57F6 0F84 83290000 je 071C817F
071C57FC 813B 31DD0F00 cmp dword ptr ds:[ebx],0FDD31 //壳验证函数
071C5802 0F84 C6290000 je 071C81CE
071C5808 813B 95B75126 cmp dword ptr ds:[ebx],2651B795
071C580E 0F84 132A0000 je 071C8227 //jmp 071C5850
071C5814 813B B482F64B cmp dword ptr ds:[ebx],4BF682B4
071C581A 0F84 582A0000 je 071C8278
071C5820 813B 0F1ACF4C cmp dword ptr ds:[ebx],4CCF1A0F
071C5826 0F84 972A0000 je 071C82C3
071C582C 813B 4A7687DF cmp dword ptr ds:[ebx],DF87764A
071C5832 0F84 FC2D0000 je 071C8634
071C5838 813B B8B8B2FB cmp dword ptr ds:[ebx],FBB2B8B8
071C583E 0F84 56320000 je 071C8A9A
071C5844 813B 8E5D2D57 cmp dword ptr ds:[ebx],572D5D8E
071C584A 0F84 86320000 je 071C8AD6
071C5850 60 pushad
071C5851 8B03 mov eax,dword ptr ds:[ebx]
ctrl+s继续搜索特征码
mov dword ptr ds:[edi],eax
popad
来到普通api处理处
071C5B4D 5F pop edi
071C5B4E 58 pop eax
071C5B4F 8907 mov dword ptr ds:[edi],eax
071C5B51 61 popad
071C5B52 8385 43010200 04 add dword ptr ss:[ebp+20143],4
071C5B59 ^ E9 ADFBFFFF jmp 071C570B
翻转一下改为
popad
mov dword ptr ds:[edi],eax
如果在071C5B4F下断,可以看到api的还原
f9运行,断在dll的典型异常处
下bp GetModuleHandleA+5
shift+f9跳过异常后,ctrl+f9返回
一步:在12ffb0下硬件访问word断点,断下两三次后取消,
二步:下tc ebp==12ffc0
断在这里
0041CC8A CC int3
0041CC8B CC int3
0041CC8C 68 08064200 push bczp.00420608
0041CC91 64:A1 00000000 mov eax,dword ptr fs:[0]
0041CC97 50 push eax
0041CC98 8B4424 10 mov eax,dword ptr ss:[esp+10]
0041CC9C 896C24 10 mov dword ptr ss:[esp+10],ebp
0041CCA0 8D6C24 10 lea ebp,dword ptr ss:[esp+10]
0041CCA4 2BE0 sub esp,eax //断在这里
0041CCA6 53 push ebx
0041CCA7 56 push esi
0041CCA8 57 push edi
0041CCA9 8B45 F8 mov eax,dword ptr ss:[ebp-8]
0041CCAC 8965 E8 mov dword ptr ss:[ebp-18],esp
0041CCAF 50 push eax
0041CCB0 8B45 FC mov eax,dword ptr ss:[ebp-4]
0041CCB3 C745 FC FFFFFFFF mov dword ptr ss:[ebp-4],-1
0041CCBA 8945 F8 mov dword ptr ss:[ebp-8],eax
0041CCBD 8D45 F0 lea eax,dword ptr ss:[ebp-10]
0041CCC0 64:A3 00000000 mov dword ptr fs:[0],eax
查看一下运行跟踪
072BEF57 014424 04 add dword ptr ss:[esp+4],eax
072BEF5B 58 pop eax
072BEF5C 83C4 04 add esp,4
072BEF5F - FF6424 FC jmp dword ptr ss:[esp-4] ; bczp.004183E0
004183DB E8 AC480000 call bczp.0041CC8C
0041CC8C 68 08064200 push bczp.00420608
0041CC91 64:A1 00000000 mov eax,dword ptr fs:[0]
0041CC97 50 push eax
0041CC98 8B4424 10 mov eax,dword ptr ss:[esp+10]
0041CC9C 896C24 10 mov dword ptr ss:[esp+10],ebp
0041CCA0 8D6C24 10 lea ebp,dword ptr ss:[esp+10]
0041CCA4 2BE0 sub esp,eax
我们到004183DB看看
004183D4 90 nop
004183D5 90 nop
004183D6 90 nop
004183D7 90 nop
004183D8 90 nop
004183D9 90 nop
004183DA 90 nop
004183DB E8 AC480000 call bczp.0041CC8C //伪oep
004183E0 BF 94000000 mov edi,94
根据堆栈补上stolen code后入口
004183D4 6A 60 push 60
004183D6 68 A0EA4300 push bczp.0043EAA0
004183DB E8 AC480000 call bczp.0041CC8C
004183E0 BF 94000000 mov edi,94
lordpe选中这个进程,correct imagesize后dump下来
importrec选中(注意打开调试选项),选中这个进程
oep:183d4
自动搜索iat,getimport后有一个不能识别,看了一下在kernel32里没有ExitProcess,应该就是这个了
修复后运行dumped_.exe出错,提示不能识别mirdll.dll里的GetVT函数。因为这个dll也是用SVKP 1.3x 加的壳,所以看不到输出表,cut这个api后重新修复一下,还是出错
跟到这里
0012FE2C ^\E2 FA loopd short 0012FE28
0012FE2E 59 pop ecx
0012FE2F 5E pop esi
0012FE30 FF15 A96B4000 call dword ptr ds:[406BA9] //指向壳
0012FE36 81C4 70000000 add esp,70
这是在堆栈中运行,重新运行dumped_跟踪一下
00406968 52 push edx
00406969 51 push ecx
0040696A 81F1 00B96E98 xor ecx,986EB900
00406970 81F2 547E69CB xor edx,CB697E54
00406976 51 push ecx
00406977 52 push edx
00406978 89E2 mov edx,esp
0040697A 81F1 00B9D400 xor ecx,0D4B900
00406980 01CA add edx,ecx
00406982 52 push edx
00406983 C3 retn //跳到堆栈解码
跟踪原程序,写一段修复代码
004368D4 90 nop
004368D5 90 nop
004368D6 8BFE mov edi,esi
004368D8 BB B24ABE39 mov ebx,39BE4AB2
004368DD 57 push edi
004368DE 51 push ecx
004368DF AC lods byte ptr ds:[esi]
004368E0 33D9 xor ebx,ecx
004368E2 32C7 xor al,bh
004368E4 D2C8 ror al,cl
004368E6 32C3 xor al,bl
004368E8 AA stos byte ptr es:[edi]
004368E9 ^ E2 F4 loopd short 4.004368DF
004368EB 59 pop ecx
004368EC 5F pop edi
004368ED C605 D5684300 00 mov byte ptr ds:[4368D5],0
004368F4 C3 retn
另一个地方还有这么一处
0040760F 52 push edx
00407610 89E1 mov ecx,esp
00407612 81F2 BE7D7640 xor edx,40767DBE
00407618 01D1 add ecx,edx
0040761A - FFE1 jmp ecx //跳到堆栈执行
0040761C 50 push eax
0040761D 25 A36F44CC and eax,CC446FA3
0012FE08 8BF7 mov esi,edi
0012FE0A 0150 1E add dword ptr ds:[eax+1E],edx
0012FE0D 8978 2A mov dword ptr ds:[eax+2A],edi
0012FE10 32C0 xor al,al
0012FE12 FF15 75234000 call dword ptr ds:[402375] ; 指向壳
同样来一段修复代码
004368F9 90 nop
004368FA C605 F6684300 01 mov byte ptr ds:[4368F6],1
00436901 8BFE mov edi,esi
00436903 BB B24ABE39 mov ebx,39BE4AB2
00436908 84C0 test al,al
0043690A 74 31 je short 4.0043693D
0043690C 51 push ecx
0043690D 57 push edi
0043690E BF 9A694300 mov edi,4.0043699A
00436913 B9 C8000000 mov ecx,0C8
00436918 8BC6 mov eax,esi
0043691A F2:AF repne scas dword ptr es:[edi]
0043691C 33C0 xor eax,eax
0043691E A3 9A694300 mov dword ptr ds:[43699A],eax
00436923 5F pop edi
00436924 59 pop ecx
00436925 AC lods byte ptr ds:[esi]
00436926 33D9 xor ebx,ecx
00436928 32C3 xor al,bl
0043692A D2C0 rol al,cl
0043692C 32C7 xor al,bh
0043692E AA stos byte ptr es:[edi]
0043692F ^ E2 F4 loopd short 4.00436925
00436931 C605 F6684300 00 mov byte ptr ds:[4368F6],0
00436938 C3 retn
00436939 90 nop
0043693A 90 nop
0043693B 90 nop
0043693C 90 nop
0043693D 51 push ecx
0043693E 57 push edi
0043693F BF 9A694300 mov edi,4.0043699A
00436944 B9 C8000000 mov ecx,0C8
00436949 8BC6 mov eax,esi
0043694B F2:AF repne scas dword ptr es:[edi]
0043694D BF 9A694300 mov edi,4.0043699A
00436952 B9 C8000000 mov ecx,0C8
00436957 33C0 xor eax,eax
00436959 F2:AF repne scas dword ptr es:[edi]
0043695B 8935 9A694300 mov dword ptr ds:[43699A],esi
00436961 5F pop edi
00436962 59 pop ecx
00436963 51 push ecx
00436964 57 push edi
00436965 AC lods byte ptr ds:[esi]
00436966 33D9 xor ebx,ecx
00436968 32C7 xor al,bh
0043696A D2C8 ror al,cl
0043696C 32C3 xor al,bl
0043696E AA stos byte ptr es:[edi]
0043696F ^ E2 F4 loopd short 4.00436965
00436971 C605 F6684300 00 mov byte ptr ds:[4368F6],0
00436978 5F pop edi
00436979 59 pop ecx
0043697A C3 retn
0043697B 90 nop
改好了保存一下,用winhex修改这两个指针
[00406BA9]=004368D6
[00402375]=004368FA
改过后程序还是不能运行,跟踪一下发现这里有问题
00422B0E CC int3
00422B0F CC int3
00422B10 - FF25 00734300 jmp dword ptr ds:[437300]
00422B16 - FF25 FC754300 jmp dword ptr ds:[<&wgs.RUN>] ; wgs.RUN
00422B1C - FF25 F8754300 jmp dword ptr ds:[<&wgs.LOAD>] ; wgs.LOAD
00422B22 56 push esi
jmp dword ptr ds:[437300] 应当是指向mirdll里的输出函数GetVT,前面说了,这个dll加了壳导致在修复输入表后不能隐式调用,修复这个api然后把dll壳脱了也不行,不知是不是我dll脱的时候出问题了。
没办法,我们自己来吧
找一段空地,我们找到00436E3A
00422B10 - FF25 00734300 jmp dword ptr ds:[437300]
改为
00422B10 /E9 25430100 jmp d1.00436E3A
00422B15 |90 nop
看一下要用的api的地址
0003720C kernel32.dll 0191 GetProcAddress
00037208 kernel32.dll 023B LoadLibraryA
补充的代码
00436E3A 60 pushad
00436E3B 68 C8624400 push d1.004462C8 ; ASCII "mirdll.dll"
00436E40 FF15 08724300 call dword ptr ds:[<&kernel32.LoadLibraryA>] ; kernel32.LoadLibraryA
00436E46 68 D8624400 push d1.004462D8 ; ASCII "GetVT"
00436E4B 50 push eax
00436E4C FF15 0C724300 call dword ptr ds:[<&kernel32.GetProcAddress>] ; kernel32.GetProcAddress
00436E52 A3 00734300 mov dword ptr ds:[437300],eax
00436E57 61 popad
00436E58 - FF25 00734300 jmp dword ptr ds:[437300]
00436E5E 90 nop
用winhex在这里写入我们要用的字串
004462C8 6472696D mird
004462CC 642E6C6C ll.d
004462D0 00006C6C ll..
004462D4 00000000 ....
004462D8 56746547 GetV
004462DC 00000054 T...
按照文章中的过程,前面的都没有错,直到下tc ebp==12ffc0回车后,程序不动,是按F9执行还是回车后他就会到目标,结果按两次F9后,弹出窗口说出错,然后结束掉了,请帮助!
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)