re | [FlareOn6]Overlong

这是一道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 }

我对其中的一些位运算和数据类型进行了处理,本质上效果是一样的。

原文地址:https://www.cnblogs.com/Mz1-rc/p/13677583.html