目前看到制作共存大多是修改包名然后替换所有包名相关的字符串,这种方式很容易出问题,比如说有些遗漏的字符串没有替换,.so中调用了相关的包名(动态绑定情况,静态可以修改IAT替换,但是很容易出错)。所以一种比较好的方法制作共存是,修改包名且修改程序入口(不修改原来的包名),在新的入口处extends
原来的入口,或是startActivity
。其实这篇教程主要目的还是java生成smali的尝试,以制作共存为例,抛砖引玉,这种Java上生成smali字节码的方法可以推广到mod制作。
当然除了apktool其他知识为了用java编写,习惯后直接编写smali也是可以的。
先用apktool反编译源程序
(apktool出错的注意检查java环境,必须是64位,oracle的javapath可能默认是32位)
java -jar apktool_2.4.0.jar d "%~1" -o "%~dpn1
AndroidManifest.xml
开头处package=""
即为包名,下例为修改后的包名
<?xml version="1.0" encoding="utf-8" standalone="no"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="auto" package="cn.natdon.onscripterv2yuri">
<intent-filter>
中"android.intent.action.MAIN"
极为程序入口, 修改后入口class为cn.natdon.onscripterv2yuri.start2
注意修改包名后所有的activity
缺省包名都要修改。
<activity android:label="@string/app_name" android:launchMode="singleInstance" android:name=".start2" android:screenOrientation="landscape"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity>
通常情况下可以用Android Studio中的java2smali插件,但是我不想安装这么臃肿的软件。介绍一种比较轻便的生成smali方法,结合vscode自动补全功能非常好用。此方法非常小巧,所用工具不到50mb。
原理很简单,javac将.java编译为编译.class,之后用dx.jar将.class整合为classes.dex文件,再用baksmali.jar反编译.dex文件得到需要的smali。这个步骤需要android.jar
库函数还有原来程序的classes.dex
转为classes.jar
(为了extends继承), 极为javac -cp中的依赖项。
写成的批处理脚本为:
make_smali.bat
@echo off set jarlib=android_api21.jar;classes.jar set dx=dx_r29.0.2.jar set baksmali=baksmali-2.3.4.jar for /f %%i in ('dir /s /b "%~f1"') do ( ::echo %%i if %%~xi EQU .java ( echo processing %%~fi javac -cp %jarlib% "%%~fi") ) java -jar %dx% --dex --output="%~dp1classes.dex" "%~f1" java -jar %baksmali% d "%~dp1classes.dex" pause
先放一张vscode的效果图吧:
在vscode中 ctrl+shift+p Java: Create Java Project
创建java环境,配置.classpath
的dependencis(要Java: Refresh
才能更新),之后即可类似于Android Studio的自动补全了。配置Build Task
可以实现自动化。
.classpath
<?xml version="1.0" encoding="UTF-8"?> <classpath> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="src" path="src"/> <classpathentry kind="output" path="bin"/> <classpathentry kind="lib" path="MiNE3.v1.5_classes.jar"/> <classpathentry kind="lib" path="D:\\AppExtend\\ReverseToolAndroid\\scripts\\android_api21.jar"/> </classpath>
tasks.json
{ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "2.0.0", "tasks": [ { "label": "MakeSmali", "type": "shell", "command": ".\\make_smali.cmd src", "group": { "kind": "build", "isDefault": true } } ] }
start.java
package cn.natdon.onscripterv2yuri; import android.os.Bundle; public class start extends cn.natdon.onscripterv2.start { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } }
start.smali
.class public Lcn/natdon/onscripterv2yuri/start; .super Lcn/natdon/onscripterv2/start; .source "start.java" # direct methods .method public constructor <init>()V .registers 1 .prologue .line 4 invoke-direct {p0}, Lcn/natdon/onscripterv2/start;-><init>()V return-void .end method # virtual methods .method public onCreate(Landroid/os/Bundle;)V .registers 2 .prologue .line 6 invoke-super {p0, p1}, Lcn/natdon/onscripterv2/start;->onCreate(Landroid/os/Bundle;)V .line 7 return-void .end method
start2.java
package cn.natdon.onscripterv2yuri; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import cn.natdon.onscripterv2.start; public class start2 extends Activity{ public void onCreate(Bundle savedInstanceState){ Intent intent = new Intent(this, start.class); startActivity(intent); } }
start2.smali
.class public Lcn/natdon/onscripterv2yuri/start2; .super Landroid/app/Activity; .source "start2.java" # direct methods .method public constructor <init>()V .registers 1 .prologue .line 7 invoke-direct {p0}, Landroid/app/Activity;-><init>()V return-void .end method # virtual methods .method public onCreate(Landroid/os/Bundle;)V .registers 4 .prologue .line 9 new-instance v0, Landroid/content/Intent; const-class v1, Lcn/natdon/onscripterv2/start; invoke-direct {v0, p0, v1}, Landroid/content/Intent;-><init>(Landroid/content/Context;Ljava/lang/Class;)V .line 10 invoke-virtual {p0, v0}, Lcn/natdon/onscripterv2yuri/start2;->startActivity(Landroid/content/Intent;)V .line 11 return-void .end method
keytool -genkey -alias abc.keystore -keyalg RSA -validity 20000 -keystore abc.keystore java -jar apktool_2.4.0.jar b "%~1" -o "%~1_rebuild.apk" jarsigner -verbose -keystore abc.keystore -signedjar "%~1_rebuild_signed.apk" "%~1_rebuild.apk" -storepass "password" abc.keystore
编译好的apk即可安装,只要原app没有校验基本上重编译的都能运行。
最后于 3小时前 被devseed编辑 ,原因: 添加内容