我来写个破文
为什么?听说看雪骗到精是可以上传文件的,我就想骗个精
破解挺容易的,适合新手吧,高手要是看了,不妨指点一下
这是我写的第一编破文,是在看雪发的第二个贴(处女贴昨晚发了,是在破解时遇到2个函数,是软件调试论坛的<<问USER32.wsprintfA和KERNEL32.lstrcmp的功能>>,后来肯了半天msdn)
现在还不能上传,被开刀的是<<加密与解密(第二版)>>第四章的TraceMe,能上传的仁兄帮我上传吧,或者我骗到精后再上传
运行TraceMe,输入用户名wenstory,密码123456789,提示”序列号错误,再来一次”,退出
用peid看一下 显示Microsoft Visual C++ 6.0,应该是没壳吧,我还不会脱壳呢
用刚从论坛下载的OllyDbg1.1打开
按CCDebuger的OllyDBG 入门系列说的,在代码处点右键->查找->所有参考文本字串
开什么玩笑,竟然找不到”序列号错误,再来一次”(我也不知道为什么找不到)
试试函数参考的办法吧
在代码处点右键->查找->当前模块中的名称 (标签),在这里找到USER32.GetDlgItemTextA在这个函数上右击,在弹出菜单上选择“在每个参考上设置断点”,
点击查看->断点,可以看到设置了一个断点在004011A3
这样,断点就设置好了
双击断点,来到004011A3处,发现向下有2个地方调用了GetDlgItemTextA函数,应该是获取用户名和密码的
004011A3 . 8B3D A0404000 mov edi, [<&USER32.GetDlgItemTextA>] ; USER32.GetDlgItemTextA
004011A9 . 53 push ebx
004011AA . 8D4424 4C lea eax, [esp+4C]
004011AE . 6A 51 push 51 ; /Count = 51 (81.)
004011B0 . 50 push eax ; |Buffer
004011B1 . 6A 6E push 6E ; |ControlID = 6E (110.)
004011B3 . 56 push esi ; |hWnd
004011B4 . FFD7 call edi ; \GetDlgItemTextA
004011B6 . 8D8C24 9C0000>lea ecx, [esp+9C]
004011BD . 6A 65 push 65 ; /Count = 65 (101.)
004011BF . 51 push ecx ; |Buffer
004011C0 . 68 E8030000 push 3E8 ; |ControlID = 3E8 (1000.)
004011C5 . 56 push esi ; |hWnd
004011C6 . 8BD8 mov ebx, eax ; |
004011C8 . FFD7 call edi ; \GetDlgItemTextA
004011CA . 8A4424 4C mov al, [esp+4C]
004011CE . 84C0 test al, al
004011D0 . 74 76 je short 00401248
004011D2 . 83FB 05 cmp ebx, 5
004011D5 . 7C 71 jl short 00401248
004011D7 . 8D5424 4C lea edx, [esp+4C]
004011DB . 53 push ebx
004011DC . 8D8424 A00000>lea eax, [esp+A0]
004011E3 . 52 push edx
004011E4 . 50 push eax
004011E5 . E8 56010000 call 00401340
而且在2次调用GetDlgItemTextA函数后就有个call 00401340,估计这就是计算密码的地方,这时我将断点移004011E3处,会省去很多麻烦(一直按F7会跳进系统空间,苦不堪言,一直按F8会跳过call 00401340,又要重来),不用怕按错进入系统空间
按F9运行
输入用户名wenstory,密码123456789,按check,停在004011E3处了
按F7单步跟进,来到00401340
00401340 /$ 55 push ebp ; 保存现场
00401341 |. 8B6C24 0C mov ebp, [esp+C]
00401345 |. 56 push esi
00401346 |. 57 push edi
00401347 |. 8B7C24 18 mov edi, [esp+18] ; edi为用户名长度
0040134B |. B9 03000000 mov ecx, 3 ; ecx置3
00401350 |. 33F6 xor esi, esi ; esi清0 esi用于保存运算结果
00401352 |. 33C0 xor eax, eax
00401354 |. 3BF9 cmp edi, ecx ; 将用户名长度与3比较
00401356 |. 7E 21 jle short 00401379 ; 用户名长度至少4位,少于4位则跳转
00401358 |. 53 push ebx ; 用户名长度入栈
00401359 |> 83F8 07 /cmp eax, 7 ; 405030数组为8位,用于保证下面的ebx取值不要越界
0040135C |. 7E 02 |jle short 00401360
0040135E |. 33C0 |xor eax, eax ; 与前2句保证ebx不要越界
00401360 |> 33D2 |xor edx, edx ; edx置0
00401362 |. 33DB |xor ebx, ebx ; ebx置0
00401364 |. 8A1429 |mov dl, [ecx+ebp] ; 取用户名第ecx位
00401367 |. 8A98 30504000 |mov bl, [eax+405030] ; 405030的内容应该是数组12,10,19,9,12,11,10,8 ebx取数组第eax位
0040136D |. 0FAFD3 |imul edx, ebx ; edx为edx(edx的ascii值)乘ebx的值
00401370 |. 03F2 |add esi, edx ; 将edx值加到esi
00401372 |. 41 |inc ecx ; ecx自增
00401373 |. 40 |inc eax ; eax自增
00401374 |. 3BCF |cmp ecx, edi ; 用户名从第4位起向后每一位都计算
00401376 |.^ 7C E1 \jl short 00401359 ; 小于用户名长度时则跳转
00401378 |. 5B pop ebx
00401379 |> 56 push esi ; /<%ld>
0040137A |. 68 78504000 push 00405078 ; |Format = "%ld"
0040137F |. 55 push ebp ; |s
00401380 |. FF15 9C404000 call [<&USER32.wsprintf>; \wsprintfA
00401386 |. 8B4424 1C mov eax, [esp+1C]
0040138A |. 83C4 0C add esp, 0C
0040138D |. 55 push ebp ; /String2
0040138E |. 50 push eax ; |String1
0040138F |. FF15 04404000 call [<&KERNEL32.lstrcm>; \lstrcmpA
00401395 |. F7D8 neg eax
00401397 |. 1BC0 sbb eax, eax
00401399 |. 5F pop edi
0040139A |. 5E pop esi
0040139B |. 40 inc eax
0040139C |. 5D pop ebp
0040139D \. C3 retn
(可以比较一下我现在和昨晚做的注释,顺便提个问题:405030是数组我是猜的,我看到输入不同的用户名这里都不改变,,而且又近着那些提示,有谁能告诉我是如何知道的吗?)
插曲又来了,在<<问USER32.wsprintfA和KERNEL32.lstrcmp的功能>>中我说输入badboy计算得到4601其实是我笔算错误的,算多几次后才发觉是4585
上面的程序看懂就知道密码是怎样生成的了
密码规则:
1 数组k为[12,10,19,9,12,11,10,8]
2 用户名至少4位()
3 密码初始为0
4 从i=3开始到i=name.Length,name[i]的ascii值×k[(i-3)%8]加到密码中
注册机已经做出,使用mfc在.Net下做的
界面
(在word里编辑是图片来的,但我没图片上传权限)
生成密码按钮的代码
void CkeygenForTraceMeDlg::OnBnClickedOk()
{
UpdateData(true);
int k[]={12,10,19,9,12,11,10,8};
int a=name.GetLength();
int j=0;
serial=0;
if(a<4)
MessageBox("用户名至少4位",MB_OK);
for(int i=3;i<a;i++)
{
serial+=(name[i]*k[j]);
j++;
j=j%8;
}
UpdateData(false);
}
其中name为第一个编辑框的value CString name;
Serial为第二个编辑框的value float serial;
C++程序期待中,因为我懒,想找个人帮我写
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)