apk,用jadx打开
反调试部分
在work.pangbai.debugme.MainActivity发现虚拟机的判断

- 通过
Class.forName
加载android.os.SystemProperties
类,获取系统属性。 getProperty(cls, "ro.kernel.qemu")
:检查是否有ro.kernel.qemu
属性,如果该属性存在且长度大于 0,说明可能是在 QEMU 模拟器上运行。getProperty(cls, "ro.hardware")
:检查ro.hardware
属性是否等于"goldfish"
,这是 Android 模拟器的硬件标识。getProperty(cls, "ro.product.model")
:检查ro.product.model
属性是否等于"sdk"
,这也是一个常见的模拟器标识。
在oncreate函数中调用了isEmu函数,如果判断是虚拟机则重载onclick函数用一个匿名的onclick监听器处理
否则用当前类的监听器

在work.pangbai.tool.app类下执行cat /proc/self/status查看本程序的状态,并获取到TracerPid查看是否有进程调试本程序。


如果有进程调试则关闭当前进程,若没有进程调试则再次调用本函数

加密部分

用jni调用so文件内的g4tk4y函数得到Blowfish加密算法的key,对输入进行Blowfish加密后进行doenc操作后进入so里的check函数
doenc对输入进行了base编码

在so中用GetStaticIntField函数得到了处于java层的静态变量

在g4tk4y函数函数中对这两个变量进行了赋值操作,将work/pangbai/tool/App下的status的给id给了3808,故上述v6等于status

在java层进行了&2操作那么status的值只可能为0,2

组成32位整数后从1开始分别遍历a=arr[i]^arr[i+1] arr[i]=arr[i+1]^ ROR|ROL(a,i)


对arr[0]也经过一次加密

逆向得到Blowfish的数据
def ROL(s,n):
return (((s<<n)&0xffffffff) | ((s>>(32-n))&0xffffffff))
def ROR(s,n):
return ((s<<(32-n))&0xffffffff | (s>>n)&0xffffffff)
a=[0x9C5F5508,0x40561970,0x58676904,0x0C13E5285,0x75DC2D4C,0x6F06EAF,0x6E7B5DA5,0x0E37EAE2A,0x0F1B9FEFD,0x6966BAC, 0x4A21BF43, 0x47DBF512]
v6=0
v16=a[11]^a[0]
if (v6):
v16=ROL(v16,12)
else:
v16=ROR(v16,12)
a[0]=v16^a[11]
for x in range(11,-1,-1):
a[x]=a[x]^a[x-1]
if (v6):
a[x]=ROL(a[x], x)
else:
a[x]=ROR(a[x], x)
a[x]^=a[x-1]
flag=""
for x in a:
flag+=hex(x).replace("0x","").rjust(8,"0")
flag=bytes.fromhex(flag)
for x in range(0,len(flag),4):
a=flag[x:x+4]
for y in range(len(a)):
print(chr(a[3-y]),end="")
XMvFLgfEmEZFtNLkyupZSOEncBR/BVaqzil47iBYYFE=
用frida获取到Blowfish的key,注意也要hook isEmu函数不然没法触发getkey函数
import frida, sys,re
def on_message(message, data):
print(message)
jscode = """
Java.perform(function(){
let MainActivity = Java.use("work.pangbai.debugme.MainActivity");
MainActivity["isEmu"].implementation = function () {
console.log(`MainActivity.isEmu is called`);
return false;
};
MainActivity["g4tk4y"].implementation = function () {
console.log(`MainActivity.g4tk4y is called`);
let result = this["g4tk4y"]();
console.log(`MainActivity.g4tk4y result=${result}`);
return result;
};
let MainActivity2 = Java.use("work.pangbai.tool.App");
MainActivity2["GetPPid"].implementation = function () {
console.log(`MainActivity2.GetPPid is called`);
let result = this["GetPPid"]();
console.log(result);
return Java.use('java.lang.String').$new("0");
};
})
"""
device = frida.get_usb_device(-1)
pid = device.spawn(['work.pangbai.debugme'])
process = device.attach(pid)
script = process.create_script(jscode)
script.on('message', on_message)
script.load()
device.resume(pid)
sys.stdin.read()
得到key jRLgC/Pi解密ECB即可

flag{U_@r4_r4v4r54_m@s74r}
Comments NOTHING