判别加密算法特征—-MD5

MD5

MD5属于单向散列算法,加密原理和过程网上都有,再次不再赘述。
但就从逆向工程的角度来看, MD5最显著的特征莫过于他有4个常数用来初始化。因此,在判断加密算法时需要注意是否具有64个常量元素的表(而不是通过四个常数)来判断,MD5常见的变种有3种

1.改变初始话的4个常数

2.改变填充的方法

3.改变Hash变化的处理过程

对是否使用MD5加密需要依靠以上三个方法进一步判断

一段反汇编代码实列

在这里插入图片描述 首先,我设置的断点是在调用了GetDlgItemTextA处,也就是输入了用户名和注册码后。在图中明显可以看出0040118B处程序已经获得了用户输入的注册码,下一步自然是对输入的注册码进行进一步的判断。此时可以注意到下面多处调用了jnz判断语句,进一步跟踪,得到
在这里插入图片描述
也就是说明前面三个是注册码的基本判断条件,见下图
在这里插入图片描述此时可以得出注册码的格式为xxxx-xxxx-xxxx-xxxx

然后,在下面的004011E0处又有一个调用函数,跟进,如下图
在这里插入图片描述很明显这可能是进行MD5初始化。当然,为了进一步继续验证向下跟进
可以发现,在下面00401203处进行了字符填充
在这里插入图片描述在跟进下面所调用的call函数后,在下面又发现了正弦函数表在这里插入图片描述此时可以断定就是MD5算法了
这是接下来的图在这里插入图片描述00401236处,这里开始对输入进行了一次处理,然后和MD5计算出来的序列进行比较,再进行strcmp比较两个注册码,这个分析就结束了。

可以干的事情

1.暴力跳转,直接跳过注册

2.分析反汇编,知道了加密算法也知道处理步骤就可以写注册机了

附上程序源码

程序的加密函数:
/*-------------------------------------------------------------*/
/* MD5Hash - MD5计算主函数                                    */
/*-------------------------------------------------------------*/
BOOL CheckSerial(HWND hWnd) 
{
	MD5_CTX context;
	long dtLength,lsLength;
	int i;
	TCHAR szName[MAXINPUTLEN]={0};
	TCHAR szHash[MAXINPUTLEN]={0};
	TCHAR szBuffer[MAXINPUTLEN]={0};
	TCHAR szSerial[MAXINPUTLEN]={0};
	TCHAR szTeam[]="www.pediy.com";
	TCHAR szSNtemp[20]={0};
	TCHAR szBase32[]="23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
	unsigned int tcTemp=0;

	dtLength=GetDlgItemText(hWnd, IDC_Name, szName, sizeof(szName)/sizeof(TCHAR)+1);  
	if (dtLength==0)
	{
		SetDlgItemText(hWnd, IDC_Serial, "Wrong Serial!");
		return FALSE;
	}
	lsLength=GetDlgItemText(hWnd,IDC_Serial,szSerial,sizeof(szSerial)/sizeof(TCHAR)+1);
	if (lsLength!=19)
	{
		SetDlgItemText(hWnd,IDC_Serial,"Wrong Serial!");
		return FALSE;
	}
	if ((szSerial[4]!='-')||(szSerial[9]!='-')||(szSerial[14]!='-'))
	{
		SetDlgItemText(hWnd,IDC_Serial,"Wrong Serial!");
		return FALSE;
	}
	memcpy(szSNtemp,szSerial,4);
	memcpy((szSNtemp+4),(szSerial+5),4);
	memcpy((szSNtemp+8),(szSerial+10),4);
	memcpy((szSNtemp+12),(szSerial+15),4);
	MD5Init(&context);
	MD5Update(&context,szName,dtLength);
	MD5Update(&context,szTeam,lstrlen(szTeam));
	MD5Final(szHash, &context);
		
	for(i=0;i<16;i++)
	{
		tcTemp=(unsigned int)szHash[i]%32;
		szBuffer[i]=szBase32[tcTemp];
	}
	if (lstrcmp(szSNtemp,szBuffer)==0)
	{
		SetDlgItemText(hWnd,IDC_Serial,"Success!");
		return TRUE;
	} 
	else
	{
		SetDlgItemText(hWnd,IDC_Serial,"Wrong Serial!");
		return FALSE;
	}
	return TRUE;
}
注册机解密函数:
/*-------------------------------------------------------------*/
/* MD5Hash - MD5计算主函数                                    */
/*-------------------------------------------------------------*/
BOOL GenerateSerial(HWND hWnd) 
{
	MD5_CTX context;
	long dtLength;
	int i;
	TCHAR szName[MAXINPUTLEN]={0};
	TCHAR szHash[MAXINPUTLEN]={0};
	TCHAR szBuffer[MAXINPUTLEN]={0};
	TCHAR szTeam[]="www.pediy.com";
	TCHAR szBase32[]="23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
	TCHAR szSerial[20]={0};

	unsigned int tcTemp=0;

	dtLength=GetDlgItemText(hWnd, IDC_Name, szName, sizeof(szName)/sizeof(TCHAR)+1);  
	if (dtLength==0)
	{
		SetDlgItemText(hWnd, IDC_Serial, "please input name");
		return FALSE;
	}
	MD5Init(&context);
	MD5Update(&context, szName, dtLength);
	MD5Update(&context,szTeam,lstrlen(szTeam));
	MD5Final(szHash, &context);

	for(i=0;i<16;i++)
	{
		tcTemp=(unsigned int)szHash[i]%32;
		szBuffer[i]=szBase32[tcTemp];
	}

	memcpy(szSerial,szBuffer,4);
	szSerial[4]='-';
	memcpy((szSerial+5),(szBuffer+4),4);
	szSerial[9]='-';
	memcpy((szSerial+10),(szBuffer+8),4);
	szSerial[14]='-';
	memcpy((szSerial+15),(szBuffer+12),4);
	
    SetDlgItemText(hWnd, IDC_Serial,szSerial);       

	return TRUE;
}

小结

1.楼主笔记而已,不严谨之处可以指出。
2.大概这个寒假还会慢慢写233,可以一起学习。
3.都看到这里了,不点个赞再走?0.0

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇

)">
下一篇>>