从零编写Android Hook Framework

0x00 背景

最近想做一个安卓的hook framework,来进行dynamic binary instrumentation。看了一些教程,完成了一部分工作。

主要是参考zhengmi大神的文章安卓动态调试七种武器之离别钩 – Hooking(上)安卓动态调试七种武器之离别钩 – Hooking(下)adbi的源代码修改的。

0x01 原理

hook原理参照zhengmi大神的文章就可以理解,我简单总结一下:

  1. 首先启动一个进程,然后ptrace想要hook的目标进程。我们启动的进程不妨称之为tracer,被hook的目标进程称之为tracee。
  2. tracer通过控制tracee的pc寄存器来使tracee调用dlopen函数来加载自己预先编译好的so文件,这个so文件里存放着我们想要注入的函数,不妨称这个so文件为libinject.so。
  3. 在tracee加载完libinject.so之后,再次利用tracer控制tracee的pc寄存器,调用libinject.so里的init函数(init函数的地址可以通过dlsym来查找)。
  4. init函数中主要做的事是:把tracee中需要hook的函数地址的头几个字节全部替换为类似于jmp的命令,使得tracee在执行到被hook的函数时(不妨称这个函数为hookee)可以跳转到libinject中我们自己替换的函数处执行(称之为hooker)。
  5. 在hooker函数中,我们首先可以做一些自己的处理(pre_hook),然后需要将hookee的头几个字节复原,再重新调用hookee,之后可以做一些自己想做的post_hook处理。最后记得将hookee的头几个字节再次替换为jmp命令,以便下次执行到hookee的时候还能跳转到自己的hooker函数。

Continue reading

[android] 从加壳的so文件中抽出symbols

0x00 背景

大家可能碰到过加壳的so文件,一般很轻松能从内存中dump出解密后的so文件,但是问题是dump出来的so文件里的symbol虽然都在,但是symbol所对应的函数地址都没有了,这样你dump出的so即使放在IDA中分析,看上去也是没有symbol的,难以分析。所以我做了一个可以把内存里的符号表也dump出来的小工具。
Continue reading

从x86汇编到shellcode

0x00 背景

假设你发现了一个windows程序的漏洞,你得注入一些shellcode来执行自己想要执行的命令,但是如果目标程序没有加载某些dll,你就无法在shellcode中直接调用那些API,所以你需要在shellcode中自行加载你需要的dll,然后调用。本文使用汇编模拟了这样一个过程,并将该汇编转换成了shellcode,使用该方法就可以生成任何你想要的payload了。注:本代码仅在win7和win10下测试过。
Continue reading

google protobuf解码

0x00 背景

谷歌出了一款协议叫做protobuffer,它可以将数据编码成二进制流,并跨平台传输。它主要用在网络传输,尤其是http上。如果你使用burp等proxy截取使用protobuf的http请求,你只能看到一些乱码,看上去跟加了密似的w。当然如果你有.proto文件,你就可以完全解码这些二进制。遗憾的是,有时候你无法拿到.proto文件,比如说,pokemongo,它使用IL2CPP编译成了汇编,不要说无法拿到.proto文件了,就连编译成的.cs文件也拿不到,这个时候就可以根据protobuf编码的规则,直接解码二进制,当然解码出来的东西并不完全准确,有些需要靠猜,而且各个field的名字也是无法复原的。

其实google自己已经提供了protobuf的解码,使用cat file.pb | protoc --decode_raw就可以了,但是这个解码提供的信息较少,且不能将float,double等type直接转换出来。另外google并没有提供改写protobuf二进制的方法,所以我自己写了这个解码器,可以讲protobuf的二进制以json的形式输出,包含较多信息,且支持编辑后写回二进制,此外还将这个解码器集成成了burp的插件,可以直接在burp中改写包含protbuf的http请求。
Continue reading