手把手教你逆向高德车机7.5.0制作共存版

前言

很多车机上自带的高德都比较老,而且不允许更新和卸载。
这就需要一个制作另一个高德

在安卓上,所有app并不是根据名字来区分唯一性的,而是包名package
也就是说我们把app安装包(apk)里的package设置成一个新的即可达到成功安装与官方版并存。

那怎么改apk呢?
这就用到了反编译也叫做逆向工程技术。
正好借此契机,大家跟着我学习一下安卓的反逆向工程技术,以后自己给软件换个图标、改个名称、破解个vip起步手到擒来。

前提工作

电脑下载并安装好一下几个软件

apktool

apktool用于对apk进行反编译及重新打包的工具
官方地址:https://apktool.org

这里建议配置成环境变量,方便后边使用(方然你觉得麻烦 不配置也行 非必须)
打开终端,输入apktool -version出现版本号,既为成功

C:\Users\Administrator> apktool -version
2.9.3
Press any key to continue . . .

dex-tools

apktool反编译后,安卓的所有代码逻辑文件都在编译文件夹里的classes.dex中。
此文件原本为java或kotlin所编写,后被打包加密而成,很难直接读取里边的代码逻辑。
dex-tools工具则用于将此dex文件转换为可读的jar(java)格式。
官方地址:https://github.com/pxb1988/dex2jar

这里建议配置成环境变量,方便后边使用(方然你觉得麻烦 不配置也行 非必须)
打开终端,输入d2j-dex2jar出现以下,既为成功

C:\Users\Administrator> d2j-dex2jar
d2j-dex2jar -- convert dex to jar
usage: d2j-dex2jar [options] <file0> [file1 ... fileN]
options:
 --skip-exceptions            skip-exceptions
 -d,--debug-info              translate debug info
 -e,--exception-file <file>   detail exception file, default is $current_dir/[fi
                              le-name]-error.zip
 -f,--force                   force overwrite
 -h,--help                    Print this help message
 -n,--not-handle-exception    not handle any exceptions thrown by dex2jar
 -nc,--no-code
 -o,--output <out-jar-file>   output .jar file, default is $current_dir/[file-na
                              me]-dex2jar.jar
 -os,--optmize-synchronized   optimize-synchronized
 -p,--print-ir                print ir to System.out
 -r,--reuse-reg               reuse register while generate java .class file
 -s                           same with --topological-sort/-ts
 -ts,--topological-sort       sort block by topological, that will generate more
                               readable code, default enabled
version: reader-v2.4, translator-v2.4, ir-v2.4

jd-gui

用于读取dex-tools生成jar文件的工具。
以便于分析安卓的代码逻辑。

官方地址:https://github.com/java-decompiler/jd-gui
如果是widnows,下载对应版本即可

开始反编译

去官网下载车机版本的高德,为方便好记 我将其改名为 gaode.apk
对其执行反编译的命令 apktool d .\gaode.apk

D:\app> apktool d .\gaode.apk
I: Using Apktool 2.9.3 on gaode.apk
I: Loading resource table...
I: Decoding file-resources...
I: Loading resource table from file: C:\Users\Administrator\AppData\Local\apktool\framework\1.apk
S: Could not decode file, replacing by FALSE value: anim/abc_slide_in_top.xml
S: Could not decode file, replacing by FALSE value: anim/activity_enter.xml
S: Could not decode file, replacing by FALSE value: anim/abc_slide_out_bottom.xml
S: Could not decode file, replacing by FALSE value: anim/abc_slide_out_top.xml
S: Could not decode file, replacing by FALSE value: anim/activity_exit.xml
S: Could not decode file, replacing by FALSE value: anim/abc_slide_in_bottom.xml
S: Could not decode file, replacing by FALSE value: anim/abc_fade_in.xml
S: Could not decode file, replacing by FALSE value: anim/abc_fade_out.xml
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...
Press any key to continue . . .

如果你要是不修改反编译的代码 只是替换下图标静态资源啥的,可以apktool -r d .\gaode.apk进行反编译,这样就不会报错了,但是反编译的代码内容是无法修改的

失败
看到一堆Could not decode file的报错提示了吗?
原因是因为反编译的时候去提取它(反编译工具apktool)认为一些必要资源的时候 没找到而报错 既资源文件误报错。

这会导致我们在回编打包的时候报错,不信你试试,在不做任何修改情况下尝试一下在打包回去 apktool b .\gaode\

D:\app> apktool b .\gaode\
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...
W: D:\app\.\gaode\res\values\anims.xml:3: error: invalid value for type 'anim'. Expected a reference.
W: D:\app\.\gaode\res\values\anims.xml:4: error: invalid value for type 'anim'. Expected a reference.
W: D:\app\.\gaode\res\values\anims.xml:5: error: invalid value for type 'anim'. Expected a reference.
W: D:\app\.\gaode\res\values\anims.xml:6: error: invalid value for type 'anim'. Expected a reference.
W: D:\app\.\gaode\res\values\anims.xml:7: error: invalid value for type 'anim'. Expected a reference.
W: D:\app\.\gaode\res\values\anims.xml:8: error: invalid value for type 'anim'. Expected a reference.
W: D:\app\.\gaode\res\values\anims.xml:9: error: invalid value for type 'anim'. Expected a reference.
W: D:\app\.\gaode\res\values\anims.xml:10: error: invalid value for type 'anim'. Expected a reference.
W: D:\app\.\gaode\res\values\anims.xml: error: file failed to compile.
brut.androlib.exceptions.AndrolibException: brut.common.BrutException: could not exec (exit code = 1): [C:\Users\ADMINI~1\AppData\Local\Temp\brut_util_Jar_12222067369825036268574268945791329902.tmp, compile, --dir, D:\app\.\gaode\res, --legacy, -o, D:\app\.\gaode\build\resources.zip]
Press any key to continue . . .

看提示大概也能明白 在anims.xml引用的这些资源不存在,刚好对应到反编译时候提示的问题。
那我们将报错的地方注释即可(因为这些资源在项目中真的没有用到,否则可不能随意注释)。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- <item type="anim" name="abc_fade_in">false</item>
    <item type="anim" name="abc_fade_out">false</item>
    <item type="anim" name="abc_slide_in_bottom">false</item>
    <item type="anim" name="abc_slide_in_top">false</item>
    <item type="anim" name="abc_slide_out_bottom">false</item>
    <item type="anim" name="abc_slide_out_top">false</item>
    <item type="anim" name="activity_enter">false</item>
    <item type="anim" name="activity_exit">false</item> -->
</resources>

失败
再次打包,依然报错

D:\app> apktool b .\gaode\
I: Using Apktool 2.9.3
I: Checking whether sources has changed...
I: Checking whether resources has changed...
I: Building resources...
W: D:\app\.\gaode\res\values\public.xml:3: error: no definition for declared symbol 'com.autonavi.amapauto:anim/abc_fade_in'.
W: D:\app\.\gaode\res\values\public.xml:4: error: no definition for declared symbol 'com.autonavi.amapauto:anim/abc_fade_out'.
W: D:\app\.\gaode\res\values\public.xml:9: error: no definition for declared symbol 'com.autonavi.amapauto:anim/abc_slide_in_bottom'.
W: D:\app\.\gaode\res\values\public.xml:10: error: no definition for declared symbol 'com.autonavi.amapauto:anim/abc_slide_in_top'.
W: D:\app\.\gaode\res\values\public.xml:11: error: no definition for declared symbol 'com.autonavi.amapauto:anim/abc_slide_out_bottom'.
W: D:\app\.\gaode\res\values\public.xml:12: error: no definition for declared symbol 'com.autonavi.amapauto:anim/abc_slide_out_top'.
W: D:\app\.\gaode\res\values\public.xml:15: error: no definition for declared symbol 'com.autonavi.amapauto:anim/activity_enter'.
W: D:\app\.\gaode\res\values\public.xml:16: error: no definition for declared symbol 'com.autonavi.amapauto:anim/activity_exit'.
W: error: failed linking references.
brut.androlib.exceptions.AndrolibException: brut.common.BrutException: could not exec (exit code = 1): [C:\Users\ADMINI~1\AppData\Local\Temp\brut_util_Jar_73040750885300977133450964023895867926.tmp, link, -o, C:\Users\ADMINI~1\AppData\Local\Temp\APKTOOL12512811945052100666.tmp, --package-id, 127, --min-sdk-version, 15, --target-sdk-version, 23, --version-code, 21000001, --version-name, 7.5.0.600064, --no-auto-version, --no-version-vectors, --no-version-transitions, --no-resource-deduping, --allow-reserved-package-id, --no-compile-sdk-metadata, --warn-manifest-validation, -e, C:\Users\ADMINI~1\AppData\Local\Temp\APKTOOL12300926364868950439.tmp, -0, arsc, -I, C:\Users\Administrator\AppData\Local\apktool\framework\1.apk, --manifest, D:\app\.\gaode\AndroidManifest.xml, D:\app\.\gaode\build\resources.zip]
Press any key to continue . . .

说明这些不存在的文件, 不但anims.xml用了,public.xml也用了。
那就好办了,同上,我们将其对应使用的到的地方注释即可

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- <public type="anim" name="abc_fade_in" id="0x7f010000" />
    <public type="anim" name="abc_fade_out" id="0x7f010001" /> -->
    <public type="anim" name="abc_grow_fade_in_from_bottom" id="0x7f010002" />
    <public type="anim" name="abc_popup_enter" id="0x7f010003" />
    <public type="anim" name="abc_popup_exit" id="0x7f010004" />
    <public type="anim" name="abc_shrink_fade_out_from_bottom" id="0x7f010005" />
    <!-- <public type="anim" name="abc_slide_in_bottom" id="0x7f010006" />
    <public type="anim" name="abc_slide_in_top" id="0x7f010007" />
    <public type="anim" name="abc_slide_out_bottom" id="0x7f010008" />
    <public type="anim" name="abc_slide_out_top" id="0x7f010009" /> -->
    <public type="anim" name="abc_tooltip_enter" id="0x7f01000a" />
    <public type="anim" name="abc_tooltip_exit" id="0x7f01000b" />
    <!-- <public type="anim" name="activity_enter" id="0x7f01000c" />
    <public type="anim" name="activity_exit" id="0x7f01000d" /> -->
    <public type="anim" name="btn_checkbox_to_checked_box_inner_merged_animation" id="0x7f01000e" />
    <public type="anim" name="btn_checkbox_to_checked_box_outer_merged_animation" id="0x7f01000f" />
...

成功
再次尝试打包,即可看到成功了

D:\app> apktool b .\gaode\
I: Using Apktool 2.9.3
I: Checking whether sources has changed...
I: Checking whether resources has changed...
I: Building resources...
I: Copying libs... (/lib)
I: Copying libs... (/kotlin)
I: Building apk file...
I: Copying unknown files/dir...
I: Built apk into: .\gaode\dist\gaode.apk
Press any key to continue . . .

修改应用逻辑代码

如上,将打包好的apk签名(在网上找找教程 简单)后安装到手机,会发现无法使用app

这个是高德地图启动的时候做了签名相关的校验,我们修改了包名及签名,所以无法通过校验。
我们来定位和分析下 这个猥琐的检验检查在代码哪儿!

通过解读AndroidManifest.xml,在其中搜索 android.intent.category.LAUNCHER,其所在 Activity 就是启动界面。

...
<activity android:configChanges="fontScale|keyboard|keyboardHidden|layoutDirection|locale|mcc|mnc|orientation|screenLayout|screenSize|smallestScreenSize|uiMode" android:exported="true" android:icon="@drawable/v3_icon" android:launchMode="singleTask" android:name="com.autonavi.auto.remote.fill.UsbFillActivity" android:relinquishTaskIdentity="false" android:screenOrientation="user">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
        <category android:name="android.intent.category.APP_MAPS"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>
...

通过此代码我们可以得知,这个启动页面对应的包逻辑代码文件为 com.autonavi.auto.remote.fill.UsbFillActivity
然后我们就可以按照这个包路径,通过以下步骤查看启动也里边的逻辑

1、将安装包 gaode.apk作为压缩包解压,后拿到里边的classes.dex
2、使用dex-toolsclasses.dex转换为能看懂的jar文件: d2j-dex2jar .\classes.dex
3、打开jd-gui,将转换的jar文件拖入其中查看并分析代码

结合错误错误提示文字搜索,很快就能定位到 校验逻辑处

找到方法 g() 的调用地点,可以看到当l90.d(ee.A().f())false会弹出异常提示,并阻止进入程序。

好了,截止目前,我们已经知道了 只要让l90的d方法返回true即可。
我们找到进入编译后的文件 gaode\smali\l90.smali,编辑此文件的d方法,将返回值改为true

smali 语法和 Java 还是有很大差别的,但是我们不需要精通,对应这个校验方法看上去很复杂,但是我们的需求只不过是让这个方法返回 true 即可,因此修改如下:

...
.method public static d(Landroid/content/Context;)Z
    .locals 1

    .line 1
    const/4 p0, 0x1

    return p0
.end method

最后的检验,我们再次打包并签名,就可以看到可以成功的安装并使用了

修改包名

要想制作共存,必须使得包名和原版不同。
打开安卓的项目配置文件 AndroidManifest.xml
搜索 package="com.autonavi.amapauto" 讲起替换为你想要的包名即可 比如package="com.baidu"

修改应用名称

默认的应用名称为高德地图, 那么我们在反编译的项目中全局搜索这几个字,最终定位到是在res\values-zh\strings.xml
找到<string name="app_name">高德地图</string> 讲起改为你想要的名字 比如 <string name="app_name">高德车机</string>

修改应用图标

使用图标生成网站,生成应用图标(安卓app图标自己做的话麻烦 需要适配不同分辨率,此网站可以帮你做),复制到res目录中。

打开安卓的项目配置文件 AndroidManifest.xml
搜索 android:icon=@drawable/v3_icon全部替换为android:icon="@mipmap/ic_launcher"

其它

什么都不改的情况下,反编译再打包就会资源错误的问题,是apktool高版本的问题,我随便选了一个低点的版本就可以了

D:\app> apktool d .\gaode.apk
I: Using Apktool 2.6.0 on gaode.apk
I: Loading resource table...
I: Decoding AndroidManifest.xml with resources...
I: Loading resource table from file: C:\Users\Administrator\AppData\Local\apktool\framework\1.apk
I: Regular manifest package...
I: Decoding file-resources...
S: Could not decode file, replacing by FALSE value: anim/activity_exit.xml
S: Could not decode file, replacing by FALSE value: anim/abc_slide_in_top.xml
S: Could not decode file, replacing by FALSE value: anim/abc_slide_in_bottom.xml
S: Could not decode file, replacing by FALSE value: anim/abc_slide_out_top.xml
S: Could not decode file, replacing by FALSE value: anim/abc_fade_out.xml
S: Could not decode file, replacing by FALSE value: anim/abc_fade_in.xml
S: Could not decode file, replacing by FALSE value: anim/activity_enter.xml
S: Could not decode file, replacing by FALSE value: anim/abc_slide_out_bottom.xml
I: Decoding values */* XMLs...
I: Baksmaling classes.dex...
I: Copying assets and libs...
I: Copying unknown files...
I: Copying original files...
Press any key to continue . . .

D:\app> apktool b .\gaode\
I: Using Apktool 2.6.0
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... (/lib)
I: Copying libs... (/kotlin)
I: Building apk file...
I: Copying unknown files/dir...
I: Built apk...
Press any key to continue . . .

后来经过验证只要不超过2.8.1以上就可以, 最后一个能用就是2.8.1!
不过如果你若将apktool降级到低版本,那很多新apk或许解包签名就可能存在问题了,比如via在apltool2.8下解包后在打包签名就会安装失败。
所以结合情况,根据需要考虑

手机上使用mt管理器 或np管理器或Apktool M修改包名更简单,也没发现问题,可能是内置的apktool低版本原因吧。
电脑端也有很多好用的软件,比如我才知道的 安卓修改大师
不过这些底层都是基于apktool
感兴趣的可以试试

更多请加群

posted @ 2024-06-17 15:09  丁少华  阅读(1370)  评论(0编辑  收藏  举报