selph
selph
Published on 2022-08-27 / 176 Visits
1
0

新160个CrackMe练习:057-bbbs-crackme04

算法难度:⭐⭐

爆破难度:⭐

反调试:?

信息收集

运行情况:

虚拟机打开提示反调试

image

查壳与脱壳:

有壳,壳拖完了还是看不到导入函数名称,算了,直接带壳调试

image

调试分析

反调试?

没错,这里我就是要打一个问号,我还以为用了啥反调试,搞得我不知道是咋回事,程序就是跑不起来,最后发现,这tm就是硬编码的弹窗有调试器然后退出进程,把那个函数nop掉即可

首先是放在调试器里跑,不管壳,直接跑,跑到弹窗,然后点击暂停,找到弹窗函数调用的地方:

image

在网上追一层,找到最上面的函数头:是我们熟悉的窗口过程函数,这里是eax保存的是消息码

image

cmp eax,133这一行下断点,然后不断运行断下观察,在eax的值为多少之后程序弹窗,过程就不演示了,结果是eax=47时弹的窗

再次运行,从eax=47这个分支跟下去,单步跟踪,找到跑飞的地方:

image

程序在这里的int 2b之后,立马就跑飞了,这里进入内核系统调用了,不知道返回到哪里了,这里在执行该指令之前,在内存布局视图中直接给代码段下断点,然后执行:

image

发现程序停在了刚刚会弹窗提示反调试的函数前面!!这个弹窗call的功能只有一个就是弹窗并退出进程

所以这里想要不弹窗正常启动软件,就需要把这个call给nop掉!然后跑起来就能进入程序界面了:

image

注册算法分析

直接就动态分析吧,这次

老样子,找窗口函数里控制码是111,参数为3eb的分支:

逻辑简单明了,获取UserId,获取Password,然后一个call,非0表示成功

image

跟进call看看,接下来就用IDA来分析:

首先是判断输入情况,UserId不能为空,Pasword长度为8位

image

接下来用UserId计算一个值,用Password计算一个值(atoi),然后异或一个固定值,最后进行比较

image

注册机

注册码生成算法:

#include <iostream>
int main()
{
	char UserId[100] = { 0 };
	std::cin >> UserId;

	unsigned int check = 0x12345678;
	for (size_t i = 0; i < strlen(UserId); i++)
		check = ((check * 2) | (check >> 7)) ^ UserId[i];

	check ^= 0xDDDDDDD0;
	std::cout << std::hex << check;
}

效果:

image


Comment