-
-
[原创]reversing.kr第13题AutoHotkey1
-
发表于: 2019-2-16 15:32 3426
-
题目的意思是找到两个md5,解密以后以空格连接作为答案,关键是要找到对应的md5字符串。
1. peid查壳,upx壳,直接使用esp定律就可以了,注意这里用ollydump脱壳的时候需要对导入表进行修复。不要勾选下面这个按钮,复制oep
3. 使用ImportRec修正导入表,注意这里的oep要进行更改。脱壳后运行发现程序报错,这里应该是有自校验函数之类的。
下面开始自校验函数的分析,直接od载入,进行关键字符串的搜索,定位关键代码处。然后用ida载入定位相应的位置处。对sub_4508c7进行分析,发现还不能进行简单的爆破,爆破之后后面还有一个自我校验,爆破之后程序直接退出了,看来得先搞定自我校验。
if ( sub_4508C7((int)a2, (char *)&h) )
{
sub_43C205("EXE corrupted", 0, a2, 0.0, 0);
return 0;
}
3.使用动静调试的方法来破解这个自校验,最终会返回0就能绕过这个检测
od运行到0x44825e处 call 004508c7,查看堆栈,传入当前文件名。单步步入0x4508c7函数进行分析
4.进入函数之后跟踪第一个函数调用call 0x450f56,使用od动态跟踪这个函数进行分析。
这里的v17是字符串
5. getmodulefilenamea函数的功能 //获取当前工程直到.exe的绝对路径的字符串 如果没找到就返回0
6.暂时不清楚下面一段代码的作用,反正就是简单的赋值操作
AuthKey = un_md5(DecryptKey) + " " + un_md5(EXE's Key) -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Ex:) DecryptKey = 1dfb6b98aef3416e03d50fd2fb525600 EXE's Key = c944634550c698febdd9c868db908d9d => AuthKey = visual studio
_DWORD *__thiscall sub_450F56(_DWORD *this) { _DWORD *result; // eax int *v2; // edi signed int v3; // esi int v4; // edx signed int v5; // ecx result = this; v2 = this; this[256] = -1; v3 = 0; do { v4 = v3 << 24; v5 = 8; do { if ( v4 >= 0 ) v4 *= 2; else v4 = 2 * v4 ^ 0x4C11DB7; --v5; } while ( v5 ); *v2 = v4; ++v3; ++v2; } while ( v3 < 256 ); return result; }
这个函数的主要目的就是从0~256做对应所示的变换,然后将值存入到0x86156c的地方,每次放入四个字节,所以做256次变换,就会占用0x400的空间小,后一个值为-1.
v6 = 0; do { v20[v6] = byte_466514[v6]; v21[v6] = byte_46650C[v6]; ++v6; }
7. fseek是设置文件指针的API ,fread是从文件指针读取内容的API,并且会让文件指针响应后移;
fseek(*v3, -8, 2);//表示当指针设置到文件尾部-8个字节处,也就是倒数第八个字节处 fread(v3 + 1, 4u, 1u, *v3);//读取四个字节放在file+4处
v9 = ftell(*v3); v10 = *v3; v25 = v9; fread(&v23, 4u, 1u, v10);//后四个字节放在v23处
8.经过一系列复杂的变换求出v11
fseek(*v3, 0, 0); v27 = 0; v11 = 0; if ( v25 > 0 ) { do { if ( (*v3)->_flag & 0x10 ) break; fread(&v22, 1u, 1u, *v3);//读取数据到v22,一次读取一个字节 v11 = sub_450F95(v22);// //result=(v17[256]<<8) ^ v17[v22^(v17[256]>>24)] //v17[256]=result //v11=result ++v27; } while ( (signed int)v27 < v25 ); }
if ( v23 != (v11 ^ 0xAAAAAAAA) ) goto LABEL_25;
将v23,倒数四个字节和v11 ^ 0xAAAAAAAA进行比较,这里倒数后四个字节要满足这些条件。这里可以进行爆破绕过。
9.读取十六个字节放入v19处。
if ( !fread(v19, 0x10u, 1u, *v3) ) goto LABEL_25;
10.将v19处的内容和刚才保存的v20,v21处的值进行比较,这里也可以经行爆破,当然只要意识到跳转到LABEL_25,LABEL_19就是失败,
v12 = 0; do { if ( v19[v12] != v20[v12] ) break; ++v12; } while ( v12 < 16 ); if ( v12 != 16 )//对这里进行爆破就可以了
11.下一个字节为3
fread(&v26, 1u, 1u, *v3); if ( v26 != 3 ) { v16 = 4; goto LABEL_19; }
12.读取下一个四字节4u和0xFAC1异或作为下一次读取的内容的长度。
fread(&v24, 4u, 1u, *v3); v14 = v24 ^ 0xFAC1; fread(v3 + 3, 1u, v24 ^ 0xFAC1, *v3);
13,跟踪这个函数,发觉是一个复杂的运算。使用od进行动态的跟踪
sub_450ABA(v3 + 3, v14, v14 + 50130);
跟踪这个函数反觉这个函数比较复杂,绕过前面的几个校验以后我们可以不用对这个函数进行深刻的分析,直接在这个函数retn的地方下断点,在内存窗口可以看到类似的md5代码,(注意这里要直接在加壳状态下运行程序)
https://www.cmd5.com/ 进行md5解密得到:
isolated 得到第一个md5.
14.后面运行的时候发现还会调用sub_450aba这个函数()
后面多次运行的时候可以在堆栈窗口看到类似md5的数据
解密得到第二个字符串:
pawn
15 最后用空格拼接得到最后的答案 isolated pawn
这个题目不知道要考查啥。
fseek(*v3, -8, 2);//表示当指针设置到文件尾部-8个字节处,也就是倒数第八个字节处 fread(v3 + 1, 4u, 1u, *v3);//读取四个字节放在file+4处
v9 = ftell(*v3); v10 = *v3; v25 = v9; fread(&v23, 4u, 1u, v10);//后四个字节放在v23处
8.经过一系列复杂的变换求出v11
fseek(*v3, 0, 0); v27 = 0; v11 = 0; if ( v25 > 0 ) { do { if ( (*v3)->_flag & 0x10 ) break; fread(&v22, 1u, 1u, *v3);//读取数据到v22,一次读取一个字节 v11 = sub_450F95(v22);// //result=(v17[256]<<8) ^ v17[v22^(v17[256]>>24)] //v17[256]=result //v11=result ++v27; } while ( (signed int)v27 < v25 ); }
if ( v23 != (v11 ^ 0xAAAAAAAA) ) goto LABEL_25;
将v23,倒数四个字节和v11 ^ 0xAAAAAAAA进行比较,这里倒数后四个字节要满足这些条件。这里可以进行爆破绕过。
9.读取十六个字节放入v19处。
if ( !fread(v19, 0x10u, 1u, *v3) ) goto LABEL_25;
10.将v19处的内容和刚才保存的v20,v21处的值进行比较,这里也可以经行爆破,当然只要意识到跳转到LABEL_25,LABEL_19就是失败,
v12 = 0; do { if ( v19[v12] != v20[v12] ) break; ++v12; } while ( v12 < 16 ); if ( v12 != 16 )//对这里进行爆破就可以了
11.下一个字节为3
fread(&v26, 1u, 1u, *v3); if ( v26 != 3 ) { v16 = 4; goto LABEL_19; }
12.读取下一个四字节4u和0xFAC1异或作为下一次读取的内容的长度。
fread(&v24, 4u, 1u, *v3); v14 = v24 ^ 0xFAC1; fread(v3 + 3, 1u, v24 ^ 0xFAC1, *v3);
13,跟踪这个函数,发觉是一个复杂的运算。使用od进行动态的跟踪
sub_450ABA(v3 + 3, v14, v14 + 50130);
跟踪这个函数反觉这个函数比较复杂,绕过前面的几个校验以后我们可以不用对这个函数进行深刻的分析,直接在这个函数retn的地方下断点,在内存窗口可以看到类似的md5代码,(注意这里要直接在加壳状态下运行程序)
https://www.cmd5.com/ 进行md5解密得到:
isolated 得到第一个md5.
14.后面运行的时候发现还会调用sub_450aba这个函数()
后面多次运行的时候可以在堆栈窗口看到类似md5的数据
解密得到第二个字符串:
pawn
15 最后用空格拼接得到最后的答案 isolated pawn
这个题目不知道要考查啥。
v9 = ftell(*v3); v10 = *v3; v25 = v9; fread(&v23, 4u, 1u, v10);//后四个字节放在v23处
8.经过一系列复杂的变换求出v11
fseek(*v3, 0, 0); v27 = 0; v11 = 0; if ( v25 > 0 ) { do { if ( (*v3)->_flag & 0x10 ) break; fread(&v22, 1u, 1u, *v3);//读取数据到v22,一次读取一个字节 v11 = sub_450F95(v22);// //result=(v17[256]<<8) ^ v17[v22^(v17[256]>>24)] //v17[256]=result //v11=result ++v27; } while ( (signed int)v27 < v25 ); }
if ( v23 != (v11 ^ 0xAAAAAAAA) ) goto LABEL_25;
将v23,倒数四个字节和v11 ^ 0xAAAAAAAA进行比较,这里倒数后四个字节要满足这些条件。这里可以进行爆破绕过。
9.读取十六个字节放入v19处。
if ( !fread(v19, 0x10u, 1u, *v3) ) goto LABEL_25;
10.将v19处的内容和刚才保存的v20,v21处的值进行比较,这里也可以经行爆破,当然只要意识到跳转到LABEL_25,LABEL_19就是失败,
v12 = 0; do { if ( v19[v12] != v20[v12] ) break; ++v12; } while ( v12 < 16 ); if ( v12 != 16 )//对这里进行爆破就可以了
11.下一个字节为3
fread(&v26, 1u, 1u, *v3); if ( v26 != 3 ) { v16 = 4; goto LABEL_19; }
12.读取下一个四字节4u和0xFAC1异或作为下一次读取的内容的长度。
fread(&v24, 4u, 1u, *v3); v14 = v24 ^ 0xFAC1; fread(v3 + 3, 1u, v24 ^ 0xFAC1, *v3);
13,跟踪这个函数,发觉是一个复杂的运算。使用od进行动态的跟踪
sub_450ABA(v3 + 3, v14, v14 + 50130);
跟踪这个函数反觉这个函数比较复杂,绕过前面的几个校验以后我们可以不用对这个函数进行深刻的分析,直接在这个函数retn的地方下断点,在内存窗口可以看到类似的md5代码,(注意这里要直接在加壳状态下运行程序)
https://www.cmd5.com/ 进行md5解密得到:
isolated 得到第一个md5.
14.后面运行的时候发现还会调用sub_450aba这个函数()
后面多次运行的时候可以在堆栈窗口看到类似md5的数据
解密得到第二个字符串:
pawn
15 最后用空格拼接得到最后的答案 isolated pawn
这个题目不知道要考查啥。
fseek(*v3, 0, 0); v27 = 0; v11 = 0; if ( v25 > 0 ) { do { if ( (*v3)->_flag & 0x10 ) break; fread(&v22, 1u, 1u, *v3);//读取数据到v22,一次读取一个字节 v11 = sub_450F95(v22);// //result=(v17[256]<<8) ^ v17[v22^(v17[256]>>24)] //v17[256]=result //v11=result ++v27; } while ( (signed int)v27 < v25 ); }
if ( v23 != (v11 ^ 0xAAAAAAAA) ) goto LABEL_25;
将v23,倒数四个字节和v11 ^ 0xAAAAAAAA进行比较,这里倒数后四个字节要满足这些条件。这里可以进行爆破绕过。
9.读取十六个字节放入v19处。
if ( !fread(v19, 0x10u, 1u, *v3) ) goto LABEL_25;
10.将v19处的内容和刚才保存的v20,v21处的值进行比较,这里也可以经行爆破,当然只要意识到跳转到LABEL_25,LABEL_19就是失败,
v12 = 0; do { if ( v19[v12] != v20[v12] ) break; ++v12; } while ( v12 < 16 ); if ( v12 != 16 )//对这里进行爆破就可以了
11.下一个字节为3
fread(&v26, 1u, 1u, *v3); if ( v26 != 3 ) { v16 = 4; goto LABEL_19; }
12.读取下一个四字节4u和0xFAC1异或作为下一次读取的内容的长度。
fread(&v24, 4u, 1u, *v3); v14 = v24 ^ 0xFAC1; fread(v3 + 3, 1u, v24 ^ 0xFAC1, *v3);
13,跟踪这个函数,发觉是一个复杂的运算。使用od进行动态的跟踪
sub_450ABA(v3 + 3, v14, v14 + 50130);
跟踪这个函数反觉这个函数比较复杂,绕过前面的几个校验以后我们可以不用对这个函数进行深刻的分析,直接在这个函数retn的地方下断点,在内存窗口可以看到类似的md5代码,(注意这里要直接在加壳状态下运行程序)
https://www.cmd5.com/ 进行md5解密得到:
isolated 得到第一个md5.
14.后面运行的时候发现还会调用sub_450aba这个函数()
后面多次运行的时候可以在堆栈窗口看到类似md5的数据
解密得到第二个字符串:
pawn
15 最后用空格拼接得到最后的答案 isolated pawn
这个题目不知道要考查啥。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
他的文章
- [原创]angr/pyvex模块学习 8672
- [原创] Valgrind VEX IR 9196
- [原创]内存映射文件-进程间共享数据 11446
- [求助]C#反编译字符串出现乱码如何解决 4059
- [原创]windows dll注入/Api钩取技术简单总结 55862
看原图
赞赏
雪币:
留言: