一道有趣的逆向题--warmup1

链接:https://pan.baidu.com/s/1dpPF6UFuqFo4MEfVCjyFww
提取码:q1ap
题目的逻辑很简单,就是输入一个字符串,然后调用judge函数检验,有趣在这个judge函数被加密了

  for ( i = 0; i <= 181; ++i )
  {
    envp = (*(judge + i) ^ 0xCu);
    *(judge + i) ^= 0xCu;
  }

在IDA中不能看到反编译代码,看到的汇编代码也是奇形怪状

.data:0000000000600B00 judge           proc far                ; CODE XREF: main+80↑p
.data:0000000000600B00                                         ; DATA XREF: main+16↑r ...
.data:0000000000600B00                 pop     rcx
.data:0000000000600B01                 test    ecx, r13d
.data:0000000000600B04                 test    [rcx-2Ch], r14d
.data:0000000000600B08                 retf    0EC49h
.data:0000000000600B08 judge           endp ; sp-analysis failed

一个比较笨的方法,通过gdb动态调试将judge函数真正的汇编代码提取出来,再通过汇编代码知道它是怎么检验的,从而得到正确的输入字符串。
但很明显这样子费时费劲,而且需要去肝汇编,其实我们已经知道judge函数的亦或加密操作,这里可以用到IDA的插件IDApython来对judge函数进行解,对于IDApython的安装 这里不讲。
具体解密操作如下 :
1、先将judge函数提取出来
2、异或0xc也就是解密
3、将异或的结果写回原函数的位置直接覆盖
这里用到IDA-python 的常用api:

get_bytes(address,count)从address处读取count个字节的内容
patch_bytes(address,buf),将adress地址处patch成buf的内容
Xrefsto(address,flags=0) 找到所有引用了adress的地址
byte(address) 获取address地址的一个字节的内容
Python>s = get_bytes(0x600b00,182)
Python>buf = ''
Python>for i in s :
Python>   buf += chr(ord(i)^0xc)
Python>
Python>from idaapi import *
Python>patch_bytes(0x600b00,buf)

写入后可以发现0x600b00处的汇编代码已经发生变化了,F5会发现反编译的结果还是不正常

image.png

我们回到IDA View-Au,将函数重新解析,先undefine(快捷键U),再create a function (快捷键P),重构完成后再按F5会提示无法反编译,这是sp指针错误的结果

image.png

更改600bb4处的sp值,再次反编译成功

image.png
image.png

解密脚本:

list = [102,109,99,100,127,107,55,100,59,86,96,59,110,112]
flag = ""
for i in range(14):
    flag += chr(list[i] ^ i)
print flag

你可能感兴趣的:(一道有趣的逆向题--warmup1)