初次跟进算法。这个crackme虽然看起来简单,但还是有些令我不明白的地方
分析如下
004023CC |. 51 PUSH ECX
004023CD |. 8DBD 70FFFFFF LEA EDI,DWORD PTR SS:[EBP-90]
004023D3 |. B9 24000000 MOV ECX,24
004023D8 |. B8 CCCCCCCC MOV EAX,CCCCCCCC
004023DD |. F3:AB REP STOS DWORD PTR ES:[EDI]
004023DF |. 59 POP ECX
004023E0 |. 894D FC MOV DWORD PTR SS:[EBP-4],ECX ; ecx好像是固定值 12fe6c
004023E3 |. 6A 01 PUSH 1
004023E5 |. 8B4D FC MOV ECX,DWORD PTR SS:[EBP-4]
004023E8 |. E8 7DEDFFFF CALL <JMP.&MFC42D.#5056>
004023ED |. C745 F8 00000>MOV DWORD PTR SS:[EBP-8],0
004023F4 |. C745 F0 00000>MOV DWORD PTR SS:[EBP-10],0
004023FB |. 8B4D FC MOV ECX,DWORD PTR SS:[EBP-4]
004023FE |. 83C1 60 ADD ECX,60
00402401 |. E8 8EFBFFFF CALL <JMP.&MFC42D.#880>
00402406 |. 50 PUSH EAX ; /假name入栈
00402407 |. 8D45 D0 LEA EAX,DWORD PTR SS:[EBP-30] ; |
0040240A |. 50 PUSH EAX ; |dest
0040240B |. E8 24EDFFFF CALL <JMP.&MSVCRTD.strcpy> ; \strcpy
00402410 |. 83C4 08 ADD ESP,8
00402413 |. 8D4D D0 LEA ECX,DWORD PTR SS:[EBP-30] ; 假name的值
00402416 |. 51 PUSH ECX ; /s
00402417 |. E8 1EEDFFFF CALL <JMP.&MSVCRTD.strlen> ; \注意eax的值 应该是name的长度
0040241C |. 83C4 04 ADD ESP,4
0040241F |. 8945 E8 MOV DWORD PTR SS:[EBP-18],EAX ; eax送ebp-18
00402422 |. C745 EC 00000>MOV DWORD PTR SS:[EBP-14],0
00402429 |. EB 09 JMP SHORT Bxm_Crac.00402434
0040242B |> 8B55 EC /MOV EDX,DWORD PTR SS:[EBP-14]
0040242E |. 83C2 01 |ADD EDX,1
00402431 |. 8955 EC |MOV DWORD PTR SS:[EBP-14],EDX
00402434 |> 8B45 EC MOV EAX,DWORD PTR SS:[EBP-14] ; 清零
00402437 |. 3B45 E8 |CMP EAX,DWORD PTR SS:[EBP-18]
0040243A |. 7D 12 |JGE SHORT Bxm_Crac.0040244E ; 比较 大等则跳(把假name比完)
0040243C |. 8B4D EC |MOV ECX,DWORD PTR SS:[EBP-14] ; ecx清零
0040243F |. 0FBE540D D0 |MOVSX EDX,BYTE PTR SS:[EBP+ECX-30] ; 假name的第一位-最后一位 依次送
00402444 |. 8B45 F8 |MOV EAX,DWORD PTR SS:[EBP-8]
00402447 |. 03C2 |ADD EAX,EDX
00402449 |. 8945 F8 |MOV DWORD PTR SS:[EBP-8],EAX ; 1-最后一位依次相加
0040244C |.^ EB DD \JMP SHORT Bxm_Crac.0040242B ; 值送ebp-8
0040244E |> 8B4D F8 MOV ECX,DWORD PTR SS:[EBP-8] ; 相加的值给ecx
00402451 |. F7D9 NEG ECX ; 取反加一(ECX补码)
00402453 |. 8B55 F8 MOV EDX,DWORD PTR SS:[EBP-8]
00402456 |. 0355 E8 ADD EDX,DWORD PTR SS:[EBP-18] ; 所有位相加的值然后加位数(EDX)
00402459 |. 0FAFCA IMUL ECX,EDX ; 相乘 结果给exc
0040245C |. 894D F4 MOV DWORD PTR SS:[EBP-C],ECX ; 保存栈中....ecx【假码的运算】
0040245F |. 8B4D FC MOV ECX,DWORD PTR SS:[EBP-4] ; 这个栈的值是0012fe6c
00402462 |. 83C1 64 ADD ECX,64
00402465 |. E8 2AFBFFFF CALL <JMP.&MFC42D.#880> ; 返回的eax是假码
0040246A |. 50 PUSH EAX ; /src
0040246B |. 8D45 B8 LEA EAX,DWORD PTR SS:[EBP-48] ; |
0040246E |. 50 PUSH EAX ; |dest
0040246F |. E8 C0ECFFFF CALL <JMP.&MSVCRTD.strcpy> ; \strcpy
00402474 |. 83C4 08 ADD ESP,8
00402477 |. C745 B0 01000>MOV DWORD PTR SS:[EBP-50],1
0040247E |. 8D4D B8 LEA ECX,DWORD PTR SS:[EBP-48]
00402481 |. 51 PUSH ECX ; /s
00402482 |. E8 B3ECFFFF CALL <JMP.&MSVCRTD.strlen> ; \返回的edx、eax eax是长度
00402487 |. 83C4 04 ADD ESP,4
0040248A |. 83E8 01 SUB EAX,1
0040248D |. 8945 B4 MOV DWORD PTR SS:[EBP-4C],EAX ; 保存长度
00402490 |. EB 09 JMP SHORT Bxm_Crac.0040249B
00402492 |> 8B55 B4 /MOV EDX,DWORD PTR SS:[EBP-4C]
00402495 |. 83EA 01 |SUB EDX,1
00402498 |. 8955 B4 |MOV DWORD PTR SS:[EBP-4C],EDX ; 保存edx
0040249B |> 837D B4 00 CMP DWORD PTR SS:[EBP-4C],0
0040249F |. 7C 22 |JL SHORT Bxm_Crac.004024C3 ; 小于则跳
004024A1 |. 8B45 B4 |MOV EAX,DWORD PTR SS:[EBP-4C]
004024A4 |. 0FBE4C05 B8 |MOVSX ECX,BYTE PTR SS:[EBP+EAX-48] ; 从假码的后面开始
004024A9 |. 83E9 30 |SUB ECX,30 ; ASCII减30 得到的是数值
004024AC |. 0FAF4D B0 |IMUL ECX,DWORD PTR SS:[EBP-50] ; 初值为一
004024B0 |. 8B55 F0 |MOV EDX,DWORD PTR SS:[EBP-10] ; 初值为零
004024B3 |. 03D1 |ADD EDX,ECX
004024B5 |. 8955 F0 |MOV DWORD PTR SS:[EBP-10],EDX ; 上面的和
004024B8 |. 8B45 B0 |MOV EAX,DWORD PTR SS:[EBP-50]
004024BB |. 6BC0 0A |IMUL EAX,EAX,0A ; eax*10
004024BE |. 8945 B0 |MOV DWORD PTR SS:[EBP-50],EAX ; 结果放ebp-50
004024C1 |.^ EB CF \JMP SHORT Bxm_Crac.00402492 ; 有点晕...
004024C3 |> 8B4D F0 MOV ECX,DWORD PTR SS:[EBP-10] ; 上循环的结果
004024C6 |. 6BC9 FF IMUL ECX,ECX,-1 ; *(-1)
004024C9 |. 894D F0 MOV DWORD PTR SS:[EBP-10],ECX
004024CC |. 837D E8 00 CMP DWORD PTR SS:[EBP-18],0
004024D0 |. 74 2F JE SHORT Bxm_Crac.00402501 ; ebp-18为假name 的长度
004024D2 |. 8B55 F0 MOV EDX,DWORD PTR SS:[EBP-10]
004024D5 |. 0FAF55 F0 IMUL EDX,DWORD PTR SS:[EBP-10] ; 平方?
004024D9 |. 8B45 F0 MOV EAX,DWORD PTR SS:[EBP-10]
004024DC |. 0FAF45 E8 IMUL EAX,DWORD PTR SS:[EBP-18] ; 假码的结果*name的长度
004024E0 |. 8B4D F4 MOV ECX,DWORD PTR SS:[EBP-C]
004024E3 |. 03CA ADD ECX,EDX ; 假name运算结果+上平方
004024E5 |. 03C1 ADD EAX,ECX
004024E7 |. 85C0 TEST EAX,EAX ; eax测试是否0
004024E9 75 16 JNZ SHORT Bxm_Crac.00402501 ; 【关键】
总结了下,算法是这样的:
sum=十位+(个位*10+个位)+(百位+个位*10^2)+(千位+个位*10^3)....
sum^2+(name的每位相加+name的位数)*(name的每位相加 的补码)+sum*(-1)*name的长度 = 0
看起来是个一元二次的方程,但好像又没那么简单。
我不知道这个算法如何来逆...方程解出来有小数怎么办呢?是不是该name就没有对应的注册码啊?困惑,的确很困惑.....哪位朋友来帮我分析分析....
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)