首先要确保你所使用的gdb和gdbserver是配对的,最好(或必须)是sdk内相同platform(api level)下的gdb和gdbserver。否则你使用的gdb可能与运行测试机上的gdbserver,因为协议不兼容,而不能正常调试。

gdb 连接后提示,"Argument to arithmetic operation not a number or boolean."

gdbserver 连接后提示,“Unable to get location for thread creation breakpoint: requested event is not supported."

这种情况下,gdb是没法正常使用的,你将会在后续的调试中,不同情况地收到”Remote 'g' packet reply is too long:"

因为这个问题可能会耗费掉了你不少的时间和注意力。这时候最好就是去将你使用的gdb配对的gdbserver从sdk放到测试机去使用。

在测试机中默认有一个远程调试服务程序/system/bin/gdbserver,如果有上面的情况出现,至少使用绝对路径下的你所安排的gdbserver。

参数传递方式:

在x86下,要清楚特殊的传参行为。android的x86 gcc对静态函数的传参规则是,前面两个参数分别应用%eax和%edx,第三个参数开始应用参数栈。而this指针不是我们熟知的vc下应用ecx,gun gcc应用%ebx,而ndk是应用%eax。

下面回到百度加固平台的libbaiduprotect.so逆向。

libbaiduprotect_x86.so是对目标app的dex进行了加固,并且它自身也是加壳了的。下面是以加壳方式存储文件和脱壳后运行在内存映像的dump对比。

壳程序一般都安排在elf格式文件的.init_array section,由linker加载时最先执行。linker有这样的执行流程:

dl_open -> do_open -> soinfo::CallConstructors

只要通过中断linker的soinfo::CallConstructors方法,就可以将加载动态库之初使用程序中断。

中断后,我们通过%eax查看this指针的对象内容,soinfo::CallConstructors是成员方法,指针的对象类型是soinfo,这个结构体包含了加载后section信息。

这个结构的第一个结构成员是不同gcc平台下的linker都一样的,so文件名,查看结果与我调试加载的库名一致,libbaiduproctect_x86.so。后面的结构组织,不同版本的linker各不相同。在这里我懒得去配对正确的版本代码,也就不去搞清它的结构。但是可以通过运行时映射信息,以及readelf查看到的section信息,清楚看到.init_array和.fini_array的section信息加载到soinfo结构了。.init_array section一共0x14字节加载在0xadfa5464。

本例中so映射在0xadf16000,.text段偏移0x2bc0,也就说在0xadf8bc0。而JNI_OnLoad函数偏移量是0x3060,位于0xadf19060。

不用翻查代码,通过查看.init_array段0x14字节的内容,可以大至清楚这个段约等同一个函数指针数组,以空指针结尾。第一个函数指针位于.text的末端,后面三个函数指针位于.text段的开端。linker将按顺序去执行这四个函数。也就是说脱壳程序的其中一个入口就在这四个函数中。

现在我们的程序中断在soinfo::CallConstructors的入口,还没有执行so文件中任何的程序,我们如果反汇编JNI_OnLoad地址的话,就只能得到无法解释的加壳内容。

而so文件.init_array段的函数指针指向的函数则是怎么也就能是加壳的,或者至少保证前面的一个函数可以被执行脱壳出后面的函数。一般地,程序在对代码段进行脱壳,都必须要修改该段的内存访问属性,从只读变为可写才能将脱壳后的代码更新上去,也就说我们只要中断mprotect同样也会将脱壳程序中断到。

libbaiduprotect_x86.so并没有对所有.text段的代码进行脱壳,只是脱壳了一部分,并且在这阶段创建了6个线程,其中包含了反调试的监控线程。由于现在程序的运行被一步步掌控,所以可以将这些线程冻结然后进行后面的调试。

在这里我将被部分脱壳后的so映像dump出来,尝试用ida来静态分析,结果发现ida对x86指令支持并不好,一些原本在gdb能够反汇编的代码,不ida却识别不了。

逆向libbaiduprotect(二)的更多相关文章

  1. 逆向libbaiduprotect(四)

    百度加固libbaiduprotect.so自身对只读字符串进行了加密保护,防止成为破解和逆向的切入口.一般地认为,只要找出这个解密算法就可以对.rodata段的只读字符串进行破解,从而窥探程序的意图 ...

  2. OD 实验(二十一) - 对反调试程序的逆向分析(二)

    程序: 运行程序 点击“Verify” 关闭该程序,启动 OD 再运行程序 逆向: 用 OD 载入程序 按 F8 往下走 执行完这个 call 指令就弹出了对话框 这个 call 指令调用了 Dial ...

  3. 逆向libbaiduprotect(三)- 移植python操作dalvik虚拟机c++函数,配合gdb控制程序运行流程

    python编译移植到测试机,并且移植ctypes模块.利用ctypes代替c程序,利用dalvik内部c++函数,在运行过程中手动命令操控dalvik虚拟机,并结合gdb进行调试.绕过zygote和 ...

  4. Python逆向(二)—— pyc文件结构分析

    一.前言 上一节我们知道了pyc文件是python在编译过程中出现的主要中间过程文件.pyc文件是二进制的,可以由python虚拟机直接执行的程序.分析pyc文件的文件结构对于实现python编译与反 ...

  5. 从零开始Android逆向教程(二)——什么是Xposed

    前言在阅读本文之前,假设你的手机已经root,并且已经成功安装好了 XposedInstaller. Xposed是什么?       Xposed 是一个 Android 平台上的动态劫持框架,通过 ...

  6. x32下PsSetLoadImageNotifyRoutine的逆向

    一丶简介 纯属兴趣爱好.特来逆向玩玩. PsSetLoadImageNotifyRoutine 是内核中用来监控模块加载.操作系统给我们提供的回调. 我们只需要填写对应的回调函数原型即可进行加监控. ...

  7. x32下逆向 PsSetCreateProcessNotifyRoutine 进程钩子

    目录 一丶前言 二丶逆向过程 1.windbg挂载 win7 32位.定位到函数反汇编位置 2.逆向 PspSetCreateProcessNotifyRoutine 3.逆向 ExReference ...

  8. Python逆向(一)—— 前言及Python运行原理

    一.前言 最近在学习Python逆向相关,涉及到python字节码的阅读,编译及反汇编一些问题.经过长时间的学习有了一些眉目,为了方便大家交流,特地将学习过程整理,形成了这篇专题.专题对python逆 ...

  9. Mysql高可用

    一.二进制日志 二进制日志,记录所有对库的修改,如update.修改表结构等等 需要开启二进制日志的原因: 1.主从复制都是通过二进制日志进行.主库写二进制日志,传输到从库,从库replay二进制日志 ...

随机推荐

  1. SpringCloud之RefreshScope 源码解读

    SpringCloud之RefreshScope @Scope 源码解读 Scope(org.springframework.beans.factory.config.Scope)是Spring 2. ...

  2. amoeba-mysql

    配置完成后无法连接 Could not create a validated object, cause: ValidateObject failed 查看logs/下面的 messageHandle ...

  3. 02 Node.js学习笔记之http服务

    在Node中可以非常轻松的构建一个Web服务器,在Node中提供了一个http模块,这个模块主要功能就是帮助你创建一个Web服务器. 创建步骤: //1.加载http模块 var http=requi ...

  4. AB实验的高端玩法系列2 - 更敏感的AB实验, CUPED!

    背景 AB实验可谓是互联网公司进行产品迭代增加用户粘性的大杀器.但人们对AB实验的应用往往只停留在开实验算P值,然后let it go...let it go ... 让我们把AB实验的结果简单的拆解 ...

  5. Java properties | FileNotFoundException: properties (系统找不到指定的文件。)

    文件存储路径的问题 错误描述 :FileNotFoundException: init.properties (系统找不到指定的文件.) 1.方法一 InputStream fis =TestProp ...

  6. Java基础(二)数据类型

    数据类型主要分为基本类型和引用类型两大类. 一.基本类型 1.基本类型又分为数值类型和boolean类型, (1)数值类型包括浮点数类型.整数类型和字符类型 整型                    ...

  7. 接口 IEnumerable

    C#提供了可供类继承的接口,在此解释一下经常遇到的IEnumerable,在此首相解释一下接口,如下例所示: /// <summary> /// 简述Interface的用法 /// &l ...

  8. 如何在Spring Boot项目中巧妙利用策略模式干掉if else!

    直入主题 我们都知道,设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路.它不是语法规定,而是一套用来提高代码可复用性.可维护性.可读性.稳健性以及安全性 ...

  9. js原生图片懒加载 或 js原生图片预加载,html标签自定义属性

    使用原声js来实现图片预加载,或图片懒加载,小伙伴们可以根据项目需要来结合vue或者是react来进行修改. 一.什么是图片懒加载或什么是图片预加载 当访问一个页面的时候,先把img元素或是其他元素的 ...

  10. 【XSY2488】【HDU5818】Joint Stacks

    这题合并栈让我们想到了左偏树. 我们可以维护val值为时间,dis值为size的左偏树,定义两个根root1和root2,表示两个栈的栈顶,建大根的左偏树. 接下来的插入,删除,两个栈合并都是左偏树的 ...