安卓逆向入门学习记录

本文介绍了安卓逆向工程的基础知识,包括APK文件结构、打包过程和安装流程,重点讲解了APK的反编译与回编译,探讨了JAVA虚拟机、Dalvik字节码和smali文件。此外,还分享了定位代码技巧和如何理解smali语法,如基本数据类型、对象、数组、类字段/变量和方法/函数的表示方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

APK文件目录

在这里插入图片描述

APK打包过程

在这里插入图片描述

APK安装流程

在这里插入图片描述

APK反编译与回编译

在这里插入图片描述

JAVA虚拟机

在这里插入图片描述

在这里插入图片描述

定位代码技巧

在这里插入图片描述

Dalvik字节码

在这里插入图片描述

smali文件

在这里插入图片描述
①基本数据类型

smali类型 java类型

V void

Z boolean

B byte

S short

C char

I int

J long (64位 需要2个寄存器存储)

F float

D double (64位 需要2个寄存器存储)

②对象

smali对象 java对象

Lpackage/name/ObjectName; package.name.ObjectName

Ljava/lang/String; java.lang.String

L 表示对象类型

package/name 表示包名

; 表示结束③数组

smali数组 java数组

[I int[] 一维数组

[[I int[][] 二维数组

[Ljava/lang/String String[] 对象数组

注:每一维最多255个④类字段/变量

Lpackage/name/ObjectName;——>FieldName:Ljava/lang/String;

smali字段 java字段

public f1:Z public boolean f1;

public f2:I public int f2;

public f3:L java/lang/String; public String f3;

1.赋值

静态static

const-string v0, “Hello Smali”

sput-object v0, Lcom/MyActivity;->name:Ljava/lang/String;

相当于java代码 MyActivity.name = “Hello Smali”

非静态instance

.local v0, act:Lcom/MyActivity;

const/4 v1, 0x2

iput v1, v0, Lcom/MyActivity;->name:Ljava/lang/String;

相当于java代码 act.name = “Hello Smali”

2.取值

静态(static fields)

sget-object v0, Lcom/MyActivity;->name:Ljava/lang/String;

相当于java代码 v0 = MyActivity.name;

非静态(instance fields)

.local v0, act:Lcom/MyActivity;

iget-object v1, v0 Lcom/MyActivity;->name:Ljava/lang/String;

相当于java代码 v1 = act.name;⑤类方法/函数

smali方法 java方法

myMethod([I)Ljava/lang/String; String myMethod(int[])

//Java代码

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

#samli代码

.method protected onCreate(Landroid/os/Bundle;)V

.locals 1

.parameter “savedInstanceState”

.prologue

.line 8

invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V

.line 9

const/high16 v0, 0x7f03

invoke-virtual {p0, v0}, Lcom/fusijie/helloworld/MainActivity;->setContentView(I)V

.line 10

return-void

.end method

#是smali注释

.method和.end method 类似Java大括号{}

.locals 指定方法中非参寄存器总数,出现在方法第一行

.registers 指定方法中寄存器总数

.prologue 表示代码开始

.line 表示java源码行号,用于调试

invoke-static 调用static方法/函数

invoke-super 调用父类方法

invoke-direct 调用private方法

invoke-virtual 调用protected或public方法

return-void 表示方法结束返回void

p0 在静态方法中表示当前对象实例

p1 表示当前onCreate方法参数

v0 表示本地(局部)变量,存放在locals寄存器

move-result 获取方法返回基本数据类型

move-result-object 获取方法返回对象

const/4 v2, 0x0

invoke-virtual {p0, v2}, Lcom/Activity;->getPreferences(I)Landroid/content/SharedPreferences;

move-result-object v1

v1保存的就是调用getPreferences(int)方法返回的SharedPreferences实例

invoke-virtual {v2}, Ljava/lang/String;->length()I

move-result v2

v2保存的则是调用String.length()返回的整型

注: Long和Double类型是64位,需要2个寄存器存储参数

例如:

myMethod(IJ)V;

参数

P1 I(int)

P2,P3 J(long)⑥条件判断语句(if)

if-eq p1, v0, :c1

:c1

invoke-direct {p0}, Lcom/paul/test/a;->d()V

解读:如果p1和v0相等,则执行c1流程

if-ne p1, v0, :c2

:c2

invoke-direct {p0}, Lcom/paul/test/a;->c()V

解读:表示不相等,则执行c2流程

if-gt 大于

if-ge 大于等于

if-lt 小于

if-le 小于等于

"if-eq vA, vB, :cond_" 如果vA等于vB则跳转到:cond_

"if-ne vA, vB, :cond_" 如果vA不等于vB则跳转到:cond_

"if-lt vA, vB, :cond_" 如果vA小于vB则跳转到:cond_

"if-ge vA, vB, :cond_" 如果vA大于等于vB则跳转到:cond_

"if-gt vA, vB, :cond_" 如果vA大于vB则跳转到:cond_

"if-le vA, vB, :cond_" 如果vA小于等于vB则跳转到:cond_

"if-eqz vA, :cond_" 如果vA等于0则跳转到:cond_

"if-nez vA, :cond_" 如果vA不等于0则跳转到:cond_

"if-ltz vA, :cond_" 如果vA小于0则跳转到:cond_

"if-gez vA, :cond_" 如果vA大于等于0则跳转到:cond_

"if-gtz vA, :cond_" 如果vA大于0则跳转到:cond_

"if-lez vA, :cond_" 如果vA小于等于0则跳转到:cond_

基础

field private isFlag:z  定义变量

.method  方法

.parameter  方法参数

.prologue  方法开始

.line 12  此方法位于第12行

invoke-super  调用父函数

const/high16 v0, 0x7fo3  把0x7fo3赋值给v0

invoke-direct  调用函数

return-void  函数返回void

.end method  函数结束

new-instance  创建实例

iput-object  对象赋值

iget-object  调用对象

invoke-static  调用静态函数

条件跳转分支:

"if-eq vA, vB, :cond_" 如果vA等于vB则跳转到:cond_

"if-ne vA, vB, :cond_" 如果vA不等于vB则跳转到:cond_

"if-lt vA, vB, :cond_" 如果vA小于vB则跳转到:cond_

"if-ge vA, vB, :cond_" 如果vA大于等于vB则跳转到:cond_

"if-gt vA, vB, :cond_" 如果vA大于vB则跳转到:cond_

"if-le vA, vB, :cond_" 如果vA小于等于vB则跳转到:cond_

"if-eqz vA, :cond_" 如果vA等于0则跳转到:cond_

"if-nez vA, :cond_" 如果vA不等于0则跳转到:cond_

"if-ltz vA, :cond_" 如果vA小于0则跳转到:cond_

"if-gez vA, :cond_" 如果vA大于等于0则跳转到:cond_

"if-gtz vA, :cond_" 如果vA大于0则跳转到:cond_

"if-lez vA, :cond_" 如果vA小于等于0则跳转到:cond_






## adb命令
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210221184215717.png)
ADB,即 Android Debug Bridge

查看当前连接设备:
adb devices

查看顶部Activity:
windows环境下:
adb shell dumpsys activity | findstr "mFocusedActivity"

安装apk文件:
adb install xxx.apk

卸载App:
adb uninstall com.zhy.app

从手机端下载文件:
adb pull /sdcard/xxx.txt

往手机SDCard传递文件:
adb push 文件名 手机端SDCard路径

启动Activity:
adb shell am start 包名/完整Activity路径

发送广播:
adb shell am broadcast -a "broadcastactionfilter"
1
-如果需要携带参数(携带一个Intent,key为name):

adb shell am broadcast -a "broadcastactionfilter" -e name zhy

启动服务:
adb shell am startservice "com.zhy.aaa/com.zhy.aaa.MyService"

可以使用screencap命令来进行手机屏幕截图,例如:
adb shell screencap /sdcard/screen.png

使用adb shell input命令向屏幕输入一些信息,
例如:
adb shell input text "insert%stext%shere"

使用adb shell input tap命令来模拟屏幕点击事件,例如:
adb shell input tap 500 1450

使用adb shell input swipe命令来模拟手势滑动事件,例如:
adb shell input swipe 100 500 100 1450 100
表示从屏幕坐标(100,500)开始,滑动到(100,1450)结束,整个过程耗时100ms.

使用adb shell input keyevent命令来模拟点按实体按钮的命令,例如:
adb shell input keyevent 25
1
该命令表示调低音量。数字25是在AOSP源码中的KeyEvent类里卖弄定义的一个事件常量。该类定义了将近300个事件常量。

am:
am(Activity Manager)命令来启动一个APP、启动Activity、启动广播和服务等等。
启动一个activity,最简单的命令可以使用adb shell am start com.package.name/com.package.name.ActivityName,例如:
adb shell am start com.example.crime/com.example.crime.MainActivity

![在这里插入图片描述](https://img-blog.csdnimg.cn/20210221185026999.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDczNjAwNQ==,size_16,color_FFFFFF,t_70)
Android官网中的ADB信息,请访问链接:https://developer.android.com/studio/command-line/adb.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值