本帖最后由 洋洋不得意 于 2019-8-6 18:56 编辑
由于附件上传老是返回服务器错误,就用百度云了。
下载地址:https://pan.baidu.com/s/1LKDIjiY8hq4I9JV1TbZasw
要求是得到解密后的三个key
萌新学习逆向,分析的可能会有错,先自行分析完再看
里面有两个文件:crackeme.exe和Dll2.dll
先把他们都拖入IDA 结果发现exe的导入只有kernel32.dll,Dll2.dll竟然不是有效的PE文件
看exe的主函数,看到流程很长
往下看,看到第一个输入密码的地方
接下来就进入一个循环计算
经过一阵分析,算法如下
[C] 纯文本查看 复制代码 char input_password[12];
char cmp_input_password[12];
for(int i = 0; i < 12; ++i)
{
cmp_input_password[i] = input_password[i] * input_password[i] + i * i;
}
接下来又进入一个循环,分析得知是在进行字符串比较,loc_4011D2那里有两行莫名其妙的代码,不知道是用来干啥的。
那么问题来了,字符串比较的一个是我们输入的密码经过计算得到的cmp_input_password那另一个是啥?往上看,发现函数入口处:
先申请了一块12字节内存,然后把常量crypt_key1经过算法算到这块内存中算法如下:
[C] 纯文本查看 复制代码 const char raw_pass_wd[] = "xipbsfzpv@\x1";//ecx=offset crypt_key1;
char pss_wd[12] = {0};//esi=malloc(12);
for(int i = 0; i < 12; ++i)
{
pss_wd[i] = raw_pass_wd[i] - 1;
}
然后又申请了一块内存,把密码经过算法算到新内存中,我称它为密码签名
算法如下
[C] 纯文本查看 复制代码
char pass_wd_sign[12];//edi=malloc(12);
for(int i = 0; i < 12; ++i)
{
pass_wd_sign[i] = pss_wd[i] * pss_wd[i] + i * i;
}
然后就可以拿着pass_wd_sign和cmp_input_password进行字符串比较了在这里发现这个算法和我们输入密码后经过计算的算法是一样的说明pss_wd就是我们要输的密码了!pss_wd算出来是
直接拿去原程序测试
成功了!不仅如此,在程序目录下还多出来一个dll
继续往下看
这里显示了两个dll的名字,Dll2.dll是之前有的,打开方式是读,DllU.dll是刚生成的,打开方式是写。拿可以判断了sub_401050这个函数应该就是生成DllU.dll的代码
跟进去看一下,发现代码很简单,就是把Dll2.dll读出来,每个字符减一写入DllU.dll
接下来就是载入DllU.dll,获取函数‘?decode@@YAPADPADH@Z’的地址,后面我叫他decode函数然后把两个常量字符调用decode计算第二个密码和第三个密码
这里可以看到decode函数有两个参数,第一个参数是加密串,第二个参数解密key2的时候传的1,解密key3的时候传的2,应该是不同的key区分不同的算法吧拖入ida中,看到有两个导出函数
Dllmain里什么都没有做那看来只有这个核心的decode了
看到decode的声明的参数是刚刚分析的参数,返回值应该就是解密后的密码了! 不过我已经拿到了crypt_key, 算法又是一个动态库,嘿嘿嘿。。。
[C] 纯文本查看 复制代码 char* (*decode)(char*,int) = (decltype(decode))GetProcAddress(LoadLibrary(L"DllU.dll"), "?decode@@YAPADPADH@Z");
char* key2 = decode("\x1e\x16\x1a\x3\x12\x16\x14\x1f\x12\x5\x77\x0", 1);
char* key3 = decode("\x46\xf6\xe6\x72\x47\xa6\xf6\xb6\x56\x12\x0", 2);
那就直接调用呗!
直接拿去试一下!
Ok! 已经搞定了秉着学习的心态, 研究一下他这个dll吧
看到流程还是很多其实就分成三个,相当于
[C] 纯文本查看 复制代码 switch(decodeType)
{
case 0:break;
case 1:break;
case 2:break;
}
根据流程写了decodeType等于1的算法
[C] 纯文本查看 复制代码 void myDecode(char* decode_str, int decode_type, char* ret_str)
{
if(decode_type == 1)
{
ZeroMemory(ret_str, 12);
for(int i = 0; i < 12; ++i)
{
ret_str[i] = decode_str[i] ^ 0x77;
}
}
}
那本次crack就到此结束吧还请各位大佬多指点! |