hacktricks/mobile-pentesting/android-app-pentesting/smali-changes.md

311 lines
14 KiB
Markdown
Raw Normal View History

2023-08-03 19:12:22 +00:00
# Smali - 反编译/【修改】/编译
2022-04-28 16:01:33 +00:00
<details>
2023-08-03 19:12:22 +00:00
<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>
2022-04-28 16:01:33 +00:00
* 你在一家**网络安全公司**工作吗?你想在 HackTricks 中看到你的**公司广告**吗?或者你想获得**PEASS 的最新版本或下载 HackTricks 的 PDF 版本**吗?请查看[**订阅计划**](https://github.com/sponsors/carlospolop)
2023-08-03 19:12:22 +00:00
* 发现我们的独家[**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 来分享你的黑客技巧。**
2022-04-28 16:01:33 +00:00
</details>
2023-08-03 19:12:22 +00:00
有时候,修改应用程序代码以访问隐藏信息可能是有趣的(也许是混淆良好的密码或标志)。然后,反编译 apk修改代码并重新编译它可能是有趣的。
2023-08-03 19:12:22 +00:00
**操作码参考:**[http://pallergabor.uw.hu/androidblog/dalvik\_opcodes.html](http://pallergabor.uw.hu/androidblog/dalvik\_opcodes.html)
2023-08-03 19:12:22 +00:00
## 快速方法
2020-12-15 10:14:26 +00:00
使用 **Visual Studio Code** 和 [APKLab](https://github.com/APKLab/APKLab) 扩展,您可以**自动反编译**、修改、**重新编译**、签名和安装应用程序,而无需执行任何命令。
2020-12-15 10:14:26 +00:00
另一个非常简化此任务的**脚本**是 [**https://github.com/ax/apk.sh**](https://github.com/ax/apk.sh)****
2022-12-27 16:55:40 +00:00
2023-08-03 19:12:22 +00:00
## 反编译 APK
2023-08-03 19:12:22 +00:00
使用 APKTool您可以访问**smali 代码和资源**
```
apktool d APP.apk
```
2023-08-03 19:12:22 +00:00
如果**apktool**出现任何错误,请尝试[安装**最新版本**](https://ibotpeaches.github.io/Apktool/install/)
一些你应该查看的**有趣文件**包括:
2023-08-03 19:12:22 +00:00
* _res/values/strings.xml_以及res/values/\*中的所有xml文件
* _AndroidManifest.xml_
2023-08-03 19:12:22 +00:00
* 任何具有_.sqlite_或_.db_扩展名的文件
2023-08-03 19:12:22 +00:00
如果`apktool`在解码应用程序时**出现问题**,请查看[https://ibotpeaches.github.io/Apktool/documentation/#framework-files](https://ibotpeaches.github.io/Apktool/documentation/#framework-files)或尝试使用参数**`-r`**(不解码资源)。然后,如果问题出现在资源而不是源代码中,您将不会遇到问题(您也不会反编译资源)。
2023-08-03 19:12:22 +00:00
## 更改smali代码
2023-08-03 19:12:22 +00:00
您可以**更改**指令,更改某些变量的**值**或**添加**新指令。我使用[**VS Code**](https://code.visualstudio.com)更改Smali代码然后安装**smalise扩展**,编辑器会告诉您是否有任何**不正确的指令**。\
这里有一些**示例**
2023-08-03 19:12:22 +00:00
* [Smali更改示例](smali-changes.md)
* [Google CTF 2018 - Shall We Play a Game?](google-ctf-2018-shall-we-play-a-game.md)
2023-08-03 19:12:22 +00:00
或者您可以[**在下面查看一些解释的Smali更改**](smali-changes.md#modifying-smali)。
2023-08-03 19:12:22 +00:00
## 重新编译APK
2023-08-03 19:12:22 +00:00
在修改代码后,您可以使用以下命令**重新编译**代码:
```bash
apktool b . #In the folder generated when you decompiled the application
```
它将在**dist**文件夹中**编译**新的APK。
2023-08-03 19:12:22 +00:00
如果**apktool**出现错误,请尝试[安装**最新版本**](https://ibotpeaches.github.io/Apktool/install/)
2023-08-03 19:12:22 +00:00
### **签署新的APK**
2023-08-03 19:12:22 +00:00
然后,您需要**生成一个密钥**(将要求您输入密码和一些可以随机填写的信息):
```bash
keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias <your-alias>
```
2023-08-03 19:12:22 +00:00
最后对新的APK进行**签名**
```bash
jarsigner -keystore key.jks path/to/dist/* <your-alias>
```
2023-08-03 19:12:22 +00:00
### 优化新应用程序
**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
```
2023-08-03 19:12:22 +00:00
### **签署新的APK再次**
2023-08-03 19:12:22 +00:00
如果您更喜欢使用\[**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
```
2023-08-03 19:12:22 +00:00
## 修改 Smali
2023-08-03 19:12:22 +00:00
对于以下的 Hello World Java 代码:
```
public static void printHelloWorld() {
2023-08-03 19:12:22 +00:00
System.out.println("Hello World")
}
```
以下是Smali代码示例
```smali
.method private static getDeviceId()Ljava/lang/String;
.registers 3
const-string v0, "android_id"
invoke-static {v0}, Landroid/os/SystemProperties;->get(Ljava/lang/String;)Ljava/lang/String;
move-result-object v0
return-object v0
.end method
```
这段Smali代码的作用是获取设备的唯一标识符。它使用`SystemProperties`类的`get`方法来获取Android设备的Android ID并将其作为字符串返回。
```
.method public static printHelloWorld()V
2023-08-03 19:12:22 +00:00
.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
```
2023-08-03 19:12:22 +00:00
Smali指令集可以在[这里](https://source.android.com/devices/tech/dalvik/dalvik-bytecode#instructions)找到。
2023-08-03 19:12:22 +00:00
### 轻微更改
2023-08-03 19:12:22 +00:00
### 修改函数内变量的初始值
2023-08-03 19:12:22 +00:00
一些变量在函数开始时使用_const_操作码定义您可以修改它们的值或者您可以定义新的变量
```
#Number
const v9, 0xf4240
const/4 v8, 0x1
#Strings
const-string v5, "wins"
```
2023-08-03 19:12:22 +00:00
### 基本操作
In this section, we will cover some basic operations that can be performed on Smali code.
在本节中我们将介绍一些可以在Smali代码上执行的基本操作。
#### Adding Log Statements
2023-08-03 19:12:22 +00:00
#### 添加日志语句
2023-08-03 19:12:22 +00:00
Adding log statements to the Smali code can be helpful for debugging and understanding the flow of the application. To add a log statement, we can use the `const-string` instruction to load the log message and the `invoke-static` instruction to call the `android.util.Log` class.
2023-08-03 19:12:22 +00:00
向Smali代码添加日志语句可以帮助调试和理解应用程序的流程。要添加日志语句我们可以使用`const-string`指令加载日志消息,并使用`invoke-static`指令调用`android.util.Log`类。
2023-08-03 19:12:22 +00:00
Here is an example of adding a log statement to a method:
2023-08-03 19:12:22 +00:00
以下是向方法添加日志语句的示例:
2023-08-03 19:12:22 +00:00
```smali
.method public doSomething()V
.locals 1
2023-08-03 19:12:22 +00:00
const-string v0, "Doing something..."
2023-08-03 19:12:22 +00:00
invoke-static {v0}, Landroid/util/Log;->d(Ljava/lang/String;)I
2023-08-03 19:12:22 +00:00
return-void
.end method
```
2023-08-03 19:12:22 +00:00
#### Modifying Method Return Values
2023-08-03 19:12:22 +00:00
#### 修改方法返回值
2023-08-03 19:12:22 +00:00
In some cases, we may want to modify the return value of a method. This can be useful for bypassing certain checks or altering the behavior of the application. To modify the return value, we can use the `move` instruction to move a value into the desired register.
在某些情况下,我们可能希望修改方法的返回值。这对于绕过某些检查或更改应用程序的行为非常有用。要修改返回值,我们可以使用`move`指令将一个值移动到所需的寄存器中。
Here is an example of modifying the return value of a method:
2023-08-03 19:12:22 +00:00
以下是修改方法返回值的示例:
2023-08-03 19:12:22 +00:00
```smali
.method public getSecretValue()Ljava/lang/String;
.locals 1
2023-08-03 19:12:22 +00:00
const-string v0, "Modified secret value"
2023-08-03 19:12:22 +00:00
move-object v0, v0
2023-08-03 19:12:22 +00:00
return-object v0
.end method
```
2023-08-03 19:12:22 +00:00
#### Modifying Method Parameters
2023-08-03 19:12:22 +00:00
#### 修改方法参数
2023-08-03 19:12:22 +00:00
Similarly, we can also modify the values of method parameters. This can be useful for manipulating the input to a method and testing different scenarios. To modify a method parameter, we can use the `move` instruction to move a value into the desired register.
2023-08-03 19:12:22 +00:00
类似地,我们还可以修改方法参数的值。这对于操作方法的输入并测试不同的场景非常有用。要修改方法参数,我们可以使用`move`指令将一个值移动到所需的寄存器中。
2023-08-03 19:12:22 +00:00
Here is an example of modifying a method parameter:
2023-08-03 19:12:22 +00:00
以下是修改方法参数的示例:
2023-08-03 19:12:22 +00:00
```smali
.method public doSomething(ILjava/lang/String;)V
.locals 0
2023-08-03 19:12:22 +00:00
const-string v0, "Modified parameter value"
2023-08-03 19:12:22 +00:00
move-object v1, v0
2023-08-03 19:12:22 +00:00
return-void
.end method
```
2023-08-03 19:12:22 +00:00
#### Modifying Field Values
2023-08-03 19:12:22 +00:00
#### 修改字段值
2023-08-03 19:12:22 +00:00
We can also modify the values of fields in a class. This can be useful for changing the behavior of the application by altering the values of certain variables. To modify a field value, we can use the `const` instruction to load a value and the `iput` instruction to store the value in the field.
2023-08-03 19:12:22 +00:00
我们还可以修改类中字段的值。通过改变某些变量的值,这对于改变应用程序的行为非常有用。要修改字段值,我们可以使用`const`指令加载一个值,并使用`iput`指令将该值存储在字段中。
2023-08-03 19:12:22 +00:00
Here is an example of modifying a field value:
2023-08-03 19:12:22 +00:00
以下是修改字段值的示例:
2023-08-03 19:12:22 +00:00
```smali
.field private static final SECRET_KEY:Ljava/lang/String; = "Original secret key"
2023-08-03 19:12:22 +00:00
.method public getSecretKey()Ljava/lang/String;
.locals 1
const-string v0, "Modified secret key"
iput-object v0, p0, Lcom/example/MyClass;->SECRET_KEY:Ljava/lang/String;
return-object v0
.end method
```
2023-08-03 19:12:22 +00:00
#### Conclusion
2023-08-03 19:12:22 +00:00
#### 结论
2023-08-03 19:12:22 +00:00
These are some of the basic operations that can be performed on Smali code. By understanding and utilizing these operations, we can effectively modify the behavior of an Android application during the pentesting process.
2023-08-03 19:12:22 +00:00
这些是可以在Smali代码上执行的一些基本操作。通过理解和利用这些操作我们可以在渗透测试过程中有效地修改Android应用程序的行为。
```
#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
```
2023-08-03 19:12:22 +00:00
### 较大的更改
2023-08-03 19:12:22 +00:00
### 日志记录
```
#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_。
2023-08-03 19:12:22 +00:00
* 新的变量应该是已声明变量的下一个数字在这个例子中应该是_v10_和_v11_记住它从v0开始
* 更改日志函数的代码并使用_v10_和_v11_代替_v5_和_v1_。
2022-05-08 23:13:03 +00:00
### Toasting
2023-08-03 19:12:22 +00:00
记得在函数开头的_.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
```
2022-04-28 16:01:33 +00:00
<details>
2023-08-03 19:12:22 +00:00
<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>
2022-04-28 16:01:33 +00:00
2023-08-03 19:12:22 +00:00
* 你在一家**网络安全公司**工作吗想要在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来分享你的黑客技巧。**
2022-04-28 16:01:33 +00:00
</details>