• 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 }

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

  • 相关阅读:
    发布google在线翻译程序(附源码)
    基于MVP架构设计ASP.Net的应用研究
    发布最新C#3.5开发的ReSharper4.0 for VS2005/2008 注册机
    基于元数据驱动模型架构在ASP.Net的应用研究
    Silverlight整合Asp.net AjAX的技术应用
    在WCF中的异常处理方法
    Windows Server 2008 的十四大最新功能特性技术总结
    微软Asp.Net架构与项目团队管理建设模型分析
    在Biztalk应用中调用程序集的方法
    Visual Studio 2008和ASP.NET 3.5的最新技术探索
  • 原文地址:https://www.cnblogs.com/Mz1-rc/p/13677583.html
Copyright © 2020-2023  润新知