大神论坛

找回密码
快速注册
查看: 362 | 回复: 0

[原创] 安卓逆向破解教程十二、so加载与动态调试,常见反调试

主题

帖子

0

积分

初入江湖

UID
561
积分
0
精华
威望
0 点
违规
大神币
68 枚
注册时间
2023-09-16 14:56
发表于 2023-09-16 16:56
本帖最后由 cdp20031308 于 2023-09-16 16:56 编辑

一、课程目标


1.了解汇编寄存器知识、so加载流程
2.了解常见so防护手段,以ollvm为例
3.学习动态调试技巧以及常见反调试

二、工具


1.教程Demo(更新)
2.MT管理器/NP管理器
3.IDA PRO
4.Android Studio
5.010 Editor

三、课程内容


1.so加载流程

作用:反调试、脱壳、注入等

流程图:

函数的基本介绍:

下断点时机:
应用级别的:java_com_XXX;
外壳级别的:JNI_Onload,.init,.init_array(反调试);
系统级别的:fopen,fget,dvmdexfileopen(脱壳);

安卓在线源码查看
AOSPXRef:http://aospxref.com

2.IDA动态调试

1.前置操作:

1.在IDA目录下的dbgsrv,选择跟手机架构一致的server
2.adb push as /data/local/tmp/
3.进入手机端命令:adb shell
4.切换获取手机的root权限:su
5.跳到对应路径:cd /data/local/tmp/
6.提权:chmod 777 as
7.XappDebug hook

2.调试步骤

分为两种模式,一种是以debug模式启动,第二种则以普通模式启动,二者的区别在于使用场景,有时候要动态调试的参数在app一启动的时候就产生了,时机较早,所以需要以debug模式去挂起app

adb shell am start -D -n com.zj.wuaipojie/.ui.ChallengeEight (去掉-D 则表示不以debug模式启动app)
adb forward tcp:23946 tcp:23946 (端口转发)
adb forward tcp:8700 jdwp:PID (pid监听)
jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700 (jdb挂起)

PS:若不是以debug启动则不需要输入后两条命令
其他的步骤具体看视频

3.常见寄存器知识

在进行动态调试,以下是一些常用的寄存器介绍:

4.常用快捷键

5.可能遇到的问题

1.'jdb' 不是内部或外部命令,也不是可运行的程序或批处理文件。

http://t.csdn.cn/paKAt

2.java.io.IOException: handshake failed - connection prematurally closed
at com.sun.tools.jdi.SocketTransportService.handshake(SocketTransportService.java:136)
at com.sun.tools.jdi.SocketTransportService.attach(SocketTransportService.java:232)
at com.sun.tools.jdi.GenericAttachingConnector.attach(GenericAttachingConnector.java:116)
at com.sun.tools.jdi.SocketAttachingConnector.attach(SocketAttachingConnector.java:90)
at com.sun.tools.example.debug.tty.VMConnection.attachTarget(VMConnection.java:519)
at com.sun.tools.example.debug.tty.VMConnection.open(VMConnection.java:328)
at com.sun.tools.example.debug.tty.Env.init(Env.java:63)
at com.sun.tools.example.debug.tty.TTY.main(TTY.java:1066)
致命错误:
无法附加到目标 VM。
解决方法:有可能是手机问题,建议低版本真机,不要用模拟器!切命令顺序不要乱!另外也有可能软件有反调试!
3.动态调试中找不到so文件
解决方法:可以尝试手动复制一份对应的so文件放到data/app/包名/lib目录下
4.device offline
解决方法:重新插拔usb,再不行就重启机子
5.0.0.0.0:23946: bind: Address already in use
解决方案:
adb shell "su -c 'lsof | grep 23946'" //获取pid
adb shell "su -c 'kill -9 PID'" //这里的pid要根据上一步获取的填写

6.常见反调试

1.调试端口检测
检测常见的23946端口,所以在运行时可以加 -p 指定一个另外的端口来过掉这个检测
2.调试进程名检测
固定的进程名 android_server gdb_server等等,所以要改个名字,例如as64
3.ptrace检测
每个进程同时刻只能被1个调试进程ptrace ,主动ptrace本进程可以使得其他调试器无法调试
实现代码:

int ptrace_protect()//ptrace附加自身线程 会导致此进程TracerPid 变为父进程的TracerPid 即zygote
{
return ptrace(PTRACE_TRACEME,0,0,0);;//返回-1即为已经被调试
}

3.SO防护手段

常见防护手段:

1.ollvm简介

LLVM(Obfuscator-LLVM)是瑞士西北应用科技大学安全实验室于2010年6月份发起的一个项目,该项目旨在提供一套开源的针对LLVM的代码混淆工具,以增加对逆向工程的难度,只不过仅更新到llvm的4.0,2017年开始就没在更新。
项目地址

源代码(c/c++)经过clang--> 中间代码(经过一系列的优化,优化用的是Pass)--> 机器码

感受一下被ollvm支配的恐惧

2.ollvm的分类

1.2.1 指令替换(Sub)

指令替换,将一条运算指令,替换为多条等价的运算指令。例如:y=x+1变为y=x+1+1-1

1.2.2 虚假控制流(bcf)

虚假控制流混淆主要通过加入包含不透明谓词(相邻数字相乘恒为偶数)的条件跳转和不可达的基本块,来干扰IDA的控制流分析和F5反汇编
常见特征:不透明谓词-->例如y > 10 || x * (x + 1) % 2 != 0

1.2.3 控制流平坦化(Fla)

控制流平坦化,主要通过一个主分发器来控制程序基本块的执行流程。该方法将所有基本代码放到控制流最底部,然后删除原理基本块之间跳转关系,添加次分发器来控制分发逻辑,然后过新的复杂分发逻辑还原原来程序块之间的逻辑关系。
常见的特征:一大堆分支函数

1.2.4 字符串加密

字符串加密的原理很简单,编写一个pass将其中的字符串信息使用一些加密算法进行加密,然后特定的时间进行还原。一般含有字符串混淆、函数名混淆、不在init_array解密等
常见的特征:datadiv_decoded

3.ollvm对抗

1.简单ollvm可以通过交叉引用分析
2.angr去除不透明谓词
3.Unicorn/Unidbg/AndroidNativeEmu模拟执行
4.IDA Trace
5.binary ninja
6.后端编译优化
7.frida辅助分析

4.IDA Trace 实战分析ollvm

1.在要trace的函数前后下断,触发断点
2.配置trace的log输出路径,并选择trace模式

  • Instruction tracing 调试器将为每条指令保存所有修改后的寄存器值。

  • Basic block tracing 调试器将保存到达临时基本块断点的所有地址。

  • Function tracing 调试器将保存发生函数调用或函数返回的所有地址。
    3.run并触发trace

感谢SharkFall大佬帮忙编译的样本

遇到ollvm平坦化怎么办?没事!chatGpt爸爸帮你解决
记一次基于unidbg模拟执行的去除ollvm混淆
Unicorn反ollvm控制流平坦化之bb
ARM64 OLLVM反混淆
OLLVM 与去平坦化 & [RoarCTF2019] polyre 详细WP
移除ollvm中的控制流平坦化、不透明谓词
【reverse】虚假控制流入门:Ubuntu20.04安装ollvm4.0踩坑记+用IDApython去除BCF
基于IDA Python的OLLVM反混淆(一) 手动去混淆
你所需要的对抗ollvm的知识都在这里
ollvm反混淆学习
记使用Trace还原ollvm混淆的函数
frida辅助分析ollvm

四、课后小作业


待更新

五、答疑


待更新

六、视频及课件地址


下方隐藏内容为本帖所有文件或源码下载链接:

游客你好,如果您要查看本帖隐藏链接需要登录才能查看, 请先登录

返回顶部