这是我在矿大CTF逆向区做的最后一题,因为其中的内容对我而言具有学习意义,所以单独拿出来写篇博文。其他矿大CTF逆向题解请详见矿大RE(完结撒花)

1592053619784

java

c.c.a中找到tu.class:

1592053539056

红框处是反调试的代码,如果修改了apk重新打包,再次运行会终止进程。

进入sd.dfh中看一下:

1592053729337

进入jh.gfds:

1592053815578

最内侧的df.gr是一个很长的二进制字符串,外侧的函数都是解密操作。

由于变量名被混淆了,解密代码很难读懂,而且flag在程序运行中明文出现过,所以可以考虑插桩,当将二进制字符串解密出flag时,可以使用log输出flag。

删掉反调试代码

我们来到smali层:

打开tu.smali,删掉下面的代码:

    .line 35
    invoke-virtual {p0}, Lc/c/a/tu;->getApplicationInfo()Landroid/content/pm/ApplicationInfo;

    move-result-object v1

    iget v2, v1, Landroid/content/pm/ApplicationInfo;->flags:I

    .line 36
    and-int/lit8 v2, v2, 0x2

    .line 35
    iput v2, v1, Landroid/content/pm/ApplicationInfo;->flags:I

    if-eqz v2, :cond_0

    .line 37
    invoke-static {}, Landroid/os/Process;->myPid()I

    move-result v1

    invoke-static {v1}, Landroid/os/Process;->killProcess(I)V

    .line 39
    :cond_0
    invoke-static {}, Landroid/os/Debug;->isDebuggerConnected()Z

    move-result v1

    if-eqz v1, :cond_1

    .line 40
    invoke-static {}, Landroid/os/Process;->myPid()I

    move-result v1

    invoke-static {v1}, Landroid/os/Process;->killProcess(I)V

    .line 42
    :cond_1
    invoke-virtual {p0}, Lc/c/a/tu;->isRunningInEmualtor()Z

    move-result v1

    if-eqz v1, :cond_2

    .line 43
    invoke-static {}, Landroid/os/Process;->myPid()I

    move-result v1

    invoke-static {v1}, Landroid/os/Process;->killProcess(I)V

    .line 45
    :cond_2
    const-string v1, "com.example.secret"

    invoke-virtual {p0, v1}, Lc/c/a/tu;->getSignature(Ljava/lang/String;)I

    move-result v0

    .line 49
    .local v0, "sig":I
    invoke-direct {p0}, Lc/c/a/tu;->checkCRC()Z

    move-result v1

    if-eqz v1, :cond_3

    .line 50
    invoke-static {}, Landroid/os/Process;->myPid()I

    move-result v1

    invoke-static {v1}, Landroid/os/Process;->killProcess(I)V

1592054095920

log插桩

来到sd.smali:

1592054494071

把上图的第27行删掉,不要销毁flag。并在此处添加

const-string v1, "iyzyi-flag"

invoke-static {v1, v0}, Landroid/util/Log;->v(Ljava/lang/String;Ljava/lang/String;)I

同时将第18行的.locals 1改为.locals 2,以增加一个临时变量。

1592059539665

编译成新的apk后,再次反编译,可以看到java代码变成了这样:

tu.class:

1592059721721

sd.class:

1592059681816

adb查看log

夜神模拟器

安装apk后,在夜神模拟器的安装目录下打开powershell,输入:

连接设备:

./adb.exe devices

输出log:

./adb.exe logcat -s iyzyi-flag:v

iyzyi-flag是log的标签。

1592060153384

base64解码后即得flag.

手机

以Honor v10为例。

多次点击版本号,进入开发者模式:

TIM图片20200613230529

进入开发人员选项,启用USB调试“仅充电”模式下允许ADB调试

tm

通过USB线和电脑连接,允许USB调试:

sdfsd

然后手机安装刚刚插桩的apk。

从网上下载adb,并在其目录下打开powershell,剩下的adb操作和夜神模拟器的操作是一样的:

1592061105576

./adb.exe logcat -c的作用是清空log缓存区。

总结

本题从难度上来说,难度不高,但是我觉得插桩这个知识点足够它作为一篇独立的博文单列出来。

Last modification:June 14th, 2020 at 12:20 am