【文章标题】: 加密解密第二版补充习题破文
【文章作者】: kanghtta
【作者邮箱】: kanghtta@hotmail.com
【作者主页】: http://kanghtta.cublog.cn
【作者QQ号】: 18381291
【软件名称】: echap517
【软件大小】: 56.5kb
【下载地址】: 电子书带
【加壳方式】: 无
【编写语言】: Visual C++
【使用工具】: peid OllyICE
【操作平台】: Win XP
【软件介绍】: Name/Group/Serial
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
大家好, 好几天没练手了,打算开始复兴数学英语准备考研,时间也比较紧,以后,一星期做一个破解练习,要不手生就
白入门了。至于考研和工作,也矛盾了一段时间,希望有经验之士给点建议。嘿嘿。。。好了,开始分析今天的程序吧。
首先,打开程序,这是个Name/Group/Serial 验正的程序,分别输入:
Name : cracker
Group : kang
Serial : kanghtta
然后 Check它,没反应,由于有了上次错误的经验,所以还是看看字串参考,不过,实际打算用一次函数参考。好了,废话不说;
2) 用PEid收集信息填入CTC 的软件信息。
3) OllyICE 载入, 右键-〉 查找-〉所有文本字串;并没有找到我感兴趣的字串,也许你可以嘿嘿,好了,函数参考;
4) ctrl + n 打开名称窗口, 上下滚动看看,有没有关于文本处理的函数. 有了 0040B258:GetDlgItemTextA
5) 下断,右键-> 在每个参考上设置断点; 看状态栏,与设置三个断点 .
/**********************************
猜测一下: 这个程序是Name/Group/Serial ,而GetDlgItemText函数有三个断点,会不会是获取Name/Group/Serial的?
好了,猜是猜,下面来看看猜得怎么样? 当然,入门练习提倡不提倡猜测,这个我不知道了,,嘿嘿...
****************************************************************/
6) F9 运行程序,在弹出的对话框的编辑控件中输入:
Name : cracker
Group : kang
Serial : kanghtta
然后Check按钮;程序被断下来了 ,代码如下,让我们分析它,注意,分析代码的时候请留意信息窗口,和堆栈/寄存器窗口;
0040140B |. FF15 58B24000 call dword ptr [<&USER32.GetDlgItemTe>; \GetDlgItemTextA 获取文本
我们想知道这里获取的文本什么,用鼠标点, 004013F5,至于为什么要点它,请看我前面的文章,或者是MSDN,
同样的工作我不能复制两遍; 我们看004013F5 处,在信息窗口看到如下:
004097F8=004097F8 (ASCII "Cracker") 这说明我们前面的猜测是对的,心里有点喜悦吧,但是小心,刚开始呢?
00401411 |. A3 E8974000 mov dword ptr [4097E8], eax 如果调用成功,eax中返回的是字串的字符数 ,F8跟进,eax值为7.
00401416 |. E8 85FFFFFF call 004013A0 关键,F7 跟进;
004013A0 /$ 833D E8974000>cmp dword ptr [4097E8], 1E 取到的字符数和1E比较
004013A7 |. 76 0A jbe short 004013B3 小于或等于则跳,程序在这跳了.跳到下面的retn
004013A9 |. C705 E8974000>mov dword ptr [4097E8], 1E 否则,用1E替换;
004013B3 \> C3 retn
0040141B |. 8B0D E8974000 mov ecx, dword ptr [4097E8] 字符数送ecx ,
00401421 |. 8935 EC974000 mov dword ptr [4097EC], esi esi=1 小于等于则跳.
00401427 |. 3BCE cmp ecx, esi 比较
00401429 |. 76 4A jbe short 00401475 小于等于1则跳
0040142B |. 8B15 F0974000 mov edx, dword ptr [4097F0] 初始化edx=1
00401431 |. 8B1D 70974000 mov ebx, dword ptr [409770] 初始化ebx=0
00401437 |> 0FBEBA F79740>/movsx edi, byte ptr [edx+4097F7] Ceacker 的字符送依次送edi
0040143E |. 0FBE82 577040>|movsx eax, byte ptr [edx+407057] 取一字符送eax
00401445 |. 0FAFF8 |imul edi, eax 相乘,结果放edi;
00401448 |. 0FBE86 1F7040>|movsx eax, byte ptr [esi+40701F]
0040144F |. 0FAFF8 |imul edi, eax 相乘
00401452 |. 0FAFFA |imul edi, edx
00401455 |. 42 |inc edx ;edx加一
00401456 |. 03DF |add ebx, edi ; edi的值和ebx相加
00401458 |. 46 |inc esi ;esi加一, 以便指向下一字符
00401459 |. 893D 74974000 |mov dword ptr [409774], edi
0040145F |. 8915 F0974000 |mov dword ptr [4097F0], edx
00401465 |. 891D 70974000 |mov dword ptr [409770], ebx
0040146B |. 8935 EC974000 |mov dword ptr [4097EC], esi
00401471 |. 3BF1 |cmp esi, ecx 循环以上操作次数 ecx-1
00401473 |.^ 72 C2 \jb short 00401437
00401475 |> 5F pop edi
00401476 |. 5E pop esi
00401477 |. 5B pop ebx
00401478 \. C3 retn
00401479 CC int3
0040147A CC int3
0040147B CC int3
0040147C CC int3
0040147D CC int3
0040147E CC int3
0040147F CC int3
00401480 /$ 8B4424 04 mov eax, dword ptr [esp+4]
00401484 |. 53 push ebx
00401485 |. 56 push esi
00401486 |. 57 push edi
00401487 |. 6A 1E push 1E ; /Count = 1E (30.)
00401489 |. 68 B0974000 push 004097B0 ; |Buffer = echap517.004097B0
0040148E |. 68 E9030000 push 3E9 ; |ControlID = 3E9 (1001.)
00401493 |. 50 push eax ; |hWnd
00401494 |. 33FF xor edi, edi ; |
00401496 |. FF15 58B24000 call dword ptr [<&USER32.GetDlgItemTe>; \GetDlgItemTextA 获取第二个字符串kang
0040149C |. A3 9C974000 mov dword ptr [40979C], eax
004014A1 |. E8 1AFFFFFF call 004013C0 比较字符数是否大于1E
004014A6 |. BA 01000000 mov edx, 1 ;初始化edx=1
004014AB |. 8B0D 9C974000 mov ecx, dword ptr [40979C] 初始化ecx=取得字符数
004014B1 |. 8BF2 mov esi, edx ;初始化esi=1
004014B3 |. 893D 74974000 mov dword ptr [409774], edi 保存上次运算的edi值
004014B9 |. 8935 F0974000 mov dword ptr [4097F0], esi
004014BF |. 8915 EC974000 mov dword ptr [4097EC], edx
004014C5 |. 3BCA cmp ecx, edx
004014C7 |. 76 38 jbe short 00401501
004014C9 |> 0FBE9E AF9740>/movsx ebx, byte ptr [esi+4097AF] 依次取kang的字符运算,
004014D0 |. 0FBE86 577040>|movsx eax, byte ptr [esi+407057]
004014D7 |. 0FAFD8 |imul ebx, eax
004014DA |. 0FBE82 1F7040>|movsx eax, byte ptr [edx+40701F]
004014E1 |. 0FAFD8 |imul ebx, eax
004014E4 |. 0FAFDE |imul ebx, esi 运送结果存ebx
004014E7 |. 46 |inc esi
004014E8 |. 03FB |add edi, ebx
004014EA |. 42 |inc edx
004014EB |. 891D 74974000 |mov dword ptr [409774], ebx 保存ebx值
004014F1 |. 8935 F0974000 |mov dword ptr [4097F0], esi
004014F7 |. 8915 EC974000 |mov dword ptr [4097EC], edx
004014FD |. 3BD1 |cmp edx, ecx
004014FF |.^ 72 C8 \jb short 004014C9
00401501 |> 893D 7C974000 mov dword ptr [40977C], edi 保存本次运算的edi
00401507 |. 013D 70974000 add dword ptr [409770], edi 和name运算后得的ebx值相加存409770
0040150D |. 5F pop edi
0040150E |. 5E pop esi
0040150F |. 5B pop ebx
00401510 \. C3 retn 返回值
返回到的程序段:
00401A01 . 83C4 04 add esp, 4
00401A04 . A1 E8974000 mov eax, dword ptr [4097E8] name字符数送eax
00401A09 . 83F8 03 cmp eax, 3 是否大于三
00401A0C . 73 07 jnb short 00401A15 大于等于跳转
00401A0E . 33C0 xor eax, eax
00401A10 . 5F pop edi
00401A11 . 5E pop esi
00401A12 . C2 1000 retn 10
00401A15 > 0FAFC0 imul eax, eax name 字符数相乘
00401A18 . 6A 0A push 0A ; /Count = A (10.)
00401A1A . A3 74974000 mov dword ptr [409774], eax ; |
00401A1F . A1 AC974000 mov eax, dword ptr [4097AC] ; |
00401A24 . 68 90974000 push 00409790 ; |Buffer = echap517.00409790
00401A29 . 0FAF05 749740>imul eax, dword ptr [409774] ; |
00401A30 . 68 EA030000 push 3EA ; |ControlID = 3EA (1002.)
00401A35 . A3 7C974000 mov dword ptr [40977C], eax ; |
00401A3A . 56 push esi ; |hWnd
00401A3B . FF15 58B24000 call dword ptr [<&USER32.GetDlgItemTe>; \GetDlgItemTextA 获取kanghtta字符串
00401A41 . 68 90974000 push 00409790 字符串kanghtta进栈
00401A46 . E8 250F0000 call 00402970
00401A4B . 83C4 04 add esp, 4
00401A4E . 8B0D A8974000 mov ecx, dword ptr [4097A8] ; echap517.00400000
00401A54 . A3 88974000 mov dword ptr [409788], eax eax=0
00401A59 . 51 push ecx
00401A5A . 56 push esi
00401A5B . E8 30F8FFFF call 00401290 此处为关键跟进
00401290 /$ A1 9C974000 mov eax, dword ptr [40979C] eax=4 Grup的字符数送eax
00401295 |. 8B0D E8974000 mov ecx, dword ptr [4097E8] ecx =7 name的字符数送ecx
0040129B |. 8B5424 08 mov edx, dword ptr [esp+8] edx=00400000
0040129F |. A3 74974000 mov dword ptr [409774], eax
004012A4 |. 8B4424 04 mov eax, dword ptr [esp+4] 字符送eax
堆栈 ss:[0012F904]=00130B64, (UNICODE "=""win32"",version=""5.2.2.3""C:\WINDOWS\WinSxS\Manifests\x86_Microsoft.Windows.Networking.RtcDll_6595b6")
eax=00000004
004012A8 |. 52 push edx
004012A9 |. 50 push eax
004012AA |. 890D 7C974000 mov dword ptr [40977C], ecx ;name字符数送: 409774
004012B0 |. C705 A4974000>mov dword ptr [4097A4], 0 ;4097A4=0
004012BA |. E8 61020000 call 00401520 关键 跟进
00401520 /$ 83EC 10 sub esp, 10
00401523 |. 8B0D 70974000 mov ecx, dword ptr [409770] 两次运算之和运算送ecx
00401529 |. 030D AC974000 add ecx, dword ptr [4097AC]
这里有个问题,4097AC中的数据是怎么来的? 数据窗口中跟随,发现004097AC 90 09 00 00 6B 61 6E 67 ?..kang.
是我们的组名前四字节!
0040152F |. 53 push ebx
00401530 |. 56 push esi
00401531 |. 81F9 FFFFFF7F cmp ecx, 7FFFFFFF 比较是超出最大范围
00401537 |. 57 push edi
00401538 |. 76 06 jbe short 00401540 不大于则跳
0040153A |. 81E9 FFFFFF7F sub ecx, 7FFFFFFF
00401540 |> 890D 70974000 mov dword ptr [409770], ecx 保存两次运算的和
00401546 |. 390D 88974000 cmp dword ptr [409788], ecx 运算之和和Code比较 也就是, 第三个输入Serial
00409788 00 00 00 00 00 00 00 00 6B 61 6E 67 68 74 74 61 ........kanghtta
0040154C 75 63 jnz short 004015B1 不相等则跳,跳转就完蛋,由此,只要输入的name 和group ,在把此处的ecx找出为Serial就成功;F8继续
ecx=017229A3
ds:[00409788]=00000000
0040154E |. 8D4424 0C lea eax, dword ptr [esp+C]
00401552 |. 68 6C844000 push 0040846C ; /Format = "REGISTERED!"
00401557 |. 50 push eax ; |s
00401558 |. FF15 60B24000 call dword ptr [<&USER32.wsprintfA>] ; \wsprintfA
0040155E |. 8D4C24 14 lea ecx, dword ptr [esp+14]
00401562 |. 8B7C24 28 mov edi, dword ptr [esp+28]
00401566 |. 83C4 08 add esp, 8
00401569 |. 51 push ecx ; /Text
0040156A |. 68 EE030000 push 3EE ; |ControlID = 3EE (1006.)
0040156F |. 57 push edi ; |hWnd
00401570 |. FF15 68B24000 call dword ptr [<&USER32.SetDlgItemTe>; \SetDlgItemTextA
00401576 |. 6A 01 push 1 ; /Enable = TRUE
00401578 |. 8B1D 64B24000 mov ebx, dword ptr [<&USER32.GetDlgI>; |USER32.GetDlgItem
0040157E |. 68 EC030000 push 3EC ; |/ControlID = 3EC (1004.)
00401583 |. 57 push edi ; ||hWnd
00401584 |. FFD3 call ebx ; |\GetDlgItem
00401586 |. 50 push eax ; |hWnd
00401587 |. 8B35 54B24000 mov esi, dword ptr [<&USER32.EnableW>; |USER32.EnableWindow
0040158D |. FFD6 call esi ; \EnableWindow
0040158F |. 8B4424 24 mov eax, dword ptr [esp+24]
00401593 |. 6A 00 push 0 ; /lParam = NULL
00401595 |. 68 001B4000 push 00401B00 ; |DlgProc = echap517.00401B00
0040159A |. 57 push edi ; |hOwner
0040159B |. 6A 68 push 68 ; |pTemplate = 68
0040159D |. 50 push eax ; |hInst
0040159E |. FF15 5CB24000 call dword ptr [<&USER32.DialogBoxPar>; \DialogBoxParamA
004015A4 |. 6A 00 push 0 ; /Enable = FALSE
004015A6 |. 68 EB030000 push 3EB ; |/ControlID = 3EB (1003.)
004015AB |. 57 push edi ; ||hWnd
004015AC |. FFD3 call ebx ; |\GetDlgItem
004015AE |. 50 push eax ; |hWnd
004015AF |. FFD6 call esi ; \EnableWindow
004015B1 |> 5F pop edi ; 跳到此处
004015B2 |. 5E pop esi
004015B3 |. 5B pop ebx
004015B4 |. 83C4 10 add esp, 10
004015B7 \. C3 retn
返回到此处:
004012BF |. 83C4 08 add esp, 8
004012C2 \. C3 retn
返回到此处;
00401A60 . 83C4 08 add esp, 8
00401A63 . 68 B0974000 push 004097B0 ; ASCII "kang"
00401A68 . 68 F8974000 push 004097F8 ; ASCII "Cracker"
00401A6D . E8 5EF8FFFF call 004012D0
00401A72 . 83C4 08 add esp, 8
00401A75 . A1 88974000 mov eax, dword ptr [409788]
00401A7A . 8B0D A4974000 mov ecx, dword ptr [4097A4]
00401A80 . 50 push eax
00401A81 . 51 push ecx
00401A82 . E8 F9F8FFFF call 00401380
00401A87 . 83C4 08 add esp, 8
00401A8A . 8B15 88974000 mov edx, dword ptr [409788]
00401A90 . 3915 A4974000 cmp dword ptr [4097A4], edx
00401A96 . 75 0A jnz short 00401AA2
00401A98 . C705 74974000>mov dword ptr [409774], 1
00401AA2 > 33C0 xor eax, eax
00401AA4 . 5F pop edi
00401AA5 . 5E pop esi
00401AA6 . C2 1000 retn 10 返回到系统领空,程序到此完蛋;
本题 是将输入的用户名和组名相加;产生注册号 两次计算的结果保存在409770地址中;
00401465 |. 891D 70974000 |mov dword ptr [409770], ebx 第一次
00401507 |. 013D 70974000 add dword ptr [409770], edi 和name运算后得的ebx值相加存409770 ,
并且处理用户名和组名的算法是一样的:
下面分别列出 ,算法:
用户名处理:
#include<iostream>
#include<string>
#include<iomanip>
using namespace std;
void main()
{
char name[]="Cracker";
char middle[]={0x66,0x51,0x4F,0x62,0x56,0x77,0x4E,0x4F,0x61,0x6E,0x6B,0x4A,0x35,0x73};
char middle1[]={0x45,0x74,0x6E,0x35,0x50,0x6E,0x63,0x35,0x41,0x58,0x69,0x31,0x44,0x46};
char *pN=name;
char *pMd=middle;
char *pMd1=middle1;
static int esi=1;
static int ebx=0;
static int edx=1;
static int edi=0;
static int eax=0;
int _409774=0;
long int _409770=0;
int _4097F0=0;
int _4097EC=0;
int ecx=strlen(pN)-1;
cout<<"ecx = "<<ecx<<endl;
for(int i=0;i<ecx;i++)
{
edi=*(pN+i);
eax=*(pMd+i);
edi=(*(pN+i))*(*(pMd+i));
eax=*(pMd1+i);
edi=edi*eax;
edi=edi*edx;
edx++;
ebx=ebx+edi;
esi++;
_409774=edi;
_4097F0=edx;
_409770=ebx;
_4097EC=esi;
cout<<"ebx = "<<dec<<ebx<<'\n'<<"edi = "<<dec<<edi<<endl;
cout<<hex<<ebx<<endl<<hex<<edi<<endl;
}
cout<<_409770<<endl<<_409774<<endl;
}
组名处理:
#include<iostream>
#include<string>
#include<iomanip>
using namespace std;
void main()
{
char group[]="kang";
char middle[]={0x66,0x51,0x4F,0x62,0x56,0x77,0x4E,0x4F,0x61,0x6E,0x6B,0x4A,0x35,0x73};
char middle1[]={0x45,0x74,0x6E,0x35,0x50,0x6E,0x63,0x35,0x41,0x58,0x69,0x31,0x44,0x46};
char *pG=group;
char *pMd=middle;
char *pMd1=middle1;
static int esi=1;
static int ebx=0;
static int edx=1;
static int edi=0;
static int eax=0;
int _409774=0;
long int _409770=0;
int _4097F0=0;
int _4097EC=0;
int ecx=strlen(pN)-1;
cout<<"ecx = "<<ecx<<endl;
for(int i=0;i<ecx;i++)
{
edi=*(pG+i);
eax=*(pMd+i);
edi=(*(pG+i))*(*(pMd+i));
eax=*(pMd1+i);
edi=edi*eax;
edi=edi*edx;
edx++;
ebx=ebx+edi;
esi++;
_409774=ebx;
_4097F0=esi;
_4097EC=edx;
cout<<"ebx = "<<dec<<ebx<<'\n'<<"edi = "<<dec<<edi<<endl;
cout<<hex<<ebx<<endl<<hex<<edi<<endl;
}
_40977C=edi;
_409770=_409770+edi;
cout<<_409770<<endl<<_409774<<endl;
}
后面的组名算法,我只是将指针改了一下,和上面那个一样; 所以没有验证;
只要将将用用户名运算得到的ebx值,也就是保存在_409770中的数据
和用组名运算得到的edi的值相加然后在
算法补充到这;嘿嘿.....又是3小时,我的时间啊! 55555.......
此程序主要是找到关键点:
00401546 |. 390D 88974000 cmp dword ptr [409788], ecx ecx和409788为kanghtta 第三个输入Serial
0040154C 75 63 jnz short 004015B1
至于破解的方法可以将jnz 改为 jz 直接爆破;
也可以将运算得的ecx值变化后输入code后能成功破解;
如我们输入的: Name: Cracker
Group: kang
在00401546处信息窗口中的数据是: ecx=017229A3
在命令窗口中输入:?0x017229A3 得到: 24258979
将24258979输入到Code中,点Check 按钮,成功破解的对话框就出来了!
在看一组: Name: kanghtta
Group: pediy
ecx=02071817
ds:[00409788]=00000000
?0x02071817 DEC: 34019351
输入Code为:34019351 Check 嘿嘿...成功破解;
--------------------------------------------------------------------------------
【经验总结】
破解了5个程序,这个是最废力的,由于是时间关系,程序算ecx的算法并没有清晰的给出,当然,也因为我处在入门阶
段,以破解成功为目的.当完成这一阶段的学习后,我会回头把这写算法详细分析出来.希望大虾们莫见怪/
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2008年04月07日 下午 10:23:31
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
上传的附件: