编译
打包流程
细化打包流程
打包用到的工具
目录
D:\sdk\build-tools\30.0.2
反编译
反编译流程中,用到了大名鼎鼎的反编译三剑客,apktool、dex2jar、jd-gui。
apktool:对Apk进行解包,主要用来解析程序代码、res资源和AndroidManifest.xml;
dex2jar:主要是将 dex 文件转换为包含 class 文件的 jar 文件;
jd-gui:将dex2jar解析出来的jar包反编译为java源码;
apksigner:签名工具。
zipalign:对齐工具。
apktool
apktool安装
下载apktool.bat以及apktool.jar文件,放到C://Windows中。安装步骤见,配置好环境之后,可以直接使用apktool的命令。
反编译
$ apktool d foo.jar
// decodes foo.jar to foo.jar.out folder
$ apktool decode foo.jar
// decodes foo.jar to foo.jar.out folder
$ apktool d bar.apk
// decodes bar.apk to bar folder
$ apktool decode bar.apk
// decodes bar.apk to bar folder
$ apktool d bar.apk -o baz
// decodes bar.apk to baz folder
d、decode表示反编译指令
-o 表示目标文件夹指令
添加环境之后,通过下面的指令就可以将apk包反编译
D:\work\tkbackground\jjchannelpackage\ToolConfigPath\tools\sign> apktool d .\appoppo-release.apk
反编译后的文件夹如下图所示:
如果想要反编译a.apk到b文件夹,可以这样写
apktool d a.apk -o b
.\apktool.bat d .\100055-bilibili-202212161214.apk
注意,如果没有添加apktool到环境变量的话,需要切换到apktool文件夹才能调用apktool工具,-o b会在apktool文件夹下创建一个b的目录,里面存放反编译之后的文件。
回编译
$ apktool b foo.jar.out
// builds foo.jar.out folder into foo.jar.out/dist/foo.jar file
$ apktool build foo.jar.out
// builds foo.jar.out folder into foo.jar.out/dist/foo.jar file
$ apktool b bar
// builds bar folder into bar/dist/bar.apk file
$ apktool b .
// builds current directory into ./dist
$ apktool b bar -o new_bar.apk
// builds bar folder into new_bar.apk
$ apktool b bar.apk
// WRONG: brut.androlib.AndrolibException: brut.directory.PathNotExist: apktool.yml
// Must use folder, not apk/jar file
回编译指令如下:
D:\work\tkbackground\jjchannelpackage\ToolConfigPath\tools\sign> apktool b .\appoppo-release\
Frameworks
FrameWork可以通过if或者install-framework安装,
-p, --frame-path <dir> - Store framework files into <dir>
-t, --tag <tag> - Tag frameworks using <tag>
$ apktool if framework-res.apk
I: Framework installed to: 1.apk
// pkgId of framework-res.apk determines number (which is 0x01)
$ apktool if com.htc.resources.apk
I: Framework installed to: 2.apk
// pkgId of com.htc.resources is 0x02
$ apktool if com.htc.resources.apk -t htc
I: Framework installed to: 2-htc.apk
// pkgId-tag.apk
$ apktool if framework-res.apk -p foo/bar
I: Framework installed to: foo/bar/1.apk
$ apktool if framework-res.apk -t baz -p foo/bar
I: Framework installed to: foo/bar/1-baz.apk
Smali Debugging
dex2jar
d2j-dex2jar .\classes.dex
使用此指令后,将classes.dex转化为了classes-dex2jar.jar
JD-GUI
资源下载
下载地址。
签名工具
keytool
功能:JDK自带的证书生成管理工具
C:\Users\liyd>where keytool
D:\software\jdk\bin\keytool.exe
D:\software\jdk\jre\bin\keytool.exe
keytool生成签名可以使用以下命令:
keytool -genkeypair -alias test -keyalg RSA -validity 36500 -keystore test.jks
-alias对应别名,后面的test是签名的别名。
-keyalg后面对应签名的算法,RSA算法。
-validity是有效期,单位天。
-keystore后面是签名的地址,默认是当前文件夹。
生成的签名文件如下图所示:
jarsigner
功能:JDK提供的针对jar包签名的通用工具
PS C:\Users\liyd\Desktop\kuaishou> jarsigner -verbose -keystore .\test.jks -signedjar .\signed.apk .\2-kuaishou-202212211505.apk test
输入密钥库的密码短语:
正在添加: META-INF/MANIFEST.MF
正在添加: META-INF/TEST.SF
正在添加: META-INF/TEST.RSA
jarsigner -verbose -keystore .\test.jks -signedjar
后面需要分别输入签名后的apk、待签名apk、签名文件的别名。
签名可以见这篇文章:
给应用重新签名,重新签名包
Smali
基本语法
跳转语句
Android逆向反编译代码注入
思路
注入步骤
- 将目标apk反编译出smali1文件。
- 将目标apk解压后,将dex文件转化为jar包。
- 通过jd打开jar文件,查看目标App业务逻辑,找到对应注入的地方。
- 开发jar包库文件。
- 将jar包文件转化为smali2文件。
- 将smali1文件与smali2文件合成smali3文件。
- 在smali1文件中调用smali2相关代码,完成注入。
- 回编译
- 重签名
- 安装测试
其中,第1步的详细步骤如下: apk -> smali1
第5步的详细步骤如下: jar -> dex -> smali2
PS C:\Users\liyd\Desktop\kuaishou> d2j-jar2dex .\classes.jar
jar2dex .\classes.jar -> classes-jar2dex.dex
call com.android.dx.command.Main.main[--dex, --no-strict, --output=C:\Users\liyd\Desktop\kuaishou\classes-jar2dex.dex, C:\Users\liyd\Desktop\kuaishou\.\classes.jar]
PS C:\Users\liyd\Desktop\kuaishou> d2j-baksmali .\classes-jar2dex.dex
baksmali .\classes-jar2dex.dex -> classes-jar2dex-out
第6步的详细步骤如下: smali1 + smali2 = smali3
零碎知识
反编译后的资源目录
android反编译后的资源包括如下:
lib ------------------ 包括so库的lib
original ----------------
res -----------------------
smali --------------------
unknown ------------------
AndroidManifest ----------------
apktool.yaml ------------------ 逆向后apktool的配置文件。
逆向后的修改
apk反编译后,可以通过修改apktool.yaml文件修改一些属性,可以修改的属性如下,修改这些属性之后,再回编APK的时候,就可以将修改的信息带过去了。
!!brut.androlib.meta.MetaInfo
apkFileName: app-release.apk
compressionType: false
doNotCompress:
- resources.arsc
- META-INF/androidx.activity_activity.version
- META-INF/androidx.annotation_annotation-experimental.version
- META-INF/androidx.appcompat_appcompat-resources.version
- META-INF/androidx.appcompat_appcompat.version
- META-INF/androidx.arch.core_core-runtime.version
- META-INF/androidx.cardview_cardview.version
- META-INF/androidx.coordinatorlayout_coordinatorlayout.version
- META-INF/androidx.core_core-ktx.version
- META-INF/androidx.core_core.version
- META-INF/androidx.cursoradapter_cursoradapter.version
- META-INF/androidx.customview_customview.version
- META-INF/androidx.documentfile_documentfile.version
- META-INF/androidx.drawerlayout_drawerlayout.version
- META-INF/androidx.dynamicanimation_dynamicanimation.version
- META-INF/androidx.emoji2_emoji2-views-helper.version
- META-INF/androidx.emoji2_emoji2.version
- META-INF/androidx.fragment_fragment.version
- META-INF/androidx.interpolator_interpolator.version
- META-INF/androidx.legacy_legacy-support-core-utils.version
- META-INF/androidx.lifecycle_lifecycle-livedata-core.version
- META-INF/androidx.lifecycle_lifecycle-livedata.version
- META-INF/androidx.lifecycle_lifecycle-process.version
- META-INF/androidx.lifecycle_lifecycle-runtime.version
- META-INF/androidx.lifecycle_lifecycle-viewmodel-savedstate.version
- META-INF/androidx.lifecycle_lifecycle-viewmodel.version
- META-INF/androidx.loader_loader.version
- META-INF/androidx.localbroadcastmanager_localbroadcastmanager.version
- META-INF/androidx.print_print.version
- META-INF/androidx.recyclerview_recyclerview.version
- META-INF/androidx.savedstate_savedstate.version
- META-INF/androidx.startup_startup-runtime.version
- META-INF/androidx.tracing_tracing.version
- META-INF/androidx.transition_transition.version
- META-INF/androidx.vectordrawable_vectordrawable-animated.version
- META-INF/androidx.vectordrawable_vectordrawable.version
- META-INF/androidx.versionedparcelable_versionedparcelable.version
- META-INF/androidx.viewpager2_viewpager2.version
- META-INF/androidx.viewpager_viewpager.version
- META-INF/com.google.android.material_material.version
- META-INF/kotlinx_coroutines_android.version
- META-INF/kotlinx_coroutines_core.version
- assets/dexopt/baseline.prof
- png
isFrameworkApk: false
packageInfo:
forcedPackageId: '127'
renameManifestPackage: null
sdkInfo:
minSdkVersion: '21'
targetSdkVersion: '32'
sharedLibrary: false
sparseResources: false
unknownFiles:
DebugProbesKt.bin: '8'
usesFramework:
ids:
- 1
tag: null
version: 2.5.0
versionInfo:
versionCode: '1'
versionName: '1.0'
比如我们应用如果依赖其他的SDK,其他SDK对编译的版本有要求的话,我们就可以修改sdkInfo中的sdk版本号。
sdkInfo:
minSdkVersion: '21'
targetSdkVersion: '32'
android apk 目录结构
见文章。
META-INF 文件夹
MANIFEST.MF:保存了整个APK文件中所有文件的文件名 + SHA-1后的 base64 编码值。意味着,MANIFEST.MF象征着 apk 包的完整性。
CERT.RSA:这个文件保存了公钥和加密方式的信息。
CERT.SF:这个文件与 MANIFEST.MF 的结构一样,只是其编码会被被私钥加密。这样一来每次安装时,通过该文件夹中的文件,就可以完成验证的过程。如果 apk 包被改变了,而篡改者没有私钥生成 CERT.SF,则无法完成校验。
参考文献
回编译相关问题
apktool 反编译时仅导入jar包,不导入res等其他资源,回编译时会报错吗
如果在使用apktool进行反编译时仅导入jar包而不导入res等其他资源,可能会导致回编译时出现错误。这是因为在反编译过程中,apktool会解析和提取apk文件中的多个部分,包括dex文件、资源文件、AndroidManifest.xml等。如果只导入jar包而不导入其他资源,可能会导致回编译时缺少必要的资源文件,从而导致错误。
关于使用baksmali.jar进行dex文件的反汇编,你提供的命令是正确的。它将会使用baksmali工具将指定的dex文件进行反汇编,并将结果输出到当前目录下的bilibili1.dex文件夹中。
总之,如果你只导入jar包而不导入其他资源进行反编译,可能会导致回编译时出现错误。建议在进行反编译时同时导入所有必要的资源文件,以确保回编译的成功。