拿到程序一看,就1m,当即决定日掉.
When I got the program, it was only 1mb, I immediately decided to crack it.
先脱压缩壳
Firstly, unpack.
方法是断VirtualProtect,由于有anti,所以断在当中
The method is to break at VirtualProtect, since there are some anti-debug stuff, I chose to make my breakpoint in the middle of the API.
75AE1DD1 > 8BFF mov edi, edi
75AE1DD3 55 push ebp
75AE1DD4 8BEC mov ebp, esp
75AE1DD6 FF75 14 push dword ptr [ebp+14]
75AE1DD9 FF75 10 push dword ptr [ebp+10]
75AE1DDC FF75 0C push dword ptr [ebp+C]
75AE1DDF FF75 08 push dword ptr [ebp+8]
75AE1DE2 6A FF push -1
75AE1DE4 E8 956F0200 call VirtualProtectEx <--------F2断在这 here looks good, I can see it's parameters too.
75AE1DE9 5D pop ebp
75AE1DEA C2 1000 retn 10
F9几次后,发现数据段解码了,等到
After several F9s, until the data section is decoded.
CTRL+G 401000
分析一下,发现是delphi的
于是根据经验,搜索'VMProtect\0'
It looks like a Delphi program, so I search 'VMProtect\0' to locate OEP.
005E03F8 \0CFF5D00 dd VMProtec.005DFF0C
005E03FC . 68 E6C48BA5 push A58BC4E6
005E0401 . E8 5F240200 call 00602865
005E0406 $ F3:A4 rep movs byte ptr es:[edi], byte ptr>
005E0408 . D1C7 rol edi, 1
005E040A . 5F pop edi
005E040B . F9 stc
005E040C . 8B7C24 50 mov edi, dword ptr [esp+50]
005E0410 . 66:89E6 mov si, sp
005E0413 . 84E6 test dh, ah
005E0415 . C74424 08 1C6>mov dword ptr [esp+8], 530A691C
005E041D . 66:0FBEF3 movsx si, bl
005E0421 . 8B7424 54 mov esi, dword ptr [esp+54]
005E0425 . F7C3 37A57822 test ebx, 2278A537
005E042B . F9 stc
005E042C . FF7424 58 push dword ptr [esp+58]
005E0430 . 9D popfd
005E0431 . 886C24 18 mov byte ptr [esp+18], ch
005E0435 . C60424 D6 mov byte ptr [esp], 0D6
005E0439 . 8D6424 5C lea esp, dword ptr [esp+5C]
005E043D .^ E9 E526FCFF jmp 005A2B27
005E0442 > FF7424 34 push dword ptr [esp+34]
005E0446 . 8F45 00 pop dword ptr [ebp]
005E0449 . 9C pushfd
005E044A . C64424 14 A5 mov byte ptr [esp+14], 0A5
005E044F . 55 push ebp
005E0450 . 8D6424 40 lea esp, dword ptr [esp+40]
005E0454 .- E9 AD010100 jmp 005F0606
005E0459 > 886424 04 mov byte ptr [esp+4], ah
005E045D . 8D6424 24 lea esp, dword ptr [esp+24]
005E0461 . 54 push esp
005E0462 .^ E9 3F45FFFF jmp 005D49A6
005E0467 . C1 67 F3 00 ascii "羐?,0
005E046B 00 db 00
005E046C . FFFFFFFF dd FFFFFFFF
005E0470 . 09000000 dd 00000009
005E0474 . 56 4D 50 72 6>ascii "VMProtect",0
发现OEP
为了省事,先dump一个,不要修复IAT。
这样的程序应该是可以在本机运行的。
OEP found, for convenient sake, I made a dump here, do not repair IAT, and the dumped file should work correctly. (just direct imports)
下一步是去VM,我的目的是破解,并且是不留VM的破解,于是继续。
My next step was to restore all VMed code, since I decided to crack the program, from top to bottom, leave no remains.
So we continue.
从demo版复制相应代码,修正一下数据地址
Copy OEP code from its DEMO version, and fix some data reference addresses.
005E03F8 \0CFF5D00 dd vmp.005DFF0C
005E03FC > $ 55 push ebp
005E03FD . 8BEC mov ebp, esp
005E03FF . 83C4 F4 add esp, -0C
005E0402 . B8 34FF5D00 mov eax, 005DFF34
005E0407 . E8 DC77E2FF call 00407BE8
005E040C . A1 D4515E00 mov eax, dword ptr [5E51D4]
005E0411 . 8B00 mov eax, dword ptr [eax]
005E0413 . E8 3C6DE7FF call 00457154
005E0418 . A1 D4515E00 mov eax, dword ptr [5E51D4]
005E041D . 8B00 mov eax, dword ptr [eax]
005E041F . BA 74045E00 mov edx, 005E0474 ; ASCII "VMProtect"
005E0424 . E8 2F69E7FF call 00456D58
005E0429 . 8B0D F4515E00 mov ecx, dword ptr [5E51F4] ; vmp.005E91E8
005E042F . A1 D4515E00 mov eax, dword ptr [5E51D4]
005E0434 . 8B00 mov eax, dword ptr [eax]
005E0436 . 8B15 5C965700 mov edx, dword ptr [57965C] ; vmp.005796A8
005E043C . E8 2B6DE7FF call 0045716C
005E0441 . 8B0D FC505E00 mov ecx, dword ptr [5E50FC] ; vmp.005E9DC4
005E0447 . A1 D4515E00 mov eax, dword ptr [5E51D4]
005E044C . 8B00 mov eax, dword ptr [eax]
005E044E . 8B15 8C035D00 mov edx, dword ptr [5D038C] ; vmp.005D03D8
005E0454 . E8 136DE7FF call 0045716C
005E0459 . A1 D4515E00 mov eax, dword ptr [5E51D4]
005E045E . 8B00 mov eax, dword ptr [eax]
005E0460 . E8 876DE7FF call 004571EC
005E0465 . E8 E23AE2FF call 00403F4C
005E046A . 0000 add byte ptr [eax], al
005E046C . FFFFFFFF dd FFFFFFFF
005E0470 . 09000000 dd 00000009
005E0474 . 56 4D 50 72 6>ascii "VMProtect",0
这样的文件应该是不能运行的,因为VM没有初始化。
After this, the VM will not be initialized, so none of any other VMed code will work correctly.
修复2处VM掉的代码
Repair two VMed code blocks.
00407B9C /$ 53 push ebx
00407B9D |. 81C4 F8FEFFFF add esp, -108
00407BA3 |. 68 05010000 push 105 ; /BufSize = 105 (261.)
00407BA8 |. 8D4424 04 lea eax, dword ptr [esp+4] ; |
00407BAC |. 50 push eax ; |PathBuffer
00407BAD |. A1 DC645E00 mov eax, dword ptr [5E64DC] ; |
00407BB2 |. 50 push eax ; |hModule => NULL
00407BB3 |. E8 28FFFFFF call ; \GetModuleFileNameA
00407BB8 |. 8BC4 mov eax, esp
00407BBA |. E8 C5EDFFFF call 00406984
00407BBF |. 8BD8 mov ebx, eax
00407BC1 |. 891D 18115E00 mov dword ptr [5E1118], ebx
00407BC7 |. 85DB test ebx, ebx
00407BC9 |. 75 0A jnz short 00407BD5
00407BCB |. A1 0C115E00 mov eax, dword ptr [5E110C]
00407BD0 |. A3 18115E00 mov dword ptr [5E1118], eax
00407BD5 |> B8 08115E00 mov eax, 005E1108
00407BDA |. E8 BDF0FFFF call 00406C9C
00407BDF |. 81C4 08010000 add esp, 108
00407BE5 |. 5B pop ebx
00407BE6 \. C3 retn
00407BE7 90 nop
00407BE8 /$ 50 push eax
00407BE9 |. 6A 00 push 0 ; /pModule = NULL
00407BEB |. E8 F8FEFFFF call ; \GetModuleHandleA
00407BF0 |. BA 08115E00 mov edx, 005E1108
00407BF5 |. 52 push edx
00407BF6 |. 8905 DC645E00 mov dword ptr [5E64DC], eax
00407BFC |. 8942 04 mov dword ptr [edx+4], eax
00407BFF |. C742 08 00000>mov dword ptr [edx+8], 0
00407C06 |. C742 0C 00000>mov dword ptr [edx+C], 0
00407C0D |. E8 8AFFFFFF call 00407B9C
00407C12 |. 5A pop edx
00407C13 |. 58 pop eax
00407C14 |. E8 27C2FFFF call 00403E40
00407C19 \. C3 retn
然后可以在壳段下访问断点,然后从DEMO版里找对应代码,把代码都nop掉。
After this, you can make memory access breakpoints at VM section, and NOP all those calls.
然后根据nag提示知道了选项对应的参数
再然后,跟据正版加壳产生的参数,知道了mask。
Then, look into its unregistered nag screen, and look around, guess what? Options are converted into a parameter into the VM generator, and that is not VMed, so registered or not only affects the calculation of the parameter.
于是重塑代码:
向导模式加壳和专家模式小有不同,方法是参考demo版,在正式版的这个函数后面没VM的某个call里下断,观察esi的值。
So I rebuilt the code by hijacking a call right after the VMed code, and did some tests to figure out the bit mask for all parameters.
最后还原了如下代码:
Then I reproduced the following code;
005D4838 > \66:BE 0800 mov si, 8
005D483C . 90 nop
005D483D . 90 nop
005D483E . 90 nop
005D483F . 837D F4 00 cmp dword ptr [ebp-C], 0
005D4843 . 74 11 je short 005D4856
005D4845 . 66:8B0D 40505>mov cx, word ptr [5D5040]
005D484C . 33D2 xor edx, edx
005D484E . 8B45 F4 mov eax, dword ptr [ebp-C]
005D4851 . E8 1AEBEDFF call 004B3370
005D4856 > 8B45 FC mov eax, dword ptr [ebp-4]
005D4859 . 8B80 EC030000 mov eax, dword ptr [eax+3EC]
005D485F . 8B10 mov edx, dword ptr [eax]
005D4861 . FF92 B4000000 call dword ptr [edx+B4]
005D4867 . 84C0 test al, al
005D4869 . 74 04 je short 005D486F
005D486B . 66:83CE 02 or si, 2
005D486F > 8B45 FC mov eax, dword ptr [ebp-4]
005D4872 . 8B80 F0030000 mov eax, dword ptr [eax+3F0]
005D4878 . 8B10 mov edx, dword ptr [eax]
005D487A . FF92 B4000000 call dword ptr [edx+B4]
005D4880 . 84C0 test al, al
005D4882 . 74 04 je short 005D4888
005D4884 . 66:83CE 04 or si, 4
005D4888 > 8B45 FC mov eax, dword ptr [ebp-4]
005D488B . 8B80 F8030000 mov eax, dword ptr [eax+3F8]
005D4891 . 8B10 mov edx, dword ptr [eax]
005D4893 . FF92 B4000000 call dword ptr [edx+B4]
005D4899 . 84C0 test al, al
005D489B . 74 04 je short 005D48A1
005D489D . 66:83CE 10 or si, 10
005D48A1 > 8B45 FC mov eax, dword ptr [ebp-4]
005D48A4 . 8B80 50050000 mov eax, dword ptr [eax+550]
005D48AA . 8B10 mov edx, dword ptr [eax]
005D48AC . FF92 B4000000 call dword ptr [edx+B4]
005D48B2 . 84C0 test al, al
005D48B4 . 74 04 je short 005D48BA
005D48B6 . 66:83CE 20 or si, 20
005D48BA > 8B45 FC mov eax, dword ptr [ebp-4]
005D48BD . 8B80 F8060000 mov eax, dword ptr [eax+6F8]
005D48C3 . 8B10 mov edx, dword ptr [eax]
005D48C5 . FF92 B4000000 call dword ptr [edx+B4]
005D48CB . 84C0 test al, al
005D48CD . 74 05 je short 005D48D4
005D48CF . 66:81CE 8000 or si, 80
005D48D4 > 8B45 FC mov eax, dword ptr [ebp-4]
005D48D7 . 8B80 F0060000 mov eax, dword ptr [eax+6F0]
005D48DD . 8B10 mov edx, dword ptr [eax]
005D48DF . FF92 B4000000 call dword ptr [edx+B4]
005D48E5 . 84C0 test al, al
005D48E7 . 74 05 je short 005D48EE
005D48E9 . 66:81CE 0001 or si, 100
其他还有很多地方用了vm,不过碰到就nop,只要加壳功能完整就行,管他显示注册给谁的?
There are many other places that are VMed, but we can always refer to DEMO to fix it, and as long as we have all protection features, who cares about what it shows of "Registered to"?
再爆破一下水印数量限制:
Then we fix the watermark count limitation:
005CBF38 /EB 23 jmp short 005CBF5D
结束了,出乎意料的简单吧,谢谢收看。
All done, unexpectedly easy, isn't it? Thanks for reading.
想要跨平台,跑一下IAT修复脚本,再用UIF建一个IAT,就行了。
If you want to fix the direct API references, run my IAT repair script and use UIF to make a new IAT, there you go.
PS: epic fail.
劳资是网盲一点看不懂 希望可以帮助能看懂的人 早点破掉vmp 这样大家都能挂起了