关于vcrkme01的算法分析
程序:vcrkme01
作者:[v0!d] 我入行时间短不知道是否是他,如果有错误还请见谅
以下是作者的文档资料:
[v0!d] - Crackme v0.01 :
~~~~~~~~~~~~~~~~~~~~~~~~
[This crack me is totally written for newbiez]
RuleZ :
~~~~~~~
1. Patching is not allwoed, cuz it is 2 easy to crack ...
2. Find a correct code for ur name...
3. Code a keygen, write a tut, then send it to me...
that's it!
P.S : to all advanced crackers plz don't try to crack this
cuz u will really be wasting ur time !!! :P
send ur solution to : v0id2k1@hotmail.com
cya
[v0!d]
工具:这次工具很简单的,就是一个OD,作者说得很清楚了, Patching is not allwoed,呵呵
说明:近来对算法有点兴趣了,今天又做了一个。不过例子是来自《加密解密实战》,只是算法和调试是我自己独立完成的。呵呵,主要是上次的那个精给了我很大的动力,我喜欢显摆,呵呵,不要见笑拉。有错的还望指出,在此先谢过!
感谢:CCDebuger的OD教程和小敏给我传的ASCII速查手册。
首先还是先运行
输入注册名:rockandtcl
注册码:123456
没有提示居然???
只好启动OD
载入后搜索所有的参看文本,找到GOOD JOB,双击进入
0040124D . 68 306A4000 push vcrkme01.00406A30
00401252 . 68 30694000 push vcrkme01.00406930
00401257 . E8 A4FDFFFF call vcrkme01.00401000
关键的CALL,设断
0040125C . 83C4 08 add esp,8
0040125F . 83F8 01 cmp eax,1
00401262 . A3 646C4000 mov dword ptr ds:[406C64],eax
00401267 . 75 65 jnz short vcrkme01.004012CE
00401269 . 8B15 28694000 mov edx,dword ptr ds:[406928]
0040126F . 6A 40 push 40
; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
00401271 . 68 80604000 push vcrkme01.00406080
; |Title = "GOOD JOB! - CRACKED!"
00401276 . 68 50604000 push vcrkme01.00406050
; |Text = "Send your solution to : v0id2k1@hotmail.com "
0040127B . 52 push edx
; |hOwner => NULL
0040127C . FF15 C4504000 call dword ptr ds[<&USER32.Message>;
\MessageBoxA
重新栽入:
点check后程序在
00401257 . E8 A4FDFFFF call vcrkme01.00401000
被断了下来,按F8进入
00401000 /$ 53 push ebx
00401001 |. 8B5C24 0C mov ebx,dword ptr ss:[esp+C] ;vcrkme01.00406A30
装入假的注册号
00401005 |. 55 push ebp
00401006 |. 56 push esi
00401007 |. 8B7424 10 mov esi,dword ptr ss:[esp+10]
装入注册名
0040100B |. 8A0B mov cl,byte ptr ds:[ebx]
取注册号第一位
0040100D |. 33ED xor ebp,ebp
0040100F |. 57 push edi
00401010 |. 8A06 mov al,byte ptr ds:[esi]
取注册名第一位
00401012 |. 3AC1 cmp al,cl
00401014 |. 0F85 69010000 jnz vcrkme01.00401183
比较,不相等则结束
0040101A |. 8BFE mov edi,esi
把注册名放在[EDI]首地址中
0040101C |. 83C9 FF or ecx,FFFFFFFF
对ECX赋值:FFFFFFFF
0040101F |. 33C0 xor eax,eax
EAX 清零
00401021 |. F2:AE repne scas byte ptr es:[edi]
00401023 |. F7D1 not ecx
00401025 |. 49 dec ecx
得到注册名的位数
00401026 |. 83F9 05 cmp ecx,5
小于5则死
00401029 |. 0F82 54010000 jb vcrkme01.00401183
0040102F |. 807B 01 2D cmp byte ptr ds:[ebx+1],2D
00401033 |. /0F85 4A010000 jnz vcrkme01.00401183
比较注册码的第二位是否为2D就是‘-’否则就死
看来我们开始的注册码就不对
重新载入
注册名不变,注册码改为:r-1234
继续上面的地方开始
00401039 |. 8BFE mov edi,esi
把注册名放入EDI的地址中
0040103B |. 83C9 FF or ecx,FFFFFFFF
0040103E |. 33C0 xor eax,eax
00401040 |. 33D2 xor edx,edx
00401042 |. F2:AE repne scas byte ptr es:[edi]
00401044 |. F7D1 not ecx
00401046 |. 49 dec ecx
以上还是计算注册名的位数
00401047 |. 74 17 je short vcrkme01.00401060
开始进入循环了
00401049 |> 0FBE0C32 /movsx ecx,byte ptr ds:[edx+esi]
逐个取注册名,换成16进制,并放入ECX中
0040104D |. 03E9 |add ebp,ecx
第一次开始的时候EBP为0,现在EBP+ECX--> EBP
0040104F |. 8BFE |mov edi,esi
00401051 |. 83C9 FF |or ecx,FFFFFFFF
00401054 |. 33C0 |xor eax,eax
00401056 |. 42 |inc edx
00401057 |. F2:AE |repne scas byte ptr es:[edi]
00401059 |. F7D1 |not ecx
0040105B |. 49 |dec ecx
算注册名的位数
0040105C |. 3BD1 |cmp edx,ecx
看是否结束
0040105E |.^ 72 E9 \jb short vcrkme01.00401049
换句话说呢就是
我们输入的是rockandtcl经过循环后EBP=72+6F+63+6B+61+6E+64+74+63+6C=425(16进制)
继续往下走
00401060 |> \81C5 64600000 add ebp,6064
EBP+6064=6489(16进制)
00401066 |. 55 push ebp
00401067 |. 68 34604000 push vcrkme01.00406034 ; ASCII "%lu"
0040106C |. 68 306B4000 push vcrkme01.00406B30
00401071 |. E8 B6030000 call vcrkme01.0040142C
把6489转化成10进制的25737,然后再转化成字符串
00401076 |. 8A16 mov dl,byte ptr ds:[esi]
00401078 |. 8BFE mov edi,esi
0040107A |. 83C9 FF or ecx,FFFFFFFF
0040107D |. 33C0 xor eax,eax
0040107F |. 8815 446B4000 mov byte ptr ds:[406B44],dl
00401085 |. C605 456B4000 2D mov byte ptr ds:[406B45],2D
保存计算好的前两位注册码r-
0040108C |. F2:AE repne scas byte ptr es:[edi]
0040108E |. F7D1 not ecx
00401090 |. 49 dec ecx
还是计算位数
00401091 |. 0FBE4431 FF movsx eax,byte ptr ds:[ecx+esi-1]
取注册码的最后一位‘l’
00401096 |. 50 push eax
00401097 |. E8 C4020000 call vcrkme01.00401360
把‘l’变成大写的‘L’,如果大写的就不变
0040109C |. A2 466B4000 mov byte ptr ds:[406B46],al
刚才我们的r-是在ds:[406B44]和[406B45]中,现在[406B46]中放着L
于是注册码就成了‘r-L’
004010A1 |. BF 306B4000 mov edi,vcrkme01.00406B30
004010A6 |. 83C9 FF or ecx,FFFFFFFF
004010A9 |. 33C0 xor eax,eax
004010AB |. F2:AE repne scas byte ptr es:[edi]
004010AD |. F7D1 not ecx
004010AF |. 2BF9 sub edi,ecx
004010B1 |. 81C5 64600000 add ebp,6064
它在做什么呢?呵呵。等会就知道了
这时候EBP=6489+6064=C4ED
004010B7 |. 8BF7 mov esi,edi
004010B9 |. 8BD1 mov edx,ecx
004010BB |. BF 446B4000 mov edi,vcrkme01.00406B44
组合现有的字符合并成新的注册码r-L25737放入EDI中
004010E2 |. F2:AE repne scas byte ptr es:[edi]
取‘-’
略去代码.....
0040110A |. E8 1D030000 call vcrkme01.0040142C
0040110F |. BF 306B4000 mov edi,vcrkme01.00406B30
; ASCII "25737"
这个CALL就是取回第二次加6064的EBP的值,这里的分析太麻烦了,我不想写了,有机会再补上。还请大家见谅,呵呵
00401141 |. BE 446B4000 mov esi,vcrkme01.00406B44 ;
ASCII "r-L25737-50413"
把计算好的值放到原来的那个后面
00401146 |> 8A10 /mov dl,byte ptr ds:[eax]
00401148 |. 8A1E |mov bl,byte ptr ds:[esi]
0040114A |. 8ACA |mov cl,dl
0040114C |. 3AD3 |cmp dl,bl
0040114E |. 75 25 |jnz short vcrkme01.00401175
00401150 |. 84C9 |test cl,cl
00401152 |. 74 16 |je short vcrkme01.0040116A
00401154 |. 8A50 01 |mov dl,byte ptr ds:[eax+1]
00401157 |. 8A5E 01 |mov bl,byte ptr ds:[esi+1]
0040115A |. 8ACA |mov cl,dl
0040115C |. 3AD3 |cmp dl,bl
0040115E |. 75 15 |jnz short vcrkme01.00401175
00401160 |. 83C0 02 |add eax,2
00401163 |. 83C6 02 |add esi,2
00401166 |. 84C9 |test cl,cl
00401168 |.^ 75 DC \jnz short vcrkme01.00401146
以上就是我们的注册码和算出来的最比对,有错的话就死
注册名:rockandtcl
注册码:r-L25737-50413
且注册名必须大于5位,注册码也必须大于???不知道是多少。呵呵。懒了点。
于是注册码的形式就是
第一个字符取注册名的第一位
然后加上字符串‘-’
最后一位的注册名换成大写的,是大写的就不用转换
组合后跟的数值是注册名各个字符的ASCII码的值的总和在加上6064(16进制)换成10进制后再转化为字符加上
然后再加上字符串‘-’
把第二次加得到的EBP的值换成10进制后再转化为字符加上
忙了一个下午,该休息会了,注册机谁有兴趣谁写吧,太累了。呵呵。
又来显摆了一回。
还请各位多多见谅,有错的地方还望指出,谢谢!
压缩包里有这篇文章的WORD的版本和草稿。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
上传的附件: