一、工具:
1、IDA
二、解题步骤
①、载入IDA(64位)
②、在函数窗口找到 main 函数,双击转到图表视图,F5 生成伪代码
阅读代码,发现除了调用一个函数没什么特别关键的
③、我们双击函数 Decry() 进入函数内部
函数看似复杂,实际分析后发现还是很复杂,代码中的字符串 src = 357761762382LL ;v9 = 512969957736LL 这是不能直接用的,需要选中然后右键转成字符,如图所示
你以为转成这样就完了吗?这里要给大家提个醒,涉及大小端存储问题,elf文件这种通常使用小端存储,而IDA会把内存中的数据自动转成大端存储,但是有些变量双击过去,在文本视图能直接看到转好的字符串,以key3为例
而有些却不能,这个时候就需要自己把字符串倒过来,比如我们在伪代码看到的 str 是 SLCDN ,可实际用这个字符串的时候应该用 NDCLS 同理,wodah 改成 hadow 然后继续分析代码,
④、双击找出 key1 和 key3 对应的字符串,并分析出 text
前面我们可以看到 join的 参数1 是 key3,参数2 是 v9 的地址
故a1 => kills ; a2 => hadow (注意大小端)
strcpy 把 a1 拷贝到 dest 中,dest => kills
strcat 把字符串 hadow 追加到 dest 的后面,此时 dest => killshadow
结尾返回了dest,故text => killshadow
次段代码对key进行了处理,同上不难分析出最终的key => ADSFKNDCLS
上面的代码是将 key 的字符全部转成小写即 key = adsfkndcls
⑤、对 str2 进行分析
if ( !strcmp(text, str2) ) 由此段代码可知,当 str2 与 text 的字符串相同时,条件满足。这里可以得知,str2 是正确的 flag 经过一些列处理得到的,我们现在只需要把处理过程逆一下,就可以的到正确的 flag
⑥、用C语言写脚本
故,最终的flag:flag{KLDQCUDFZO}
三、收获
1、按 h 键把字符变 ASCII 码
2、str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97
刚开始对这个处理过程进行逆向分析的时候我的想法是把这个表达式逆过来算,最后发现结果很奇怪,百思不得其解,在一个视频看到了另一种思路,str2[i] == (v1 - 39 - key[v3 % v5] + 97) % 26 + 97 保持原有的表达式,通过对限定范围内的字符进行比较,符合条件就输出,这种方法更清晰简单
3、
在写脚的时候我会下意识的把条件表达式里的v3也加上++,导致结果错误,正确的写法应该把v3++ 分开写,注意 break 不能漏写,每打印完一个就要跳出内层循环。