您的位置  > 互联网

bat.dex.sh文件反编译的APK文件

在开始学习之前,我们首先需要准备一个APK文件。 为了尊重所有开发者,我不会使用市面上的任何软件来演示,而是自己写一个Demo进行测试。

这里我希望代码尽可能简单,所以我们新建一个项目,在里面添加一个按钮,点击按钮的时候会弹出一个Toast。 就是这么简单。 代码如下:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "you clicked button", Toast.LENGTH_SHORT).show();
            }
        });
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

.xml 中的资源如下所示:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin">
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"/>
RelativeLayout>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

然后我们将代码打包成APK包,命名为Demo.apk,安装到手机上。 结果如下:

好了,准备工作到这里就基本完成了,下面我们开始反编译这个Demo程序。反编译代码

要反编译APK文件中的代码,我们需要使用以下两个工具:

下载并解压这两个工具,然后我们开始反编译Demo程序。 解压压缩包后,你会发现里面有很多文件,如下图:

其中,我们需要用到d2j-.bat文件。 当然,如果您使用的是Linux或Mac系统,则必须使用d2j-.sh文件。

然后我们还将解压Demo.apk文件。 如果不知道如何直接解压,可以先将文件重命名为Demo.zip,然后用解压软件打开。 解压后,你会发现里面有一个.dex文件,如下图:

这个 .dex 文件是存储所有 java 代码的地方。 我们将其复制到解压后的目录中,在cmd中进入同一目录,然后执行:

d2j-dex2jar classes.dex
 
 
  • 1

执行结果如下图所示:

没有报错,说明我们已经成功转换了。 现在观察该目录,你会发现多了一个文件,如下图:

可以看到,-.jar文件就是我们借助工具成功转换的jar文件。 但对于我们来说,jar文件是不可读的,所以我们需要使用jd-gui工具将jar文件转换为java代码。

下面的内容非常简单。 使用jd-gui工具打开-.jar文件。 结果如下图:

OK,可以看到我们的代码反编译工作已经成功了,里面的代码非常清晰,90%以上的恢复工作已经基本完成了。 但如果想要实现100%的代码还原,还是非常困难的,因为()方法传入的参数实际上只是一个资源的id值,所以这里的反编译只能针对对应的id值进行。 恢复,但不能变成像R那样直观的代码显示..

另外,除此之外,还有很多其他的代码也被反编译了,因为当前项目中有引用-v4和-v7的包,而这些引用也会作为代码的一部分被打包到.dex文件中,所以这些代码将反编译时也一并恢复。

好了,现在我们已经学会了如何反编译代码,下面我们来看看如何反编译资源。反编译资源

其实细心的朋友可能已经注意到,刚才的Demo.apk解压目录下有资源文件,包括.xml文件和res目录。 进入res目录,内容如下图:

不是所有的资源文件都在这里吗? 其实这些资源文件在打包的时候就已经编译好了。 如果我们直接打开它们,我们看不到纯文本。 不信的话我们打开.xml文件来看一下。 内容如下图所示:

正如您所看到的,这段代码完全不可读。 当然,如果你打开.xml看一下,结果也好不到哪儿去:

可见,直接解压APK包并不能获取其原始资源文件,因此我们还需要对资源进行反编译。

如果要反编译APK文件中的资源,则需要使用另一个工具:

我想补充几句关于下载这个工具的信息。 我们需要的只是 .bat 和 .jar 文件。 目前,.jar的最新版本是2.0.3。 这里我下载最新的,然后将.0.3.jar重命名为.jar,并放在同一个文件夹下,如下图:

接下来的工作就非常简单了。 我们将Demo.apk复制到这两个文件同一个目录下,然后cmd也进入这个目录,在cmd中执行以下命令:

apktool d Demo.apk
 
 
  • 1

其中,d的意思,表示我们要解码Demo.apk这个文件。 除了这个基本用法之外,我们还可以添加一些额外的参数来控制更多的行为:

常见的用法有很多。 上述命令的执行结果如下图所示:

这说明资源反编译成功了。

当然,即使你和我进行一模一样的操作,这里仍然可能反编译失败。 例如会报如下错误:

出现这个错误的原因很可能是你之前使用的旧版本已经被反编译,然后会在你系统的C:\Users\\\目录下生成一个名为1.apk的缓存文件。 删除这个缓存文件,然后重新执行反编译命令应该可以成功。

现在你会发现当前目录下多了一个Demo文件夹,这个文件夹里存放的是反编译结果。 我们可以打开.xml来看一下,如下图:

这个怎么样? 这样就可以完全看懂了,然后就可以看res/下的.xml文件了,如下图:

可以看到.xml中的内容与源代码中的内容基本相同。 外层有一层,内层有一层。 您可以到其他目录查看其他资源。 基本上都可以正常恢复。 这样我们就掌握了反编译的方法了

那么对于反编译后的文件夹,我们是否可以将其重新打包成APK文件呢? 答案是肯定的,但我真的想不出我们这样做的任何正当理由。 有人会说中国化。 是的,汉化的方法确实是反编译一个APK,然后翻译里面的资源,然后重新打包。 不过这还是破解别人的程序,所以我不这么认为。 这是何等荣耀的事啊。 所以我们先不去讨论这件事本身的对错。 这里我们只是从技术角度学习一下重封装的相关知识。

首先我们看一下反编译后的包目录,如下图:

其中,该文件夹中存放的是未反编译的原始.xml文件,res文件夹中存放的是所有反编译后的资源,smali文件夹中存放的是所有反编译后的代码。 .xml 是反编译恢复后的文件。 这里值得一提的是smali文件夹。 如果你进入这个文件夹,你会发现它的目录结构和我们源码中src的目录结构几乎一样。 主要区别在于所有java文件都变成了smali文件。 smali文件实际上是真正的源代码,但其语法与Java完全不同。 它有点类似于汇编语法,是虚拟机使用的寄存器语言。 语法结构大致如下:

你看起来有点迷失方向,不是吗? 但如果你能读懂 smali 文件,那么你就可以做出可怕的事情——你可以随意修改应用程序中的逻辑并破解它!

不过我对这种黑科技并不是很感兴趣,所以没有做过具体的研究,但即便如此,我也已经可以在一定程度上修改程序的逻辑了。 例如,当我们点击一​​个按钮时,就会弹出一个像“你”这样的吐司。 逻辑写在按钮点击事件的匿名类中。 因此,这段代码反编译后,肯定会在$1.smali这个文件中。 我们打开来看一下。 你瞧,部分代码如下所示:

虽然大部分代码我都看不懂,但是第47行太明显了。 Toast显示的内容不是在这里定义的吗? 所以如果我们想破解Demo程序,我们可以把这个字符串改一下,比如我改成Your app is was。

关于smali的语法,网上有很多资料。 如果你对这项技术非常感兴趣,可以直接网上搜索。 我这里只是简单介绍一下,不会深入讲解相关知识。

更改一个代码后,让我们更改另一个资源。 比如我们要更换Demo应用程序图标,首先要准备一张新图片,如下图:

那么从.xml文件中可以看出,应用程序图标使用了.png图片,所以我们将上面的篮球图片命名为.png,然后将其复制到所有以res/开头的文件夹中,即可完成替换操作。

进行两处更改后,现在让我们将反编译的 Demo 文件夹重新打包成 APK。 其实很简单。 只需要在cmd中执行以下命令即可:

apktool b Demo -o New_Demo.apk
 
 
  • 1

其中,b表示build,表示我们要将Demo文件夹打包成APK文件。 -o 用于指定新生成的APK文件的名称。 这里的新文件名为 .apk。 执行结果如下图所示:

现在你会发现在同一目录中生成了一个新的APK文件:

但别高兴得太早。 目前,此 .apk 无法安装,因为它尚未签名。 那么如果这是别人的程序,我们从哪里可以得到它的原始签名文件呢? 显然是没有办法获取到的,所以我们只能使用自己的签名文件对APK文件进行重新签名,但这也说明我们重新打包的软件完全是盗版软件。 大家来这里学习技能是有好处的,希望大家不要做坏事。

所以这里我将使用之前生成的签名文件。 您可以使用 或 非常简单地生成签名文件。

获得签名文件后,可以在cmd中执行签名命令进行签名。 命令格式如下:

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore 签名文件名 -storepass 签名密码 待签名的APK文件名 签名的别名
 
 
  • 1

命令文件存放在jdk的bin目录下。 需要在系统的环境变量中配置 bin 目录,然后才能在任何地方执行此命令。

签名后的APK文件现在可以安装到手机上了,但是在此之前,强烈建议我们对签名后的APK文件进行对齐操作,因为这样可以让我们的程序在系统中运行得更快。 对齐操作需要用到一个工具,该工具存放在/build-tools/目录下。 您可以通过将此目录配置到系统环境变量中来在任何地方执行此命令。 命令格式如下:

zipalign 4 New_Demo.apk New_Demo_aligned.apk
 
 
  • 1

4是固定值,不能更改,后面指定要对齐的APK文件名以及对齐后的APK文件名。 运行该命令后,会生成一个.apk文件,如下图:

这个.apk就是我们重新打包签名并对齐后的文件。 现在将其安装到手机上。 效果如下图:

可以看到,应用图标已经成功变成了篮球,并且点击按钮后弹出的Toast提示也变成了我们修改后的文字,说明重新打包操作确实已经成功了。