# Smali - Decompiling/\[Modifying]/Compiling

<details>

<summary><strong>从零开始学习AWS黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS Red Team Expert）</strong></a><strong>！</strong></summary>

其他支持HackTricks的方式：

* 如果您想看到您的**公司在HackTricks中被广告**或**下载PDF格式的HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family)，我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。

</details>

有时修改应用程序代码以访问隐藏信息（也许是混淆良好的密码或标志）是很有趣的。然后，将apk反编译，修改代码，然后重新编译可能是有趣的。

**操作码参考：** <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代码和资源**：

```bash
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>或尝试使用参数\*\*`-r`\*\*（不解码资源）。然后，如果问题出现在资源而不是源代码中，您将不会遇到问题（也不会反编译资源）。

## 更改smali代码

您可以更改**指令**，更改某些变量的**值**或**添加**新指令。我使用[**VS Code**](https://code.visualstudio.com)更改Smali代码，然后安装**smalise扩展程序**，编辑器将告诉您是否有任何**不正确的指令**。\
一些**示例**可以在这里找到：

* [Smali更改示例](/mobile-pentesting/android-app-pentesting/smali-changes.md)
* [Google CTF 2018 - 我们玩个游戏吧？](/mobile-pentesting/android-app-pentesting/google-ctf-2018-shall-we-play-a-game.md)

或者您可以[**查看下面一些解释的Smali更改**](#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/)而不是jarsigner，您应该在应用zipalign优化后对apk进行签名。但请注意，您只需要在zipalign之前使用jarsigner签名应用程序一次，或者在zipalign之后使用apksigner签名一次。

```bash
apksigner sign --ks key.jks ./dist/mycompiled.apk
```

## 修改 Smali

对于以下的 Hello World Java 代码：

```java
public static void printHelloWorld() {
System.out.println("Hello World")
}
```

Smali 代码将是：

```java
.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
```

### 轻微更改

### 修改函数内变量的初始值

一些变量在函数开始时使用操作码\_const\_定义，您可以修改其值，或者定义新变量：

```bash
#Number
const v9, 0xf4240
const/4 v8, 0x1
#Strings
const-string v5, "wins"
```

### 基本操作

```bash
#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
```

### 更大的变化

### 日志记录

```bash
#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>"
```

Recommendations:

* 如果您要在函数内部使用已声明的变量（声明为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**显示其值。

```bash
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><strong>从零开始学习AWS黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS Red Team Expert）</strong></a><strong>！</strong></summary>

其他支持HackTricks的方式：

* 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family)，我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hacktricks.xsx.tw/mobile-pentesting/android-app-pentesting/smali-changes.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
