game
题目描述:菜鸡最近迷上了玩游戏,但它总是赢不了,你可以帮他获胜吗
PEiD 查壳,发现没有壳
拉进 ida x32,直接 shift + F12 查看字符串,发现 flag 字样
双击进入汇编代码,发现函数 sub_45E940,双击函数进入代码图,按 F5 反汇编进入伪代码
发现声明了非常多的变量,但是地址都是连续的
char v58; // [esp+114h] [ebp-50h]
char v59; // [esp+120h] [ebp-44h]
但是 v58、v59 是不连续的,并且最后的处理逻辑是 v2 和 v59 相比较
for ( i = 0; i < 56; ++i )
{
*(&v2 + i) ^= *(&v59 + i);
*(&v2 + i) ^= 0x13u;
}
所以判断 v2 和 v59 分别为两个数组,
从 v2 到 v58 共 57 个元素,v59 到 v115 共 57 个元素
在 v2 处右键,选择 set lvar type
将 char v2
修改为 char v2[57]
点击确定后,伪代码发生变化,原先的 v2 至 v58 全部变成了 v2 数组的元素形式,
原来的 v59 变成了 v3,同理在 v3 处选择 set lvar type
则原函数伪代码变成
int sub_45E940()
{
signed int i; // [esp+D0h] [ebp-94h]
char v2[57]; // [esp+DCh] [ebp-88h]
char v3[57]; // [esp+120h] [ebp-44h]
sub_45A7BE("done!!! the flag is ");
v3[0] = 18;
v3[1] = 64;
v3[2] = 98;
v3[3] = 5;
v3[4] = 2;
v3[5] = 4;
v3[6] = 6;
v3[7] = 3;
v3[8] = 6;
v3[9] = 48;
v3[10] = 49;
v3[11] = 65;
v3[12] = 32;
v3[13] = 12;
v3[14] = 48;
v3[15] = 65;
v3[16] = 31;
v3[17] = 78;
v3[18] = 62;
v3[19] = 32;
v3[20] = 49;
v3[21] = 32;
v3[22] = 1;
v3[23] = 57;
v3[24] = 96;
v3[25] = 3;
v3[26] = 21;
v3[27] = 9;
v3[28] = 4;
v3[29] = 62;
v3[30] = 3;
v3[31] = 5;
v3[32] = 4;
v3[33] = 1;
v3[34] = 2;
v3[35] = 3;
v3[36] = 44;
v3[37] = 65;
v3[38] = 78;
v3[39] = 32;
v3[40] = 16;
v3[41] = 97;
v3[42] = 54;
v3[43] = 16;
v3[44] = 44;
v3[45] = 52;
v3[46] = 32;
v3[47] = 64;
v3[48] = 89;
v3[49] = 45;
v3[50] = 32;
v3[51] = 65;
v3[52] = 15;
v3[53] = 34;
v3[54] = 18;
v3[55] = 16;
v3[56] = 0;
v2[0] = 123;
v2[1] = 32;
v2[2] = 18;
v2[3] = 98;
v2[4] = 119;
v2[5] = 108;
v2[6] = 65;
v2[7] = 41;
v2[8] = 124;
v2[9] = 80;
v2[10] = 125;
v2[11] = 38;
v2[12] = 124;
v2[13] = 111;
v2[14] = 74;
v2[15] = 49;
v2[16] = 83;
v2[17] = 108;
v2[18] = 94;
v2[19] = 108;
v2[20] = 84;
v2[21] = 6;
v2[22] = 96;
v2[23] = 83;
v2[24] = 44;
v2[25] = 121;
v2[26] = 104;
v2[27] = 110;
v2[28] = 32;
v2[29] = 95;
v2[30] = 117;
v2[31] = 101;
v2[32] = 99;
v2[33] = 123;
v2[34] = 127;
v2[35] = 119;
v2[36] = 96;
v2[37] = 48;
v2[38] = 107;
v2[39] = 71;
v2[40] = 92;
v2[41] = 29;
v2[42] = 81;
v2[43] = 107;
v2[44] = 90;
v2[45] = 85;
v2[46] = 64;
v2[47] = 12;
v2[48] = 43;
v2[49] = 76;
v2[50] = 86;
v2[51] = 13;
v2[52] = 114;
v2[53] = 1;
v2[54] = 117;
v2[55] = 126;
v2[56] = 0;
for ( i = 0; i < 56; ++i )
{
v2[i] ^= v3[i];
v2[i] ^= 0x13u;
}
return sub_45A7BE("%s\n");
}
将函数修改为 main 函数,并且最后输出 v2
祭出十年前的 VC6.0,直接把代码复制上去,sub_45A7BE 修改成 printf
#include "stdafx.h"
int main(int argc, char* argv[])
{
signed int i; // [esp+D0h] [ebp-94h]
char v2[57]; // [esp+DCh] [ebp-88h]
char v3[57]; // [esp+120h] [ebp-44h]
printf("done!!! the flag is ");
// ... 中间赋值部分
for ( i = 0; i < 56; ++i )
{
v2[i] ^= v3[i];
v2[i] ^= 0x13u;
}
printf("%s\n", v2);
return 0;
}
编译运行,得到结果
zsctf{T9is_tOpic_1s_v5ry_int7resting_b6t_others_are_n0t}