引言
这是一个入门级示例,原因是之前写了一个安卓小工具有个小bug,但是源码丢失,想要反编译再编译。
工具准备:
- android studio
- jadx
- 记事本
- apktool
- android sdk
其中工具apksigner.bat位于android-sdk中,如果没有配置环境变量,可以使用绝对路径,如D:\Android\android-sdk\build-tools\35.0.0\apksigner.bat sign --ks key.jks --out signed_app.apk app_cm2.apk
准备签名文件
准备一个jks签名文件,这里为了方便,使用android studio来生成。



在上图中配置好保存即可,要记住密码哦,后面会用到。
示例
public class MainActivity extends AppCompatActivity {
private static String text = "Hello world";
private static int code = 63;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
// toast
Toast.makeText(this.getApplicationContext(), text, Toast.LENGTH_SHORT).show();
// 按钮事件绑定
findViewById(R.id.button).setOnClickListener((v -> {
TextView textView = findViewById(R.id.textView);
if (code==63) {
Toast.makeText(MainActivity.super.getApplicationContext(), "你需要修改启动吐司Hello ZunMX, 但是校验时不校验", Toast.LENGTH_LONG).show();
textView.setText("你需要修改启动吐司Hello ZunMX, 但是校验时不校验");
} else {
Toast.makeText(MainActivity.super.getApplicationContext(), "老铁666", Toast.LENGTH_LONG).show();
textView.setText("老铁666");
}
}));
}
}
目标1:修改text为"Hello ZunMX"
目标2:if (code==63) 改成 if (code!=63) 或者把63改成其它的


反编译
定位代码
把apk拉到jadx-gui中,找到关键区域代码

反编译代码
找到apk路径:执行 apktool d app-release.apk
E:\Code\Andorid\cm2\app\release
{17:31:53.52} apktool d app-release.apk
I: Using Apktool 2.9.3 on app-release.apk
I: Loading resource table...
I: Decoding file-resources...
I: Loading resource table from file: C:\Users\36083\AppData\Local\apktool\framework\1.apk
I: Decoding values */* XMLs...
I: Decoding AndroidManifest.xml with resources...
I: Regular manifest package...
I: Baksmaling classes.dex...
I: Copying assets and libs...
I: Copying unknown files...
I: Copying original files...
I: Copying META-INF/services directory
查看smali代码
.class public Ltop/zunmx/cm2/MainActivity;
.super Landroidx/appcompat/app/AppCompatActivity;
.source "MainActivity.java"
# static fields
.field private static code:I = 0x3f
.field private static text:Ljava/lang/String; = "Hello world"
# direct methods
.method static constructor <clinit>()V
.locals 0
return-void
.end method
.method public constructor <init>()V
.locals 0
.line 15
invoke-direct {p0}, Landroidx/appcompat/app/AppCompatActivity;-><init>()V
return-void
.end method
.method static synthetic access$001(Ltop/zunmx/cm2/MainActivity;)Landroid/content/Context;
.locals 0
.line 15
invoke-super {p0}, Landroidx/appcompat/app/AppCompatActivity;->getApplicationContext()Landroid/content/Context;
move-result-object p0
return-object p0
.end method
.method static synthetic access$101(Ltop/zunmx/cm2/MainActivity;)Landroid/content/Context;
.locals 0
.line 15
invoke-super {p0}, Landroidx/appcompat/app/AppCompatActivity;->getApplicationContext()Landroid/content/Context;
move-result-object p0
return-object p0
.end method
.method static synthetic lambda$onCreate$0(Landroid/view/View;Landroidx/core/view/WindowInsetsCompat;)Landroidx/core/view/WindowInsetsCompat;
.locals 4
.line 25
invoke-static {}, Landroidx/core/view/WindowInsetsCompat$Type;->systemBars()I
move-result v0
invoke-virtual {p1, v0}, Landroidx/core/view/WindowInsetsCompat;->getInsets(I)Landroidx/core/graphics/Insets;
move-result-object v0
.line 26
iget v1, v0, Landroidx/core/graphics/Insets;->left:I
iget v2, v0, Landroidx/core/graphics/Insets;->top:I
iget v3, v0, Landroidx/core/graphics/Insets;->right:I
iget v0, v0, Landroidx/core/graphics/Insets;->bottom:I
invoke-virtual {p0, v1, v2, v3, v0}, Landroid/view/View;->setPadding(IIII)V
return-object p1
.end method
# virtual methods
.method synthetic lambda$onCreate$1$top-zunmx-cm2-MainActivity(Landroid/view/View;)V
.locals 3
.line 33
sget p1, Ltop/zunmx/cm2/R$id;->textView:I
invoke-virtual {p0, p1}, Ltop/zunmx/cm2/MainActivity;->findViewById(I)Landroid/view/View;
move-result-object p1
check-cast p1, Landroid/widget/TextView;
.line 34
sget v0, Ltop/zunmx/cm2/MainActivity;->code:I
const/16 v1, 0x3f
const/4 v2, 0x1
if-ne v0, v1, :cond_0
.line 35
invoke-static {p0}, Ltop/zunmx/cm2/MainActivity;->access$001(Ltop/zunmx/cm2/MainActivity;)Landroid/content/Context;
move-result-object v0
const-string v1, "\u4f60\u9700\u8981\u4fee\u6539\u542f\u52a8\u5410\u53f8Hello ZunMX, \u4f46\u662f\u6821\u9a8c\u65f6\u4e0d\u6821\u9a8c"
invoke-static {v0, v1, v2}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v0
invoke-virtual {v0}, Landroid/widget/Toast;->show()V
.line 36
invoke-virtual {p1, v1}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
goto :goto_0
.line 38
:cond_0
invoke-static {p0}, Ltop/zunmx/cm2/MainActivity;->access$101(Ltop/zunmx/cm2/MainActivity;)Landroid/content/Context;
move-result-object v0
const-string v1, "\u8001\u94c1666"
invoke-static {v0, v1, v2}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v0
invoke-virtual {v0}, Landroid/widget/Toast;->show()V
.line 39
invoke-virtual {p1, v1}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
:goto_0
return-void
.end method
.method protected onCreate(Landroid/os/Bundle;)V
.locals 2
.line 21
invoke-super {p0, p1}, Landroidx/appcompat/app/AppCompatActivity;->onCreate(Landroid/os/Bundle;)V
.line 22
invoke-static {p0}, Landroidx/activity/EdgeToEdge;->enable(Landroidx/activity/ComponentActivity;)V
.line 23
sget p1, Ltop/zunmx/cm2/R$layout;->activity_main:I
invoke-virtual {p0, p1}, Ltop/zunmx/cm2/MainActivity;->setContentView(I)V
.line 24
sget p1, Ltop/zunmx/cm2/R$id;->main:I
invoke-virtual {p0, p1}, Ltop/zunmx/cm2/MainActivity;->findViewById(I)Landroid/view/View;
move-result-object p1
new-instance v0, Ltop/zunmx/cm2/MainActivity$$ExternalSyntheticLambda0;
invoke-direct {v0}, Ltop/zunmx/cm2/MainActivity$$ExternalSyntheticLambda0;-><init>()V
invoke-static {p1, v0}, Landroidx/core/view/ViewCompat;->setOnApplyWindowInsetsListener(Landroid/view/View;Landroidx/core/view/OnApplyWindowInsetsListener;)V
.line 30
invoke-virtual {p0}, Ltop/zunmx/cm2/MainActivity;->getApplicationContext()Landroid/content/Context;
move-result-object p1
sget-object v0, Ltop/zunmx/cm2/MainActivity;->text:Ljava/lang/String;
const/4 v1, 0x0
invoke-static {p1, v0, v1}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object p1
invoke-virtual {p1}, Landroid/widget/Toast;->show()V
.line 32
sget p1, Ltop/zunmx/cm2/R$id;->button:I
invoke-virtual {p0, p1}, Ltop/zunmx/cm2/MainActivity;->findViewById(I)Landroid/view/View;
move-result-object p1
new-instance v0, Ltop/zunmx/cm2/MainActivity$$ExternalSyntheticLambda1;
invoke-direct {v0, p0}, Ltop/zunmx/cm2/MainActivity$$ExternalSyntheticLambda1;-><init>(Ltop/zunmx/cm2/MainActivity;)V
invoke-virtual {p1, v0}, Landroid/view/View;->setOnClickListener(Landroid/view/View$OnClickListener;)V
return-void
.end method
修改位置

其中2选一

重打包
执行命令 apktool b app-release -o app_cm2.apk
I: Using Apktool 2.9.3
I: Checking whether sources has changed...
I: Smaling smali folder into classes.dex...
I: Checking whether resources has changed...
I: Building resources...
I: Copying libs... (/kotlin)
I: Copying libs... (/META-INF/services)
I: Building apk file...
I: Copying unknown files/dir...
I: Built apk into: app_cm2.apk
签名
执行命令 apksigner.bat sign --ks key.jks --out signed_app.apk app_cm2.apk 并且输入签名密码
Keystore password for signer #1:
将生成signed_app.apk文件,即为修改后的版本
测试


评论 0
还没有评论,来说点什么吧。