freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

安卓学习思路方法总结(四)
2021-08-12 17:06:30

这是系列文章的第四篇

安卓学习(一)

安卓学习思路方法总结(二)

安卓学习思路方法总结(三)

我们继续

Android Studio动态调试

前言

Android Studio本身并不可以反编译APK 开发用的比较多

它通过导入反编译出来的完整的的Smali代码,然后设置好调试所需的条件,设置断点

断点准备好的条件后,连接模拟器运行待调试的APK的应用程序,然后执行程序的流程运行到Smali代码的时候,断点处会触发一个断点会自动断下来,从而可以进一步分析和调试,整个程序会非常的清晰。

安装

首先来安装一下

https://ibotpeaches.github.io/Apktool/
https://bitbucket.org/JesusFreke/smali/downloads/
https://developer.android.google.cn/studio/

image-20210805161808409

一路默认过去就可以

image-20210805161919811

image-20210805161947592

image-20210805162017553

image-20210805162042442

然后一路next

image-20210805164600449

导入项目包

既然Android Studio不可以反编译

那么我们就首先把APK丢到Android Killer中

image-20210805164909385

image-20210805164932533

image-20210805164954328

我们要的就是这个 反编译完的项目包--Project

image-20210805165135999

image-20210805165231324

image-20210805165252591

然后继续一路默认即可

image-20210805165606553

image-20210805165942265

添加插件

image-20210805170030847

image-20210805170250468

image-20210805170511650

给项目root权限

image-20210805170646825

image-20210805170718958

设置sdk

image-20210805170835000

image-20210805170852032

image-20210805171011400

远程调试

image-20210805171117366

image-20210805171147129

image-20210806115137056

自定义Name 端口不要被占用 选中项目文件夹 即可

image-20210805171407483

安装补丁

image-20210805232842375

adb基本操作

识别设备

adb devices

image-20210806115248075

这个就是我的安卓机

进入安卓机

adb shell

image-20210806115315667

之前有提到过的

image-20210806000641560

安卓的底层操作系统是Linux操作系统

这个安卓机 我已经将它root过了

查看进程

adb shell ps

image-20210806115350484

参数解释

adb shell ps
PID:ID
PPID:父进程ID
VSIZE:进程的虚拟内存大小kb单位RSS:实际占用的大小
RSS:实际占用的大小
WCHAN:进程睡眠的函数名称
PC∶电脑内核函数名称
NAME:包名

注册机破解

安卓机中打开注册机程序

项目的入口点

我们找一下

image-20210805172823537

然后我们重新看进程

adb shell ps

image-20210806115419773

PID就是:2550

进行转发端口 进行调试

简单来讲 就是把模拟器中的注册机程序和Android Studio进行联动起来

adb forward tcp:8700 jdwp:13362

image-20210806115531211

设置好指定程序后

进行debug

image-20210806115618788

成功连接

这里记录一个

万能重启命令

adb kill-server
adb start-server
adb remount

我们找到checkSN()下断点

image-20210806120336205

然后上安卓机

打开注册机APK

image-20210806131830131

image-20210819151705175

点击注册

image-20210806120535690

这时候会自动断点跳转到const/4 v7, 0x0

image-20210806120736806

F7:单步步入
F8:单步步步
F9:跳转到下一个断点

当我们F8 一步步向下走之后

image-20210806121942195

看到了跳转MD5算法 开始拼接sb

继续向下走

image-20210806122051127

开始循环拼接sb

image-20210806122241886

image-20210806122257037

userSN="8d9d5d4c03dd33d5"

这个就是我们的注册码

总共循环了32次

在往下走 就跳出循环了

image-20210806122329691

尝试注册码 注册

image-20210819151340350

IDA动态调试

安装

可以看这里:安卓(一)

Android Killer反编译APK

当我们拿到一个APK

进行Android Killer进行反编译

image-20210806102309507

导出文件

image-20210806102403016

image-20210806102416377

image-20210806102432197

image-20210806104219599

我们找的就是这个.so文件

打开IDA

image-20210806101614285

image-20210806101640818

当我们把so文件直接丢进来之后

会有一个弹窗

image-20210806104415226

IDA提供了两种方法去解析

ELF就是so的一个文件格式

Binary file是二进制文件格式

那肯定是选第一个咯

image-20210806104723113

然后呢

这个包下除了.so文件 还多出好多文件

image-20210806104817404

IDA是递归下降的反汇编工具

image-20210806140455305

地址越来越大

这里是导航条

image-20210806140538676

蓝色:表示常规的指令函数
- 深蓝:用户写的函数编译后的代码区
- 浅蓝:编译器自己添加的函数,像启动函数,异常函数等等

黑色:节与节之间的间隙
#禁区,不存在任何数据

银白色:数据内容

粉色:表示外部导入符号
#有关输入表的一些数据信息

暗黄色:表示IDA未识别的内容

主界面

IDA View三种反汇编视图:文本视图、图表视图、路径视图

Hex View:十六进制窗口
Imports:导入函数窗口
Struceures:结构体窗口
Exports:导出函数窗口
Enums:枚举窗口
Strings:字符串窗口

image-20210806140958295

image-20210806141437961

十六进制 修改 按F2即可

默认是6张表

表的添加这里

image-20210806141607633

快捷键

空格键:切换文本视图与图表视图
ESC:返回上一个操作地址
G:搜索地址和符号
N:对符号进行重命名
冒号键:常规注释
分号键:可重复注释
ALt+M:添加标签
Ctrl+M:查看标签
Ctrl+S:查看段的信息so


代码数据切换
C--代码
D--数据
A--ascii字符串
U--解析成未定义的内容

X:查看交叉应用
F5:查看伪代码
ALt+T:搜索文本
ALt+B:搜索十六进制

G:搜索地址和符号

image-20210806142012795

Ctrl+S:查看段的信息so

image-20210806142034527

ALt+T:搜索文本

image-20210806142426423

ALt+B:搜索十六进制

image-20210806142410895

环境安装

上传android_server

首先来到IDA的dbgsrv目录

C:\IDA 7.0\dbgsrv

image-20210806170510753

我把它复制到桌面了

然后利用adb把android_serverpush到指定目录下

adb push C:\Users\Administrator\Desktop\android_server data/local/tmp

这边我还是上我的安卓机

image-20210806170824849

image-20210806171122084

进行查看

image-20210806171139420

进行加权

chmod 777 android_server

image-20210806171228188

image-20210806171345573

这里还要提一句 : 记住安卓的底层是Linux的操作系统

因为安卓的机制问题 进行更名

mv android_server a001

image-20210806171537912

运行a001

image-20210806171757944

可以看到它监听的是23946端口

注:指定端口:

./a001 -p1-65535

我们继续

端口转发

adb forward tcp:23946 tcp:23946

image-20210806172132715

安装APK到安卓机上

这次使用的是install

adb install C:\Users\Administrator\Desktop\javandk1.apk

image-20210806172245243

IDA中Debugger调试

进行Debugge选择

image-20210806172632757

image-20210806172702683

进行配置

image-20210806172722601

23946就是默认端口

image-20210812022849738

调出安卓机的进程窗口

ctrl+f :进行搜索ndk

image-20210812022953229

双击选择之后进来ndk

image-20210812023059042

image-20210812023124211

image-20210812023309088

加载模块列表

image-20210812023400746

image-20210812023523238

分别代表

库挂起入口点

开始结束

加载卸载

表示程序在运行中只要涉及到进程的入口点、涉及到线程的开始和结束、涉及到库的加载和卸载

都可以让程序进行 debugger(断点)操作!

运行IDA

左上角小三角 或者F9都可以

image-20210812023735845

普通调试

环境调整

运行android_server

因为安卓的在调试的时候apk等安全机制会对 android_server进行关键名称检测

所以我做了修改

端口转发

adb forward tcp:23946 tcp:23946

image-20210812024837314

挂起程序

挂起程序(需要程序的包名+类名)
使用AndroidKiller进行反编译APK

image-20210812024710109

adb shell am start -D -n com.example.javandk1/.MainActivity

注:类名前面要加斜杠相对路径

安卓机弹出一个窗口

image-20210812031413475

运行ddms

image-20210812025319178

小图标变红色了

运行IDA

进行连接

image-20210812025452886

image-20210812025511958

还是要记得加载模块列表

image-20210812023523238

然后运行

image-20210812025820338

IDA加载so文件

打开ddms

image-20210812025901417

查看下调试程序的端口号:8600

命令

jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8600

image-20210812031742779

image-20210812030017329

图标变成了绿色

image-20210812030034323

IDA也成功加载so文件

Moules模块

ndk1-1/oat/arm/base.odex

image-20210812030535105

双击进入

image-20210812032004172

安卓逆向-JNI

1、编写C代码

#include <stdio.h>
int main (){
printf("a001")
return 0;
}

2、编写.mk文件代码

mk文件就是在构建工具时,会被 Build System解析多次!

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := a001
LOCAL_SRC_FILES := a001.c 
LOCAL_ARM_MODE := arm 
LOCAL_LDLIBS += -llog 
include $(BUILD_HARED_LIBRARY)

代码分析

1、LOCAL_PATH := $(call my-dir):获取JNI文件路径
每个mk必须以 local开始,my-dir是由 Build System提供的,
返回的是一个包含mk文件的路径,要获取相应的文件目录路径去调用JNI属性

2、include $(CLEAR_VARS) :CLEAR VARS变量也是由 Build System提供,
指定清理 LOCAL_开头的文件,但不会清理 LOCAL_PATH开头的

3、LOCAL_MODULE := a001:定义的模块名称,如果这里编译岀so文件前面+lib后面+so

4、LOCAL_SRC_FILES := a001.c:表示同文件目录下c文件

5、LOCAL_ARM MODE:=arm:编译后的指令集,arm每个指令有四个字节

6、include $(BUILD_HARED_LIBRARY):把文件构建成可执行程序
如果是动态链接库就用:include(shared library)
如果是静态链接库:include $(static library)

3、编写application.mk代码

APP_ABI := x86 armeabi-v7a

这里说明一下

v7a是可以兼容armeabi的,一般就加上就好

v7a的意思是第7代及以上的ARM处理器,目前大部分都支持,为了性能优化,都会写上!

x86是可以兼容armeabi

那么在不设计到平台情况下,只需要改MODULESRC_FILES即可!

4、进行编译

image-20210812135357852

放在jni目录下

image-20210812135425897

编译

image-20210812135312788

可看到生成了两个文件:libsobj

image-20210812135455392

armeabi-v7ax86下面的文件是ELF文件

image-20210812135512350

都是linux下的文件

注:PIE安全机制从4.1引入

但是 Android L之前的系统版本并不会去检验可执行文件是否基于PIE编译岀的。因此不会报错。

但是 Android L已经开启验证,如果调用的可执行文件不是基于PIE方式编译的,则无法运行。

所以需要在Android.mk中加入flag

LOCAL_CFLAGS += -pie -fPIE
LOCAL_LDFLAGS += -pie -fPIE

5、进行adb push上传

adb push C:\Users\Administrator\Desktop\libs\armeabi-v7a\aaa data/local/tmp

image-20210812135851654

加权

chmod +x

执行

image-20210812140013359

请注意:这里使用的技术仅用于学习知识目的,如果列出的技术用于其他任何目标,我概不负责。

OK!就到这里

安卓学习(一)

安卓学习思路方法总结(二)

安卓学习思路方法总结(三)

# android安全 # 移动安全 # Android # 安卓逆向
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录