0x01.EasyEncryption
测试文件:https://www.lanzous.com/i7soysb
1.IDA打开
int sub_416560() { int v0; // eax int v1; // edx int v2; // edx int v3; // ecx int v4; // ST08_4 char v6[4]; // [esp+310h] [ebp-7E0h] char Str; // [esp+700h] [ebp-3F0h] int v8; // [esp+AECh] [ebp-4h] int savedregs; // [esp+AF0h] [ebp+0h] sub_41132A((int)&unk_424091); sub_411294(std::cout, "输入flag: "); sub_41113B(std::cin, &Str); sub_4111F4(&Str, (int)v6); // v6="artqkoehqpkbihv" if ( (unsigned __int8)sub_4112B7(v6) ) { sub_41105F("you are right\n"); system("pause"); sub_411339(v3, v2); } else { v0 = sub_411294(std::cout, "wrong"); sub_41114A(v0, 10); } v4 = v1; sub_41137A(&savedregs, &dword_416660, 0); return sub_411339((unsigned int)&savedregs ^ v8, v4); }
2.代码分析
输入flag之后,首先经过sub_4111F4(&Str, (int)v6)函数处理,再经过sub_4112B7(v6)函数判断。因为v6未知,所以首先通过最后一个函数找到v6
2.1 sub_4112B7函数分析
打开sub_4112B7函数
int __cdecl sub_413980(char *Str) { int v1; // edx int v2; // ecx int v3; // edx int v4; // ecx int v5; // edx int v6; // ecx char *Str1; // [esp+D0h] [ebp-8h] sub_41132A((int)&unk_42405B); Str1 = (char *)sub_4112D5(Str); // Base64 if ( !j_strcmp(Str1, "YXJ0cWtvZWhxcGtiaWh2") ) { free(Str1); sub_411339(v6, v5); } else { free(Str1); sub_411339(v2, v1); } return sub_411339(v4, v3); }
通过分析得到,sub_4112D5函数是Base6加密,因此这个函数实际上就是将Str进行Base64加密,得到字符串Str1与"XJ0cWtvZWhxcGtiaWh2"比较。将"XJ0cWtvZWhxcGtiaWh2"进行Base64解密,得到Str,即v6="artqkoehqpkbihv"
2.2 sub_4111F4函数分析
接着,打开sub_4111F4函数,太长了,就不贴出来了。这个函数,分为三个部分:
0x01 第一部分:
for ( i = 0; byte_41EC80[i]; ++i ) { v16 = (unsigned __int8)byte_41EC80[i] - 97; v2 = j_abs(v16); v15[i] = v2; }
byte_41EC80已知,可以写出脚本变换,得到v15
Serial = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" Li = [] for i in Serial: Li.append(abs(ord(i) - 97)
0x02 第二部分
v10 = j_strlen(Str); if ( v10 % i <= 0 ) { v3 = v10 % i; // 余数 v9 = v10 / i; // 商 } else { v3 = v10 % i; v9 = v10 / i + 1; }
0x03 第三部分
for ( j = 0; j < v9; ++j ) { for ( k = 0; k < i; ++k ) { if ( Str[v14] ) // 输入的字符值不能为0 { if ( Str[v14] < 97 || Str[v14] > 122 ) // 输入只能是小写字母 exit(1); if ( (Str[v14] + v15[k] - 97) % 26 + 97 > 122 ) v4 = (Str[v14] + v15[k] - 97) % 26 + 71; else v4 = (Str[v14] + v15[k] - 97) % 26 + 97; v8 = v4; v3 = v14 + a2; *(_BYTE *)(v14++ + a2) = v8; } } }
第二部分,第三部分和v6,结合分析,可以得到输入的flag应该是15,那么v9=1,v3=15,而第三部分实际上就是一个根据输入字符,进行选择变换得到v14(即v6),因为输入只能是小写字母,那我逆向变换的时候,只要得到的是小写字母,那就行了
3.脚本解密
Serial = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" Li = [] for i in Serial: Li.append(abs(ord(i) - 97)) print(Li) t1 = len(Li) - 1 enc = "artqkoehqpkbihv" v10 = len(enc) v14 = 0 Str = ‘‘ for j in range(1): for k in range(v10): for n in range(10): tmp1 = ord(enc[v14]) - 71 + 26 * n + 97 - Li[k] tmp2 = ord(enc[v14]) - 97 + 26 * n + 97 - Li[k] if tmp1 >= 97 and tmp1 <= 122: print ("SUCCESS!") Str += chr(tmp1) break elif tmp2 >= 97 and tmp2 <= 122: print ("SUCCESS!") Str += chr(tmp2) break else: print("ERROR!") v14 = v14 + 1 print (Str)
4.get flag!
flag{umpnineissogood}
0x02 crackme
测试文件:https://www.lanzous.com/i7sucre
1.函数定位
首先定位到起始的函数sub_412AB0
int __stdcall sub_412AB0(int a1, int a2, int a3, int a4) { size_t i; // [esp+D8h] [ebp-8h] for ( i = 0; i < j_strlen(BASE64_table_41A080); ++i ) { if ( BASE64_table_41A080[i] <= 122 && BASE64_table_41A080[i] >= 97 ) { BASE64_table_41A080[i] -= 32; } else if ( BASE64_table_41A080[i] <= 90 && BASE64_table_41A080[i] >= 65 ) { BASE64_table_41A080[i] += 32; } } MessageBoxA(0, "hooked", "successed", 0); AddVectoredExceptionHandler(0, Handler); return 0; }
2.程序分析
根据起始函数,这里首先对Base64的序列进行的变换,将大小写进行对换。
#include <iostream> #include <string> using namespace std; string Str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int main() { char v2; size_t i; // [esp+D8h] [ebp-8h] for (i = 0; i < Str.length(); ++i) { if (Str[i] <= 122 && Str[i] >= 97) { Str[i] -= 32; } else if (Str[i] <= 90 && Str[i] >= 65) { Str[i] += 32; } } cout << Str << endl; system("PAUSE"); return 0; }
SetUnhandledExceptionFilter()函数:https://baike.baidu.com/item/SetUnhandledExceptionFilter/2334228?fr=aladdin
AddVectoredExceptionHandler()函数:https://www.cnblogs.com/suanguade/p/6674232.html
这道就是将base64的表置换,重排“1UTAOIkpyOSWGv/mOYFY4R!!”,用base64来加密重排字符串,在经过一次sm4加密
对Base64的“添加了异常VEH向量”还有疑问,明天看下...
原文地址:https://www.cnblogs.com/Mayfly-nymph/p/11972774.html