感觉是有点意外做出来的,估计也不是官方的预期解,就拿出来分享分享吧。也算是自己记录一下。
首先拿到题,看样子是个ELF文件,查了一下发现确实为64位的ELF文件。这里就还是使用IDA配合linux来远程调试。
打开先瞅瞅是干啥的。发现是个小游戏。歌词大意看上去就是说只有打败boss才可以找到flag。选项1貌似可以刷小怪获得奖励,选项3貌似可以通过商店升级。从题目的提示也看出来大概也确实是这样。
大概有了一个初步的熟悉。就尝试再看看分析下反编译的代码。打开发现ida分析出大概的全局流程如下,整体貌似流程并不复杂:
可以看到在判断完bossexist后,其中一个结果就是会调用outflag。猜测这大概就是输出flag的程序。所以这块就着重分析bossexist这块程序。查看相关对应的函数的反汇编代码后。可以发现,在bossexist<=1时,就会打印flag了。
所以大概这里猜想,只要能打赢,就可以获得flag。那此时思路有三个,一个是修改战斗值eff,使得大于5000000应该就不会被干掉。还有就是尝试直接跳到打印flag的代码处,看是否可以直接打印出来flag。(但看到有一些加密的手段估计不太会成功。)最后就是修改cmp判断后的逻辑,只要一直能通过理应就可以获lag。
由于断点在boss函数内部,所以跑起来后选择打boss后断下。
这里尝试用第三种思路,也就是修改每一处判断的逻辑。这里动态调试时发现只要修改这里两处的逻辑就可以顺利打过每一次boss。由于jle指令的跳转是根据zf寄存器来判断的,所以这里把zf改成1,即可通过判断。
然后重复打三次就可以获得flag。也对应着前面bossexist<=1这个逻辑。
为什么不用前两种?
首先,第一种修改数值的方法理论上是和修改跳转是一致的,但是要修改的数值比较多,比较麻烦。
其次,如果直接将程序修改运行至打印flag,会触发异常。导致不成功。不知道是不是题目中说的不允许patch的意思。
END