1

160Crackme之02Afkayas.1

 2 years ago
source link: https://bbs.pediy.com/thread-271308.htm
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

师承15PB
课后练习160Crackme之记录篇

02.Afkayas.1

【1】运行exe

双击运行exe,随意输入Name和Serial看结果
结果弹出MessageBox并包含字符串L"You Get Wrong"
图片描述

【2】进入OD调试

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]

【25】写个VS验证一下?

插入代码
#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;
}

图片描述
图片描述

AKA-是在je爆破点上方汇编代码最后比较加进去的!!!

【公告】欢迎大家踊跃尝试高研班11月试题,挑战自己的极限!

上传的附件:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK