当我们辛辛苦苦写的代码被别人抄走的时候一定会让我们非常的抓狂。要学会防守,我们也需要知道别人进攻的方式,接下来我们学习下如何破解Apk。Apktool是家喻户晓的逆向工具,我们学习下如何使用它。
http://ibotpeaches.github.io/Apktool/install/http://ibotpeaches.github.io/Apktool/install/
这个是官方的教程链接。目前最新版本是2.1.1,不断地更新到最新的版本是很有用的,旧版本的一些bug,在新版本很多都得到了解决。
选择自己的操作系统对应的教程,我们这里选择的是Mac,步骤已经非常的详细了,我这里就不再赘述了。
安装成功后,我们写一个Demo测试一下效果。
建一个工程随便写点什么,在Android Studio工程的app/build/outputs/apk目录下找到apk然后运行命令,教程地址 http://ibotpeaches.github.io/Apktool/ 。
命令是apktool d 后面跟apk的名字,然后运行。
运行完在apk的文件目录下得到一个新的文件夹打开是这样的。
打开清单文件
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.caoxiao.forapktooldemo" platformBuildVersionCode="23" platformBuildVersionName="6.0-2704002">
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme">
<activity android:name="com.example.caoxiao.forapktooldemo.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
intent-filter>
activity>
application>
manifest>
xml文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_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">
<TextView
android:id="@id/helloTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<Button
android:id="@id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
RelativeLayout>
MainActivity.smali
.class public Lcom/example/caoxiao/forapktooldemo/MainActivity;
.super Landroid/support/v7/app/AppCompatActivity;
.source "MainActivity.java"
# instance fields
.field private btn:Landroid/widget/Button;
.field private helloTV:Landroid/widget/TextView;
# direct methods
.method public constructor ()V
.locals 0
.prologue
.line 10
invoke-direct {p0}, Landroid/support/v7/app/AppCompatActivity;->()V
return-void
.end method
.method static synthetic access$000(Lcom/example/caoxiao/forapktooldemo/MainActivity;)Landroid/widget/TextView;
.locals 1
.param p0, "x0" # Lcom/example/caoxiao/forapktooldemo/MainActivity;
.prologue
.line 10
iget-object v0, p0, Lcom/example/caoxiao/forapktooldemo/MainActivity;->helloTV:Landroid/widget/TextView;
return-object v0
.end method
# virtual methods
.method protected onCreate(Landroid/os/Bundle;)V
.locals 2
.param p1, "savedInstanceState" # Landroid/os/Bundle;
.prologue
.line 17
invoke-super {p0, p1}, Landroid/support/v7/app/AppCompatActivity;->onCreate(Landroid/os/Bundle;)V
.line 18
const v0, 0x7f040019
invoke-virtual {p0, v0}, Lcom/example/caoxiao/forapktooldemo/MainActivity;->setContentView(I)V
.line 20
const v0, 0x7f0c0050
invoke-virtual {p0, v0}, Lcom/example/caoxiao/forapktooldemo/MainActivity;->findViewById(I)Landroid/view/View;
move-result-object v0
check-cast v0, Landroid/widget/TextView;
iput-object v0, p0, Lcom/example/caoxiao/forapktooldemo/MainActivity;->helloTV:Landroid/widget/TextView;
.line 21
const v0, 0x7f0c0051
invoke-virtual {p0, v0}, Lcom/example/caoxiao/forapktooldemo/MainActivity;->findViewById(I)Landroid/view/View;
move-result-object v0
check-cast v0, Landroid/widget/Button;
iput-object v0, p0, Lcom/example/caoxiao/forapktooldemo/MainActivity;->btn:Landroid/widget/Button;
.line 22
iget-object v0, p0, Lcom/example/caoxiao/forapktooldemo/MainActivity;->btn:Landroid/widget/Button;
new-instance v1, Lcom/example/caoxiao/forapktooldemo/MainActivity$1;
invoke-direct {v1, p0}, Lcom/example/caoxiao/forapktooldemo/MainActivity$1;->(Lcom/example/caoxiao/forapktooldemo/MainActivity;)V
invoke-virtual {v0, v1}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V
.line 29
return-void
.end method
这个是Dalvik汇编语言,咋一看肯定是不知所云,我们跟源代码对比下。
package com.example.caoxiao.forapktooldemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private TextView helloTV;
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
helloTV = (TextView) findViewById(R.id.helloTV);
btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
helloTV.setText("ApkTool");
Toast.makeText(MainActivity.this, getResources().getString(R.string.app_name), Toast.LENGTH_SHORT).show();
}
});
}
}
能看到线索了吧。我们甚至可以直接修改MainActivity.smali的代码,然后运行apktool b命令重新打包,这个暂时脱离了逆向工程的主题后续有空再分析。关于Apktool的使用先将到这,后续还会有 dex2jar和jd-gui的使用教程,这两个工具主要可以帮助我们分析代码,也是逆向工程的神器。