程序带UPX的壳,直接用UPX工具脱壳,也可采用OEP定律,但是不是很完美(不影响分析和调试)。
通过IDA分析,其中form1:主界面;form2:注册框;form3:about页
由于form2的OK按钮灰选,主要的功能由下图可知位于edidchange函数内,也就是更改下方四个的编辑框
启动时判断当前目录下是否存在reg.dat的文件,没有弹出警告
004383DC > $ 55 push ebp
004383DD . 8BEC mov ebp,esp
004383DF . 83C4 F4 add esp,-0xC
004383E2 . B8 E4824300 mov eax,crackme_.004382E4 ;
004383E7 . E8 4CCFFCFF call crackme_.00405338
004383EC . BA 98844300 mov edx,crackme_.00438498 ; Reg.dat
004383F1 . B8 60A74300 mov eax,crackme_.0043A760
004383F6 . E8 67C6FCFF call crackme_.00404A62
004383FB . BA 80000000 mov edx,0x80
00438400 . B8 60A74300 mov eax,crackme_.0043A760
00438405 . E8 87C8FCFF call crackme_.00404C91
0043840A . E8 69A3FCFF call crackme_.00402778
0043840F . 85C0 test eax,eax
00438411 . 74 15 je short crackme_.00438428
00438413 . 6A 00 push 0x0 ; /Style = MB_OK|MB_APPLMODAL
00438415 . 68 A0844300 push crackme_.004384A0 ; |Missing!
0043841A . 68 AC844300 push crackme_.004384AC ; |Hey, where is my little Reg.dat\rI love it so much that I can't\rlive without it. Return it back! Arrgh!
0043841F . 6A 00 push 0x0 ; |hOwner = NULL
00438421 . E8 BED5FCFF call <jmp.&user32.MessageBoxA> ; \MessageBoxA
四个监听函数功能基本一致,就是传入当前修改的id,然后调用用一个函数sub_437D1C
CODE:00437E70 _TForm2_Edit1Change proc near ; DATA XREF: CODE:00437B47↑o
CODE:00437E70 mov eax, 1
CODE:00437E75 call sub_437D1C
CODE:00437E7A retn
CODE:00437E7A _TForm2_Edit1Change endp
CODE:00437E7A
CODE:00437E7A ; ---------------------------------------------------------------------------
CODE:00437E7B align 4
CODE:00437E7C
CODE:00437E7C ; =============== S U B R O U T I N E =======================================
CODE:00437E7C
CODE:00437E7C
CODE:00437E7C _TForm2_Edit2Change proc near ; DATA XREF: CODE:00437B59↑o
CODE:00437E7C mov eax, 2
CODE:00437E81 call sub_437D1C
CODE:00437E86 retn
CODE:00437E86 _TForm2_Edit2Change endp
CODE:00437E86
CODE:00437E7C
CODE:00437E7C _TForm2_Edit2Change proc near ; DATA XREF: CODE:00437B59↑o
CODE:00437E7C mov eax, 2
CODE:00437E81 call sub_437D1C
CODE:00437E86 retn
CODE:00437E86 _TForm2_Edit2Change endp
CODE:00437E86
CODE:00437E86 ; ---------------------------------------------------------------------------
CODE:00437E87 align 4
CODE:00437E88
CODE:00437E88 ; =============== S U B R O U T I N E =======================================
CODE:00437E88
CODE:00437E88
CODE:00437E88 _TForm2_Edit3Change proc near ; DATA XREF: CODE:00437B6B↑o
CODE:00437E88 mov eax, 3
CODE:00437E8D call sub_437D1C
CODE:00437E92 retn
CODE:00437E92 _TForm2_Edit3Change endp
CODE:00437E92
这一段主要是:根据操作执行加或者减,同时将被修改的string转换成int储存起来,然后执行函数sub_437BD8
CODE:00437D1C sub_437D1C proc near ; CODE XREF: _TForm2_Edit1Change+5↓p
CODE:00437D1C ; _TForm2_Edit2Change+5↓p ...
CODE:00437D1C
CODE:00437D1C var_4 = dword ptr -4
CODE:00437D1C
CODE:00437D1C push ebp
CODE:00437D1D mov ebp, esp
CODE:00437D1F push 0
CODE:00437D21 push ebx
CODE:00437D22 mov ebx, eax ; eax button id
CODE:00437D24 xor eax, eax
CODE:00437D26 push ebp
CODE:00437D27 push offset loc_437DEE
CODE:00437D2C push dword ptr fs:[eax]
CODE:00437D2F mov fs:[eax], esp
CODE:00437D32 mov eax, ebx
CODE:00437D34 dec eax
CODE:00437D35 jz short loc_437D45 ; switch id
CODE:00437D37 dec eax
CODE:00437D38 jz short loc_437D69
CODE:00437D3A dec eax
CODE:00437D3B jz short loc_437D8D
CODE:00437D3D dec eax
CODE:00437D3E jz short loc_437DB1
CODE:00437D40 jmp loc_437DD3
CODE:00437D45 ; ---------------------------------------------------------------------------
CODE:00437D45
CODE:00437D45 loc_437D45: ; CODE XREF: sub_437D1C+19↑j
CODE:00437D45 lea edx, [ebp+var_4]
CODE:00437D48 mov eax, ds:dword_43A728
CODE:00437D4D mov eax, [eax+1E8h]
CODE:00437D53 call sub_41D1C0 ; edit control
CODE:00437D58 mov eax, [ebp+var_4]
CODE:00437D5B call sub_406930 ; strToInt
CODE:00437D60 mov ds:dword_43A738[ebx*4], eax
CODE:00437D67 jmp short loc_437DD3
CODE:00437D69 ; ---------------------------------------------------------------------------
CODE:00437D69
CODE:00437D69 loc_437D69: ; CODE XREF: sub_437D1C+1C↑j
CODE:00437D69 lea edx, [ebp+var_4]
CODE:00437D6C mov eax, ds:dword_43A728
CODE:00437D71 mov eax, [eax+1ECh]
CODE:00437D77 call sub_41D1C0
CODE:00437D7C mov eax, [ebp+var_4]
CODE:00437D7F call sub_406930
CODE:00437D84 mov ds:dword_43A738[ebx*4], eax
CODE:00437D8B jmp short loc_437DD3
CODE:00437D8D ; ---------------------------------------------------------------------------
CODE:00437D8D
CODE:00437D8D loc_437D8D: ; CODE XREF: sub_437D1C+1F↑j
CODE:00437D8D lea edx, [ebp+var_4]
CODE:00437D90 mov eax, ds:dword_43A728
CODE:00437D95 mov eax, [eax+1F0h]
CODE:00437D9B call sub_41D1C0 ; editControl
CODE:00437DA0 mov eax, [ebp+var_4]
CODE:00437DA3 call sub_406930 ; strToint
CODE:00437DA8 mov ds:dword_43A738[ebx*4], eax
CODE:00437DAF jmp short loc_437DD3
CODE:00437DB1 ; ---------------------------------------------------------------------------
CODE:00437DB1
CODE:00437DB1 loc_437DB1: ; CODE XREF: sub_437D1C+22↑j
CODE:00437DB1 lea edx, [ebp+var_4]
CODE:00437DB4 mov eax, ds:dword_43A728
CODE:00437DB9 mov eax, [eax+1F4h]
CODE:00437DBF call sub_41D1C0
CODE:00437DC4 mov eax, [ebp+var_4]
CODE:00437DC7 call sub_406930
CODE:00437DCC mov ds:dword_43A738[ebx*4], eax
CODE:00437DD3
CODE:00437DD3 loc_437DD3: ; CODE XREF: sub_437D1C+24↑j
CODE:00437DD3 ; sub_437D1C+4B↑j ...
CODE:00437DD3 call sub_437BD8
CODE:00437DD8 xor eax, eax
CODE:00437DDA pop edx
CODE:00437DDB pop ecx
CODE:00437DDC pop ecx
CODE:00437DDD mov fs:[eax], edx
CODE:00437DE0 push offset loc_437DF5
CODE:00437DE5
CODE:00437DE5 loc_437DE5: ; CODE XREF: sub_437D1C+D7↓j
CODE:00437DE5 lea eax, [ebp+var_4]
CODE:00437DE8 call sub_4036FC
CODE:00437DED retn
先判断注册码的长度不小于5,然后将注册码的每个字符依次对10取整(总共取4个字符,依次是1、3、4、5),然后依次判断每个结果,保证不超过10,否则继续取整,最后一步就是将最终的结果和edit框的数据依次比较,保证每个都相等才表示成功,否则失败。
CODE:00437BD8 push ebp
CODE:00437BD9 mov ebp, esp
CODE:00437BDB push 0
CODE:00437BDD push 0
CODE:00437BDF push ebx
CODE:00437BE0 push esi
CODE:00437BE1 xor eax, eax
CODE:00437BE3 push ebp
CODE:00437BE4 push offset loc_437D0C
CODE:00437BE9 push dword ptr fs:[eax]
CODE:00437BEC mov fs:[eax], esp
CODE:00437BEF lea edx, [ebp+var_4]
CODE:00437BF2 mov eax, ds:dword_43A728
CODE:00437BF7 mov eax, [eax+20Ch]
CODE:00437BFD call sub_41D1C0 ; get code string
CODE:00437C02 mov eax, [ebp+var_4]
CODE:00437C05 call sub_403978 ; string len
CODE:00437C0A cmp eax, 5 ; len >= 5
CODE:00437C0D jl loc_437CC2
CODE:00437C13 mov eax, [ebp+var_4] ; var_4 code string
CODE:00437C16 movzx eax, byte ptr [eax] ; first chr
CODE:00437C19 mov ecx, 0Ah
CODE:00437C1E cdq
CODE:00437C1F idiv ecx ; eax 商 edx 余
CODE:00437C21 mov ds:dword_43A72C, eax
CODE:00437C26 mov eax, [ebp+var_4]
CODE:00437C29 movzx eax, byte ptr [eax+2] ; third chr
CODE:00437C2D mov ecx, 0Ah
CODE:00437C32 cdq
CODE:00437C33 idiv ecx ; same
CODE:00437C35 mov ds:dword_43A730, eax
CODE:00437C3A mov eax, [ebp+var_4]
CODE:00437C3D movzx eax, byte ptr [eax+3] ; four chr
CODE:00437C41 mov ecx, 0Ah
CODE:00437C46 cdq
CODE:00437C47 idiv ecx ; same
CODE:00437C49 mov ds:dword_43A734, eax
CODE:00437C4E mov eax, [ebp+var_4]
CODE:00437C51 movzx eax, byte ptr [eax+4] ; five chr
CODE:00437C55 mov ecx, 0Ah
CODE:00437C5A cdq
CODE:00437C5B idiv ecx ; same
CODE:00437C5D mov ds:dword_43A738, eax
CODE:00437C62 mov esi, 1
CODE:00437C67 mov ebx, offset dword_43A72C ; ebx first result
CODE:00437C6C
CODE:00437C6C loc_437C6C: ; CODE XREF: sub_437BD8+BC↓j
CODE:00437C6C lea edx, [ebp+var_8]
CODE:00437C6F mov eax, [ebx]
CODE:00437C71 call sub_406900 ; intToStr
CODE:00437C76 mov eax, [ebp+var_8]
CODE:00437C79 call sub_403978 ; result len
CODE:00437C7E dec eax
CODE:00437C7F jz short loc_437C8D ; len > 1(result >10)
CODE:00437C81 mov eax, [ebx]
CODE:00437C83 mov ecx, 0Ah
CODE:00437C88 cdq
CODE:00437C89 idiv ecx
CODE:00437C8B mov [ebx], eax ; 再取余一次
CODE:00437C8D
CODE:00437C8D loc_437C8D: ; CODE XREF: sub_437BD8+A7↑j
CODE:00437C8D inc esi
CODE:00437C8E add ebx, 4 ; next result
CODE:00437C91 cmp esi, 5 ; run 5 time
CODE:00437C94 jnz short loc_437C6C
CODE:00437C96 mov esi, 1
CODE:00437C9B mov eax, offset dword_43A72C ; first result
CODE:00437CA0 mov edx, offset unk_43A73C ; first edit.text
CODE:00437CA5
CODE:00437CA5 loc_437CA5: ; CODE XREF: sub_437BD8+E6↓j
CODE:00437CA5 mov ecx, [edx]
CODE:00437CA7 cmp ecx, [eax] ; is not equal true:continue false:go to end
CODE:00437CA9 jz short loc_437CB2
CODE:00437CAB mov ecx, 1
CODE:00437CB0 jmp short loc_437CC7
CODE:00437CB2 ; ---------------------------------------------------------------------------
CODE:00437CB2
CODE:00437CB2 loc_437CB2: ; CODE XREF: sub_437BD8+D1↑j
CODE:00437CB2 xor ecx, ecx
CODE:00437CB4 inc esi
CODE:00437CB5 add edx, 4 ; next edit.text
CODE:00437CB8 add eax, 4 ; next result
CODE:00437CBB cmp esi, 5 ; run 5 times
CODE:00437CBE jnz short loc_437CA5
CODE:00437CC0 jmp short loc_437CC7
CODE:00437CC2 ; ---------------------------------------------------------------------------
CODE:00437CC2
CODE:00437CC2 loc_437CC2: ; CODE XREF: sub_437BD8+35↑j
CODE:00437CC2 mov ecx, 1
CODE:00437CC7
CODE:00437CC7 loc_437CC7: ; CODE XREF: sub_437BD8+D8↑j
CODE:00437CC7 ; sub_437BD8+E8↑j
CODE:00437CC7 test ecx, ecx
CODE:00437CC9 jnz short loc_437CDF
CODE:00437CCB mov eax, ds:dword_43A728
CODE:00437CD0 mov eax, [eax+1E0h]
CODE:00437CD6 mov dl, 1
CODE:00437CD8 call sub_41D158
CODE:00437CDD jmp short loc_437CF1
CODE:00437CDF ; ---------------------------------------------------------------------------
CODE:00437CDF
CODE:00437CDF loc_437CDF: ; CODE XREF: sub_437BD8+F1↑j
CODE:00437CDF mov eax, ds:dword_43A728
CODE:00437CE4 mov eax, [eax+1E0h]
CODE:00437CEA xor edx, edx
CODE:00437CEC call sub_41D158
CODE:00437CF1
CODE:00437CF1 loc_437CF1: ; CODE XREF: sub_437BD8+105↑j
CODE:00437CF1 xor eax, eax
CODE:00437CF3 pop edx
CODE:00437CF4 pop ecx
CODE:00437CF5 pop ecx
CODE:00437CF6 mov fs:[eax], edx
CODE:00437CF9 push offset loc_437D13
CODE:00437CFE
CODE:00437CFE loc_437CFE: ; CODE XREF: sub_437BD8+139↓j
CODE:00437CFE lea eax, [ebp+var_8]
CODE:00437D01 mov edx, 2
CODE:00437D06 call sub_403720
CODE:00437D0B retn
CODE:00437D0C ; ---------------------------------------------------------------------------
CODE:00437D0C
CODE:00437D0C loc_437D0C: ; DATA XREF: sub_437BD8+C↑o
CODE:00437D0C jmp sub_4031A0
CODE:00437D11 ; ---------------------------------------------------------------------------
CODE:00437D11 jmp short loc_437CFE
CODE:00437D13 ; ---------------------------------------------------------------------------
CODE:00437D13
CODE:00437D13 loc_437D13: ; CODE XREF: sub_437BD8+133↑j
CODE:00437D13 ; DATA XREF: sub_437BD8+121↑o
CODE:00437D13 pop esi
CODE:00437D14 pop ebx
CODE:00437D15 pop ecx
CODE:00437D16 pop ecx
CODE:00437D17 pop ebp
CODE:00437D18 retn
综上:每次点击edit框时触发判断机制,序列号的长度不小于,将序列号的1、3、4、5均对10取整,且保证结果小于10,否则继续对于10取整,将最终的结果分别与edit框的值比较,都相等则成功。
注册码计算:
def crack_32_crackme_2(src):det = ""src = src[:1] + src[2:]print(src)for i in range(4):temp = ord(src[i])if temp >= 100:det += str(temp//100)else:det += str(temp//10)print(det)if __name__ == "__main__":crack_32_crackme_2("zfy12")