[CrackMe]damn.exe的逆向及注册机编写

1. 脱壳过程

这个crackme有2个文件
[CrackMe]damn.exe的逆向及注册机编写_第1张图片
发现加了壳
[CrackMe]damn.exe的逆向及注册机编写_第2张图片
先来脱壳, 使用ESP守恒, pushad后立马下硬件访问断点
[CrackMe]damn.exe的逆向及注册机编写_第3张图片
F9直接运行, 立马到popad处
[CrackMe]damn.exe的逆向及注册机编写_第4张图片
接着走几步就到了OEP
[CrackMe]damn.exe的逆向及注册机编写_第5张图片
下面使用LordPE来转储映像, 为了防止别人修改PE中的ImageSize, 先尝试修正下ImageSize, 然后dump full即可
[CrackMe]damn.exe的逆向及注册机编写_第6张图片
[CrackMe]damn.exe的逆向及注册机编写_第7张图片
接着用x64dbg调试器重新打开dump后的文件, 准备修复入口点和IAT表, 在这之前往内存里瞄了一眼, 发现主模块的PE头部被设置了只读属性, 首先先将其改成可读写
[CrackMe]damn.exe的逆向及注册机编写_第8张图片
[CrackMe]damn.exe的逆向及注册机编写_第9张图片
这样就舒服多了
[CrackMe]damn.exe的逆向及注册机编写_第10张图片
使用ImportREC打开当前被调试的进程, 并且修改OEP为之前脱壳后第一句代码的RVA地址,注意, 这个地址要减去ImageBase才是RVA地址, 接着选择IAT自动搜索, 如果没什么问题会弹出如下弹框
[CrackMe]damn.exe的逆向及注册机编写_第11张图片
然后选择获取导入表, 即可发现该exe所导入的模块, 并且其后面都是有效
[CrackMe]damn.exe的逆向及注册机编写_第12张图片
最后选择修正转储选择要修正的转储文件即可
[CrackMe]damn.exe的逆向及注册机编写_第13张图片

2. 逆向分析过程

这个程序比较简单, 作者的目的估计主要是为了让我们练习脱壳。脱完壳后, 再次调试就发现图片变成了CRACKED
[CrackMe]damn.exe的逆向及注册机编写_第14张图片
但是不进行调试的状态, 就会显示是LOCKED状态
[CrackMe]damn.exe的逆向及注册机编写_第15张图片
这里先解决这个问题, 让它永远变成cracked状态, 可以确定的是, 他做这些事肯定是在WM_INITDIALOG中的,因为在程序运行的过程中是没有任何变化, 定位WndProc然后找到WM_INITDIALOG后重新跑
[CrackMe]damn.exe的逆向及注册机编写_第16张图片
可以看到了关键API LoadBitmapA
[CrackMe]damn.exe的逆向及注册机编写_第17张图片
使用Resource hacker查看一下程序有什么bitmap资源, Ooops, 找到了这张图片的资源ID是101, 十六进制是0x65
[CrackMe]damn.exe的逆向及注册机编写_第18张图片
这里圈出来的call决定了最终你将选择哪张图片
[CrackMe]damn.exe的逆向及注册机编写_第19张图片
里面是把0x401000和0x402000处的代码计算哈希然后运算决定的, 很明显脱壳会对这个造成影响
[CrackMe]damn.exe的逆向及注册机编写_第20张图片
这里直接选择进行爆破, 直接把0x65传入LoadBitmapA中
[CrackMe]damn.exe的逆向及注册机编写_第21张图片
好了, 这样永远就是cracked的状态了。
[CrackMe]damn.exe的逆向及注册机编写_第22张图片
下面继续进行破解, 运行以下后发现Register按钮是被禁用的, 尝试搜索以下EnableWindow这个API, 定位到该位置后发现上方还有2个GetDlgItemText, 很明显是为了获取name和输入的key的。在EnableWindow上面还有一个call应该就是key的生成算法
[CrackMe]damn.exe的逆向及注册机编写_第23张图片
随便进行了一次测试, 由于这里要求密码必须是8位, 所以首先我把密码设置成8位, 这样方便调试Key运算的部分
[CrackMe]damn.exe的逆向及注册机编写_第24张图片
这个函数最终会返回eax, 也就是说如果eax为1, 那么EnableWindow就会激活Register按钮, 那也就能顺利注册, 否则就不行
[CrackMe]damn.exe的逆向及注册机编写_第25张图片
再看以下Key运算部分, 这里是一个jne循环, 如果ecx不为4就会循环满足某个条件会让ecx增加1, 只有ecx为4才是正确的serial
[CrackMe]damn.exe的逆向及注册机编写_第26张图片
这里经过红色框部分的运算后, 满足2个橘色框的条件则ecx有机会增加1,经过4次判断都满足条件key即为正确
[CrackMe]damn.exe的逆向及注册机编写_第27张图片

3. 编写注册机

这个注册机编写很容易, 为了躲避使用ror之类的带进位指令, 我直接使用了内联汇编来编写
[CrackMe]damn.exe的逆向及注册机编写_第28张图片
下面放出核心代码:

BOOL GetSerialKey(LPCSTR pszName, LPSTR pszKeyBuf, DWORD nKeyBufSize)
{
	int iNameLen = 0;
	DWORD dwFix = 0x44414D4E;
	DWORD dwTmp = 0;
	CHAR cch = 0;
	int iKeyLen = 0;
	int iPtr1 = 1;
	int iPtr0 = 0;

	if (!pszName || !pszKeyBuf || nKeyBufSize < 9)
	{
		return(FALSE);
	}

	iNameLen = strlen(pszName);
	if (!iNameLen)
	{
		return(FALSE);
	}

	for (size_t nIdx = 0; nIdx < iNameLen; ++nIdx)
	{
		cch = pszName[nIdx];
		dwTmp += cch;
		__asm
		{
			push eax
			push ecx
			xor ecx, ecx
			mov cl, byte ptr [nIdx]
			ror dword ptr[dwFix], 1
			ror dword ptr[dwFix], cl
			pop ecx
			pop eax 
		}
		dwFix ^= dwTmp;
	}
	dwFix |= 0x10101010;
	
	for (size_t nIdx = 0; nIdx < 4; ++nIdx)
	{
		__asm
		{
			push eax 
			xor eax, eax
			rol dword ptr[dwFix], 8
			mov al, byte ptr[dwFix]
			mov cch, al

			mov byte ptr[dwTmp], al
			and cch, 0xF
			shr byte ptr[dwTmp], 4
			and byte ptr[dwTmp], 0xF
			cmp cch, 0xA
			sbb cch, 0x69
			mov al, cch
			das
			mov cch, al
		}
		pszKeyBuf[nIdx * 2 + 1] = cch;
		__asm
		{
			mov al, byte ptr[dwTmp]
			mov cch, al
			cmp cch, 0xA
			sbb cch, 0x69
			mov al, cch
			das 
			mov cch, al
			pop eax 
		}
		pszKeyBuf[nIdx * 2] = cch;
	}

	return(TRUE);
}

(完)

你可能感兴趣的:(crackme,assembly)