-
-
160Crackme之02Afkayas.1
-
发表于: 2022-1-27 12:28 23788
-
师承15PB
课后练习160Crackme之记录篇
双击运行exe,随意输入Name和Serial看结果
结果弹出MessageBox并包含字符串L"You Get Wrong"
OD打开exe软件并运行至程序入口点;
右键查找字符串找到相关代码
栈回溯->发现jcc过来的,并非call调用
爆破点[0040258B]je
追踪[00402579]test si,si是关键
往上追踪:si为什么会等于0
发现字符串:AKA-XXXXXX很诡异;大胆推测:Name或者Serial其中一个
je往上第一个[00402563]call 进入前si已经为0;
继续往上一个[00402550]call 进入前si已经为0;
继续往上一个[00402533]call 进入前si不为0;->探讨为什么si会变成0
探讨发现,AKA-XXXXX随Name的改变而改变->大胆推测:算法问题,每个账号都有对应的密码,而AKA-XXXXX就是密码->实验证明推理正确
改变思路:研究如何根据输入的Name计算得出Serial算法
继续向上最终call,在[004024F4]call 发现异常,指向完此call后EBP-1C存的既然是Serial对应的数字部分
进入函数查看,发现Serial对应的数字部分早就已经算好了,怎么算的?倒推继续往上找call
发现[0040243F]call 有问题,call完后真正的Serial对应数字部分出来了,马上跟进去找
进去第一个call没什么变化(我的做法是先f8过去call看对应的寄存器堆栈内存的变化,如果没变化就看下一个call,知道有我感兴趣的变化,我在进入call);然而第二个[740DBEE3]call有意思,进去看看
跟踪到[7638E97E]call 进去看看
跟踪到[7638E941]call 进去看看
进去后发现[7638E8B3]-[7638E8D3]是生成Serial数字的关键点
仔细观察后,发现[7638E8BA]的EBP+8的09 E8 0B 00 是重点,要去知道他怎么来的
BE809/A EAX==商;EDX==余数
余数EDX+=30->每次得出的结果是Serial数字的倒序
循环到EAX==0 结束
EBP+8 [12F3000] 09 E8 0B 00
原来[0012F318]就已经是这个数了
在追踪[0012F3A0]也是这个数
最终发现[0040243E]处push edi让[0012F3A0]变成09 E8 0B 00的
也就是说追踪EDI的变化
往上查询,发现从[00402415]后开始edi从0开始变化
edi先==Name的位数 [0040241B]
edi在*0x17CFB [00402420]
然后带符号扩展使得ax(输入Name的第一位)->edx [00402433]
edi在+=edx [00402436]
此时基本破解,但注意到两个溢出跳转[00402427]和[00402438]
AKA-是在je爆破点上方汇编代码最后比较加进去的!!!
插入代码
#include<stdio.h>
#include<vector>
using std::vector;
/
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
Crackme2 破解
思路:输入Name 获取 Serial
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
/
int
main()
{
/
/
1.
接收Name
printf(
"输入Name的位数:"
);
int
Num
=
0
;
scanf_s(
"%d"
, &Num);
printf(
"输入Name:"
);
int
Name
=
0
;
scanf_s(
"%d"
, &Name);
int
SerialNum
=
0
;
while
(Name
/
10
)
{
Name
/
=
10
;
}
SerialNum
=
Num
*
0x17CFB
;
SerialNum
+
=
(char)Name
+
0x30
;
vector<
int
> Serial;
while
(SerialNum)
{
Serial.push_back(SerialNum
%
0xA
+
0x30
);
SerialNum
/
=
0xA
;
}
for
(
int
i
=
Serial.size()
-
1
; i >
=
0
; i
-
-
)
{
printf(
"%d"
, Serial[i]
-
0x30
);
}
return
0
;
}
插入代码
#include<stdio.h>
#include<vector>
using std::vector;
/
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
Crackme2 破解
思路:输入Name 获取 Serial
[招生]系统0day安全班,企业级设备固件漏洞挖掘,Linux平台漏洞挖掘!