动态方式破解apk进阶篇(IDA调试so源码)

来源 https://blog.csdn.net/qq_21051503/article/details/74907449

下面就说关于在IDA中Android so的动态调试的问题以及在so的三个层次下断点的操作。

问题篇:

1.动态调试的作用以及与我们常说的脱壳区别之处?

2.IDA的下断点调试的原理?

3.有无反调试的步骤区别?以及原理?

4.反调试与反附加的区别?

5.IDA动态调试so时有哪三个层次?以及如何下断点?

注意:so的动态调试与脱壳在步骤上有很多的相似之处,关于脱壳在后面会详细介绍加壳以及脱壳的发展历程。

解答原理篇:

第一个问题:

曰:动态调试作用有二:

其一:dump内存,即:找准时机dump出解密后的正确文件;

其二:查看每一步状态,进一步分析出正确的逻辑;

脱壳只是我们在调试系统级别的.so文件后 ,找准时机dump出正确而真实的.so文件,而动态调试只不过是手动脱壳的一种表现方式。

第二个问题:

曰:(由于师哥说面试时喜欢问,此处列出来)

下断点原理:

由于下断点有硬件断点和软件断点,我们在这里只说IDA中的软件断点原理:

X86系列处理器提供了一条专门用来支持调试的指令,即INT 3,这条指令的目的就是使CPU中断(break)到调试器,以供调试者对执行现场进行各种分析。

当我们在IDA中对代码的某一行设置断点时,即:F2,调试器会先把这里的本来指令的第一个字节保存起来,然后写入一条INT 3指令,因为INT 3指令的机器码为11001100b(0xCC)当运行到这的时候CPU会捕获一条异常,转去处理异常,CPU会保留上上下文环境,然后中断到调试器,大多数调试器的做法是在被调试程序中断到调试器时,会先将所有断点位置被替换为INT 3的指令恢复成原来的指令,然后再把控制权交给用户。这样我们就可以愉快的开始调试了。如下图所示也是写调试器的原理图:

第三个问题:

曰:先说无反调试:

1.adb push d:\android_server(IDA的dbgsrv目录下)  /data/local/tmp/android_server(这个目录其实可以随便放,有的反调试会检测这)

2.adb shell

3.su(一定要有root权限)

4.cd /data/local/tmp

5.chmod 777 android_server(执行权限要给)

6.再开一个cmd
adb forward tcp:23946 tcp:23946(端口转发,调试手机上的某个进程要有协议支持通信)

7.打开待调试的应用程序,就可以愉快的调试了

再来说有反调试:

曰:在很多情况下我们遇到的是有反调试并且用上面的步骤,附加进去以后直接就退出了,这样的例子数不胜数,那就是反调试惹的货。

这时候我们就要改变调试战略了

在上文的基础上:

1.启动android_server;

2.端口转发adb forward tcp:23946 tcp:23946;

3.adb shell am start -D -n 包名/类名;

(说明:以启动模式启动,是停在加载so文件之前,报名在AndroidMainfest文件中可以找到)

4.打开IDA,附加上对应的进程之后,设置IDA中的load so的时机,在debug options中设置一下,后面会有实战部分;

5.adb forward tcp:8700 jdwp:进程号;(jdwp是后面jdb调试器的协议,转换到待调试的指定的应用程序);

6.jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=8700(jdb进行附加);

7.可以愉快的下断点,开始调试了;

第四个问题:

曰:反调试就是阻止你进行动态调试所采用的一种手段,在下一篇中会进行具体的讲解反调试的手段,以及解决反调试的办法。

反附加,在这块重要的是说jdb的反附加,很多情况下jdb会附加不上,就是会出现“无法附加到目标的VM”这样的问题那是因为在每个应用程序下,有这个android:debuggable="true"才能调试,因为篇幅问题,照样会在下一篇中会针对反附加寻找目前所有解决办法。

第五个问题:

曰:我们知道在so的加载时候有个这个过程:

.init->->.init array->->JNI_Onload->->java_com_XXX;

还有我们在脱壳的过程中会在一些系统级的.so中下断点比如:fopen,fget,dvmdexfileopen,等等

而.init以及.init_array一般会作为壳的入口地方,那我们索性叫它外壳级的.so文件

这里归纳为三类:

应用级别的:java_com_XXX;

外壳级别的:JNI_Onload,.init,.init_array;

系统级别的:fopen,fget,dvmdexfileopen;

对于在应用级别的和系统级别的就不说了比较简单容易理解,这里也是在实现篇中会重点说的,看到上面的.so的加载执行过程我们知道如果说反调试放在外壳级别的.so文件的话我们就会遇程序在应用级核心函数一下断点就退出的尴尬,事实上多数的反调试会放在这,那么过反调试就必须要在这些地方下断点,那么我们就重点的说如何在.init_array和JNI_Onload处理下断点。

实现篇:

这里我们会拿阿里有一年的比赛样本,会放在附件中。

在JNI_Onload处下断点方法一:(双开定位)

1.启动android_server;

2.端口转发以及调试模式启动:如图所示:

3.打开IDA,设置

4.附加上对应的进程进去之后如图:

5.这一步很重要在Debugger option下面选择这三个选项(让在load so的每个接口处停下来)

6.jdwp协议端口转发

7.jdb附加

8.F9执行,忽略提示框;这时候运行到linker处,如图:

9.这时候找JNI_Onload的绝对地址:

基地址+相对地址;

基地址为:ctrl+s显示为:

相对地址,用IDA静态分析libcrack.so可得到相对地止:

绝对地址为:4151E000+1B9C=4151FB9C

按下“G”键输入4151FB9C

如图所示:按下F2下好断点,再按F9执行到断点处就可以愉快的调试了

在JNI_Onload处下断点方法二:(简单好用)

1.首先把要分析的libcrackme.so文件拉进IDA里面在要下断点的JNI_Onload处下好断点如图所示:

2.启动android_server与上面一样;

3.端口转发以及调试模式启动:如图所示

4.先设置一下Debugger 如图所示

5.IDA进行附加进程回到之前静态分析libcrackme.so的IDA界面单击Debugger -> Process options 配置调试信息,这里只需配置hostname为localhost,其余的保持默认设置即可

6.单击Debugger -> Attach to process进行附加进程

7.jdwp转发(当然打开DDMS就不需要这一步了)jdb附加

8.F9执行一路取消就OK,得到如图所示:

是不是很简单??

在.iniy_array处下断点(与上面方法二雷同)

得到的结果是:

OK,搞定

在JNI_Onload处下断点方法三:(适合于脱壳的时候)

1.可以根据看源码,对应不同版本的系统源码就会发现一点,如下在vm/Native.cpp路径下:

2.我们逆向去看,首先把系统中的libdvm.so a db pull出来,拉到IDA中去分析;

找到JNI_Onload处进行分析:F5可以看到,首先V20进行“JNI_Onload”符号查找,同时在V23有对V20的调用,

回到ARM指令处可以看到如下:

0x50008就是偏移处,这个时候我们就开始下断:

加载上要调试的APK以后,找到libdvm.so的基址,然后加上50008,下断点。如果看不到汇编,那就P一下,下断点,这个比较适合于脱壳的时候。

附件:点击打开链接

====================================参考1

1.adb push d:\android_server(IDA的dbgsrv目录下)  /data/local/tmp/android_server(这个目录其实可以随便放,有的反调试会检测这)
2.adb shell 
3.su(一定要有root权限)
4.cd /data/local/tmp
5.chmod 777 android_server(执行权限要给)
6.再开一个cmd
adb forward tcp:23946 tcp:23946(端口转发,调试手机上的某个进程要有协议支持通信)
7.打开待调试的应用程序,就可以愉快的调试了

====================================参考2

2、前期准备
2.1  安装样本程序

adb install AliCrackme_2.apk
2.2 上传android_server文件

adb push android_server /data/local/tmp/
adb shell chmod 777 /data/local/tmp/android_server
 
3、调试步骤
3.1  开启android_server,监听23946端口,与IDA pro通信

adb shell /data/local/tmp/android_server
adb shell android_server
3.2  设置本地端口转发

adb forward tcp:23946 tcp:23946
3.3  以调试模式启动程序

adb shell am start -D -n com.yaotong.crackme/.MainActivity
3.4 启动IDA pro,点击Debugger->attach->Remote ARMLinux/Android debugger,输入localhost,选择要调试的进程即可。

================================自己实现

adb forward tcp:8008 tcp:8008

http://127.0.0.1:8008/#

使用logcat功能需要先转发端口到本地。

adb forward tcp:8887 tcp:8887

================================自己实现

1 android_server

adb push d:\android_server /data/local/tmp/

adb shell chmod 777 /data/local/tmp/android_server

2 把那个android_server配置文件放到/system/xbin 里面

3.1 statr

开启android_server,监听23946端口,与IDA pro通信

3.2  设置本地端口转发

adb forward tcp:23946 tcp:23946

3.3  以调试模式启动程序

adb shell am start -D -n com.yaotong.crackme/.MainActivity

adb shell am start -D -n com.yaotong.crackme/com.yaotong.crackme.MainActivity

3.4 启动IDA pro,点击Debugger->attach->Remote ARMLinux/Android debugger,输入localhost,选择要调试的进程即可。

3.5 附加程序成功后,选择,Debugger option,勾选

suspend on process entry point

suspend on thread start/exit

suspend on library load/unload

三项,然后按f9运行调试程序,此时IDA pro 挂起

动态方式破解apk进阶篇(IDA调试so源码)的更多相关文章

  1. Android逆向之旅---动态方式破解apk进阶篇(IDA调试so源码)

    Android逆向之旅---动态方式破解apk进阶篇(IDA调试so源码) 来源 https://blog.csdn.net/jiangwei0910410003/article/details/51 ...

  2. Android动态方式破解apk进阶篇(IDA调试so源码)

    一.前言 今天我们继续来看破解apk的相关知识,在前一篇:Eclipse动态调试smali源码破解apk 我们今天主要来看如何使用IDA来调试Android中的native源码,因为现在一些app,为 ...

  3. Android动态方式破解apk前奏篇(Eclipse动态调试smail源码)

    一.前言 今天我们开始apk破解的另外一种方式:动态代码调试破解,之前其实已经在一篇文章中说到如何破解apk了: Android中使用静态方式破解Apk  主要采用的是静态方式,步骤也很简单,首先使用 ...

  4. Android动态方式破解apk终极篇(加固apk破解方式)

    一.前言 今天总算迎来了破解系列的最后一篇文章了,之前的两篇文章分别为: 第一篇:如何使用Eclipse动态调试smali源码 第二篇:如何使用IDA动态调试SO文件 现在要说的就是最后一篇了,如何应 ...

  5. 查看和调试Qt源码(动态编译的QT也可进入源码)good

    简述 在调试程序的时候,有时需要调试进入 Qt 源码,这不仅有利于我们了解内部实现机制,而且对于解决一些隐蔽性问题很有帮助. 都知道 F11 是“单步进入”,可是在调试的过程中,按下 F11 却无法进 ...

  6. 比特币学习笔记(二)---在windows下调试比特币源码

    根据我一贯的学习经验,学习开源代码的话,单单看是不够的,必须一边看一边调试才能尽快理解,所以我们要想法搭建windows下bitcoin源码的调试环境. 紧接着昨天的进度,想要调试linux下的比特币 ...

  7. Maven 依赖调解源码解析(二):如何调试 Maven 源码和插件源码

    本文是系列文章<Maven 源码解析:依赖调解是如何实现的?>第二篇,主要介绍如何调试 Maven 源码和插件源码.系列文章总目录参见:https://www.cnblogs.com/xi ...

  8. 第三篇:白话tornado源码之请求来了

    上一篇<白话tornado源码之待请求阶段>中介绍了tornado框架在客户端请求之前所做的准备(下图1.2部分),本质上就是创建了一个socket服务端,并进行了IP和端口的绑定,但是未 ...

  9. 使用VS2012调试ReactOS源码

    目录 一 下载并安装VS2012 二 下载并安装WDK80 三 下载ReactOS0315源码 四 下载并安装RosBE211 五 用RosBE命令行编译ReactOS源码 六 用VS2012编译nt ...

随机推荐

  1. SAP云平台的Document Service

    SAP云平台以微服务的方式提供了Document的CRUD(增删改查)操作.该微服务基于标准的CMIS协议(Content Management Interoperability Service). ...

  2. 使用Java connector消费ABAP系统的函数

    Java Connector(JCO)环境的搭建:Step by step to download and configure JCO in your laptop 我的ABAP系统有个函数名叫ZDI ...

  3. 卓越管理的实践技巧(2)成功的委派任务 Setup for Successful Delegation

    Setup for Successful Delegation 前文卓越管理的秘密(Behind Closed Doors)最后一部分提到了总结的13条卓越管理的实践技巧并列出了所有实践技巧名称的索引 ...

  4. UVA 12901 Refraction 折射 (物理)

    一道物理题,解个2次方程就行了... 求h最小的情况对应如下图所示 做法不唯一,我想避免精度损失所以在化简的时候尽可能地去避免sqrt和浮点数乘除. 似乎精度要求很低,直接用角度算也可以 #inclu ...

  5. FreeRTOS笔记

    任务的创建和删除(静态方法) 任务创建后要开启调度器. FreeRTOSConfig.h 1. 改宏 使能静态创建函数. 会出现,有两个函数未定义. Cortex-M中断管理(上) NVIC:嵌套向量 ...

  6. virtualvenv+django+uWSGI+nginx 部署 踩坑记录

    原创博文 转载请注明出处! uwsgi: unrecognized option '--http:8089' uwsgi: unrecognized option '--http' uwsgi trk ...

  7. 创建 Django 步骤

    1.创建项目 django-admin startproject 项目名称 2.创建APP python manage.py startapp app名称 3.修改settings.py文件 3.1设 ...

  8. Java底层基础题

    一.Java底层基础题 1.SpringMVC的原理以及返回数据如何渲染到jsp/html上? 答:Spring MVC的核心就是DispatcherServlet , 一个请求经过Dispatche ...

  9. 《鸟哥的Linux私房菜》学习笔记(1)——文件与目录

    在Linux中,任何设备都是文件,不仅如此,连数据通信的接口也有专门的文件负责.可以说,一切皆文件,目录也是一种文件,是路径映射.因此,文件系统是Linux的基础. 一.文件与目录管理命令 1.ls( ...

  10. 打造一款属于自己的web服务器——从简单开始

    距离开篇已经过了很久,期间完善了一下之前的版本,目前已经能够完好运行,基本上该有的功能都有了,此外将原来的测试程序改为示例项目,新项目只需按照示例项目结构实现controller和view即可,详情见 ...