这是我在矿大CTF逆向区做的最后一题,因为其中的内容对我而言具有学习意义,所以单独拿出来写篇博文。其他矿大CTF逆向题解请详见矿大RE(完结撒花)。
java
c.c.a中找到tu.class:
红框处是反调试的代码,如果修改了apk重新打包,再次运行会终止进程。
进入sd.dfh中看一下:
进入jh.gfds:
最内侧的df.gr是一个很长的二进制字符串,外侧的函数都是解密操作。
由于变量名被混淆了,解密代码很难读懂,而且flag在程序运行中明文出现过,所以可以考虑插桩,当将二进制字符串解密出flag时,可以使用log输出flag。
删掉反调试代码
我们来到smali层:
打开tu.smali,删掉下面的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| .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。并在此处添加
1 2 3
| 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缓存区。
总结
本题从难度上来说,难度不高,但是我觉得插桩这个知识点足够它作为一篇独立的博文单列出来。