这是一道win32的逆向题。
一共只有3个函数。
主程序如下:
整体逻辑非常清晰,通过调用一个解密函数对加密过的字符串进行解密,但是解密的长度push的不够长,导致只解密了前面一段内容。
因此有两种解决方案:
1.动态调试直接修改硬编码,将1C改成需要的长度AE,如下图:
修改完毕之后直接通过MessageBox得到解密好的flag。
*注:这里不适合直接修改汇编代码,因为会使偏移发生变化,具体的原因我猜测应该是与硬编码有关,但是并没有弄清楚。
**注:后来我仔细跟踪了一下,是因为修改汇编的时候覆盖了下一条push语句,导致栈空间发生变化,所以解密不成功。
2.将加密字符串提出来,自己写解密逻辑代码解密:
原本的解密函数逻辑:
直接贴代码了:
1 #include <stdio.h> 2 #include <string.h> 3 4 unsigned char encoded_str[] = { 5 0xE0,0x81,0x89,0xC0,0xA0,0xC1,0xAE,0xE0,0x81,0xA5, 6 0xC1,0xB6,0xF0,0x80,0x81,0xA5,0xE0,0x81,0xB2,0xF0,0x80, 7 0x80,0xA0,0xE0,0x81,0xA2,0x72,0x6F,0xC1,0xAB,0x65,0xE0, 8 0x80,0xA0,0xE0,0x81,0xB4,0xE0,0x81,0xA8,0xC1,0xA5,0x20, 9 0xC1,0xA5,0xE0,0x81,0xAE,0x63,0xC1,0xAF,0xE0,0x81,0xA4, 10 0xF0,0x80,0x81,0xA9,0x6E,0xC1,0xA7,0xC0,0xBA,0x20,0x49, 11 0xF0,0x80,0x81,0x9F,0xC1,0xA1,0xC1,0x9F,0xC1,0x8D,0xE0, 12 0x81,0x9F,0xC1,0xB4,0xF0,0x80,0x81,0x9F,0xF0,0x80,0x81, 13 0xA8,0xC1,0x9F,0xF0,0x80,0x81,0xA5,0xE0,0x81,0x9F,0xC1, 14 0xA5,0xE0,0x81,0x9F,0xF0,0x80,0x81,0xAE,0xC1,0x9F,0xF0, 15 0x80,0x81,0x83,0xC1,0x9F,0xE0,0x81,0xAF,0xE0,0x81,0x9F, 16 0xC1,0x84,0x5F,0xE0,0x81,0xA9,0xF0,0x80,0x81,0x9F,0x6E, 17 0xE0,0x81,0x9F,0xE0,0x81,0xA7,0xE0,0x81,0x80,0xF0,0x80, 18 0x81,0xA6,0xF0,0x80,0x81,0xAC,0xE0,0x81,0xA1,0xC1,0xB2, 19 0xC1,0xA5,0xF0,0x80,0x80,0xAD,0xF0,0x80,0x81,0xAF,0x6E, 20 0xC0,0xAE,0xF0,0x80,0x81,0xA3,0x6F,0xF0,0x80,0x81,0xAD,0x00}; 21 int decode_0(unsigned char* a1, unsigned char* a2){ 22 int v3; // [esp+0h] [ebp-8h] 23 unsigned char v4; // [esp+4h] [ebp-4h] 24 25 if ( (a2[0] / 8 )== 30) 26 { 27 v4 = a2[3] & 0x3F | ((a2[2] & 0x3F) << 6) | ((a2[1] & 0x3F) << 12) | ((a2[0] & 7) << 18); 28 v3 = 4; 29 } 30 else if ( (a2[0] / 16 )==14 ) 31 { 32 v4 = a2[2] & 0x3F | ((a2[1] & 0x3F) << 6) | ((a2[0] & 0xF) << 12); 33 v3 = 3; 34 } 35 else if ((a2[0] / 32 )== 6) 36 { 37 v4 = a2[1] & 0x3F | ((a2[0] & 0x1F) << 6); 38 v3 = 2; 39 } 40 else 41 { 42 v4 = a2[0]; 43 v3 = 1; 44 } 45 *a1 = v4; 46 return v3; 47 } 48 void main(){ 49 int i; 50 unsigned char* a2 = encoded_str; 51 int len = strlen((char *)a2); 52 int v3; 53 unsigned char decoded_str[200] = {0}; 54 unsigned char* d = decoded_str; 55 56 for ( i = 0; i < len; ++i ) 57 { 58 a2 += decode_0(d, a2); // 具体解密 59 60 v3 = *d; 61 d++; 62 if ( !v3 ) 63 break; 64 } 65 printf("%s ", decoded_str); 66 return; 67 }
我对其中的一些位运算和数据类型进行了处理,本质上效果是一样的。