黑客精神
java层程序首先判断有没有注册,如果没注册执行注册,否则执行native层的work函数。
逆向.so文件,入口为JNI_onload首先y修改变量类型为JNIEnv*
就可以看到各个函数名称,JNI_Onload函数利用注册本地方法将函数名称混淆了一下
进入界面注册函数执行init_sn()函数读取/sdcard/reg.dat目录中的文件判断是否相等于字符串"EoPAoY62@ElRD"
输入注册按钮之后,将输入的数值加密存储在/sdcard/reg.dat
解密
key = "W3_arE_whO_we_ARE"
result = "EoPAoY62@ElRD"
length = len(result)
index = 0
v13 = 2016
flag = ""
while index < length:
if index % 3 == 1:
v13 = (v13 + 5) % 16
v19 = key[v13 + 1]
elif index % 3 == 2:
v13 = (v13 + 7) % 15
v19 = key[v13 + 2]
else:
v13 = (v13 + 3) % 13
v19 = key[v13 + 3]
flag += chr(ord(result[index]) ^ ord(v19))
index = index + 1
print(flag)
FridaHook
在网上看到了一种frida Hook的解法
adb install 安装apk
adb shell pm list packages
adb forward tcp:27042 tcp:27042
import frida
import sys
js = """
var flag=false;
Java.perform(function () {
var imports = Module.enumerateImportsSync("libmyjni.so");
for (var i = 0; i < imports.length; i++) {
if (imports[i].name == "fputs") {
var strncmp = imports[i].address;
console.log(imports[i].name);
console.log(imports[i].address);
var targetfunc = imports[i].address;
break;
}
}
if (targetfunc) {
Interceptor.attach(targetfunc, {
onEnter: function (args) {
var data = Memory.readCString(args[0]);
console.log(data)
if(data=="Eo")
{
flag=true;
}
}
});
}
var MyApp = Java.use("com.gdufs.xman.MyApp");
var myapp = MyApp.$new();
console.log("input: 11");
myapp.saveSN("11");
var dict = "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()";
for (var j = 0; j < dict.length; j++) {
for (var i = 0; i < dict.length; i++) {
myapp.saveSN(dict[j] + dict[i] );
if (flag) {
console.log("[+]Found dict : " + dict[j] + dict[i] );
return;
}
}
}
});
"""
def message(words, data):
if words["type"] == 'send':
print("[*] {0}".format(words["payload"]))
else:
print(words)
process = frida.get_usb_device().attach("com.gdufs.xman")
script = process.create_script(js)
script.on("message", message)
script.load()
sys.stdin.read()