首页
社区
课程
招聘
一个crackme的算法
发表于: 2010-3-29 23:13 3795

一个crackme的算法

2010-3-29 23:13
3795
初次跟进算法。这个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期)

上传的附件:
收藏
免费 0
支持
分享
最新回复 (7)
雪    币: 54
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
输入的用户名每个字符转换成ASCII码,累加。所得的累加值与用户名长度的和乘以取负的累加值,记做n
输入的序列号每个字符转换成ASCII码,每个码值减去48后乘以参数k之后累加(k=1,10,100...)。累加值取负后记做c
c^4+n+用户名长度*c=0则注册成功
……
真的很难逆……
崩溃了……
2010-3-30 16:30
0
雪    币: 151
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
3
注意
004024E7  |.  85C0          TEST EAX,EAX                             ;  eax测试是否0
这里不是说方程等于0,而是求出的值低32位为0

sum^2+(name的每位相加+name的位数)*(name的每位相加 的补码)+sum*(-1)*name的长度 mod 0x100000000 = 0

注册码就是sum的补码,你可以试试看
2010-3-31 10:36
0
雪    币: 440
活跃值: (87)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
4
记用户名为Name(字符串), 注册码为Serial(10进制整数),
sum为Name中所有字符的ASCII码和。

-sum * ( sum + strlen(Name) ) + serial * serial - serial * strlen(Name) = 0
(mod 0x100000000)


sum          =  s
strlen(Name) =  t
serial       =  x

x^2 - t * x - s*(s+t) = 0

(x + s ) * (x - (s+t)) = 0

所以 x = s + t
即 serial = sum + strlen(Name)
2010-3-31 14:49
0
雪    币: 249
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
感谢各位回帖的朋友
3L提醒了我 初涉算法  还不太熟悉
4L的推理是对的 试验过了.  但我还是有点晕。。。
我再慢慢看下    再次感谢!!
2010-3-31 19:34
0
雪    币: 423
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
太深奥了!哥哥们是强人啊!
2010-3-31 19:40
0
雪    币: 249
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
看懂了  呵呵
我分析中也出了点小错误.
最后只需用因式分解...
另...4L的格式很好、很专业
值得学习!!
2010-3-31 19:47
0
雪    币: 151
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
8
能看懂就很好,分析算法一定要戒骄戒躁
2010-4-1 12:05
0
游客
登录 | 注册 方可回帖
返回
//