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文件