⾮常详细的androidso库逆向调试教程
⽬录
前⾔
应⽤环境准备
创建默认的native application
修改stringFromJNI⽅法,便于调试
修改androidManifest⽂件
修改
编译运⾏,获取so
hook环境准备
使⽤ida pro进⾏hook
adb与⼿机的准备
ida pro的⼯作准备
使⽤ida pro进⾏调试
进⾏调试
结束
前⾔
好久没有写博客了,最近的精⼒全放在逆向上⾯。⽬前也只是略懂⽪⽑。
android java层的逆向⽐较简单,主要就是脱壳、反编译源码,通过xposed进⾏hook。
接下来介绍⼀下,如何去调试hook native层的源码,也就是hook so⽂件。
应⽤环境准备
⾸先,为了⽅便学习,⼀上来就hook第三⽅app难度极⼤,因此我们⾃⼰来创建⼀个native的项⽬,⾃⼰来hook⾃⼰的项⽬作为学习的练⼿点。
创建默认的native application
打开as,选择File -> new project -> naive c++  创建包含c++的原⽣⼯程。
默认的native⼯程,帮我们实现了stringFromJNI⽅法,那我们就来探索如何hook这个stringFromJNI,并修改他的值。
修改stringFromJNI⽅法,便于调试
as默认实现的stringFromJNI只有在Activity onCreate的时候调⽤,为了便于调试,我们增加⼀个点击事件,每次点击重新调⽤,并且返回⼀个随机的值。
java代码增加如下⽅法:
binding.sampleText.setOnClickListener {
Log.e("MainActivity", "stringFromJNI")
= stringFromJNI()
}
修改native-lib.cpp代码:
#include <jni.h>
#include <string>
using namespace std;
int max1(int num1, int num2);
#define random(x) rand()%(x)
extern "C" JNIEXPORT jstring JNICALL
Java_com_noober_naticeapplication_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
int result = max1(random(100), random(100));
string hello = "Hello from C++";
string hello2 = hello.append(to_string(result));
return env->NewStringUTF(hello2.c_str());
}
int max1(int num1, int num2)
{
// 局部变量声明
int result;
if (num1 > num2)
result = num1;
else
result = num2;
return result;
}
修改的代码很简单,相信不会 c++ 的同学也看得懂,就是随机输⼊两个数,取其中⼩的那⼀位拼接在“Hello from C++”后⾯,并返回。主要⽬的是让我们每次点击的时候,返回内容可以动态。
修改androidManifest⽂件
在application中增加下⾯两⾏代码:
android:extractNativeLibs="true"
android:debuggable="true"
android:debuggable: 让我们可以对apk进⾏调试,如果是第三⽅已经打包好了app,我们需要对其manifest⽂件进⾏修改,增加这⾏代码,然后进⾏重打包,否则⽆法进⾏so的调试。
android:extractNativeLibs: 很多⼈在进⾏调试的时候发现ida pro⼀切正常,但是却⼀直没有加载我们
的libnative
-lib.so, 是因为缺少这⾏代码。如果不加,可能会使so直接⾃⾝的base.apk进⾏加载,导致ida pro⽆法识别。
修改
在cmakelists中增加下⾯代码。so⽂件⽣成路径,这样编译之后就可以在main-cpp-jniLibs⽬录下到⽣产的so⽂件。
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/jniLibs/${ANDROID_ABI})
编译运⾏,获取so
上述⼯作做好之后,直接编译运⾏,同时会⽣成4个so⽂件,我们取⼿机运⾏时对应使⽤的那个so进⾏hook。
我这边使⽤的是arm64-v8a⽬录下的libnative-lib.so。
android学习教程hook环境准备
系统:windows 10 64位
⼯具ida pro 7.5
java8环境
android sdk tools和adb⼯具
arm64-v8a⽬录下的libnative-lib.so
android 真机
使⽤ida pro进⾏hook
adb与⼿机的准备
1、⾸先到ida pro的dbgsrv⽂件夹,⾥⾯有很多server⽂件
64代表的含义是64位,否则就是32位,我们根据我们需要调试的so的指令集进⾏选择。因为我这边调试的是arm64-v8a,这⾥我们就选择android_server64的⽂件。连接真机后,打开cmd,输⼊以下指令:
adb push "\\Mac\Home\Desktop\IDA PRO 7.5 (x86, x64, ARM, ARM64)\dbgsrv\android_server64"  /data/local/tmp
2、如果是真机,则需要输⼊su,模拟器不需要
#真机
su
3、修改权限
chmod 777 /data/local/tmp/android_server64
4、运⾏
/data/local/tmp/android_server64
5、新打开⼀个cmd,在本地执⾏adb 做端⼝转发
adb forward tcp:23946 tcp:23946
ida pro的⼯作准备
1、打开ida pro,因为我们的so是64位的,所以打开。点击new,选择libnative-lib.so。
2、选择debugger-select debugger
3、选择Remote ARM Linux/Android debugger
4、点击debugger-Debugger options
勾选Suspend on process entry point ,也就是在断点处进⾏挂起暂停
5、点击debugger-Process options
填写hostname为localhost
6、到exports标签,ctrl+f,搜索java关键字,到我们要hook的函数。
7、双击打开,按F5,进⾏反汇编操作。这样就可以看到反汇编之后的c ++代码了。然后我们随便加上断点进⾏调试。
8、执⾏adb命令,进⼊调试状态,也就是打开我们要调试的app的启动activity,我这边如下:
adb shell am start -D -ber.ber.naticeapplication.MainActivity
9、点击debugger-Attach to process
选择我们需要调试的进程。
10、adb 执⾏如下命令,关联运⾏的so与本地要调试的so。
jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700
11、此时ida卡在libc.so的位置,点击继续执⾏,弹出如下界⾯,关联so到本地,选择same。如果没有弹出则需要通过快捷键ctrl+s, 打开所有已经加载的so,到我们的libnative-lib.so
12、此时就会⾃动进⼊断点。
使⽤ida pro进⾏调试
ida pro 常⽤调试快捷键
F2下断点
F7单步步⼊
F8单步步过
F9执⾏到下个断点
G调到函数地址
Debugger-debugger windows-locals 查看变量
进⾏调试
简单分析反汇编代码,我们发现返回值是v5,通过f8,执⾏到return的上⼀⾏。打开locals, 获取所有变量的值。
复制bytes的地址0x7FFE2CDEB9LL,切换到代码界⾯,输⼊快捷键g,输⼊地址跳转。这样我们便从内存中得到了数据结果,可以看出本次返回的值就是"Hello from c++89"
当然我们也可以在locals中直接修改值,这样就达到了我们hook so动态修改数据的⽬的。
结束
以上就是所有⽂章内容,主要是为了给没有接触过so调试的同学学习,以及⾃⼰记录。关于如何去进⼀步so hook,会在后⾯的研究后继续分享。
到此这篇关于android so库逆向调试的⽂章就介绍到这了,更多相关android so库逆向调试内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。