当前位置:文档之家› Android动态代码注入调试

Android动态代码注入调试

目录一、动态代码注入技术 (1)二、动态分析工具jdb介绍 (2)四、jdb动态分析Android实例应用程序 (10)五、jdb动态分析第三方文件管理器应用程序 (17)六、动态注入动态链接库 (20)一、动态代码注入技术Android动态代码注入即是不修改源程序只修改进程的寄存器、内存值等就能控制程序实现既定目标的一种方法。

动态代码注入技术本质上就是一种调度技术,动态代码注入相比于普通的调试,最大的区别就是动态代码注入是一个“自动化调试并达到加载自定义动态链接库”的过程。

所谓自动化,其实就是通过代码实现,在Linux上通过Ptrace就可以完成查看变量值、修改变量值、跟踪进程跳转、查看进程调试堆栈等待所有功能,当然,Ptrace功能是比较原始的,平时调试中的功能还需要很多高层逻辑封装才可以实现。

一般而言,我们要对一个进程进行动态注入,主要有以下几个方便目的:增强目标进程的功能、修复目标进程缺陷、劫持目标进程函数、窃取目标进程数据、篡改目标进程数据。

如上图所示,进程A注入到进程B后,通过司改寄存器和内存,让进程B加载自定义的动态链接库a,当a被加载后,a会尝试加载其他模块,比如加载dex文件等等,具体的注入过程如下:∙ATTATCH,指定目标进程,开始调试;∙GETREGS,获取目标进程的寄存器,保存现场;∙SETREGS,修改PC等相关寄存器,使其指向mmap;∙POPETEXT,把so path写入mmap申请的地址空间;∙SETRESG,修改PC等相关寄存器,使其指向dlopen;∙SETREGS,恢复现场;∙DETACH,解除调试,使其恢复;下面就介绍一些简单的进程注入方法:二、动态分析工具jdb介绍JDB是一个简单的Java命令行调试器,包含在JDK中。

使用JDB命令可以分析简单的Java程序。

三、jdb动态分析java应用程序以下是作示例的代码:文件名:Debug.java编译生成的Class文件:Debug.classpublic class Debug{public static void passCheck(String secret){String password = secret;System.out.println("JDBDemoTest-Incoming Password is:"+password);}public static void test(){System.out.println("JDBDemoTest-We are in test method");System.out.println("JDBDemoTest-We are in test method");}public static void main(String args[]){System.out.println("JDBDemoTest-We are in main method");test();passCheck("srini0x00");}}这段代码片段中,Debug类的main方法调用了该类中的其他两个方法,使用-g命令编译后执行,会产生以下输出,如下图:运行JDB要调试Java程序,需要一条JDB到JVM的通信信道,因为Java 程序实际上是运行在JVM(java虚拟机)中的,如下所示,有两种连接JDB和JVM的方法。

方法1:直接使用JDB来加载类文件,JDB会自动创建一个JAVA 虚拟机,并建立连接。

图中的Debug代表编译后生成的类文件。

方法2:使用“java -Xdebug -Xrunjdwp:transport=dt_socket, server=y,address=54321 Debug”命令启动一个Java虚拟机,Java虚拟机会监听54321端口。

然后使用“jdb -attach 54321”命令启动JDB连接到JVM。

开始调试现在开始用第一种方法来调试示例程序,执行一条run命令来让JDB启动Java虚拟机,如下图:图中显示,启动了Java虚拟机后,程序立刻执行完成并退出了。

为了中断程序执行以便手工单步调试,需要在程序运行之前设置断点。

用“stop in”命令在方法开始的地方设置断点,如下图:使用run命令运行程序来触发断点。

触发断点后,JDB会自动显示将要执行的下一行代码:System.out.println(“JDBDenoTest-We are in main method”);可以使用“list“命令来查看当前的上下文代码。

使用“clear“命令查看设置的所有断点:使用”threadgroups”命令查看所有的线程组。

使用“threads”查看所有线程:如上图,当前的system线程组中有三个线程,而main线程组中有一线程,这就是将要调试的线程。

使用“classes”命令查看当前Java虚拟机所加载的类的信息:上图中显示了当前Java虚拟机所加载的全部类中的部分类,要查看特定类的更加详细的信息,可以使用“class<classname>”命令,下图显示了Debug类的详细信息:同样,也能查看其它类的详细信息,例如下图就显示了java.io.FileInputStream类的详细信息:使用“methods <classname>”命令查看所加载的方法:以上介绍了JDB调试的常用命令,现在将深入程序的执行流程,体验怎样用JDB来帮助调试程序。

可以使用“next”命令执行下一行代码:执行完当前代码后,JDB会自动显示下一行代码:调用test方法。

这里,再执行“next”命令后,会执行完test方法并中断到下一行代码:passCheck方法。

想进入passCheck方法进行调试,就使用“step”命令。

在test方法处输入step命令:输入“next”命令继续运行下一条代码:如果想直接离开该方法,而不是运行余下的代码,可以使用“step up”命令。

当前代码已经离开test方法,回到main方法,等待执行下一条。

“where”命令会打印显示当前的调用栈:当前程序正在main方法中,现在使用“step”命令进入方法,并检查调用栈:如上图,程序当前正在”Debug.passCheck”中运行,而“Debug. passCheck”又是被“Debug.main”调用的。

假如想查看passChe ck方法的局部变量信息,可以使用“locals”命令查看所有的局部变量。

如图显示,该方法接收了一个main方法传入的密码变量,因为参数还没有被赋值给局部变量,所只显示了参数而没有局部变量,先执行下一行代码再查看局部变量“password”。

可以使用“pri nt”命令打印出指定变量的内容:四、jdb动态分析Android实例应用程序使用jdb分析Android应用程序的步骤为:1、启动模拟器启动模拟器之前首先使用Android list targets命令查看SDK支持的API 等级。

然后使用“android create avd -n Android411 -t 2”创建模拟器。

创建模拟器完成后使用“android list avd”命令查看创建后的模拟器。

使用“emulator -avd Android411”命令启动模拟器。

2、安装测试应用等到模拟器启动成功后使用“adb install”命令安装应用程序到模拟器。

3、打开终端,输入“adb jdwp”命令,查看Dalvik虚拟机监听在模拟器的哪一个端口。

这条命令会显示所有可以连接并调试的端口,如下图:4、现在打开刚安装的测试应用,再使用“adb jdwp”命令查看应用监听的端口,如图:比较两次命令执行的结果,发现运行测试应用后多出了554端口,这就是测试应用对应的端口,需要用JDB去连接该端口。

5、在连接之前,需要使用adb来转发端口。

6、现在就可以用JDB连接调试android应用了。

远程代码注入下面就实现在应用运行时通过远程代码注入的方式改变变量值达到测试远程代码注入方法的目的。

为此,需要设置断点来控制程序的执行流程。

但之前并不知道该应用所使用的类和方法。

可以使用“classes”命令来查看类和方法。

现在用“methods com.example.debug.MainActivity$1”命令查看 MainActivity$1类中的方法。

在MainActivity$1.onClick方法中设置断点“stop in com.exam ple.debug.MainActivity$1.onClick(android.view.View)”为了触发这个断点,需要手动点击应用的按钮,如下图,点击后断点被触发:使用“locals”命令查看局部变量:使用“next”命令执行下一行代码:再使用“locals”命令查看本地变量,看上一行代码做了什么:如上图,TextView已经被加载并赋值给了tv参数,对应代码中与TextView的代码已经被执行。

使用“next”命令执行下一行,并检查局部变量:上图中列出了所有的局部变量,其中secret的字符串变量的值“Try Again”就是原程序点击按钮后显示的信息。

在源程序中setText方法被用来设置值“Try Again”。

使用”step”命令进入“setText”方法动态修改界面空间中将要显示的值。

使用“locals”命令查看该方法中的局部变量:使用“set”命令将“text”变量的值从“Try Again”改为“Test Android Project By JDB”。

然后再次点击按钮会发现界面中控件显示的内容改变了,而这种改变是在不修改原程序代码的前提下改变的,这就是Android系统中的动态代码注入技术:即不修改源代码,只是在程序运行期间动态修改源程序内容的方法。

按钮被点击之前显示的值是“Crack Me”按钮被点击之后显示的值是“Try Again”动态注入代码后再次点击按钮会显示新注入的内容五、jdb动态分析第三方文件管理器应用程序安装apk文件到模拟器JDB连接模拟器使用“methods”命令进入FileViewInteractionHub类,查看类中的所有方法。

找到要分析的方法“onOperationSetting”在“onOperationSetting”方法中设置断点。

使用“next”命令继续执行程序,使用“step”命令进入方法,使用“locals”命令查看方法中的变量,查看到text控件中原本将要显示的值是“Setting Soft Value”,使用“set”命令修改这个变量值为“Test Android FileExplorer Settings By JDB Command”,使用“run”命令继续运行程序。

相关主题