unity延迟执行下一行代码_逆向基础十七:Android Gdb调试与延迟绑定研究

下面主要分析如何使用Gdb进行远程调试和本地调试Android原生程序,并验证Android手机以及X64环境上是否开启了延迟绑定技术。 1、远程调试 我们对基于libjni_pcap.so动态库编写的Android原生代码,进行Android Gdb远程调试。所需的工具包括Android手机端的gdbserver和PC端的gdb,它们可以从NDK安装包中获取。 首先需要将gdbserver放到Android手机中,运行如下命令,开启gdbserver。 7df2143046a3d3213dbbac51f462c4e4.png 然后在PC端如下图所示,执行adb forward端口转发命令。 00e5e08bb3584a898e774b1e8ef72850.png 接着在PC端,启动gdb,并执行target remote:12345命令连接远端gdbserver。 60141522b036815c4cdc4cf7cddc21eb.png 最后可以设置断点,输入continue命令,直至程序断在预期的位置。 3fe6088f284817b667139aac35972e5b.png 2、本地调试 Andorid Gdb本地调试,是指通过下载gcc源码,基于Android NDK环境,设置CC/CXX/AS等环境变量,执行./configure --host=aarch64-linux-adnroid生成Makefile文件,最终生成Android手机下直接能运行的gdb,对Android程序进行调试。 下面通过Gdb分析打印“Hello World”的Android原生程序,验证Android手机上是否开启了延迟绑定技术。 首先在Android手机上启动gdb。 8c6eec93d47e6a600c9b7dbfe35eed62.png 然后查看汇编代码,在Arm64环境上,printf的GOT表地址为64位,基地址保存在X17中,偏移地址保存在X16中,通过PLT表最后一行代码br跳转到GOT表中。所以在printfs的PLT表代码最后一行加断点,并在printf执行完加断点。 e0b87d5fdc70f8e8f606de1b62e420d4.png 接着运行程序,当程序断在printf的PLT表最后一行执行前时,查看到X16寄存器的值。 58618b2425d50515da2268eaea721ba4.png 最后查看X16寄存器的内容,也就是printf的GOT表地址里存放的内容,该值已经是printf函数的地址了。 d374a0b70b4a96394f3a7d25bc848d52.png 综合上面的实验,测试的Android手机是关闭延迟绑定的。另外实验发现Android手机通过设置LD_BIND_NOW也无法打开延迟绑定,但是在X64或者ARM开发板上,默认开启延迟绑定的情况下可以通过设置环境变量关闭延迟绑定,具体验证过程详见“X64环境延迟绑定研究”。 3、X64环境延迟绑定研究 首先查看main函数的反汇编,callq指令调用puts输出”Hello World”,再查看puts的PLT表代码,分别是jmpq、pushq、jmpq三条指令,最后在调用puts前后以及puts的PLT代码最后一行下断点。 a780d41a102a237920c1e68aaa6030af.png 根据上面puts的PLT表代码,可知puts对应的GOT表地址为0x601018,puts的PLT表第一行jmpq到GOT表地址,根据打印此时GOT表内容为0x400416,即puts的PLT表第二行代码所在地址。Puts的PLT表第二行pushq指令,作用是把puts的GOT条目压栈,puts的GOT条目的偏移地址就是0。当程序执行完puts后,查看puts的GOT表,发现其内容已经是puts符号的真实地址了。 59cf85269863a995c9bfe5b55011976e.png 下面进一步说明GOT表,GOT表存放在.got.plt段,通过info file命令可以查看到.got.plt段的地址是0x601000,dynamic段的地址是0x600e28。 6776319f28ef6f161bf9a7c6dccfef98.png 因为puts的GOT表地址是0x601018,那么.got.plt段前三个条目存放内容可以按如下方式show出来,其中GOT[0]为dynamic段的基地址,GOT[1]为link_map结构体的地址,GOT[2]为_dl_runtime_resolve函数的地址。 8bbb15a3b4633a2ef72634b02d9160d0.png 这样puts的PLT表最后一行jmpq代码的目的就是根据GOT表前三个条目计算出puts的地址,填写到GOT[3]中。 上面puts的GOT表中puts的地址,并不是在程序加载时进行函数解析,而是在调用时通过plt和got.plt节对函数进行解析,这种方法叫做延迟绑定,延迟绑定可以提高程序加载时的性能,我们也可以设置LD_BIND_NOW,取消延迟绑定,使其在程序加载时就完成函数的解析,如下是对此说明的验证。 e61d7572de976fbc3646526672e0b659.png

欢迎扫码关注,一起学习

3534f247c4e3ac9a19c6bca706582d6a.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值