9

Pintools/angr 在 Linux/Windows 下的安装与使用

 2 years ago
source link: https://damaoooo.github.io/2020/11/23/Pintools%E5%92%8Cangr%20%E5%9C%A8linux%E5%92%8Cwindows%E4%B8%8B%E7%9A%84%E5%AE%89%E8%A3%85%E4%B8%8E%E4%BD%BF%E7%94%A8/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
damaoooo的blog
Pintools/angr 在 Linux/Windows 下的安装与使用
发表于2020-11-23|更新于2020-11-23
阅读量:101

Pintools/angr 在 Linux/Windows 下的安装与使用

由于跑Re有时候遇见一些特别恶心的题,自己逆太麻烦,就可以跑pintools,但是Windows下的命令行真的好多坑,而且尝试在windows上面安装的时候发现Windows由于库太繁琐,花费的时间更久,于是放弃windows上跑pintools的计划,在linux下面跑,一番折磨终于安装上了Pintools,傻xCSDN一堆没用的教程,把坑和过程记录于下

Linux

下载源码并解压

直接下载pintools的源码,地址

linux下面使用wget 即可,然后tar -zxvf pin-xxxxxx.tar.gz

编译instruction数量的插件

可能需要搞个make,大多数的系统都带有make,如果没有的话就sudo apt-get install make

目前用的比较多的就是inscount0/1/2 插件,就是我们传说中的看某个输入对应要消耗多少指令

cd source/tools/ManualExamples
make obj-intel64/inscount0.so TARGET=intel64

要编译成32位的可以用

make obj-ia32/inscount0.so

其中默认这个inscout0.cpp是输出到一个文件里面的,不太方便我们进行其他操作,我们需要在inscout0.cpp里面改一下再编译

41 VOID Fini(INT32 code, VOID *v)
42 {
43 // Write to a file since cout and cerr maybe closed by the application
44 // OutFile.setf(ios::showbase);
45 // OutFile << "Count " << icount << endl;
46 // OutFile.close();
47 std::cout << "Count:" << icount << std::endl;
48 }

Fini函数上面的给注释掉,填写这个cout,内容自定,然后再编译,编译出来了之后这个inscount0.so 的使用方法就是

pin -t <yourpintool> -- <executable>

然后就可以在stdin里面看到使用的指令,比如我用

plaintext
pin -t myinscout.so -- /bin/sh -c exit

就可以看到输出

plaintext
Count:1089205

于是就可以写python脚本了,以祥云杯的re1为例,由于结果是逐位比较的,所以就直接爆破就是

python
from subprocess import Popen, PIPE
from sys import argv
import string

pinPath = '/home/damaoooo/Downloads/pin-3.16-98275-ge0db48c31-gcc-linux/pin'
toolPath = '/home/damaoooo/Downloads/pin-3.16-98275-ge0db48c31-gcc-linux/source/tools/ManualExamples/obj-intel64/myinscount0.so'
elfPath = '/home/damaoooo/test/main'
pinRead = lambda : p.communicate()[0]
pinWrite = lambda cont : p.stdin.write(cont.encode())

table = '0123456789abcdef'
flag = ''
if __name__ == '__main__':
last = 0
found = 0
last_letter = ''
for idx in range(38 - 6):
for i in table:
if i == last_letter:
continue
found = 0
p = Popen([pinPath, '-t', toolPath, '--', elfPath], stdin=PIPE, stdout=PIPE)
s = 'flag{%s}'%(flag + i*(38 - 6 - len(flag)))+'\n'
pinWrite(s)
now = int(pinRead().split('Count:'.encode())[1])
delta = now - last
print('input{} -> ins{} -> delta({})'.format(s[:-1], now, now - last))
last = now
last_letter = i
if delta > 0 and delta < 10:
flag += i
found = 1
last_letter = ''
break
if found == 0:
flag = flag[:-1]


print(flag)

这里采用subprocess来开启一个进程,然后读取stdinstdout的输入输出进行交互进行爆破

Windows

windows下想用pintools真的非常困难了

首先还是下载源码包,修改源码,最难的是编译,因为windows下面的make,真的很难用

首先是要安装visual studio, 然后就是安装cygwin的make,最后添加环境之后,make还是不成功。

硬了,拳头硬了,而且看其他的博客说windows上面,即便是输入相同,输出的指令也不同,不得不说在这方面linux还是要好得多

弃坑不搞了

不如用angr来代替

安装pip install angr

现在angr已经支持python3 了,不要再去找老教程里面还在python2 的啦

python
import angr

# 新建工程,这个auto_load_libs加不加我这边影响确实不大
proj = angr.Project('<execute>', auto_load_libs=False)

# 创建模拟状态
state = proj.factory.entry_state()

# 创建模拟器
simgr = proj.factory.simgr(state)

# 开始探索
simgr.explore(find=0x54444444, avoid=0x400000)

# 输出结果
print (simgr.found[0].posix.dumps(0))

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK