【文章标题】: 加密解密第二版补充习题09
【文章作者】: kanghtta
【作者邮箱】: kanghtta@hotmail.com
【作者主页】: http://kanghtta.cublog.cn
【作者QQ号】: 18381291
【软件名称】: czCrackMe_09
【软件大小】: 96kb
【下载地址】: 见附件
【加壳方式】: 无
【编写语言】: MASM
【使用工具】: peid OllyICE
【操作平台】: xp
【软件介绍】: Name/Serial 难度 3
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
大家好,今天洛阳下了点小雨,这段时间刚开始学习PE文件格式,由于自我感觉它很重要,所以打算花点时间学学。就把Crackme
冷落了,但至少 一星期一个是必须的。好了,废话不说了,以后尽量做到直奔主题。JMP 正文
正文:
用PEid打开,无壳,信息收集见上文;这个程序在我的屏幕上看起来有些好笑,一个按钮隐藏在位图后面,不过,
不用担心,它能用;
2)运行程序,name/serial 系列号保护方式,输入name: kanghtta serial:cracker
嘿嘿。。messagebox : sorry Cracker, wrong。 首先考虑用字串参考;
3)OD载入 ,反汇编窗口中,右键-〉查找-〉所有参考文本字串
文本字串参考位于 czCrackM:.text, 条目 7
地址=0040144E 反汇编=push 00403041 文本字串=ASCII " Sorry Cracker, wrong."
4)在字串上直接回车,当然你也可以右键-〉反汇编窗口跟随 在00401340处F2,F9运行窗口;
输入:name: kanghtta serial:Cracker 后,check 它,程序被断下来;
00401340 |. 6A 40 push 40 ; /Count = 40 (64.)
00401342 |. 68 30314000 push 00403130 ; |Buffer = czCrackM.00403130
00401347 |. FF35 C3304000 push dword ptr [4030C3] ; |hWnd = NULL
0040134D |. E8 A6030000 call <jmp.&USER32.GetWindowTextA> ; \GetWindowTextA 取name,
00401352 |. 83F8 04 cmp eax, 4 ;name不得小于4位,否则完蛋
00401355 |. 0F8E E9000000 jle 00401444
0040135B |. 6A 40 push 40 ; /Count = 40 (64.)
0040135D |. 68 70314000 push 00403170 ; |Buffer = czCrackM.00403170
00401362 |. 68 B90B0000 push 0BB9 ; |ControlID = BB9 (3001.)
00401367 |. FF75 08 push dword ptr [ebp+8] ; |hWnd
0040136A |. E8 77030000 call <jmp.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA 取 serial
0040136F |. 83F8 04 cmp eax, 4 ; serial不得小于四位,否则完蛋
00401372 |. 0F8E CC000000 jle 00401444
00401378 |. A3 BF304000 mov dword ptr [4030BF], eax
0040137D |. FF35 C3304000 push dword ptr [4030C3] ; /hWnd = NULL
00401383 |. E8 AC030000 call <jmp.&USER32.SetFocus> ; \SetFocus 设置键盘焦点
00401388 |. BF 30314000 mov edi, 00403130 name地址送edi
0040138D |. BE 30314000 mov esi, 00403130 name地址送esi
00401392 |> AC /lods byte ptr [esi] 将name按字节送al
00401393 |. 0C 00 |or al, 0 判断字符串是否结束
00401395 |. 74 05 |je short 0040139C
00401397 |. 0C 20 |or al, 20 第五位置1
00401399 |. AA |stos byte ptr es:[edi] 运算后的字符按字节存储
0040139A |.^ EB F6 \jmp short 00401392
0040139C |> BF 70314000 mov edi, 00403170 serial地址送edi
004013A1 |. BE 70314000 mov esi, 00403170 serial地址送esi
004013A6 |. 8D1D 30314000 lea ebx, dword ptr [403130] name送ebx
004013AC |> AC /lods byte ptr [esi] 按字节从串取,这里取的serial,
004013AD |. 0C 00 |or al, 0
004013AF |. 74 0A |je short 004013BB
004013B1 |. 8A13 |mov dl, byte ptr [ebx] name按字节送dl
004013B3 |. 2AD0 |sub dl, al 相减
004013B5 |. 8AC2 |mov al, dl 结果送al
004013B7 |. AA |stos byte ptr es:[edi] 存入serial串
004013B8 |. 43 |inc ebx ebx指针加一 ,指向下一字符
004013B9 |.^ EB F1 \jmp short 004013AC
004013BB |> 8B0D BF304000 mov ecx, dword ptr [4030BF] serial字符数送ecx
004013C1 |> 80C9 00 /or cl, 0
004013C4 |. 74 60 |je short 00401426
004013C6 |. 51 |push ecx serial字符数进栈
004013C7 |. 68 70314000 |push 00403170 运算后的serial字串进栈
004013CC |. E8 83020000 |call 00401654 F7跟进
00401654 /$ 55 push ebp
00401655 |. 8BEC mov ebp, esp ; 现场保存
00401657 |. 51 push ecx
00401658 |. 57 push edi
00401659 |. 52 push edx
0040165A |. 56 push esi
0040165B |. 33C9 xor ecx, ecx ; ecx清零
0040165D |. 8B7D 08 mov edi, dword ptr [ebp+8] ;serial指针送edi
00401660 |. FF75 08 push dword ptr [ebp+8] ; /String
00401663 |. E8 FC000000 call <jmp.&KERNEL32.lstrlenA> ; \lstrlenA ;计算serial的字符串长度
00401668 |. EB 23 jmp short 0040168D ; 跳转处判断eax是否为零,不为跳回40166A处
0040166A |> 33D2 /xor edx, edx ;edx清零
0040166C |. 8A17 |mov dl, byte ptr [edi] ;serial送dl
0040166E |. 80EA 30 |sub dl, 30 ;减30
00401671 |. 8BF0 |mov esi, eax ;serial字符数送esi
00401673 |. 4E |dec esi ;serial字符数减一
00401674 |. 50 |push eax ;保存serial字符数
00401675 |. 8BC2 |mov eax, edx ;相减的结果送eax
00401677 |. 53 |push ebx ; 保存ebx
00401678 |. BB 0A000000 |mov ebx, 0A 0A送ebx
0040167D |. EB 03 |jmp short 00401682
0040167F |> F7E3 |/mul ebx 结果存:edx:eax
00401681 |. 4E ||dec esi
00401682 |> 83FE 00 | cmp esi, 0 serial字符串是否处理完,没有就将ebx值相乘,循环乘seial字符数-1次
00401685 |.^ 77 F8 |\ja short 0040167F
00401687 |. 5B |pop ebx
00401688 |. 03C8 |add ecx, eax ;相乘的结果和ecx
0040168A |. 58 |pop eax ;eax出栈,字符数
0040168B |. 47 |inc edi
0040168C |. 48 |dec eax
0040168D |> 0BC0 or eax, eax ; 判断eax是否为零
0040168F |.^ 75 D9 \jnz short 0040166A ;不为零返回循环
00401691 |. 8BC1 mov eax, ecx
00401693 |. 5E pop esi
00401694 |. 5A pop edx
00401695 |. 5F pop edi
00401696 |. 59 pop ecx
00401697 |. C9 leave
00401698 \. C2 0400 retn 4
004013D1 |. F7E1 |mul ecx
004013D3 |. 68 B0314000 |push 004031B0
004013D8 |. 50 |push eax
004013D9 |. E8 BE020000 |call 0040169C 调用: wsprintf 转换 % Lu
004013DE |. BF B0314000 |mov edi, 004031B0
004013E3 |. BE B0314000 |mov esi, 004031B0 004031B0 03 06 02 03 05 09 06 07 03 .
004013E8 |> AC |/lods byte ptr [esi]
004013E9 |. 0C 00 ||or al, 0
004013EB |. 74 06 ||je short 004013F3
004013ED |. 83E0 0F ||and eax, 0F
004013F0 |. AA ||stos byte ptr es:[edi]
004013F1 |.^ EB F5 |\jmp short 004013E8
004013F3 |> 8B0D BF304000 |mov ecx, dword ptr [4030BF] 字符数送ecx
004013F9 |. D1E9 |shr ecx, 1 逻辑右移一位
004013FB |. BF F0304000 |mov edi, 004030F0 目的串送edi
00401400 |. BE B0314000 |mov esi, 004031B0 源串送esi
00401405 |. 8D99 B0314000 |lea ebx, dword ptr [ecx+4031B0] 源串地址+ecx送ebx
0040140B |> 80C9 00 |/or cl, 0
0040140E |. 74 12 ||je short 00401422
00401410 |. AC ||lods byte ptr [esi] ;从esi串按字节将数字串串取出
00401411 |. 33D2 ||xor edx, edx ;edx清0
00401413 |. 8A13 ||mov dl, byte ptr [ebx] 取ebx数字送dl
00401415 |. 02C2 ||add al, dl 相加
00401417 |. 8A17 ||mov dl, byte ptr [edi]
00401419 |. 02C2 ||add al, dl al和dl加
0040141B |. 24 0F ||and al, 0F 取al低4位
0040141D |. AA ||stos byte ptr es:[edi] al存004030F0
0040141E |. 49 ||dec ecx 循环计数器减一
0040141F |. 43 ||inc ebx ebx指针加一
00401420 |.^ EB E9 |\jmp short 0040140B 循环以上直到ecx为0跳转
00401422 |> 59 |pop ecx
00401423 |. 49 |dec ecx
00401424 |.^ EB 9B \jmp short 004013C1 跳转直到ecx为0
00401426 |> BE F0304000 mov esi, 004030F0 运算结果送esi
0040142B |. 8B1D BF304000 mov ebx, dword ptr [4030BF] serial字符数送ebx
00401431 |. 8BCB mov ecx, ebx
00401433 |. D1E9 shr ecx, 1 ecx逻辑右移一位
00401435 |> 8A06 /mov al, byte ptr [esi]
00401437 |. 80C9 00 |or cl, 0 是否为0,为0 则注册成功
0040143A |. 74 39 |je short 00401475
0040143C |. 38D8 |cmp al, bl 按字节比较004030F0和字符数,相同则ecx减一;减到0 则注册成功;
0040143E |. 75 04 |jnz short 00401444
00401440 |. 46 |inc esi
00401441 |. 49 |dec ecx
00401442 |.^ EB F1 \jmp short 00401435
00401444 |> 68 00200000 push 2000 ; /Style = MB_OK|MB_TASKMODAL
00401449 |. 68 18304000 push 00403018 ; |Title = " Error"
0040144E |. 68 41304000 push 00403041 ; |Text = " Sorry Cracker, wrong."
00401453 |. FF75 08 push dword ptr [ebp+8] ; |hOwner
00401456 |. E8 BB020000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA
0040145B |. 6A 40 push 40 ; /Length = 40 (64.)
0040145D |. 68 F0304000 push 004030F0 ; |Destination = czCrackM.004030F0
00401462 |. E8 0F030000 call <jmp.&KERNEL32.RtlZeroMemory> ; \RtlZeroMemory
00401467 |. 6A 40 push 40 ; /Length = 40 (64.)
00401469 |. 68 B0314000 push 004031B0 ; |Destination = czCrackM.004031B0
0040146E |. E8 03030000 call <jmp.&KERNEL32.RtlZeroMemory> ; \RtlZeroMemory
00401473 |. EB 2F jmp short 004014A4
00401475 |> 68 00200000 push 2000 ; /Style = MB_OK|MB_TASKMODAL
0040147A |. 68 2D304000 push 0040302D ; |Title = " <Registered>"
0040147F |. 68 5A304000 push 0040305A ; |Text = " You did it!"
00401484 |. FF75 08 push dword ptr [ebp+8] ; |hOwner
00401487 |. E8 8A020000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA
0040148C |. 6A 40 push 40 ; /Length = 40 (64.)
0040148E |. 68 F0304000 push 004030F0 ; |Destination = czCrackM.004030F0
00401493 |. E8 DE020000 call <jmp.&KERNEL32.RtlZeroMemory> ; \RtlZeroMemory
00401498 |. 6A 40 push 40 ; /Length = 40 (64.)
0040149A |. 68 B0314000 push 004031B0 ; |Destination = czCrackM.004031B0
0040149F |. E8 D2020000 call <jmp.&KERNEL32.RtlZeroMemory> ; \RtlZeroMemory
004014A4 |> EB 0E jmp short 004014B4
004014A6 |> 66:83F8 67 cmp ax, 67
004014AA |. 75 08 jnz short 004014B4
004014AC |. FF75 08 push dword ptr [ebp+8] ; /hWnd
004014AF |. E8 26020000 call <jmp.&USER32.DestroyWindow> ; \DestroyWindow
004014B4 |> EB 15 jmp short 004014CB
004014B6 |> FF75 14 push dword ptr [ebp+14] ; /lParam
004014B9 |. FF75 10 push dword ptr [ebp+10] ; |wParam
004014BC |. FF75 0C push dword ptr [ebp+C] ; |Message
004014BF |. FF75 08 push dword ptr [ebp+8] ; |hWnd
004014C2 |. E8 0D020000 call <jmp.&USER32.DefWindowProcA> ; \DefWindowProcA
004014C7 |. C9 leave
004014C8 |. C2 1000 retn 10
004014CB |> 33C0 xor eax, eax
004014CD |. C9 leave
004014CE \. C2 1000 retn 10
算法分析:
#include<iostream.h>
#include<windows.h>
#include<string.h>
#include<assert.h>
#include<iomanip.h>
#define C_ECX 0x7C80BDE6
long _cover(int count,char lpszSerial[])
{
int ecx=C_ECX;
int edx=0;
for(int i=0;i<count;i++)
{
edx=lpszSerial[i]-0x30;
int esi=count;
esi--;
int eax=edx;
int ebx=0x0A;
for(int j=0;j<esi;j++)
{
eax=ebx*eax;
}
ecx=ecx+eax;
}
return ecx;
}
bool _check_Key(int count,char *lpStr)
{ int bl=count;
count=count/2;
for(int i=0;i<=count;i++)
{
if(lpStr[i]!=bl)
return 0;
}
return 1;
}
void main()
{
char szName[20]={0,0,0};
char szSerial[20]={0,0,0};
//输入用户名
cout<<"请输入用户名 (大于4位):"<<endl;
cin>>szName;
int n_count=strlen(szName); //求用户名长度
assert(n_count>4);
//输入系列号
cout<<"请输入注册号(大于4位):"<<endl;
cin>>szSerial;
int s_count=strlen(szSerial);//求注册号长度
assert(s_count>4);
for(int i=0;i<n_count;i++)
{
szName[i]=szName[i]|0x20;
cout<<szName[i];
}
cout<<endl;
for(int j=0;j<s_count;j++)
{
char szMd1=szName[j];
szMd1-=szSerial[j];
szSerial[j]=szMd1;
cout<<szSerial[j];
}
cout<<endl;
char temp_string[10]={0,0,0};
char end_string[10]={0,0,0};
long int middle=0;
for(int k=0;k<s_count;k++)
{
middle=_cover(s_count,szSerial);
middle=middle*s_count;
wsprintf(temp_string,"%lu",middle);
i=0;
cout<<hex<<middle<<endl;
while(temp_string[i])
{ temp_string[i]&=0x0f;
i++;
}
middle=s_count/2;
i=middle;
j=0;
while(middle)
{
end_string[j]+=(temp_string[j]+temp_string[i]);
end_string[j]&=0x0f;
j++;
i++;
middle--;
}
}
s_count=strlen(szSerial);
cout<<"s_count"<<s_count<<endl;
bool a;
a=_check_Key(s_count,end_string);
if(a)
{
cout<<"you did it"<<endl;
}
esle cout<<"sorry cracker wrong"<<endl;
}
分析的过程中,被人打断多次,看有同学能弄出这个CRACKER的注册机来,注意:我要的是注册机算法,不是暴破,关于怎么爆破,我不需要;请另发别出;谢谢;
程序基本上是,反汇编到C 的还原 ;嘿嘿,转换的中间数值不知道怎么得出;
大虾们帮个忙?
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2008年04月20日 PM 12:29:44
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
上传的附件: