mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
165 lines
7.5 KiB
Markdown
165 lines
7.5 KiB
Markdown
# Smali - Decompiling/\[Modifying]/Compiling
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|
|
|
|
때때로 숨겨진 정보를 접근하기 위해 애플리케이션 코드를 수정하는 것이 흥미로울 수 있습니다(아마도 잘 난독화된 비밀번호나 플래그). 그러므로 apk를 디컴파일하고 코드를 수정한 후 다시 컴파일하는 것이 흥미로울 수 있습니다.
|
|
|
|
**Opcodes reference:** [http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html](http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html)
|
|
|
|
## Fast Way
|
|
|
|
**Visual Studio Code**와 [APKLab](https://github.com/APKLab/APKLab) 확장을 사용하면 **자동으로 디컴파일**, 수정, **재컴파일**, 서명 및 애플리케이션을 설치할 수 있습니다. 어떤 명령도 실행할 필요가 없습니다.
|
|
|
|
또한 이 작업을 많이 용이하게 하는 **스크립트**는 [**https://github.com/ax/apk.sh**](https://github.com/ax/apk.sh)입니다.
|
|
|
|
## Decompile the APK
|
|
|
|
APKTool을 사용하면 **smali 코드와 리소스**에 접근할 수 있습니다:
|
|
```bash
|
|
apktool d APP.apk
|
|
```
|
|
If **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
|
|
```
|
|
새 APK는 _**dist**_ 폴더 **내부**에서 **컴파일**됩니다.
|
|
|
|
만약 **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) 파일에 중요한 최적화를 제공하는 아카이브 정렬 도구입니다. [More information here](https://developer.android.com/studio/command-line/zipalign).
|
|
```bash
|
|
zipalign [-f] [-v] <alignment> infile.apk outfile.apk
|
|
zipalign -v 4 infile.apk
|
|
```
|
|
### **새 APK 서명하기 (다시?)**
|
|
|
|
만약 **apksigner**를 사용하고 싶다면, **zipalign으로 최적화를 적용한 후 apk를 서명해야 합니다**. 하지만 **jarsigner로 애플리케이션을 한 번만 서명해야 한다는 점에 유의하세요** (zipalign 이전) 또는 **aspsigner로 서명해야 합니다** (zipalign 이후).
|
|
```bash
|
|
apksigner sign --ks key.jks ./dist/mycompiled.apk
|
|
```
|
|
## Smali 수정
|
|
|
|
다음 Hello World Java 코드:
|
|
```java
|
|
public static void printHelloWorld() {
|
|
System.out.println("Hello World")
|
|
}
|
|
```
|
|
스말리 코드는 다음과 같습니다:
|
|
```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
|
|
```
|
|
Smali 명령어 집합은 [여기](https://source.android.com/devices/tech/dalvik/dalvik-bytecode#instructions)에서 확인할 수 있습니다.
|
|
|
|
### 경량 변경
|
|
|
|
### 함수 내 변수의 초기 값 수정
|
|
|
|
일부 변수는 _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>"
|
|
```
|
|
추천 사항:
|
|
|
|
- 함수 내에서 선언된 변수를 사용할 경우 (선언된 v0, v1, v2...) 이 줄들을 _.local \<number>_와 변수 선언(_const v0, 0x1_) 사이에 넣으세요.
|
|
- 함수 코드 중간에 로깅 코드를 넣고 싶다면:
|
|
- 선언된 변수의 수에 2를 추가하세요: 예: _.locals 10_에서 _.locals 12_로.
|
|
- 새로운 변수는 이미 선언된 변수의 다음 숫자가 되어야 합니다 (이 예에서는 _v10_과 _v11_이어야 하며, v0에서 시작한다는 것을 기억하세요).
|
|
- 로깅 함수의 코드를 변경하고 _v5_와 _v1_ 대신 _v10_과 _v11_을 사용하세요.
|
|
|
|
### 토스트
|
|
|
|
함수 시작 부분에서 _.locals_의 수에 3을 추가하는 것을 잊지 마세요.
|
|
|
|
이 코드는 **함수의 중간에** 삽입되도록 준비되었습니다 (**변수**의 **숫자**는 필요에 따라 **변경**하세요). 이 코드는 **this.o**의 **값**을 **가져와서**, **String**으로 **변환**한 다음 **그 값으로** **토스트**를 **만들** 것입니다.
|
|
```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
|
|
```
|
|
{{#include ../../banners/hacktricks-training.md}}
|