发新帖

Android逆向系列之动态调试(六)–IDA调试so文件

[复制链接]
5865 0

一、前奏

> 1.demo.apk、IDA6.6以上、adb等工具 > > demo.apk的主逻辑代码如下: > > > > 2.什么是so文件? > > so文件是unix的动态连接库,我们知道Android系统是类linux,所以这里也沿用其动态链接库so,一般用c语言实现,是二进制文件,作用相当于windows下的.dll文件,在Android中调用动态库文件(.so)都是通过jni的方式。 > > Android中加载so文件的提供的API: void System.load(String pathName); > > Android系统目前支持以下七种不同的CPU架构:ARMv5,ARMv7 (从2010年起),x86 (从2011年起),MIPS (从2012年起),ARMv8,MIPS64和x86_64 (从2014年起),每一种都关联着一个相应的ABI。我们将apk解压后,在/lib目录下可以看到不同cpu架构的文件夹,其中的so文件是功能相同的,只是实现的指令等细节不同,主流是ARM架构,所以这里我们也是重点分析arm下的so文件。 > > 3.分析so文件 > > 一般逆向so文件,光动态分析仍旧是不够的,一般我们需要先静态简单分析一下,再结合动态调试,这样才能事半功倍。 > > 我们直接将libencrypt.so文件拖进IDA,如下图: > > > > 这里我们找到 Java_类名_方法名 的函数,重点分析这个函数(当然有时候并没有java开头,这时可以借助jd-gui等工具找出函数名) > > 我们简单分析下arm代码,BLX调用函数,然后有一个判断跳转,再使用BL调用 get_encrypt_str函数,然后有一常量字符串,再调用strcmp进行比较 > (这里为了演示,相对逻辑简单,当然静态分析就可以了,但这并不是目的) > > 强大的F5,如果ARM指令看着费劲,可以使用F5查看对应的c语言 > Shirt+F12快捷键,速度打开so中所有的字符串内容窗口 > > > > 具体就不分析了C语言你们比我厉害多了。 > > 问题分析:这里我们看一下划线处,是不是觉得有点奇葩。 > > 解决方法: > > 还原JNI函数方法名,一般JNI函数方法名首先是一个指针加上一个数字,比如v3+676。然后将这个地址作为一个方法指针进行方法调用,并且第一个参数就是指针自己,比如(v3+676)(v3…)。这实际上就是我们在JNI里经常用到的JNIEnv方法。因为Ida并不会自动的对这些方法进行识别,所以当我们对so文件进行调试的时候经常会见到却搞不清楚这个函数究竟在干什么,因为这个函数实在是太抽象了。解决方法非常简单,只需要对JNIEnv指针做一个类型转换即可。 > 选中a1变量,然后按一下y键,输入:JNIEnv,确定即可。 >

二、准备调试

> 1.调试准备 > > 在IDA目录下的dbgsrv目录下找到android_server,是不是有点眼熟,是的,没错!有点类似gdbserver,操作也是类似,具体可查看上一篇文章; > > adb remount > > adb push android_server /system/bin > > adb shell chmod 755 /system/bin/android_server > > adb shell android_server > > adb forward tcp:23946 tcp:23946 > > 2.IDA-attach > > 模拟器里启动要调试的APP > > 启动IDA,打开debugger->attach->remote Armlinux/andoid debugger > > 填写hostname为127.0.0.1或localhost(推荐),端口确定为23946或你自定义转发的端口,其他默认,点击确定 > > 弹出Choose process to attach to窗口,找到app的进程名,点击ok,等待分析后即可进入调试界面 > > > > 问题分析:为什么会断在libc.so中 > > 问题解决: > > android系统中libc是c层中最基本的函数库,libc中封装了io、文件、socket等基本系统调用。所有上层的调用都需要经过libc封装层。所以libc.so是最基本的,所以会断在这里,而且我们还需要知道一些常用的系统so,比如linker;这个linker是用于加载so文件的模块,如何在.init_array处下断点;还有一个就是libdvm.so文件,他包含了DVM中所有的底层加载dex的一些方法 > > 3.定位函数 > >使用快捷键Ctrl+s打开segment窗口,选择so文件,这里可以使用Ctrl+f进行搜索;同时这里需要记下so文件的起始地址(A8924000) > > 用另一个IDA打开so文件,找到对应函数的便宜位置,在上面的图可以看到偏移为:00000E9C > > 绝对地址=基址+偏移地址=A8924000+00000E9C=A8924E9C > > 按下快捷键G,输入A8924E9C即可跳转到正确的函数。然后使用F2或者点击前面的小圆点 下一个断点 > > > > 问题分析:窗口里有多个so文件怎么办?应该选择哪一个? > > 问题解决: > > 其实这里并不是多个so文件,而是so文件对应的不同Segement信息被映射到内存中,包括代码段,数据段等,很明显,代码段会有执行权限的特点,所以我们选择带有X属性的so文件,即是我们想要调试的so文件。 > > > > 4.调试 > > 按F9或点击绿色三角形按钮运行程序 > > 触发断点:这里是点击程序的按钮,具体视应用不同而不同 > > 接着就是F7/F8调试的常规步骤了!! > > 5.调试步骤小结 > > (1)调试步骤: > >\1. adb shell am start -D -n {pkgname}/{Activity} > > \2. ida android_server放到手机,以root身份运行,PC端idapro远程连接、 attach、下断点 > > \3. adb forward tcp:8700 jdwp:{pid} > > \4. jdb -connect “com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700” > > (2)调试步骤: > > \1. adb shell am start -D -n {pkgname}/{Activity} > > \2. adb forward tcp:23946 tcp:23946 > > \3. ida android_server放到手机,以root身份运行,PC端idapro远程连接、 attach、下断点 > >\4. 打开DDMS,查看端口 > > \5. jdb -connect “com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700” > > 参考资料: http://blog.csdn.net/jiangwei0910410003/article/details/51500328

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

举报 使用道具

回复
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表