攻防世界 Reverse 新手练习区 game

game

题目描述:菜鸡最近迷上了玩游戏,但它总是赢不了,你可以帮他获胜吗

PEiD 查壳,发现没有壳

攻防世界 Reverse 新手练习区 game

拉进 ida x32,直接 shift + F12 查看字符串,发现 flag 字样

攻防世界 Reverse 新手练习区 game

双击进入汇编代码,发现函数 sub_45E940,双击函数进入代码图,按 F5 反汇编进入伪代码

攻防世界 Reverse 新手练习区 game

发现声明了非常多的变量,但是地址都是连续的

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

攻防世界 Reverse 新手练习区 game

char v2 修改为 char v2[57]

攻防世界 Reverse 新手练习区 game

点击确定后,伪代码发生变化,原先的 v2 至 v58 全部变成了 v2 数组的元素形式,

原来的 v59 变成了 v3,同理在 v3 处选择 set lvar type

攻防世界 Reverse 新手练习区 game

则原函数伪代码变成

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

编译运行,得到结果

攻防世界 Reverse 新手练习区 game

zsctf{T9is_tOpic_1s_v5ry_int7resting_b6t_others_are_n0t}
上一篇:s-100与s-57电子海图的区别二 电子海开发一百篇第五十二篇


下一篇:vmware centos7 克隆