第一次慢慢跟着riijj牛慢慢分析,学习注册机制作,没经验,我只有跟着大牛走了,参考riijj大牛的破文和他的CrackMe,
输出的注册码为16进制的ASII2码,我只能做到这样了。先看反汇编代码,源码和CrackMe在后面。调试了一下午,代码都花在调试上了
00401230 /$ 8B0D BC564000 MOV ECX,DWORD PTR DS:[4056BC]
00401236 |. 83EC 30 SUB ESP,30
00401239 |. 8D4424 00 LEA EAX,DWORD PTR SS:[ESP]
0040123D |. 53 PUSH EBX
0040123E |. 56 PUSH ESI
0040123F |. 8B35 94404000 MOV ESI,DWORD PTR DS:[<&USER32.GetDlgIte>; USER32.GetDlgItemTextA
00401245 |. 6A 10 PUSH 10 ; /Count = 10 (16.)
00401247 |. 50 PUSH EAX ; |Buffer
00401248 |. 68 E8030000 PUSH 3E8 ; |ControlID = 3E8 (1000.)
0040124D |. 51 PUSH ECX ; |hWnd => 00020624 (class='#32770',parent=00020642)
0040124E |. 33DB XOR EBX,EBX ; |
00401250 |. FFD6 CALL ESI ; \GetDlgItemTextA
00401252 |. 83F8 03 CMP EAX,3 ; 比较用户名的长度,用户名要大于3
00401255 |. 73 0B JNB SHORT ncrackme.00401262
00401257 |. 5E POP ESI
00401258 |. B8 01000000 MOV EAX,1
0040125D |. 5B POP EBX
0040125E |. 83C4 30 ADD ESP,30
00401261 |. C3 RETN
00401262 |> A1 BC564000 MOV EAX,DWORD PTR DS:[4056BC]
00401267 |. 8D5424 28 LEA EDX,DWORD PTR SS:[ESP+28]
0040126B |. 6A 10 PUSH 10
0040126D |. 52 PUSH EDX
0040126E |. 68 E9030000 PUSH 3E9
00401273 |. 50 PUSH EAX
00401274 |. FFD6 CALL ESI
00401276 |. 0FBE4424 08 MOVSX EAX,BYTE PTR SS:[ESP+8] ; 取用户名的第一位放入EAX
0040127B |. 0FBE4C24 09 MOVSX ECX,BYTE PTR SS:[ESP+9] ; 取出用户名的第二位放入ECX
00401280 |. 99 CDQ ; 把EAX扩展成为EDX:EAX
00401281 |. F7F9 IDIV ECX ; EDX:EAX除以ECX
00401283 |. 8BCA MOV ECX,EDX ; 余数放入ECX
00401285 |. 83C8 FF OR EAX,FFFFFFFF ; EAX=0xFFFFFFFF
00401288 |. 0FBE5424 0A MOVSX EDX,BYTE PTR SS:[ESP+A] ; 扩展第三位放入EDX
0040128D |. 0FAFCA IMUL ECX,EDX ; 刚才的余数乘以取出的第三位
00401290 |. 41 INC ECX ; ECX加1
00401291 |. 33D2 XOR EDX,EDX ; EDX清零
00401293 |. F7F1 DIV ECX ; EAX除以ECX
00401295 |. 50 PUSH EAX ; 结果放入堆栈
00401296 |. E8 A5000000 CALL ncrackme.00401340 ; 调用函数
0040129B |. 83C4 04 ADD ESP,4
0040129E |. 33F6 XOR ESI,ESI ; ESI=0
004012A0 |> E8 A5000000 /CALL ncrackme.0040134A
004012A5 |. 99 |CDQ ; 扩展EAX为EDX:EAX
004012A6 |. B9 1A000000 |MOV ECX,1A ; ECX=1A
004012AB |. F7F9 |IDIV ECX ; 除以ECX
004012AD |. 80C2 41 |ADD DL,41 ; 余数加41
004012B0 |. 885434 18 |MOV BYTE PTR SS:[ESP+ESI+18],DL ; 把结果让如[ESP+ESI+18]的地方
004012B4 |. 46 |INC ESI ; ESI+1
004012B5 |. 83FE 0F |CMP ESI,0F ; 比较ESI是否小于0F
004012B8 |.^ 72 E6 \JB SHORT ncrackme.004012A0 ; 小于就回跳
004012BA |. 57 PUSH EDI
004012BB |. 8D7C24 0C LEA EDI,DWORD PTR SS:[ESP+C] ; 注册名地址放入到EDI
004012BF |. 83C9 FF OR ECX,FFFFFFFF ; ECX=0xFFFFFFFF
004012C2 |. 33C0 XOR EAX,EAX ; EAX=0
004012C4 |. 33F6 XOR ESI,ESI ; ESI=0
004012C6 |. F2:AE REPNE SCAS BYTE PTR ES:[EDI]
004012C8 |. F7D1 NOT ECX ; ECX取反
004012CA |. 49 DEC ECX ; 减一得到用户名长度
004012CB |. 74 59 JE SHORT ncrackme.00401326
004012CD |> 8A4434 0C /MOV AL,BYTE PTR SS:[ESP+ESI+C] ; 取出用户名的第一位
004012D1 |. C0F8 05 |SAR AL,5 ; 右移5
004012D4 |. 0FBEC0 |MOVSX EAX,AL ; 扩展后送入EAX
004012D7 |. 8D1480 |LEA EDX,DWORD PTR DS:[EAX+EAX*4] ; EDX=EAX*5
004012DA |. 8D04D0 |LEA EAX,DWORD PTR DS:[EAX+EDX*8] ; EAX=EAX+EDX*8
004012DD |. 8D0440 |LEA EAX,DWORD PTR DS:[EAX+EAX*2] ; EAX=EAX*3
004012E0 |. 85C0 |TEST EAX,EAX ; 测试是否小于或等于0
004012E2 |. 7E 0A |JLE SHORT ncrackme.004012EE
004012E4 |. 8BF8 |MOV EDI,EAX ; EAX的结果放入EDX
004012E6 |> E8 5F000000 |/CALL ncrackme.0040134A ; 又调用刚才的一次
004012EB |. 4F ||DEC EDI ; 判断EDI是否为0
004012EC |.^ 75 F8 |\JNZ SHORT ncrackme.004012E6
004012EE |> E8 57000000 |CALL ncrackme.0040134A
004012F3 |. 99 |CDQ ; 扩展EAX为64位的EDX:EAX
004012F4 |. B9 1A000000 |MOV ECX,1A ; ECX等于1A
004012F9 |. 8D7C24 0C |LEA EDI,DWORD PTR SS:[ESP+C] ; 装入用户名的地址到EDI
004012FD |. F7F9 |IDIV ECX ; EDX:EAX除以ECX
004012FF |. 0FBE4C34 2C |MOVSX ECX,BYTE PTR SS:[ESP+ESI+2C] ; 取注册码的一位放入到ECX
00401304 |. 80C2 41 |ADD DL,41 ; 余数加上41
00401307 |. 0FBEC2 |MOVSX EAX,DL ; DL扩展为32位后放入EAX
0040130A |. 2BC1 |SUB EAX,ECX ; EAX得到的结果减去注册码的第一个
0040130C |. 885434 1C |MOV BYTE PTR SS:[ESP+ESI+1C],DL ; 放回用户名的地方
00401310 |. 99 |CDQ ; 扩展EAX为64位形式
00401311 |. 33C2 |XOR EAX,EDX ; EAX和EDX异或
00401313 |. 83C9 FF |OR ECX,FFFFFFFF ; ECX=0xFFFFFFFF
00401316 |. 2BC2 |SUB EAX,EDX ; EAX-EDX
00401318 |. 03D8 |ADD EBX,EAX ; EBX=EBX+EAX
0040131A |. 33C0 |XOR EAX,EAX ; EAX=0
0040131C |. 46 |INC ESI ; ESI+1
0040131D |. F2:AE |REPNE SCAS BYTE PTR ES:[EDI] ; 在用户名里面搜索0
0040131F |. F7D1 |NOT ECX ; 取反
00401321 |. 49 |DEC ECX ; ECX-1等于用户名长度
00401322 |. 3BF1 |CMP ESI,ECX
00401324 |.^ 72 A7 \JB SHORT ncrackme.004012CD
00401326 |> 5F POP EDI
00401327 |. 8BC3 MOV EAX,EBX
00401329 |. 5E POP ESI
0040132A |. 5B POP EBX
0040132B |. 83C4 30 ADD ESP,30
0040132E \. C3 RETN
源代码:
#include<stdio.h>
#include<string.h>
unsigned long u;char m[14];int kk;
unsigned long o(void)
{
unsigned long p;
u*=0x343FD;
p=u;
p=u+0X269EC3;
u=p;
p>>=16;
p&=0x7FFF;
return p;
}
void q(unsigned long *f)
{
u=*f;
}
int main(void)
{
char a[10];int l;int y;int MyEax;int MyEdx;int MyEdi;
int c;int d;unsigned long e;int MyEsi=0;int k;unsigned long MyEcx;
printf("请输入用户名:");
scanf("%s",a);
d=strlen(a);
while(d>=3)
{
c=(int)a[0]%(int)a[1];
e=0xFFFFFFFF;
c*=(int)a[2];
c+=1;
e/=c;
q(&e);
while(MyEsi<0xF)
{
e=o();
l=e%0x1A;
m[MyEsi]=l+0x41;
MyEsi++;
}
k=strlen(a);
for(y=0;y<k;y++)
{
MyEax=(int)a[y];
MyEax>>=5;
MyEdx=MyEax*5;
MyEax=MyEax+MyEdx*8;
MyEax*=3;MyEdi=MyEax;
if(MyEdi<=0){
MyEcx=o();
MyEcx%=0x1A;
MyEcx+=0x41;
kk=(int)MyEcx;
printf("%x\n",kk);
}
else{
while(MyEdi!=0){
o();
MyEdi-=1;
}
MyEcx=o();
MyEcx%=0x1A;
MyEcx+=0x41;
kk=(int)MyEcx;
printf("%x\n",kk);
}
}
return 0;
}
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)