收获

  • 结合程序运行、IDA 和 OllyDBG 分析程序的逻辑

  • 使用 OllyDBG 修改程序跳转逻辑


【攻防世界】gametime


思路

将文件拖入 exeinfo 查看,为 32 位程序

攻防世界-gametime1.png

运行程序可知是一个游戏,根据提示的内容:“当看到 s 的时候,按下空格键”

攻防世界-gametime2.png

按照游戏要求输入,发现游戏规为:
当看到 s 的时候,按下 ‘ ‘;
当看到 x 的时候,按下 ‘x’;
当看到 m 的时候,按下 ‘m’

但进行到 TRAINING COMPLETE! 后,速度开始越来越快

IDA 查看主函数:

攻防世界-gametime3.png

最开始是一段屏幕输出,后面有两组三条 if 判断语句,根据游戏的规则,猜测这两组 if 语句应该是用来检测用户的输入是否对应为:’ ‘、’x’、’m’

除此之外,发现第一组三条 if 语句在输出 TRAINING COMPLETE! 之前,而第二组三条 if 语句在输出 TRAINING COMPLETE! 之后。前面一组判断速度比较慢,可以直接输入;但后面一组判断速度很快,输入正确有难度

最后面一片代码应该就是对 flag 的处理,输出 flag

查看判断函数:

攻防世界-gametime4.png

为了不让程序结束,根据 main 中:

if ( !sub_401507(5, ' ', 0xC8u, v25, &v23) )
    return 0;
if ( !sub_401507(2, 'x', 0xC8u, v25, v25) )
    return 0;
if ( !sub_401507(1, 'm', 0xC8u, v25, v25) )
    return 0;

可知,必须让 sub_401507() 返回非 0,即 sub_401507() 执行 return 1
根据 if ( sub_401260(a2, 500 * dwMilliseconds) ),即让此判断恒为真

结合游戏发现,当用户输入错误时,会输出:UDDER FAILURE! http://imgur.com/4Ajx21P \n
即:用户输入正确时,sub_401260(a2, 500 * dwMilliseconds) 非 0,执行 if ( sub_401260(a2, 500 * dwMilliseconds) ),判断函数 sub_401507() 返回 1,从而跳过 if ( !sub_401507(5, ' ', 0xC8u, v25, &v23) ),使程序继续执行下去;若输入错误,则输出 UDDER FAILURE! http://imgur.com/4Ajx21P \n,程序终止

由于游戏速度太快,很难输入正确,于是想通过修改 if ( sub_401260(a2, 500 * dwMilliseconds) ) 判断语句,让用户输入错误时,使程序继续执行

用 OllyDBG 打开,首先定位到刚刚的输入错误语句:UDDER FAILURE! http://imgur.com/4Ajx21P \n

攻防世界-gametime5.png

发现前面的一个 jnz 跳转语句

攻防世界-gametime6.png

跟随该跳转地址:000E1586

攻防世界-gametime7.png

功能为:给 al 赋值为 1,然后结束调用,对应 “return 1”
所以这里的 jnz 跳转控制的就是 if ( sub_401260(a2, 500 * dwMilliseconds) ) 语句的执行

原来的逻辑是,输入正确则执行 if 语句,用 jnz 控制跳转
要想将逻辑改为,输入错误则执行 if 语句,将 jnz 跳转改为 je 跳转即可

攻防世界-gametime8.png

同理,将另外一组跳转也修改掉,在 OllyDBG 中执行程序,只要输入错误即可,比如一直按回车:

攻防世界-gametime9.png

等待程序执行自动输出 flag 即可


结果

no5c30416d6cf52638460377995c6a8cf5