re题(38)BUUCTF-[FlareOn6]Overlong

BUUCTF在线评测 (buuoj.cn)

运行一下.exe文件

查壳是32位的文件,放到ida反汇编

对unk_402008前28位进行一个操作,我们看到运行.exe文件的窗口正好是28个字符,而unk_402008中不止28个数据,所以猜测MessageBoxA()函数肯定是没输出完

进入sub_401160看看,一个循环

对数据进行加密再输出

写解密脚本我们需要多处理一些数据,我改成了64个数据

解密脚本:

#include <stdio.h>
#include <string.h>

unsigned char encoded_str[] = {
0xE0,0x81,0x89,0xC0,0xA0,0xC1,0xAE,0xE0,0x81,0xA5,
0xC1,0xB6,0xF0,0x80,0x81,0xA5,0xE0,0x81,0xB2,0xF0,0x80,
0x80,0xA0,0xE0,0x81,0xA2,0x72,0x6F,0xC1,0xAB,0x65,0xE0,
0x80,0xA0,0xE0,0x81,0xB4,0xE0,0x81,0xA8,0xC1,0xA5,0x20,
0xC1,0xA5,0xE0,0x81,0xAE,0x63,0xC1,0xAF,0xE0,0x81,0xA4,
0xF0,0x80,0x81,0xA9,0x6E,0xC1,0xA7,0xC0,0xBA,0x20,0x49,
0xF0,0x80,0x81,0x9F,0xC1,0xA1,0xC1,0x9F,0xC1,0x8D,0xE0,
0x81,0x9F,0xC1,0xB4,0xF0,0x80,0x81,0x9F,0xF0,0x80,0x81,
0xA8,0xC1,0x9F,0xF0,0x80,0x81,0xA5,0xE0,0x81,0x9F,0xC1,
0xA5,0xE0,0x81,0x9F,0xF0,0x80,0x81,0xAE,0xC1,0x9F,0xF0,
0x80,0x81,0x83,0xC1,0x9F,0xE0,0x81,0xAF,0xE0,0x81,0x9F,
0xC1,0x84,0x5F,0xE0,0x81,0xA9,0xF0,0x80,0x81,0x9F,0x6E,
0xE0,0x81,0x9F,0xE0,0x81,0xA7,0xE0,0x81,0x80,0xF0,0x80,
0x81,0xA6,0xF0,0x80,0x81,0xAC,0xE0,0x81,0xA1,0xC1,0xB2,
0xC1,0xA5,0xF0,0x80,0x80,0xAD,0xF0,0x80,0x81,0xAF,0x6E,
0xC0,0xAE,0xF0,0x80,0x81,0xA3,0x6F,0xF0,0x80,0x81,0xAD,0x00};
int decode_0(unsigned char* a1, unsigned char* a2){
    int v3; // [esp+0h] [ebp-8h]
    unsigned char v4; // [esp+4h] [ebp-4h]

    if ( (a2[0] / 8 )== 30)
    {
        v4 = a2[3] & 0x3F | ((a2[2] & 0x3F) << 6) | ((a2[1] & 0x3F) << 12) | ((a2[0] & 7) << 18);
        v3 = 4;
    }
    else if ( (a2[0] / 16 )==14 )
    {
        v4 = a2[2] & 0x3F | ((a2[1] & 0x3F) << 6) | ((a2[0] & 0xF) << 12);
        v3 = 3;
    }
    else if ((a2[0] / 32 )== 6)
    {
        v4 = a2[1] & 0x3F | ((a2[0] & 0x1F) << 6);
        v3 = 2;
    }
    else
    {
        v4 = a2[0];
        v3 = 1;
    }
    *a1 = v4;
    return v3;
}
void main(){
    int i;
    unsigned char* a2 = encoded_str;
    int len = strlen((char *)a2);
    int v3;
    unsigned char decoded_str[200] = {0};
    unsigned char* d = decoded_str;

    for ( i = 0; i < len; ++i )
    {
        a2 += decode_0(d, a2);  // 具体解密

        v3 = *d;
        d++;
        if ( !v3 )
            break;
    }
    printf("%s \n", decoded_str);
    return;
}


//I never broke the encoding: I_a_M_t_h_e_e_n_C_o_D_i_n_g@flare-on.com

我们也可以OD动调让它自动解密,省的写脚本

我们找到call MessageBoxA,往上找push,看看压入栈的数据,push 0x1C是我们要修改的处理数据的数量

我们在前面一条语句F2下个断点

对1C修改

我改成了40(这里是16进制)

然后F8单步补过

运行到这里右下角我们可以看到MessageBoxA函数的运行结果

第三种我们也可以直接用010直接修改数据,保存

再运行修改后的程序,得到flag

本题用窗口输出,然而窗口只输出一部分字符,我们需要修改数据来改变输出字符的数量,

三种方法,一种是找到所有数据,自己写脚本输出,第二种OD修改数据,单步调试,第三种,因为是MessageBoxA输出,所以可以修改数据然后运行.exe文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值