已经被壳保护了 用UPXEasyGUI脱壳
发现是Delphi编写,利用dede静态分析工具
一下子发现了这么多的事件,真不知道该如何入手
先OD看看 注册提示
看看到底是怎么注册的
004473E7 . 81BB 04030000 340C0000 CMP DWORD PTR DS:[EBX+304],0C34 ;a if [BX+304] != 0c34 continue else end
004473F1 . 0F84 88000000 JE CKme002.0044747F
004473F7 . 81BB 08030000 0D230000 CMP DWORD PTR DS:[EBX+308],230D ;b if [BX+308] != 230d continue else end
00447401 . 74 7C JE SHORT CKme002.0044747F
00447403 . 81BB 10030000 940F0000 CMP DWORD PTR DS:[EBX+310],0F94 ;c if [BX+310] == 0f94 continue else end
0044740D . 75 70 JNZ SHORT CKme002.0044747F
0044740F . 8B83 18030000 MOV EAX,DWORD PTR DS:[EBX+318]
00447415 . 3B83 14030000 CMP EAX,DWORD PTR DS:[EBX+314] ;d if [BX+314] == [BX+318] continue else end
0044741B . 75 62 JNZ SHORT CKme002.0044747F
0044741D . 81BB 1C030000 E7030000 CMP DWORD PTR DS:[EBX+31C],3E7 ;e if [BX+31c] != 3e7 continue else end
00447427 . 74 56 JE SHORT CKme002.0044747F
00447429 . 33D2 XOR EDX,EDX
0044742B . 8B83 D8020000 MOV EAX,DWORD PTR DS:[EBX+2D8]
00447431 . 8B08 MOV ECX,DWORD PTR DS:[EAX]
00447433 . FF51 5C CALL DWORD PTR DS:[ECX+5C]
00447436 . 33D2 XOR EDX,EDX
00447438 . 8B83 DC020000 MOV EAX,DWORD PTR DS:[EBX+2DC]
0044743E . 8B08 MOV ECX,DWORD PTR DS:[EAX]
00447440 . FF51 5C CALL DWORD PTR DS:[ECX+5C]
00447443 . 33D2 XOR EDX,EDX
00447445 . 8B83 E0020000 MOV EAX,DWORD PTR DS:[EBX+2E0]
0044744B . 8B08 MOV ECX,DWORD PTR DS:[EAX]
0044744D . FF51 5C CALL DWORD PTR DS:[ECX+5C]
00447450 . 33D2 XOR EDX,EDX
00447452 . 8B83 E4020000 MOV EAX,DWORD PTR DS:[EBX+2E4]
00447458 . 8B08 MOV ECX,DWORD PTR DS:[EAX]
0044745A . FF51 5C CALL DWORD PTR DS:[ECX+5C]
0044745D . A1 A8984400 MOV EAX,DWORD PTR DS:[4498A8]
00447462 . 83C0 70 ADD EAX,70
00447465 . BA 8C744400 MOV EDX,CKme002.0044748C ; 厉害厉害真厉害!佩服佩服真佩服!!
0044746A . E8 EDC4FBFF CALL CKme002.0040395C
0044746F . BA B8744400 MOV EDX,CKme002.004474B8 ; 注册了
上面a b c d e 五个条件缺一不可都得满足,那么从第一个开始分析吧
1.if [BX+304] != 0c34 continue else end
我们首先找到给[BX+304] 赋值的代码
在FormCreate中找到了相应赋值操作
首先用OD下断点
00446D1E |. E8 A9CBFDFF CALL CKme002.004238CC
00446D23 |. C783 08030000 8E020000 MOV DWORD PTR DS:[EBX+308],28E ; [BX+308] = 28E
00446D2D |. C783 0C030000 09000000 MOV DWORD PTR DS:[EBX+30C],9 ; [BX+30C] = 9
00446D37 |. C783 14030000 0B000000 MOV DWORD PTR DS:[EBX+314],0B ; [BX+314] = 0B
00446D41 |. 33C0 XOR EAX,EAX
00446D43 |. 8983 18030000 MOV DWORD PTR DS:[EBX+318],EAX ; [BX+308] = 0
00446D49 |. BA EC6D4400 MOV EDX,CKme002.00446DEC ; x:\ajj.126.c0m\j\o\j\o\ok.txt
00446D4E |. 8D85 30FEFFFF LEA EAX,[LOCAL.116]
00446D54 |. E8 EDE7FBFF CALL CKme002.00405546
00446D59 |. 8D85 30FEFFFF LEA EAX,[LOCAL.116]
00446D5F |. E8 07EAFBFF CALL CKme002.0040576B
00446D64 |. E8 8BBAFBFF CALL CKme002.004027F4
00446D69 |. 85C0 TEST EAX,EAX
00446D6B |. 75 4B JNZ SHORT CKme002.00446DB8 ; 判断文件是否存在 if not exist end
00446D6D |. 8D55 FC LEA EDX,[LOCAL.1]
00446D70 |. 8D85 30FEFFFF LEA EAX,[LOCAL.116]
00446D76 |. E8 5DD1FBFF CALL CKme002.00403ED8 ; 读取文件内容
00446D7B |. E8 44BAFBFF CALL CKme002.004027C4
00446D80 |. 8B45 FC MOV EAX,[LOCAL.1] ; 文件内容
00446D83 BA 146E4400 MOV EDX,CKme002.00446E14 ; "ajj写的CKme真烂!"
00446D88 |. E8 0BCFFBFF CALL CKme002.00403C98 ; strcmp 比较函数
00446D8D |. 74 0A JE SHORT CKme002.00446D99 ; if not equal [BX+304] = 0C34
00446D8F |. C783 04030000 340C0000 MOV DWORD PTR DS:[EBX+304],0C34
00446D99 |> 8D85 30FEFFFF LEA EAX,[LOCAL.116]
00446D9F |. E8 44E8FBFF CALL CKme002.004055E8
00446DA4 |. E8 1BBAFBFF CALL CKme002.004027C4
00446DA9 |. B2 01 MOV DL,1
00446DAB |. 8B83 F0020000 MOV EAX,DWORD PTR DS:[EBX+2F0]
00446DB1 |. E8 EED1FDFF CALL CKme002.00423FA4
00446DB6 |. EB 0A JMP SHORT CKme002.00446DC2
00446DB8 |> C783 04030000 340C0000 MOV DWORD PTR DS:[EBX+304],0C34
00446DC2 |> 33C0 XOR EAX,EAX
结合着DEDE的静态反汇编,很快的理解了函数的意思
就是要创建一个 x:\ajj.126.c0m\j\o\j\o\ok.txt 路径的文件,并且里面的内容必须是 “ajj写的CKme真烂! ”
再看界面 已经出现了第二个输入框 说明第一关已经过去了
2.if [BX+308] != 230d continue else end
找给 [BX+308] 赋值的代码
在FormCreate中找到了相应赋值操作
00446D23 |. C783 08030000 8E020000 MOV DWORD PTR DS:[EBX+308],28E ; [BX+308] = 28E
终于在Button1MouseDown中找到了
00446FA4 /. 55 PUSH EBP
00446FA5 |. 8BEC MOV EBP,ESP
00446FA7 |. 8B90 08030000 MOV EDX,DWORD PTR DS:[EAX+308] ; DX = 28E
00446FAD |. 81FA 0D230000 CMP EDX,230D ; if DX == 230D end
00446FB3 |. 74 20 JE SHORT CKme002.00446FD5
00446FB5 |. 80F9 01 CMP CL,1 ; elif CL == 1 [AX+308]=[AX+308]+3 then end
00446FB8 |. 75 09 JNZ SHORT CKme002.00446FC3
00446FBA |. 8380 08030000 03 ADD DWORD PTR DS:[EAX+308],3
00446FC1 |. EB 12 JMP SHORT CKme002.00446FD5
00446FC3 |> 81FA 94020000 CMP EDX,294 ; elif DX < 294 [AX+308] = 230D
00446FC9 |. 7D 0A JGE SHORT CKme002.00446FD5
00446FCB |. C780 08030000 0D230000 MOV DWORD PTR DS:[EAX+308],230D
00446FD5 |> 5D POP EBP
00446FD6 \. C2 0C00 RETN 0C
00446FD9 8D40 00 LEA EAX,DWORD PTR DS:[EAX]
00446FDC . 81B8 08030000 9D020000 CMP DWORD PTR DS:[EAX+308],29D ; if [AX+308] == 29D DL = 1 else end
00446FE6 . 75 0D JNZ SHORT CKme002.00446FF5
00446FE8 . B2 01 MOV DL,1
00446FEA . 8B80 F0020000 MOV EAX,DWORD PTR DS:[EAX+2F0]
00446FF0 . 8B08 MOV ECX,DWORD PTR DS:[EAX]
00446FF2 . FF51 5C CALL DWORD PTR DS:[ECX+5C]
00446FF5 > C3 RETN
Panel1DbClick
00446FDC 81B8080300009D020000 cmp dword ptr [eax+$0308], $0000029D
00446FE6 750D jnz 00446FF5
00446FE8 B201 mov dl, $01
* Reference to control Edit2 : TEdit
|
00446FEA 8B80F0020000 mov eax, [eax+$02F0]
00446FF0 8B08 mov ecx, [eax]
00446FF2 FF515C call dword ptr [ecx+$5C]
00446FF5 C3 ret
并且发现当鼠标左键点击时 CL = 0 相反 CL= 1 并且只能右击5 到达29D 双击空白处启动TEXT2 已经可以输入字符串了
3.if [BX+310] == 0f94 continue else end
在函数FromMouseMove
0044710A |. 8B8B E0020000 MOV ECX,DWORD PTR DS:[EBX+2E0] ; image3
00447110 |. 8079 47 01 CMP BYTE PTR DS:[ECX+47],1
00447114 |. 75 19 JNZ SHORT CKme002.0044712F
00447116 |. 3D E2000000 CMP EAX,0E2 ; if AX > 0E2 con then end
0044711B |. 7E 12 JLE SHORT CKme002.0044712F
0044711D |. 81FA 2C010000 CMP EDX,12C ; if DX > 12C con then end
00447123 |. 7E 0A JLE SHORT CKme002.0044712F
00447125 |. C783 10030000 10000000 MOV DWORD PTR DS:[EBX+310],10
0044712F |> 8B8B DC020000 MOV ECX,DWORD PTR DS:[EBX+2DC] ; image2
00447135 |. 8079 47 01 CMP BYTE PTR DS:[ECX+47],1
00447139 |. 75 6C JNZ SHORT CKme002.004471A7
0044713B |. 83F8 17 CMP EAX,17 ; if AX < 17 con then end
0044713E |. 7D 67 JGE SHORT CKme002.004471A7
00447140 |. 81FA 2C010000 CMP EDX,12C ; if DX > 12C con then end
00447146 |. 7E 5F JLE SHORT CKme002.004471A7
00447148 |. 83BB 10030000 10 CMP DWORD PTR DS:[EBX+310],10 ; if [BX+310] == 10 continue then end
0044714F |. 75 56 JNZ SHORT CKme002.004471A7
00447151 |. 83BB 0C030000 09 CMP DWORD PTR DS:[EBX+30C],9 ; if [BX+30C] != 9 con then end
00447158 |. 74 4D JE SHORT CKme002.004471A7
0044715A |. C783 10030000 940F0000 MOV DWORD PTR DS:[EBX+310],0F94 ; [BX+310] = 0F94
00447164 |. 8B83 0C030000 MOV EAX,DWORD PTR DS:[EBX+30C]
那么转化为了 if [BX+30C] != 9 con then end
在一开始的时候有个赋值,是在初始化的时候
00446D2D |. C783 0C030000 09000000 MOV DWORD PTR DS:[EBX+30C],9 ; [BX+30C] = 9
0044701C |. E8 6BD0FDFF CALL CKme002.0042408C
00447021 |. 8B45 FC MOV EAX,[LOCAL.1] ; "12312312"
00447024 |. E8 5FCBFBFF CALL CKme002.00403B88
00447029 |. 83F8 08 CMP EAX,8 ; if length == 8 con then end
0044702C |. 0F85 92000000 JNZ CKme002.004470C4
00447032 |. 8D55 F8 LEA EDX,[LOCAL.2]
00447035 |. 8B83 F0020000 MOV EAX,DWORD PTR DS:[EBX+2F0]
0044703B |. E8 4CD0FDFF CALL CKme002.0042408C
00447040 |. 8B45 F8 MOV EAX,[LOCAL.2]
00447043 |. 8078 01 5F CMP BYTE PTR DS:[EAX+1],5F ; if s[2] == '_' con then end
00447047 |. 75 7B JNZ SHORT CKme002.004470C4
00447049 |. 8D55 F4 LEA EDX,[LOCAL.3]
0044704C |. 8B83 F0020000 MOV EAX,DWORD PTR DS:[EBX+2F0]
00447052 |. E8 35D0FDFF CALL CKme002.0042408C
00447057 |. 8B45 F4 MOV EAX,[LOCAL.3]
0044705A |. 8078 05 2C CMP BYTE PTR DS:[EAX+5],2C ; if s[6] == ',' con then end
0044705E |. 75 64 JNZ SHORT CKme002.004470C4
00447060 |. 8D55 F0 LEA EDX,[LOCAL.4]
00447063 |. 8B83 E8020000 MOV EAX,DWORD PTR DS:[EBX+2E8]
00447069 |. E8 1ED0FDFF CALL CKme002.0042408C
0044706E |. 8B45 F0 MOV EAX,[LOCAL.4] ; "123"名字长度必须三的倍数
00447071 |. E8 12CBFBFF CALL CKme002.00403B88 ; length
00447076 |. 83C0 03 ADD EAX,3 ; length + 3
00447079 |. B9 03000000 MOV ECX,3 ; cx = 3
0044707E |. 99 CDQ
0044707F |. F7F9 IDIV ECX ; 除法
00447081 |. 85D2 TEST EDX,EDX ; 判断Dx是否为零
就这样使得其不等于9 ==1过了
4.if [BX+314] == [BX+318] continue else end
首先搜索[BX+314] 一开始初始化 [BX+314] = 0B 然后赋值成了1 所以 [EBX+314],3D
00447164 |. 8B83 0C030000 MOV EAX,DWORD PTR DS:[EBX+30C] ; 根据 [BX+30C] 进行Switch
0044716A |. 83E8 01 SUB EAX,1 ; Switch (cases 1..3)
0044716D |. 72 0A JB SHORT CKme002.00447179
0044716F |. 74 14 JE SHORT CKme002.00447185
00447171 |. 48 DEC EAX
00447172 |. 74 1D JE SHORT CKme002.00447191
00447174 |. 48 DEC EAX
00447175 |. 74 26 JE SHORT CKme002.0044719D
00447177 |. EB 2E JMP SHORT CKme002.004471A7
00447179 |> C783 14030000>MOV DWORD PTR DS:[EBX+314],41
00447183 |. EB 22 JMP SHORT CKme002.004471A7
00447185 |> C783 14030000>MOV DWORD PTR DS:[EBX+314],3D ; Case 1 of switch 0044716A
0044718F |. EB 16 JMP SHORT CKme002.004471A7
00447191 |> C783 14030000>MOV DWORD PTR DS:[EBX+314],34 ; Case 2 of switch 0044716A
0044719B |. EB 0A JMP SHORT CKme002.004471A7
0044719D |> C783 14030000>MOV DWORD PTR DS:[EBX+314],0DF ; Case 3 of switch 0044716A
004471A7 |> 81BB 10030000>CMP DWORD PTR DS:[EBX+310],0F94 ; Default case of switch 0044716A
004471B1 |. 75 46 JNZ SHORT CKme002.004471F9
004471B3 |. 8D55 FC LEA EDX,[LOCAL.1]
(1)Image1MouseDown事件:
00447234 .. PUSH EBP
...
00447311 .. MOV EBX,ECX ; EBX = ECX
0044723B .. MOV ESI,EAX ; ESI = EAX
0044723D .. PUSH 0
0044723F .. MOV CX,WORD PTR DS:[447270] ; CX = 4
00447246 .. MOV DL,2 ; DL = 2
00447248 .. MOV EAX,CKme002_.0044727C ; EAX = addr where store "注册尚未成功..."
0044724D .. CALL CKme002_.00445694 ; show the dialog with failure infomation
00447252 .. TEST BL,BL ; if BL == 0
00447254 .. JNZ SHORT CKme002_.0044725D
00447256 .. ADD DWORD PTR DS:[ESI+318],2 ; Mem[ESI+318] += 2
0044725D .. CMP BL,1 ; if BL == 1
00447260 .. JNZ SHORT CKme002_.00447269
00447262 .. ADD DWORD PTR DS:[ESI+318],11 ; Mem[ESI+318] += 0x11
00447269 .. POP ESI
(2)Image2MouseDown事件:
004472A0 .. PUSH EBP
...
00447311 .. MOV EBX,ECX ; EBX = ECX
004472A7 .. MOV ESI,EAX ; ESI = EAX
004472A9 .. PUSH 0
004472AB .. MOV CX,WORD PTR DS:[4472DC] ; CX = 4
004472B2 .. MOV DL,2 ; DL = 2
004472B4 .. MOV EAX,CKme002_.004472E8 ; EAX = addr where store "注册尚未成功..."
004472B9 .. CALL CKme002_.00445694 ; show the dialog with failure infomation
004472BE .. TEST BL,BL ; if BL == 0
004472C0 .. JNZ SHORT CKme002_.004472C9 ;
004472C2 .. ADD DWORD PTR DS:[ESI+318],3 ; Mem[ESI+318] += 3
004472C9 .. CMP BL,1 ; if BL == 1
004472CC .. JNZ SHORT CKme002_.004472D5 ;
004472CE .. ADD DWORD PTR DS:[ESI+318],13 ; Mem[ESI+318] += 0x13
004472D5 .. POP ESI
(3)Image3MouseDown事件:
0044730C .. PUSH EBP
...
00447311 .. MOV EBX,ECX ; EBX = ECX
00447313 .. MOV ESI,EAX ; ESI = EAX
00447315 .. PUSH 0
00447317 .. MOV CX,WORD PTR DS:[447348] ; CX = 4
0044731E .. MOV DL,2 ; DL = 2
00447320 .. MOV EAX,CKme002_.00447354 ; EAX = addr where store "注册尚未成功..."
00447325 .. CALL CKme002_.00445694 ; show the dialog with failure infomation
0044732A .. TEST BL,BL ; if BL == 0
0044732C .. JNZ SHORT CKme002_.00447335
0044732E .. ADD DWORD PTR DS:[ESI+318],5 ; Mem[ESI+318] += 5
00447335 .. CMP BL,1 ; if BL == 1
00447338 .. JNZ SHORT CKme002_.00447341
0044733A .. ADD DWORD PTR DS:[ESI+318],17 ; Mem[ESI+318] += 0x17
00447341 .. POP ESI
(4)Image4MouseDown事件:
00447378 .. PUSH EBP
...
00447311 .. MOV EBX,ECX ; EBX = ECX
0044737F .. MOV ESI,EAX ; ESI = EAX
00447381 .. PUSH 0
00447383 .. MOV CX,WORD PTR DS:[4473B4] ; CX = 4
0044738A .. MOV DL,2 ; DL = 2
0044738C .. MOV EAX,CKme002_.004473C0 ; EAX = addr where store "注册尚未成功..."
00447391 .. CALL CKme002_.00445694 ; show the dialog with failure infomation
00447396 .. TEST BL,BL ; if BL == 0
00447398 .. JNZ SHORT CKme002_.004473A1
0044739A .. ADD DWORD PTR DS:[ESI+318],7 ; Mem[ESI+318] += 7
004473A1 .. CMP BL,1 ; if BL == 1
004473A4 .. JNZ SHORT CKme002_.004473AD
004473A6 .. ADD DWORD PTR DS:[ESI+318],1B ; Mem[ESI+318] += 0x1B
004473AD .. POP ESI
初始值为零 经过右击图片1 左击图片1,2,3即可相等
5.if [BX+31c] != 3e7 continue else end
004474C0 .. MOV DWORD PTR DS:[EAX+31C],3E7 ; Mem[EAX+31C] = 0x3E7
004474CA .. RETN
Mem[EBX+31C](EBX+31C和EAX+31C指向同一片内存)有且只有1次被赋值,发生在上述的Button1Click事件中,该事件是鼠标左键双击“注册”按钮时触发的。而且,鼠标左键双击“注册”按钮,会先触发Button1MouseDown事件,再触发Button1Click事件,然后再依次触发一遍。
因此,只需用鼠标左键双击“注册”按钮,Mem[EBX+31C]就会被赋值0x3E7,从而条件c5对应的判断跳转不会成功,说明我们破解了作者的第五层防御。