看题看题
运行一下程序
是64位的Linux程序
经典输入flag,虽然这里叫password
拖入IDA看看
非常简短的程序,只要sub_4006FD不返回true,我们就能输出Nice
我们来看看sub_4006FD
看着就头疼,循环了12次,所以我们的flag的长度应该是12位,每次循环用这一堆玩意 【 *(char *)(v3[i % 3] + 2 * (i / 3)) 】减去这一堆玩意【 *(char *)(i + a1)】,如果不等1,那就返回1,我们不能让它返回1,所以我们要让这俩玩意相减的结果等于1。
【 *(char *)(i + a1)】其实就是a1[i],a1就是我们输入的flag,每次取我们输入的falg的一个字符
【 *(char *)(v3[i % 3] + 2 * (i / 3)) 】看着就头疼,看不明白,懒得看,反正总会得出一个字符和我们的a1[i]相减,这个值是固定的,我们可以仿写这个代码,然后求出哪个值和它相减得1,从而得出flag。
但是我不写
我直接打上断点动态调
IDA Pro启动!
咦?怎么没有跳到断点
也没有让我输入password,
怎么回事?
我环境配错了?
我的ida版本有问题?
经过一系列排查。。。
不是我的问题,
你敢耍老子!
看我不狠狠的逆你这个小骚题
先点一点暂停
发现程序停在了这里
jmp指令,自己跳自己,死循环,
f5看看c代码
查资料中。。。
我知道了!
getenv用来检查环境变量LD_PRELOAD是否存在,一些调试工具或注入库可能会通过设置 “LD_PRELOAD” 来预先加载特定的共享库
这是就是一个反调试代码,LD_PRELOAD如果存在就会进入死循环
我的代码我做主
小改一手
他不是跳自己吗,我让它跳loc_4007E6,也就是下面的代码
修改后
点击继续运行
这个时候我们就跳出了循环
输入password,我这里输入的是flag{123456}
我们执行到sub这个指令这里
经过上面的一系列操作,【 *(char *)(v3[i % 3] + 2 * (i / 3)) 】的值已经计算完成,保存到了edx里,【 *(char *)(i + a1)】的值也有了,保存在了eax里,
然后使用sub指令计算edx-eax,把计算结果保存在edx里,
把dex的值放到eax里
然后拿eax和1比较
最后就是根据比较结果进行跳转了。
我输入的字符是flag{123456}
所以eax现在的值是0x66,对应ascii码的“ f ”
而edx的值是0x44
那么0x44减去多少得1呢?
用屁股都能想出来,那肯定是0x43啦,对应ascii码的 “C”
因为我们没有输入正确的字符,为了让程序运行下去,我们就要悄咪咪的修改eax的值,把他改成0x43,
修改后我们继续执行
依旧是执行到sub dex,eax这里(可以打个断点,好调试),可以看到这次edx的值为0x70,那么我们第二个字符就是0x70-1=0x6F,对应ascii码的“o”
(别问我为什么0x70-1不等于0x69)
以此类推
调完之后直接Nice!
最后的password就是Code_Talkers
(最后感觉不如写代码)