160CM-021
1. 爆破
首先,拖入PE看一下,这是一个delphi程序,因此用IDR打开先看看。
从IDR中查看控件资源,可以发现用户名输入框输入字符后,会进行一些响应的处理,然后点击注册按钮,再进行注册校验。
以前比较傻,OD和IDA中识别不了delphi的库函数,自己一个一个对照IDR中来进行改名。其实只需要在IDR中导出map函数,OD中的LoadMapEx插件就能自动导入进去,IDA的话需要安装一个LoadMap的插件,就可以将IDR中能识别的函数名都自动载入进去,方便阅读程序。
随便输入一些信息,在OD中跟踪注册函数就能发现,关键跳转有两处,将这两处都nop掉就破解完成了。
2. 注册算法分析
要分析注册算法的话,还是在IDA中看一下,注册按钮的执行程序如下图,先判断输入框是否为空,都不为空的话,再获取SN1和SN2,分别与某个变量(42F714、42F718)比较,都一致的话提示注册成功。
而42F714和42F718这两个变量是在输入用户名的时候,由事件响应函数TForm1.Edit1KeyPress生成的。用IDA打开该函数,F5生成伪代码,是一个switch..case结构,稍加修改,就能得到注册机算法如下:
#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
int code_cal(int code_ascii, unsigned long *code1, unsigned long *code2)
{
switch (code_ascii)
{
case 0x61:
*code1 += 1063;
*code2 += 121;
break;
case 0x62:
*code1 += 1724;
*code2 += 111;
break;
case 0x63:
*code1 += 1169;
*code2 += 738;
break;
case 0x64:
*code1 += 18253;
*code2 += 762;
break;
case 0x65:
*code1 += 1024;
*code2 += 14;
break;
case 0x66:
*code1 += 1744;
*code2 += 13;
break;
case 0x67:
*code1 += 1661;
*code2 += 12;
break;
case 0x68:
*code1 += 1872;
*code2 += 11;
break;
case 0x69:
*code1 += 1084;
*code2 += 99;
break;
case 0x6A:
*code1 += 1892;
*code2 += 888;
break;
case 0x6B:
*code1 += 192;
*code2 += 77;
break;
case 0x6C:
*code1 += 10109;
*code2 += 555;
break;
case 0x6D:
*code1 += 2078;
*code2 += 90;
break;
case 0x6E:
*code1 += 3591;
*code2 += 98;
break;
case 0x6F:
*code1 += 142;
*code2 += 7468;
break;
case 0x70:
*code1 += 632432;
*code2 += 575475;
break;
case 0x71:
*code1 += 3415;
*code2 += 648;
break;
case 0x72:
*code1 += 24555;
*code2 += 538;
break;
case 0x73:
*code1 += 2224;
++*code2;
break;
case 0x74:
*code1 += 1211;
*code2 += 64;
break;
case 0x75:
*code1 += 2242;
*code2 += 75;
break;
case 0x76:
*code1 += 7334;
*code2 += 78;
break;
case 0x78:
*code1 += 917;
*code2 += 38;
break;
case 0x77:
*code1 += 9502;
*code2 += 5;
break;
case 0x79:
*code1 += 11539;
*code2 += 8;
break;
case 0x7A:
*code1 += 6400;
*code2 += 456;
break;
case 0x41:
*code1 += 1064;
*code2 += 5648;
break;
case 0x42:
*code1 += 726576;
*code2 += 2;
break;
case 0x43:
*code1 += 3462;
*code2 += 9999;
break;
case 0x44:
*code1 += 4516;
*code2 += 74445628;
break;
case 0x45:
*code1 += 73482;
*code2 += 35644;
break;
case 0x46:
*code1 += 15554;
*code2 += 34328;
break;
case 0x47:
*code1 += 254376;
*code2 += 444444;
break;
case 0x48:
*code1 += 37348;
*code2 += 2615621;
break;
case 0x49:
*code1 += 27458;
*code2 += 3131331;
break;
case 0x4A:
*code1 += 333476;
*code2 += 12121212;
break;
case 0x4B:
*code1 += 275546;
*code2 += 71111;
break;
case 0x4C:
*code1 += 1834457;
*code2 += 76628;
break;
case 0x4D:
*code1 += 10349;
*code2 += 734348;
break;
case 0x4E:
*code1 += 1025;
*code2 += 897376628;
break;
case 0x4F:
*code1 += 1652;
*code2 += 3243223;
break;
case 0x50:
*code1 += 156;
*code2 += 8247348;
break;
case 0x51:
*code1 += 342;
*code2 += 236752;
break;
case 0x52:
*code1 += 34343;
*code2 += 783434;
break;
case 0x53:
*code1 += 7635344;
*code2 += 8734342;
break;
case 0x54:
*code1 += 42344;
*code2 += 78368;
break;
case 0x55:
*code1 += 87442;
*code2 += 12334;
break;
case 0x56:
*code1 += 7641;
*code2 += 7235;
break;
case 0x58:
*code1 += 9834;
*code2 += 732523528;
break;
case 0x57:
*code1 += 15552;
*code2 += 323528;
break;
case 0x59:
*code1 += 33553;
*code2 += 7238;
break;
case 0x5A:
*code1 += 52763;
*code2 += 726628;
break;
default:
*code1 = 0;
*code2 = 0;
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
char name[50];
int i,length;
unsigned long Code1 = 0, Code2 = 0;
printf("请输入用户名:");
scanf_s("%s", name, 50);
length = strlen(name);
for (i = 0; i < length; i++)
{
code_cal(name[i],&Code1,&Code2);
}
printf("Serial 1为:%lu\n", Code1);
printf("Serial 2为:%lu\n", Code2);
system("pause");
return 0;
}
编译后执行,输入用户名abcde,计算得到SN1和SN2.
再输入程序输入框,验证成功。
3. 总结
这个程序的算法还是比较简单的,这一次主要掌握的map文件的用户,借助插件,对于delphi和vb函数,可以方便的将函数名注释从IDR或VB Decomplier中导入到OD或IDA中,方便分析代码。
|