Java动态so库修改,Adnroid so文件动态调试技巧
前言android的so文件调试,网上写了不少,但是按着网上来,却不一定是正确的,于是自己便总结了一份,给需要的人,同时也方便自己查阅。
SO动态调试技巧SO加载流程
调试前奏: 在调试前需要那些工具
调试流程: 调试的相关细节
引言
随着攻防对抗的升级,或者是java没有相应的API函数,需要借助更底层的函数来支撑,也就有了JNI技术,让JAVA可以调用其他语言封装的库函数,在ANDROID上,也有对应的NDK技术,因此在调试之前,我们最好先了解JNI的相关技术,这样寻找问题的时候定位会更加快.比如常见的断点处。
SO加载流程
so文件在加载的时候,粗略的流程,通常会经过 1.init->->.init array->->JNI_Onload->->java_com_XXX;
这几个步骤,根据断点的位置,可以初步划分为如下几种:
应用级:java_com_XXX;
外壳级:JNI_Onload,.init,.init_array;
系统级:fopen,fget,dvmdexfileopen;
.init和.init array常做为壳的入口,对于so反调试的情况,可以在这两个函数上下断点,而对于应用具体的函数调用就会在相应的
特殊情况下文会细述。函数下断点,而对于加壳函数不管怎么操作,最后都会去读取dex文件或者其他文件,那就需要系统函数,那在系统函数上下断点就显得有必要。
调试准备
调试流程
在调试的时候,确保apk的AndroidManifest.xml文件中android:debuggable=”true”字段为true。如果不是的话,可以先解包修改,然后再打包签名。
添加android_server
需要在一个root手机上或者是模拟器上,添加一个android_server文件,这个文件来源于ida的dbgsrv文件夹。
1
2
3
4
5adb push d:\android_server(IDA的dbgsrv目录下) /data/local/tmp/android_server(这个目录其实可以随便放,有的反调试会检测这)
adb shell
su(一定要有root权限)
cd /data/local/tmp
chmod 777 android_server(执行权限要给)
启动端口转发1./android_server
重新打开一个窗口
1
2adb forward tcp:23946 tcp:23946
adb shell am start -D -n 包名/类名;#包名和类名,可以在AndroidManifest.xml里找到
打开IDA,加载需要的so文件,并设置好断点,点击debugger,选择attch to process选择对应的进程。在debug option勾选suspend on process entry point,suspend on thread start/exit,suspend on library load/unload.
启动JDWP端口转发1
2adb forword tcp:8700 jdwp:进程号 #可通过ps|grep 进程名 查找
jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700
IDA调试
通过以上步骤,在IDA界面按F9执行,程序将会在相应的断点停下,然后可以按f8进行单步调试。
如果之前没有断点,可以计算基地址和so代码的相对地址,通过跳转并添加断点(按F2),基地址可以通过
基地址为:ctrl+s显示对应的so模块地址,相对地址,可以通过静态加载so取得。
特殊情况
模拟机无法使用android_server
在使用模拟器的时候,由于是x86架构,无法启动android_server,这时候可以使用gbdserver一样可以调试
so文件反调试
如果下断点,无法越过so文件的反调试,可以通过自己写代码加载so对应的函数绕过。调用JNI_Onload代码如下所示。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44#include
#include
#include
#include
int main()
{
JavaVM* vm;
JNIEnv* env;
jint res;
JavaVMInitArgs vm_args;
JavaVMOption options[1];
options[0].optionString = "-Djava.class.path=.";
vm_args.version=0x00010002;
vm_args.options=options;
vm_args.nOptions =1;
vm_args.ignoreUnrecognized=JNI_TRUE;
printf("[+] dlopen libdvm.so\n");
void *handle = dlopen("/system/lib/libdvm.so", RTLD_LAZY);//RTLD_LAZY RTLD_NOW
if(!handle){
printf("[-] dlopen libdvm.so failed!!\n");
return 0;
}
//这里我先创建一个java虚拟机。因为JNI_ONload函数参数第一个参数为JavaVM。
typedef int (*JNI_CreateJavaVM_Type)(JavaVM**, JNIEnv**, void*);
JNI_CreateJavaVM_Type JNI_CreateJavaVM_Func = (JNI_CreateJavaVM_Type)dlsym(handle, "JNI_CreateJavaVM");
if(!JNI_CreateJavaVM_Func){
printf("[-] dlsym failed\n");
return 0;
}
res=JNI_CreateJavaVM_Func(&vm,&env,&vm_args)
void* si=dlopen("/data/local/tmp/libbaiduprotect.so",RTLD_LAZY);
if(si == NULL){
printf("[-] dlopen err!\n");
return 0;
}
typedef jint (*FUN)(JavaVM* vm,void* res);
FUN func_οnlοad=(FUN)dlsym(si,"JNI_OnLoad");
if(func_οnlοad==NULL)//我将断点下在了这里可以正好获取到JNI_Onload的函数地址。
return 0;
func_onload(vm,NULL);
return 0;
}
通过这样的方法可以绕过。当然反调试的情况不止这一种,将会在下篇中继续添加。
Java动态so库修改,Adnroid so文件动态调试技巧相关推荐
- Java程序获取和修改.wav音频文件的内部结构
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/79498075冷血之心的博客) wav音频文件是一种无损的音频文件, ...
- Java程序员应该知道的10个Eclipse调试技巧
为什么80%的码农都做不了架构师?>>> Eclipse是众多Java程序员实用的开发工具,其中开发技巧也是繁多,但作为优秀的Java程序员,需要掌握最起码的调试技巧. 1 条 ...
- LVGL学习之路——基于lv_lib_freetype库的TTF字体文件动态加载中文字体(阿里普惠字体)
前言 在学习lvgl中,在英文字体上很多人都用过,但是中文字体往往需要靠取模去实现.那么我就在想,如何像windows那样加载动态的字体呢,这样想做多大字体都行.于是就开始了字体的移植. 什么是t ...
- java 动态解析 xml_通过读取xml文件动态建表
Ada female 21 13300008888 Ada@gmail.com 将上面的xml描述在数据库中创建一张表 import java.io.*; import java.sql.*; imp ...
- mysql动态函数库_mysql自定义函数与动态查询
介绍下mysql自定义函数的例子,以及插入单引号的方法,动态执行查询与字符串拼接的相关内容. 1.mysql自定义函数的例子 mysql不能像oracle 一样写 动态SQL. 代码示例: DROP ...
- 静态库、动态库、静态链接、动态链接、系统运行库混合、MD MT默认库冲突问题
一.静态库项目 静态库lib:(注意和"静态运行库"区分) 就是.lib文件,一个.c或.cpp会编译成一个.obj,多个.obj可以组合成一个.lib库.lib=多个obj. ...
- 【Linux后端开发必问】操作系统系列(Linux常用命令、文件权限修改、静态与动态库的制作)
目录 一.说说常用的Linux命令 二.文件权限如何修改 三.静态库和动态库的制作 1.静态库 2.动态库的制作 3.两者优势对比 一.说说常用的Linux命令 1.cd命令:用于切换当前目录: 2. ...
- graalvm把java编译为c/c++能够使用的动态库(dll/so)
graalvm把java编译为c/c++能够使用的动态库(dll/so) 1.安装graalvm oracle官方企业版 github的openjdk版本 1.1 下载对应系统版本,配置环境变量 本人 ...
- linux 生成dll文件,Linux和Windows平台 动态库.so和.dll文件的生成
Linux动态库的生成 1. 纯cpp文件打包动态库 将所有cpp文件和所需要的头文件放在同一文件夹,然后执行下面命令 gcc -shared - fpic *.c -o xxx.so: g++ -s ...
- java web配置dll文件_JavaWeb项目中dll文件动态加载方法解析(详细步骤)
相信很多做Java的朋友都有过用Java调用JNI实现调用C或C++方法的经历,那么Java Web中又如何实现DLL/SO文件的动态加载方法呢.今天就给大家带来一篇JAVA Web项目中DLL/SO ...
最新文章
- php http传参数,http - PHP的URL传参数(英文句号变成了下划线)的问题,求解释。...
- 域名怎么设置非80端口_深信服网关怎么设置端口映射
- 怎么使用oracle的加权平均数_GPA不足,怎么短期有效提升?快来收获100%录取的秘诀!...
- 判断网络是否为真正的公网IP
- MVC如何添加Model
- android 双线程等待,在Java/Android中启动另一个线程之前如何等待线程完成?
- Enabled AWE
- 《黑马程序员 MySQL数据库入门到精通,从MySQL安装到MySQL高级、MySQL优化全囊括》——学习笔记基础篇
- CentOS故障排除详解(2): 进程相关
- Keil uVision4 C51完整版
- 微软OneDrive使用体验
- STM32F103_study67_The punctual atoms(STM32 OLED display experiment)
- Android学习之仿QQ讨论组和微信群聊头像
- Phpstudy官网于2016年被入侵,犯罪分子篡改软件并植入后门
- 如何查看你的公网ip?
- [译] FACE ID 对易用性意味着什么
- linux vi 保存退出与不保存退出
- 赢得阵亡将士纪念日的十大怪异项目
- Java eclipse安装全过程
- Laravel开发系列四:安装JetStream