Android APP破解利器Frida之反调试对抗

本文详细介绍了如何使用Frida工具来应对Android应用的反调试技术,包括OWASP Level2的CrackMe APK破解过程,通过Frida注入Zygote、打补丁和Hook函数等方法,最终成功绕过反调试保护并获取解密字符串。
摘要由CSDN通过智能技术生成
本文讲的是 Android APP破解利器Frida之反调试对抗在我发表了关于Frida的第二个博文后不久, @muellerberndt 决定发布另外一个新的OWASP Android  破解 APP,我很想知道我是否可以再次使用Frida解决这个CrackMe。如果你想跟随我一起操作,你需要做以下准备:

· OWASP Level2的CrackMe APK

· Android SDK和模拟器(我使用的是Android 7.1 x64映像)

· Frida安装(以及frida-server二进制文件

· ByteCode viewer

· radare2(或你喜欢使用的其他一些反汇编程序)

· apktool

如果你需要知道如何安装Frida,请查看Frida的相关 文档。对于Frida的使用,你还可以查看本教程系列的第I部分。我想你在继续本文的操作之前已经拥有所有需要的东西,并且基本上熟悉了Frida的使用。另外,确保Frida可以连接到你的设备或模拟器(例如使用frida -ps -U 命令)。

警告:本教程不仅仅是一个快速破解Crackme的练习。相反,我将向你展示各种方法来克服所遇到的具体问题。如果你只是寻找一个快速的破解方案,请在本教程末尾查看相关的Frida脚本。

注意:如果你遇到了下面这个错误:

Error: access violation accessing 0xebad8082

或者使用Frida时会出现了类似的错误,再模拟器中擦除用户数据,重新启动并重新安装该apk可能有助于解决此类错误问题。

做好多次尝试的准备。该应用程序可能会崩溃,模拟器也可能会重新启动,一切也可能会搞砸,但是,它依旧可以正常工作。

先把APP跑起来

在开始时,我们做的事情和之前破解UnCrackable1是一样的,先运行应用程序:接下来,当你在模拟器中运行它时,它会检测到它是在有root权限的设备上运行的。

Android APP破解利器Frida之反调试对抗

我们可能会尝试像之前破解UnCrackable 1一样Hook OnClickListener。但首先我们来看看我们是否可以连接到Frida来进行篡改:

michael@sixtyseven:~/Development$ frida -U sg.vantagepoint.uncrackable2
     ____
    / _  |   Frida 9.1.27 - A world-class dynamic instrumentation framework
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at http://www.frida.re/docs/home/
Failed to attach: ambiguous name; it matches: sg.vantagepoint.uncrackable2 (pid: 5184), sg.vantagepoint.uncrackable2 (pid: 5201)

这是什么东西?有两个名称相同的进程?我们可以使用frida -ps -U命令来验证一下:

5184  sg.vantagepoint.uncrackable2
5201  sg.vantagepoint.uncrackable2

奇怪。我们试着将Frida注入到父进程:

michael@sixtyseven:~/Development$ frida -U 5184
     ____
    / _  |   Frida 9.1.27 - A world-class dynamic instrumentation framework
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at http://www.frida.re/docs/home/
Failed to attach: unable to access process with pid 5184 due to system restrictions; try `sudo sysctl kernel.yama.ptrace_scope=0`, or run Frida as root

看起来它并不起作用,因为当我们使用root权限运行Frida时,我们得到了相同的结果,所以提出的解决方案并没有什么帮助。这里到底发生了什么?我们来看看应用程序吧。解压缩apk并使用ByteCodeViewer 查看classes.dex并进行反编译(例如CFR-Decompiler):

package sg.vantagepoint.uncrackable2;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.c;
import android.text.Editable;
import android.view.View;
import android.widget.EditText;
import sg.vantagepoint.a.a;
import sg.vantagepoint.a.b;
import sg.vantagepoint.uncrackable2.CodeCheck;
import sg.vantagepoint.uncrackable2.MainActivity;
public class MainActivity
extends c {
    private CodeCheck m;
    static {
        System.loadLibrary("foo"); //[1]
    }
    private void a(String string) {
        AlertDialog alertDialog = new AlertDialog.Builder((Context)this).create();
        alertDialog.setTitle((CharSequence)string);
        alertDialog.setMessage((CharSequence)"This in unacceptable. The app is now going to exit.");
        alertDialog.setButton(-3, (CharSequence)"OK", (DialogInterface.OnClickListener)new /* Unavailable Anonymous Inner Class!! */);
        alertDialog.setCancelable(false);
        alertDialog.show();
    }
    static /* synthetic */ void a(MainActivity mainActivity, String string) {
        mainActivity.a(string);
    }
    private native void init(); //[2]
    protected void onCreate(Bundle bundle) {
        this.init(); //[3]
        if (b.a() || b.b() || b.c()) {
            this.a("Root detected!");
        }
        if (a.a((Context)this.getApplicationContext())) {
            this.a("App is debuggable!");
        }
        new /* Unavailable Anonymous Inner Class!! */.execute((Object[])new Void[]{null, null, null});
        this.m = new CodeCheck();
        super.onCreate(bundle);
        this.setContentView(2130968603);
    }
    public void verify(View view) {
        String string = ((EditText)this.findViewById(2131427422)).getText().toString();
        AlertDialog alertDialog = new AlertDialog.Builder((Context)this).create();
        if (this.m.a(string)) {
            alertDialog.setTitle((CharSequence)"Success!");
            alertDialog.setMessage((CharSequence)"This is the correct secret.");
        } else {
            alertDialog.setTitle((CharSequence)"Nope...");
            alertDialog.setMessage((CharSequence)"That's not it. Try again.");
        }
        alertDialog.setButton(-3, (CharSequence)"OK", (DialogInterface.OnClickListener)new /* Unavailable Anonymous Inner Class!! */);
        alertDialog.show();
    }
}

我们注意到一个调用static的静态调用System.load加载了foo库(参见[1])。该应用程序还在其onCreate方法的第一行调用了this.init()(参见[3]),该方法被声明为一种native方法(参见[2]),因此它可能是foo的一部分。

现在让我们来看看foo库。在radare2中,打开这个库文件(你可以在lib文件夹中找到各种架构的多个库文件,我在这里使用的是lib/x86_64),分析并列出其导出函数:

michael@sixtyseven:~/Development/UnCrackable2/lib/x86_64$ r2 libfoo.so
 -- Don't look at the code. Don't look.
[0x000007a0]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze len bytes of instructions for references (aar)
[x] Analyze fu
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值