动态方式破解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云平台的Cloud Foundry环境下添加新的Service(服务)

    我想在SAP云平台的Cloud Foundry环境下使用MongoDB的服务,但是我在Service Marketplace上找不到这个服务. cf marketplace返回的结果也没有. 解决方案 ...

  2. UVA 11491 Erasing and Winning 奖品的价值 (贪心)

    题意:给你一个n位整数,让你删掉d个数字,剩下的数字要尽量大. 题解:因为最后数字位数是确定的,而且低位数字对答案的贡献是一定不及高位数字的,所以优先选择选最大且最靠左边的数字,但是有一个限制,选完这 ...

  3. KMP算法入门讲解

    字符串匹配问题.假设文本是一个长度为$n$的字符串$T$,模板是一个长度为$m$的字符串$P$,且$m\leq n$.需要求出模板在文本中的所有匹配点$i$,即满足$T[i]=P[0],T[I+1]= ...

  4. NFS缓存IO机制

    NFS的缓存IO机制<一> async 参数模式下分析 NFS 默认的mount参数为async,async 参数表示内核不会透传程序的IO请求给sever,对于写IO会延迟执行,积累一定 ...

  5. java String中的replace(oldChar,newChar) replace(CharSequence target,CharSequence replacement) replaceAll replaceFirst 面试题:输入英文语句,单词首字符大写后输出 char String int 相互转换

    package com.swift; import java.util.Scanner; public class FirstChat_ToCaps_Test { public static void ...

  6. js中实现杨辉三角

    实现效果:杨辉三角 即: 提示用户输入要实现的杨辉三角行数: 请输入杨辉三角的行数: 8 代码实现后的效果如下: 1 1.1 1.2.1 1.3.3.1 1.4.6.4.1 1.5.10.10.5.1 ...

  7. [51Nod] 1218 最长递增子序列 V2

    如何判断一个元素是否一定在LIS中?设f[i]为以ai结尾的LIS长度,g[i]为以ai开头的LIS长度,若f[i]+g[i]-1==总LIS,那么i就一定在LIS中出现 显然只出现一次的元素一定是必 ...

  8. python中的sort、sorted排序

    我们通常会遇到对数据库中的数据进行排序的问题,今天学习一下对列表和字典的排序方法. 列表 第一种:内建方法sort sort()对列表排序是永久性的排序. 用法:sort(*, key=None, r ...

  9. Anaconda安装和环境的搭建

    Anaconda安装 在官网上下载最新的Anaconda https://www.anaconda.com/distribution/ 我使用的是2018.12,Python 3.7这个版本的. 安装 ...

  10. python爬虫基础18-Chrome调试前端工具

    01 Chrome调试 抓包工具原理 Chrome 开发者工具是一套内置在Google Chrome中Web开发和调试工具.使用开发者工具来重演,调试和剖析您的网站. 其中常用的有Elements(元 ...