首页
论坛
课程
招聘
[原创]程序破解01(keygenme1.exe)
2022-8-19 20:10 4707

[原创]程序破解01(keygenme1.exe)

2022-8-19 20:10
4707

@

目录
(程序破解01(keygenme1.exe))

暴力破解

1、软件暴力破解的思路比较简单,一是寻找程序的关键跳转,并修改其跳转逻辑;二是动态调试程序,在内存中寻找正确的注册码(一般在strcmp函数附近)。
2、具体分析
2.1 对程序进行查壳分析
程序查壳分析
2.2 程序未加壳,利用olldbg加载改程序,寻找关键提示字符
智能搜索
关键提示字符
2.3 跳转至关键提示地址,修改程序的关键跳转逻辑或从内存中直接提取出注册码,如下图所示,我们可以将跳转修改为jmp,或直接复制出注册码。
暴力破解

算法分析

暴力破解的思路比较简单,下面分析程序生成注册码的代码逻辑(主要是太菜只能多动手,当作简单的练习拉~)
1、寻找check按钮的消息处理函数位置
这里我使用了两种方法,利用od下消息断点和利用IDA分析流程(第一种失败了,从系统的消息处理函数开始,没找到程序自己的消息处理函数,不知道原因,欢迎大佬指出,感谢~)。

 

1.1 利用od下消息断点
1.1.1 打开od图像界面窗口(点导航栏的w)
窗口界面
1.1.2 在check 按钮处下消息断点(这里是0x202消息,具体是0x201还是0x202,请自行测试)
消息断点
1.1.3 点击check 触发系统消息处理函数,并在代码段下内存访问断点,运行程序(后面找了很久没找到,请大佬指点~)
代码段内存访问断点
代码段
1.2 利用IDA分析代码逻辑
1.2.1 根据IDA的自动分析,start函数中DialogBoxParamA函数的 DialogFunc参数即为消息处理函数。
start函数
1.2.2 寻找check按钮的消息处理函数,这里是先寻找WM_COMMAND消息,再寻找对应的按钮。
消息处理函数
1.2.3 在OD中加载程序,跳转至消息处理函数处
消息处理函数
2.分析代码逻辑
本程序的注册码一共分4个部分,下面逐一分析
2.1 代码片段一
本部分主体为一个循环,循环次数为用户名的长度,最后的结构地址保存在ebx中,故我们重点分析给ebx赋值的语句:
从下往上分析
sub ebx,eax ebx的值来自eax
sub eax,0x19 eax的值来自eax-0x19
movzx eax,byte ptr ds:[ecx+edi] eax的值来自用户名字符串的某一个字符的编码值,并扩展到eax中
故这段代码的逻辑是,循环取出用户名字符串中的每一个字符,减去0x19后再用ebx的值减去它,循环结束后,ebx的值即为注册码的第一段。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov edi,keygenme.0040DCF8                ;  ASCII "admin"
mov edx,dword ptr ds:[0x40DC86]
movzx eax,byte ptr ds:[ecx+edi]
sub eax,0x19
sub ebx,eax
inc ecx
cmp ecx,edx
jnz short keygenme.00401242
push ebx                               
push keygenme.0040DBF8                   ; |%lX
push keygenme.0040E0F8                   ; |s = keygenme.0040E0F8
call <jmp.&user32.wsprintfA>             ; \wsprintfA

2.2 代码片段二
本段代码最后的结果保存在ebx中
ebx=ebx eax
eax=eax
ebx
eax=ebx
所以ebx=ebx ebx ebx
(ebx即为代码片段一的结果)

1
2
3
4
5
6
7
8
9
10
11
12
13
xor eax,eax
xor edx,edx
xor ecx,ecx
add eax,ebx
imul eax,ebx
add ecx,eax
sub edx,ebx
xor edx,eax
imul ebx,eax
push ebx                                 ; /<%lX> =
push keygenme.0040DBF8                   ; |%lX
push keygenme.0040E1F8                   ; |s = keygenme.0040E1F8
call <jmp.&user32.wsprintfA>             ; \wsprintfA

2.3 代码片段三
本段代码最后的结果保存在ecx中
ecx=ecx-eax
ecx=ecxebx
ecx=ecx ^ ebx
ebx=ebx+eax
eax=0x0040E0F8
所以 ecx = 0x40E0F8
0x40E0F8- 0x40E0F8

1
2
3
4
5
6
7
8
9
10
11
12
13
xor eax,eax
xor ebx,ebx
xor edx,edx
xor ecx,ecx
mov eax,keygenme.0040E0F8               
add ebx,eax
xor ecx,ebx
imul ecx,ebx
sub ecx,eax
push ecx                                 ; /<%lX> = 0x0
push keygenme.0040DBF8                   ; |%lX
push keygenme.0040E2F8                   ; |s = keygenme.0040E2F8
call <jmp.&user32.wsprintfA>             ; \wsprintfA

2.4 代码片段四
代码片段四为"Bon-"

 

3.编写算法程序
代码片段二、三、四的逻辑比较简单,故分享代码片段二的实现代码,用C语言实现,其它代码片段实现要注意imul的操作数是有符号数(其它语言也不会,只能用C了。。。)

1
2
3
4
5
6
7
8
9
10
const char st[5] = { 'a','d','m','i','n'};
unsigned int ebxx = 0;
unsigned int tmp = 0;
for (int i = 0; i < 5; i++)
{
    tmp = (unsigned int)st[i];
    tmp -= 0x19;
    ebxx -= tmp;
}
sprintf(format1, "%lX", ebxx);

看雪2022 KCTF 秋季赛 防守篇规则,征题截止日期11月12日!(iPhone 14等你拿!)

收藏
点赞1
打赏
分享
最新回复 (1)
雪    币: 224
活跃值: 活跃值 (95)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
happysamuel 活跃值 2022-8-21 16:07
2
0
动手能力强,学习,很好的方法
游客
登录 | 注册 方可回帖
返回