【BJDCTF】Easy
收获
OllyDBG 动态调试
当 main 中没有与 flag 有关的信息时,寻找其他可能与 flag 相关的函数
C 语言获取数据 高位 和 低位 的方法:
#include<windows.h>
LOWORD 取 32 bits 低 16 bits
HIWORD 取 32 bits 高 16 bits
LOBYTE 取 16 bits 低 8 bits
HIBYTE 取 16 bits 高 8 bits
思路
在 main 函数中未发现与 flag 有关的信息
设置时间,并将时间分解为 tm 结构,赋值给 v5,但是 v5 也没有使用
查看字符串也没有与 flag 有关的信息
依次查看其他的函数,发现大部分函数都是调用系统函数或是没有什么实际用处的函数
只有 __ques
函数的内容看起来不是没用的函数,比较正常
同时,在 __ques
函数中,包含打印操作:
for ( j = 50; j >= 0; --j )
{
if ( v2[j] )
{
if ( v2[j] == 1 )
{
putchar(42); // '*'
++v7;
}
}
else
{
putchar(32); // ' '
++v7;
}
if ( !(v7 % 5) )
putchar(32);
}
result = putchar(10); // '\n'
程序会输出 '*'
、' '
、'\n'
三种字符,而且函数名 __ques
让人联想到 question,这个函数很可能与 flag 有关
完整的 __ques
函数:
将这个函数拷贝出来,在 CLion 中跑一遍
但是 LODWORD
、HIDWORD
两个函数总是报错,导入库 #incluede<windows.h>
或者自己定义:
#define LODWORD(l) ((WORD)((DWORD_PTR)(l) & 0xffffffff))
#define HIDWORD(l) ((WORD)((DWORD_PTR)(l) >> 32))
都会报错,实在没办法了
但是由于 LODWORD(l)
的作用就是取数据 l
的 低 32位,HIDWORD(l)
就是取数据 l
的 高 32位
尝试手动实现该功能,将:
LODWORD(v6) = v4[2 * i - 1];
HIDWORD(v6) = v0;
替换为:
v6 = v0 * pow(2, 32) + v4[2 * i - 1];
虽然能跑,但是有几个位置输出不全:
大致能看出该程序打印的是一些字符,大概率就是 flag 了
既然 flag 是由该程序输出,而 main 中却并没有调用该函数,因此才导致 main 函数的内容看起来和 flag 无关,因此只需要手动让该程序执行 __ques
函数就可以了
这里使用 OllyDBG 进行动态调试
首先在 IDA 中注意到函数 __ques
的起始地址:0x00401520
在 OllyDBG 中 ctrl + g
定位到该地址:
在 __ques
函数入口处 F2 下断点
并将此位置设置为新 EIP,即让程序直接从这里开始执行
同样,在 IDA 中找到 __ques
函数的结束地址:0x00401723
(在 retn 返回之前)
在 OllyDBG 中该地址处 F2 下断点,便于查看 __ques
函数的输出信息:
F9 运行程序:
结果
HACKIT4FUN