一点二进制

虽然转到二进制已经有段时间了。。但是却没写过什么题目,所以在 buu 找到了些简单的题目来写。

easyre

首先是第一题,easyre

题目给了个可执行文件,先放到 exeinfo 里面看看情况。

exeinfo的检测

所以是个没加壳层的64位程序,用 ida64 打开并找到 main 函数。

按下 f5 生成伪代码,flag 如图所示。

flag

reverse1

丢到 exeinfo 分析。

exeinfo

直接运行试试。

直接运行

拖到 ida 里面看看。

string views

按下 shift + f12 ,切换到字符串的界面,联想到运行时的 "input the flag" 和 "wrong flag" , 可以通过查找交叉引用找到调用的函数。

xref
伪代码

不难发现这个地方的 sub_14001128F() 函数应该是类似于 scanf() 一类的函数,将用户输入存入 Str1 中并与 Str2 比较。

所以只要找到 Str2 的值就能找到 flag 。

显然代码上半部分对 Str2 进行了处理,首先我们找到 Str2 的原始值。

Str2

显然 Str2 = "{hello_world}",再来看看上面的代码,是将 Str2 中的 ascii 码为 111 的字符替换为 48 。

在这两个数字上按下 r ,结果如图。

所以 flag 即为 "{hell0_worl0}" 。

reverse2

不是 win 上的可执行程序。。所以直接拖到 ida64 上看看。

如法炮制,同样是通过找寻找使用类似 “flag” 字样的字符串找到主函数。

主函数伪代码

这里已经将数字转换成了 ascii 字符,所以只要找到 flag 的原始值即可。

flag变量

所以加密后的 flag 为 "{hack1ng_fo1_fun}" 。

reverse3

用 exeinfo 查看信息。

exeinfo

无壳32位程序,先尝试运行。

尝试运行

拖到 ida 里面,先去找找有无包含 "flag" 字样的字符串。

奇怪的字符串

的确找到了,但是也出现了一条奇怪的字符串,非常像是 base64 编码使用的字母。

通过 "wrong flag!" 找到主函数。

主函数

函数伪代码比较长,为了分析方便,再贴一段代码块。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
int __cdecl main_0(int argc, const char **argv, const char **envp)
{
size_t v3; // eax
const char *v4; // eax
size_t v5; // eax
char v7; // [esp+0h] [ebp-188h]
char v8; // [esp+0h] [ebp-188h]
signed int j; // [esp+DCh] [ebp-ACh]
int i; // [esp+E8h] [ebp-A0h]
signed int v11; // [esp+E8h] [ebp-A0h]
char Destination[108]; // [esp+F4h] [ebp-94h] BYREF
char Str[28]; // [esp+160h] [ebp-28h] BYREF
char v14[8]; // [esp+17Ch] [ebp-Ch] BYREF

for ( i = 0; i < 100; ++i )
{
if ( (unsigned int)i >= 100 )
j____report_rangecheckfailure();
Destination[i] = 0;
}
sub_41132F("please enter the flag:", v7);
sub_411375("%20s", (char)Str);
v3 = j_strlen(Str);
v4 = (const char *)sub_4110BE(Str, v3, v14);
strncpy(Destination, v4, 40u);
v11 = j_strlen(Destination);
for ( j = 0; j < v11; ++j )
Destination[j] += j;
v5 = j_strlen(Destination);
if ( !strncmp(Destination, Str2, v5) )
sub_41132F("rigth flag!\n", v8);
else
sub_41132F("wrong flag!\n", v8);
return 0;
}

22行应该是读取输入到 Str ,24行将 v4 拷贝到 Destination 上,然后27~28将 Destination 上每一位都加上所在下标。

所以搞清楚 v4 是什么就可以求出 Destination 了,所以接下来来看看24行的那个奇怪函数究竟做了什么。

奇怪函数的内部

emmm, 完全看不懂,但是里面有个奇怪的变量,点进去看看。

奇怪的变量

猜测这个函数应该用于 base64 编码,那么 main 函数里面干的事情就如下。

  1. Destination: [char;100] 置0。
  2. 读入输入至变量 Str 中。
  3. 将 Str base64 加密后存入 v4。
  4. 将 v4 拷贝到 Destination 上。
  5. 将 Destination 上每一位都加上自己的下标。
  6. 比较 Destination 和 Str2 。

继续查找 Str2 。

Str2

综上,可以编写以下脚本。

1
2
3
4
5
6
7
8
9
import base64

s = "e3nifIH9b_C@n@dH"
temp = ""

for i in range(0, len(s)):
temp += chr(ord(s[i]) - i)

print(base64.b64decode(temp))
运行结果

一点二进制
https://ooj2003.github.io/2022/07/30/二进制新人的第一道题/
作者
OOJ2003
发布于
2022年7月30日
更新于
2022年8月11日
许可协议