还是一个Delphi程序,DeDe看一下发现几个比较重要的事件,分别下断分析函数执行逻辑。
在ResoucesHacker中可以看到窗口控件的信息:
在00442E22
处看到一个cmp
,修改跳转路径之后发现ok按钮可用了:
00442E22 | 8078 47 00 | cmp byte ptr ds:[eax+47],0 |
00442E26 | 75 0F | jne along3x.1.442E37 |
00442E28 | B2 01 | mov dl,1 |
00442E2A | 8B83 CC020000 | mov eax,dword ptr ds:[ebx+2CC] |
00442E30 | 8B08 | mov ecx,dword ptr ds:[eax] |
00442E32 | FF51 60 | call dword ptr ds:[ecx+60] |
在Ok按钮的处理函数中爆破掉两个跳转指令之后按钮消失:
00442D80 | 8078 47 01 | cmp byte ptr ds:[eax+47],1 |
00442D84 | 75 12 | jne along3x.1.442D98 |
00442D86 | BA 002E4400 | mov edx,along3x.1.442E00 |
00442D8B | 8B83 E0020000 | mov eax,dword ptr ds:[ebx+2E0] |
00442D91 | E8 5A05FEFF | call along3x.1.4232F0 |
00442D96 | EB 3F | jmp along3x.1.442DD7 |
00442D98 | 8D55 FC | lea edx,dword ptr ss:[ebp-4] |
00442D9B | 8B83 E0020000 | mov eax,dword ptr ds:[ebx+2E0] |
00442DA1 | E8 1A05FEFF | call along3x.1.4232C0 |
00442DA6 | 8B45 FC | mov eax,dword ptr ss:[ebp-4] |
00442DA9 | E8 C248FCFF | call along3x.1.407670 |
00442DAE | 50 | push eax |
00442DAF | 8D55 FC | lea edx,dword ptr ss:[ebp-4] |
00442DB2 | 8B83 DC020000 | mov eax,dword ptr ds:[ebx+2DC] |
00442DB8 | E8 0305FEFF | call along3x.1.4232C0 |
00442DBD | 8B45 FC | mov eax,dword ptr ss:[ebp-4] |
00442DC0 | 5A | pop edx |
00442DC1 | E8 DAFDFFFF | call along3x.1.442BA0 |
00442DC6 | 84C0 | test al,al |
00442DC8 | 74 0D | je along3x.1.442DD7 |
00442DCA | 33D2 | xor edx,edx |
00442DCC | 8B83 CC020000 | mov eax,dword ptr ds:[ebx+2CC] |
00442DD2 | E8 D903FEFF | call along3x.1.4231B0 |
同样在Cancella
按钮的处理函数中也有如下逻辑:
00442EE7 | E8 08FCFFFF | call along3x.1.442AF4 |
00442EEC | 84C0 | test al,al |
00442EEE | 74 1C | je along3x.1.442F0C |
爆破之后发现两个按钮都消失了,达到了题目效果:
还是要看一下判断逻辑,找到Cancella
按钮处理函数中关键的跳转前的判断函数:
00442ECF | E8 9C47FCFF | call along3x.1.407670 | 获取密码
00442ED4 | 50 | push eax | eax:"1234567890"
00442ED5 | 8D55 FC | lea edx,dword ptr ss:[ebp-4] | [ebp-4]:"1234567890"
00442ED8 | 8B83 DC020000 | mov eax,dword ptr ds:[ebx+2DC] | eax:"1234567890"
00442EDE | E8 DD03FEFF | call along3x.1.4232C0 | 获取用户名
00442EE3 | 8B45 FC | mov eax,dword ptr ss:[ebp-4] | [ebp-4]:"1234567890"
00442EE6 | 5A | pop edx |
00442EE7 | E8 08FCFFFF | call along3x.1.442AF4 |
00442EEC | 84C0 | test al,al |
00442EEE | 74 1C | je along3x.1.442F0C |
单步步进看一下,找到如下运算过程:
00442AF4 | 55 | push ebp |
00442AF5 | 8BEC | mov ebp,esp |
00442AF7 | 83C4 F8 | add esp,FFFFFFF8 |
00442AFA | 53 | push ebx | ebx:",(D"
00442AFB | 56 | push esi |
00442AFC | 8955 F8 | mov dword ptr ss:[ebp-8],edx |
00442AFF | 8945 FC | mov dword ptr ss:[ebp-4],eax | [ebp-4]:"ZZZZZZZZZZ"
00442B02 | 8B45 FC | mov eax,dword ptr ss:[ebp-4] | [ebp-4]:"ZZZZZZZZZZ"
00442B05 | E8 DE10FCFF | call along3x.1.403BE8 | 判断字符串是否为空
00442B0A | 33C0 | xor eax,eax | eax:"ZZZZZZZZZZ"
00442B0C | 55 | push ebp |
00442B0D | 68 902B4400 | push along3x.1.442B90 |
00442B12 | 64:FF30 | push dword ptr fs:[eax] |
00442B15 | 64:8920 | mov dword ptr fs:[eax],esp |
00442B18 | 8B45 FC | mov eax,dword ptr ss:[ebp-4] | [ebp-4]:"ZZZZZZZZZZ"
00442B1B | E8 140FFCFF | call along3x.1.403A34 | 获取name字段长度
00442B20 | 83F8 05 | cmp eax,5 | 用户名长度是否大于5
00442B23 | 7E 53 | jle along3x.1.442B78 |
00442B25 | 8B45 FC | mov eax,dword ptr ss:[ebp-4] | [ebp-4]:"ZZZZZZZZZZ"
00442B28 | 0FB640 04 | movzx eax,byte ptr ds:[eax+4] | 取用户名第5位字母的ASCII
00442B2C | B9 07000000 | mov ecx,7 |
00442B31 | 33D2 | xor edx,edx |
00442B33 | F7F1 | div ecx |
00442B35 | 8BC2 | mov eax,edx | 用户名第5位字母的ASCII值/7
00442B37 | 83C0 02 | add eax,2 | 取余+2
00442B3A | E8 E1FEFFFF | call along3x.1.442A20 | 余数+2的阶乘
00442B3F | 8BF0 | mov esi,eax | eax:"ZZZZZZZZZZ"
00442B41 | 33DB | xor ebx,ebx | ebx:",(D"
00442B43 | 8B45 FC | mov eax,dword ptr ss:[ebp-4] | [ebp-4]:"ZZZZZZZZZZ"
00442B46 | E8 E90EFCFF | call along3x.1.403A34 | 判断用户名是否为空
00442B4B | 85C0 | test eax,eax | eax:"ZZZZZZZZZZ"
00442B4D | 7E 16 | jle along3x.1.442B65 |
00442B4F | BA 01000000 | mov edx,1 |
00442B54 | 8B4D FC | mov ecx,dword ptr ss:[ebp-4] | [ebp-4]:"ZZZZZZZZZZ"
00442B57 | 0FB64C11 FF | movzx ecx,byte ptr ds:[ecx+edx-1] | 对用户名循环取值
00442B5C | 0FAFCE | imul ecx,esi | name[i]*(余数+2的阶乘)
00442B5F | 03D9 | add ebx,ecx | 对上一步运算求和
00442B61 | 42 | inc edx |
00442B62 | 48 | dec eax | eax:"ZZZZZZZZZZ"
00442B63 | 75 EF | jne along3x.1.442B54 |
00442B65 | 2B5D F8 | sub ebx,dword ptr ss:[ebp-8] | 求和的结果-注册码 |
00442B68 | 81FB 697A0000 | cmp ebx,7A69 | 判断差是否等于0x7A69
00442B6E | 75 04 | jne along3x.1.442B74 |
00442B70 | B3 01 | mov bl,1 |
00442B72 | EB 06 | jmp along3x.1.442B7A |
00442B74 | 33DB | xor ebx,ebx | ebx:",(D"
00442B76 | EB 02 | jmp along3x.1.442B7A |
00442B78 | 33DB | xor ebx,ebx | ebx:",(D"
00442B7A | 33C0 | xor eax,eax | eax:"ZZZZZZZZZZ"
00442B7C | 5A | pop edx |
00442B7D | 59 | pop ecx |
00442B7E | 59 | pop ecx |
00442B7F | 64:8910 | mov dword ptr fs:[eax],edx |
00442B82 | 68 972B4400 | push along3x.1.442B97 |
00442B87 | 8D45 FC | lea eax,dword ptr ss:[ebp-4] | [ebp-4]:"ZZZZZZZZZZ"
00442B8A | E8 290CFCFF | call along3x.1.4037B8 |
00442B8F | C3 | ret |
可以分析出算法:用户名第5个字母的ASCII码处以7的余数加2为X,算出X的阶乘Y,Y乘用户名ASCII值的和得Z,Z-serial=0x7A69时验证通过。
公式:
serial = ((((name[4]%7) + 2)!)*(name[0] + name[1] + ... + name[i])) - 0x7A69
按照这个逻辑得出ZZZZZZZZZZ
对应的注册码是36256663
,输入之后发现Cancella
按钮消失且Ok按钮状态改变:
但是此时点Ok按钮还是没有任何反应,因此猜测Ok按钮处也有验证算法,话不多说下断:
Ok按钮的处理函数如下:
00442D64 | 55 | push ebp | OK_Click
00442D65 | 8BEC | mov ebp,esp |
00442D67 | 6A 00 | push 0 |
00442D69 | 53 | push ebx |
00442D6A | 8BD8 | mov ebx,eax | eax:",(D"
00442D6C | 33C0 | xor eax,eax | eax:",(D"
00442D6E | 55 | push ebp |
00442D6F | 68 ED2D4400 | push along3x.1.442DED |
00442D74 | 64:FF30 | push dword ptr fs:[eax] |
00442D77 | 64:8920 | mov dword ptr fs:[eax],esp |
00442D7A | 8B83 D0020000 | mov eax,dword ptr ds:[ebx+2D0] | eax:",(D"
00442D80 | 8078 47 01 | cmp byte ptr ds:[eax+47],1 |
00442D84 | 75 12 | jne along3x.1.442D98 |
00442D86 | BA 002E4400 | mov edx,along3x.1.442E00 |
00442D8B | 8B83 E0020000 | mov eax,dword ptr ds:[ebx+2E0] | eax:",(D"
00442D91 | E8 5A05FEFF | call along3x.1.4232F0 |
00442D96 | EB 3F | jmp along3x.1.442DD7 |
00442D98 | 8D55 FC | lea edx,dword ptr ss:[ebp-4] |
00442D9B | 8B83 E0020000 | mov eax,dword ptr ds:[ebx+2E0] | eax:",(D"
00442DA1 | E8 1A05FEFF | call along3x.1.4232C0 |
00442DA6 | 8B45 FC | mov eax,dword ptr ss:[ebp-4] |
00442DA9 | E8 C248FCFF | call along3x.1.407670 |
00442DAE | 50 | push eax | eax:",(D"
00442DAF | 8D55 FC | lea edx,dword ptr ss:[ebp-4] |
00442DB2 | 8B83 DC020000 | mov eax,dword ptr ds:[ebx+2DC] | eax:",(D"
00442DB8 | E8 0305FEFF | call along3x.1.4232C0 |
00442DBD | 8B45 FC | mov eax,dword ptr ss:[ebp-4] |
00442DC0 | 5A | pop edx |
00442DC1 | E8 DAFDFFFF | call along3x.1.442BA0 | 隐藏Ok按钮的判断函数
00442DC6 | 84C0 | test al,al |
00442DC8 | 74 0D | je along3x.1.442DD7 | Ok按钮隐藏
00442DCA | 33D2 | xor edx,edx |
00442DCC | 8B83 CC020000 | mov eax,dword ptr ds:[ebx+2CC] | eax:",(D"
00442DD2 | E8 D903FEFF | call along3x.1.4231B0 |
00442DD7 | 33C0 | xor eax,eax | eax:",(D"
00442DD9 | 5A | pop edx |
00442DDA | 59 | pop ecx |
00442DDB | 59 | pop ecx |
00442DDC | 64:8910 | mov dword ptr fs:[eax],edx |
00442DDF | 68 F42D4400 | push along3x.1.442DF4 |
00442DE4 | 8D45 FC | lea eax,dword ptr ss:[ebp-4] |
00442DE7 | E8 CC09FCFF | call along3x.1.4037B8 |
00442DEC | C3 | ret |
00442DED | E9 8604FCFF | jmp along3x.1.403278 |
00442DF2 | EB F0 | jmp along3x.1.442DE4 |
00442DF4 | 5B | pop ebx |
00442DF5 | 59 | pop ecx |
00442DF6 | 5D | pop ebp |
00442DF7 | C3 | ret |
找到442BA0,进去看一下:
00442BF9 | 8D45 F4 | lea eax,dword ptr ss:[ebp-C] | [ebp-C]:"362566MI"
00442BFC | E8 0310FCFF | call along3x.1.403C04 |
00442C01 | 8D4430 FF | lea eax,dword ptr ds:[eax+esi-1] |
00442C05 | 50 | push eax |
00442C06 | 8B45 F8 | mov eax,dword ptr ss:[ebp-8] | [ebp-8]:"36256663"
00442C09 | 0FB64430 FF | movzx eax,byte ptr ds:[eax+esi-1] |
00442C0E | F7E8 | imul eax | 每个数字平方
00442C10 | 0FBFC0 | movsx eax,ax |
00442C13 | F7EE | imul esi | *剩余注册码的长度
00442C15 | B9 19000000 | mov ecx,19 |
00442C1A | 99 | cdq |
00442C1B | F7F9 | idiv ecx | /19
00442C1D | 83C2 41 | add edx,41 | 余数+41
00442C20 | 58 | pop eax |
00442C21 | 8810 | mov byte ptr ds:[eax],dl |
00442C23 | 4E | dec esi |
00442C24 | 85F6 | test esi,esi |
00442C26 | 75 D1 | jne along3x.1.442BF9 |
首先注册码长度要大于5,倒序对注册码中每个数字进行处理,第i个数字的平方乘以未处理注册码字符的长度再与19取余,结果加41后得出用户名的第i个字母。
当注册码为36256663
时运算得出的用户名为BHALFVMI
,输入程序发现Ok按钮也消失了: