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

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

红框处是反调试的代码,如果修改了apk重新打包,再次运行会终止进程。
进入sd.dfh中看一下:

进入jh.gfds:

最内侧的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
log插桩
来到sd.smali:

把上图的第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,以增加一个临时变量。

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

sd.class:

adb查看log
夜神模拟器
安装apk后,在夜神模拟器的安装目录下打开powershell,输入:
连接设备:
./adb.exe devices
输出log:
./adb.exe logcat -s iyzyi-flag:v
iyzyi-flag是log的标签。

base64解码后即得flag.
手机
以Honor v10为例。
多次点击版本号,进入开发者模式:

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

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

然后手机安装刚刚插桩的apk。
从网上下载adb,并在其目录下打开powershell,剩下的adb操作和夜神模拟器的操作是一样的:

./adb.exe logcat -c的作用是清空log缓存区。
总结
本题从难度上来说,难度不高,但是我觉得插桩这个知识点足够它作为一篇独立的博文单列出来。