mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-27 07:01:09 +00:00
272 lines
15 KiB
Markdown
272 lines
15 KiB
Markdown
# Smali - 反编译/【修改】/编译
|
||
|
||
<details>
|
||
|
||
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks 云 ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 推特 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 YouTube 🎥</strong></a></summary>
|
||
|
||
* 你在一家**网络安全公司**工作吗?你想在 HackTricks 中看到你的**公司广告**吗?或者你想获得**PEASS 的最新版本或下载 HackTricks 的 PDF**吗?请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
|
||
* 发现我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)收藏品——[**The PEASS Family**](https://opensea.io/collection/the-peass-family)
|
||
* 获取[**官方 PEASS & HackTricks 商品**](https://peass.creator-spring.com)
|
||
* **加入**[**💬**](https://emojipedia.org/speech-balloon/) [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**Telegram 群组**](https://t.me/peass),或者**关注**我在**推特**上的[**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
|
||
* **通过向**[**hacktricks 仓库**](https://github.com/carlospolop/hacktricks) **和**[**hacktricks-cloud 仓库**](https://github.com/carlospolop/hacktricks-cloud) **提交 PR 来分享你的黑客技巧。**
|
||
|
||
</details>
|
||
|
||
有时候,修改应用程序代码以访问隐藏信息可能是有趣的(也许是混淆良好的密码或标志)。然后,反编译 apk,修改代码并重新编译它可能是有趣的。
|
||
|
||
**操作码参考:**[http://pallergabor.uw.hu/androidblog/dalvik\_opcodes.html](http://pallergabor.uw.hu/androidblog/dalvik\_opcodes.html)
|
||
|
||
## 快速方法
|
||
|
||
使用**Visual Studio Code**和[APKLab](https://github.com/APKLab/APKLab)扩展,您可以**自动反编译**、修改、**重新编译**、签名和安装应用程序,而无需执行任何命令。
|
||
|
||
另一个非常简化此任务的**脚本**是[**https://github.com/ax/apk.sh**](https://github.com/ax/apk.sh)****
|
||
|
||
## 反编译 APK
|
||
|
||
使用 APKTool,您可以访问**smali 代码和资源**:
|
||
```
|
||
apktool d APP.apk
|
||
```
|
||
如果**apktool**出现任何错误,请尝试[安装**最新版本**](https://ibotpeaches.github.io/Apktool/install/)
|
||
|
||
一些**你应该查看的有趣文件**包括:
|
||
|
||
* _res/values/strings.xml_(以及res/values/\*中的所有xml文件)
|
||
* _AndroidManifest.xml_
|
||
* 任何具有_.sqlite_或_.db_扩展名的文件
|
||
|
||
如果`apktool`在解码应用程序时**出现问题**,请查看[https://ibotpeaches.github.io/Apktool/documentation/#framework-files](https://ibotpeaches.github.io/Apktool/documentation/#framework-files)或尝试使用参数**`-r`**(不解码资源)。然后,如果问题出现在资源而不是源代码中,您将不会遇到问题(您也不会反编译资源)。
|
||
|
||
## 更改smali代码
|
||
|
||
您可以**更改**指令,更改某些变量的**值**或**添加**新指令。我使用[**VS Code**](https://code.visualstudio.com)更改Smali代码,然后安装**smalise扩展**,编辑器会告诉您是否有任何**不正确的指令**。\
|
||
这里有一些**示例**:
|
||
|
||
* [Smali更改示例](smali-changes.md)
|
||
* [Google CTF 2018 - Shall We Play a Game?](google-ctf-2018-shall-we-play-a-game.md)
|
||
|
||
或者您可以[**在下面查看一些解释的Smali更改**](smali-changes.md#modifying-smali)。
|
||
|
||
## 重新编译APK
|
||
|
||
在修改代码后,您可以使用以下命令**重新编译**代码:
|
||
```bash
|
||
apktool b . #In the folder generated when you decompiled the application
|
||
```
|
||
它将在_dist_文件夹中**编译**新的APK。
|
||
|
||
如果**apktool**出现错误,请尝试[安装**最新版本**](https://ibotpeaches.github.io/Apktool/install/)
|
||
|
||
### **签署新的APK**
|
||
|
||
然后,您需要**生成一个密钥**(将要求您输入密码和一些可以随机填写的信息):
|
||
```bash
|
||
keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias <your-alias>
|
||
```
|
||
最后,对新的APK进行**签名**:
|
||
```bash
|
||
jarsigner -keystore key.jks path/to/dist/* <your-alias>
|
||
```
|
||
### 优化新应用程序
|
||
|
||
**zipalign** 是一个归档对齐工具,为 Android 应用程序(APK)文件提供重要的优化。[更多信息请参考这里](https://developer.android.com/studio/command-line/zipalign)。
|
||
```bash
|
||
zipalign [-f] [-v] <alignment> infile.apk outfile.apk
|
||
zipalign -v 4 infile.apk
|
||
```
|
||
### **签署新的APK(再次?)**
|
||
|
||
如果您更喜欢使用\[**apksigner**]\([**https://developer.android.com/studio/command-line/apksigner**](https://developer.android.com/studio/command-line/apksigner))\*\*而不是jarsigner,**您应该在使用zipalign进行优化后签署apk**。但请注意,您只需要使用jarsigner(在zipalign之前)或aspsigner(在zipalign之后)对应用程序进行一次签署。
|
||
```bash
|
||
apksigner sign --ks key.jks ./dist/mycompiled.apk
|
||
```
|
||
## 修改 Smali
|
||
|
||
对于以下的 Hello World Java 代码:
|
||
```
|
||
public static void printHelloWorld() {
|
||
System.out.println("Hello World")
|
||
}
|
||
```
|
||
Smali 代码如下:
|
||
```
|
||
.method public static printHelloWorld()V
|
||
.registers 2
|
||
sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
|
||
const-string v1, "Hello World"
|
||
invoke-virtual {v0,v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
|
||
return-void
|
||
.end method
|
||
```
|
||
Smali指令集可以在[这里](https://source.android.com/devices/tech/dalvik/dalvik-bytecode#instructions)找到。
|
||
|
||
### 轻微更改
|
||
|
||
### 修改函数内变量的初始值
|
||
|
||
一些变量在函数开始时使用_const_操作码定义,您可以修改它们的值,或者您可以定义新的变量:
|
||
```
|
||
#Number
|
||
const v9, 0xf4240
|
||
const/4 v8, 0x1
|
||
#Strings
|
||
const-string v5, "wins"
|
||
```
|
||
### 基本操作
|
||
|
||
In this section, we will cover some basic operations that can be performed on Smali code.
|
||
|
||
在本节中,我们将介绍一些可以在Smali代码上执行的基本操作。
|
||
|
||
#### Modifying Constants
|
||
|
||
#### 修改常量
|
||
|
||
To modify a constant value in Smali code, you need to locate the instruction that loads the constant value onto the stack and replace it with a new value.
|
||
|
||
要修改Smali代码中的常量值,您需要找到将常量值加载到堆栈上的指令,并将其替换为新值。
|
||
|
||
For example, if you want to change the constant value `123` to `456`, you would locate the instruction `const/16 v0, 123` and replace `123` with `456`.
|
||
|
||
例如,如果您想将常量值`123`更改为`456`,您需要找到指令`const/16 v0, 123`并将`123`替换为`456`。
|
||
|
||
#### Modifying Method Calls
|
||
|
||
#### 修改方法调用
|
||
|
||
To modify a method call in Smali code, you need to locate the instruction that invokes the method and replace it with a new method call.
|
||
|
||
要修改Smali代码中的方法调用,您需要找到调用方法的指令,并将其替换为新的方法调用。
|
||
|
||
For example, if you want to change the method call `invoke-virtual {v0, v1}, Lcom/example/Class;->method()V` to `invoke-static {v0, v1}, Lcom/example/Class;->method()V`, you would locate the instruction `invoke-virtual {v0, v1}, Lcom/example/Class;->method()V` and replace `invoke-virtual` with `invoke-static`.
|
||
|
||
例如,如果您想将方法调用`invoke-virtual {v0, v1}, Lcom/example/Class;->method()V`更改为`invoke-static {v0, v1}, Lcom/example/Class;->method()V`,您需要找到指令`invoke-virtual {v0, v1}, Lcom/example/Class;->method()V`并将`invoke-virtual`替换为`invoke-static`。
|
||
|
||
#### Modifying Field Access
|
||
|
||
#### 修改字段访问
|
||
|
||
To modify a field access in Smali code, you need to locate the instruction that accesses the field and replace it with a new field access.
|
||
|
||
要修改Smali代码中的字段访问,您需要找到访问字段的指令,并将其替换为新的字段访问。
|
||
|
||
For example, if you want to change the field access `iget-object v0, v1, Lcom/example/Class;->field:Landroid/widget/TextView;` to `sget-object v0, Lcom/example/Class;->field:Landroid/widget/TextView;`, you would locate the instruction `iget-object v0, v1, Lcom/example/Class;->field:Landroid/widget/TextView;` and replace `iget-object` with `sget-object`.
|
||
|
||
例如,如果您想将字段访问`iget-object v0, v1, Lcom/example/Class;->field:Landroid/widget/TextView;`更改为`sget-object v0, Lcom/example/Class;->field:Landroid/widget/TextView;`,您需要找到指令`iget-object v0, v1, Lcom/example/Class;->field:Landroid/widget/TextView;`并将`iget-object`替换为`sget-object`。
|
||
|
||
#### Modifying Control Flow
|
||
|
||
#### 修改控制流
|
||
|
||
To modify the control flow in Smali code, you need to locate the instructions that define the control flow and modify them accordingly.
|
||
|
||
要修改Smali代码中的控制流,您需要找到定义控制流的指令并相应地进行修改。
|
||
|
||
For example, if you want to change the condition for a branch instruction, you would locate the instruction `if-eqz v0, :label` and modify the condition `if-eqz` to `if-nez`.
|
||
|
||
例如,如果您想更改分支指令的条件,您需要找到指令`if-eqz v0, :label`并将条件`if-eqz`修改为`if-nez`。
|
||
|
||
#### Modifying Exception Handling
|
||
|
||
#### 修改异常处理
|
||
|
||
To modify exception handling in Smali code, you need to locate the instructions that define the exception handling and modify them accordingly.
|
||
|
||
要修改Smali代码中的异常处理,您需要找到定义异常处理的指令并相应地进行修改。
|
||
|
||
For example, if you want to change the catch type for an exception handler, you would locate the instruction `.catch Ljava/lang/Exception;` and modify `Ljava/lang/Exception;` to the desired catch type.
|
||
|
||
例如,如果您想更改异常处理程序的catch类型,您需要找到指令`.catch Ljava/lang/Exception;`并将`Ljava/lang/Exception;`修改为所需的catch类型。
|
||
|
||
#### Modifying Local Variables
|
||
|
||
#### 修改局部变量
|
||
|
||
To modify local variables in Smali code, you need to locate the instructions that define the local variables and modify them accordingly.
|
||
|
||
要修改Smali代码中的局部变量,您需要找到定义局部变量的指令并相应地进行修改。
|
||
|
||
For example, if you want to change the value of a local variable `v0` to `123`, you would locate the instruction `const/16 v0, 0` and replace `0` with `123`.
|
||
|
||
例如,如果您想将局部变量`v0`的值更改为`123`,您需要找到指令`const/16 v0, 0`并将`0`替换为`123`。
|
||
|
||
#### Modifying Method Parameters
|
||
|
||
#### 修改方法参数
|
||
|
||
To modify method parameters in Smali code, you need to locate the instructions that define the method parameters and modify them accordingly.
|
||
|
||
要修改Smali代码中的方法参数,您需要找到定义方法参数的指令并相应地进行修改。
|
||
|
||
For example, if you want to change the value of a method parameter `p0` to `456`, you would locate the instruction `const/16 p0, 0` and replace `0` with `456`.
|
||
|
||
例如,如果您想将方法参数`p0`的值更改为`456`,您需要找到指令`const/16 p0, 0`并将`0`替换为`456`。
|
||
```
|
||
#Math
|
||
add-int/lit8 v0, v2, 0x1 #v2 + 0x1 and save it in v0
|
||
mul-int v0,v2,0x2 #v2*0x2 and save in v0
|
||
|
||
#Move the value of one object into another
|
||
move v1,v2
|
||
|
||
#Condtions
|
||
if-ge #Greater or equals
|
||
if-le #Less or equals
|
||
if-eq #Equals
|
||
|
||
#Get/Save attributes of an object
|
||
iget v0, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I #Save this.o inside v0
|
||
iput v0, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I #Save v0 inside this.o
|
||
|
||
#goto
|
||
:goto_6 #Declare this where you want to start a loop
|
||
if-ne v0, v9, :goto_6 #If not equals, go to: :goto_6
|
||
goto :goto_6 #Always go to: :goto_6
|
||
```
|
||
### 较大的更改
|
||
|
||
### 日志记录
|
||
```
|
||
#Log win: <number>
|
||
iget v5, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I #Get this.o inside v5
|
||
invoke-static {v5}, Ljava/lang/String;->valueOf(I)Ljava/lang/String; #Transform number to String
|
||
move-result-object v1 #Move to v1
|
||
const-string v5, "wins" #Save "win" inside v5
|
||
invoke-static {v5, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I #Logging "Wins: <num>"
|
||
```
|
||
推荐:
|
||
|
||
* 如果你要在函数内使用已声明的变量(声明为v0、v1、v2...),请将这些行放在_.local \<number>_和变量声明(_const v0, 0x1_)之间。
|
||
* 如果你想在函数的代码中间插入日志代码:
|
||
* 将已声明变量的数量增加2:例如,从_.locals 10_变为_.locals 12_。
|
||
* 新的变量应该是已声明变量的下一个数字(在这个例子中应该是_v10_和_v11_,记住它从v0开始)。
|
||
* 更改日志函数的代码,并使用_v10_和_v11_代替_v5_和_v1_。
|
||
|
||
### Toasting
|
||
|
||
记得在函数开头的_.locals_数量上加3。
|
||
|
||
这段代码准备好了可以插入到**函数的中间**(根据需要**更改**变量的**数量**)。它将获取**this.o**的**值**,将其转换为**字符串**,然后用其值**制作**一个**toast**。
|
||
```
|
||
const/4 v10, 0x1
|
||
const/4 v11, 0x1
|
||
const/4 v12, 0x1
|
||
iget v10, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I
|
||
invoke-static {v10}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;
|
||
move-result-object v11
|
||
invoke-static {p0, v11, v12}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
|
||
move-result-object v12
|
||
invoke-virtual {v12}, Landroid/widget/Toast;->show()V
|
||
```
|
||
<details>
|
||
|
||
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks云 ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 推特 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
||
|
||
* 你在一家**网络安全公司**工作吗?想要在HackTricks中看到你的**公司广告**吗?或者你想要**获取PEASS的最新版本或下载HackTricks的PDF**吗?请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
|
||
* 发现我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)收藏品——[**The PEASS Family**](https://opensea.io/collection/the-peass-family)
|
||
* 获取[**官方PEASS和HackTricks周边产品**](https://peass.creator-spring.com)
|
||
* **加入**[**💬**](https://emojipedia.org/speech-balloon/) [**Discord群组**](https://discord.gg/hRep4RUj7f) 或者 [**Telegram群组**](https://t.me/peass),或者**关注**我在**Twitter**上的[**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
|
||
* **通过向**[**hacktricks repo**](https://github.com/carlospolop/hacktricks) **和**[**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud) **提交PR来分享你的黑客技巧。**
|
||
|
||
</details>
|