前言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文件动态调试技巧相关推荐

  1. Java程序获取和修改.wav音频文件的内部结构

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/79498075冷血之心的博客) wav音频文件是一种无损的音频文件, ...

  2. Java程序员应该知道的10个Eclipse调试技巧

    为什么80%的码农都做不了架构师?>>>    Eclipse是众多Java程序员实用的开发工具,其中开发技巧也是繁多,但作为优秀的Java程序员,需要掌握最起码的调试技巧. 1 条 ...

  3. LVGL学习之路——基于lv_lib_freetype库的TTF字体文件动态加载中文字体(阿里普惠字体)

    前言   在学习lvgl中,在英文字体上很多人都用过,但是中文字体往往需要靠取模去实现.那么我就在想,如何像windows那样加载动态的字体呢,这样想做多大字体都行.于是就开始了字体的移植. 什么是t ...

  4. java 动态解析 xml_通过读取xml文件动态建表

    Ada female 21 13300008888 Ada@gmail.com 将上面的xml描述在数据库中创建一张表 import java.io.*; import java.sql.*; imp ...

  5. mysql动态函数库_mysql自定义函数与动态查询

    介绍下mysql自定义函数的例子,以及插入单引号的方法,动态执行查询与字符串拼接的相关内容. 1.mysql自定义函数的例子 mysql不能像oracle 一样写 动态SQL. 代码示例: DROP ...

  6. 静态库、动态库、静态链接、动态链接、系统运行库混合、MD MT默认库冲突问题

    一.静态库项目 静态库lib:(注意和"静态运行库"区分)   就是.lib文件,一个.c或.cpp会编译成一个.obj,多个.obj可以组合成一个.lib库.lib=多个obj. ...

  7. 【Linux后端开发必问】操作系统系列(Linux常用命令、文件权限修改、静态与动态库的制作)

    目录 一.说说常用的Linux命令 二.文件权限如何修改 三.静态库和动态库的制作 1.静态库 2.动态库的制作 3.两者优势对比 一.说说常用的Linux命令 1.cd命令:用于切换当前目录: 2. ...

  8. graalvm把java编译为c/c++能够使用的动态库(dll/so)

    graalvm把java编译为c/c++能够使用的动态库(dll/so) 1.安装graalvm oracle官方企业版 github的openjdk版本 1.1 下载对应系统版本,配置环境变量 本人 ...

  9. linux 生成dll文件,Linux和Windows平台 动态库.so和.dll文件的生成

    Linux动态库的生成 1. 纯cpp文件打包动态库 将所有cpp文件和所需要的头文件放在同一文件夹,然后执行下面命令 gcc -shared - fpic *.c -o xxx.so: g++ -s ...

  10. java web配置dll文件_JavaWeb项目中dll文件动态加载方法解析(详细步骤)

    相信很多做Java的朋友都有过用Java调用JNI实现调用C或C++方法的经历,那么Java Web中又如何实现DLL/SO文件的动态加载方法呢.今天就给大家带来一篇JAVA Web项目中DLL/SO ...

最新文章

  1. php http传参数,http - PHP的URL传参数(英文句号变成了下划线)的问题,求解释。...
  2. 域名怎么设置非80端口_深信服网关怎么设置端口映射
  3. 怎么使用oracle的加权平均数_GPA不足,怎么短期有效提升?快来收获100%录取的秘诀!...
  4. 判断网络是否为真正的公网IP
  5. MVC如何添加Model
  6. android 双线程等待,在Java/Android中启动另一个线程之前如何等待线程完成?
  7. Enabled AWE
  8. 《黑马程序员 MySQL数据库入门到精通,从MySQL安装到MySQL高级、MySQL优化全囊括》——学习笔记基础篇
  9. CentOS故障排除详解(2): 进程相关
  10. Keil uVision4 C51完整版
  11. 微软OneDrive使用体验
  12. STM32F103_study67_The punctual atoms(STM32 OLED display experiment)
  13. Android学习之仿QQ讨论组和微信群聊头像
  14. Phpstudy官网于2016年被入侵,犯罪分子篡改软件并植入后门
  15. 如何查看你的公网ip?
  16. [译] FACE ID 对易用性意味着什么
  17. linux vi 保存退出与不保存退出
  18. 赢得阵亡将士纪念日的十大怪异项目
  19. Java eclipse安装全过程
  20. Laravel开发系列四:安装JetStream

热门文章

  1. android studio 包重复
  2. 山东大学往年c语言期末试题及答案,山东大学历年C语言题库.pdf
  3. linux 创建软连接_linux删除原理
  4. scala访问MySQL数据库
  5. P1379 八数码难题
  6. sqool导出oracle数据
  7. STM32正交编码器驱动电机
  8. 转:Java中abstract和interface的区别
  9. 三目运算符?:结合性
  10. Windows服务器配置与管理-------DHCP服务器搭建与管理