-
-
[原创]安卓FRIDA2
-
发表于: 3天前 292
-
继续来看一道题目:

要求注册,
我们来看myapp

这里我们使用手机进行操作
function hook_java() {
Java.perform(function (){
var MyApp = Java.use("com.gdufs.xman.MyApp");
MyApp.saveSN.implementation = function (str) {
console.log("MyApp.saveSN:", str);
this.saveSN(str);
};
});
}
function main() {
hook_java();
}
setImmediate(main);

这里我们发现只要是输入注册码后就会自动退出
那我们把这个杀死进程的东西给杀死掉
这时候我们在手机进行输入并点击好的就不会将自动退出去
下一步我们去分析他的so文件

这个使用动态注册

我们修复函数名字
我们看到首先去找到class,然后将返回值给到native_class,再用registernative将其找到的class进行注册,我们点开off_5004

他这个格式是函数名加参数加地址如下图所示:



这就是三个函数(类似的)
我们找到saveSN的真正位置

对n2进行hook


我们发现n2的地址是0xc27181f9
但是我们看看ida中的n2

他是0x11f8,那是因为这个函数是thumb函数,便宜的地址要加上模块的地址

这个thumb是需要再加一个1

这里就可以看的很清楚了
这里我们回到so文件

在之前的jadx中我们知道saveSN中的str只有一个参数
而在so文件里面有很多个参数,那是因为他给你自动加上去

这里a3就是我们的str,而a1是个JNIEnv*类型的数据
我们现在要hook的是v7,也就是GetStringUTFChars的返回值

这里我们可以看到有名字了


我们对其进行枚举:
function hook_libart() {
var module_libart = Process.findModuleByName("libart.so");
var symbols = module_libart.enumerateSymbols();
console.log(symbols[15].name);
for(var i = 0; i < symbols.length ; i++){
console.log(symbols[i].name);
}
}
这里会打印很多名字
var addr_GetStringUTFChars = null;
for (var i = 0; i < symbols.length; i++) {
var name = symbols[i].name;
if (name.indexOf("art") >= 0) {//先找到这个
if ((name.indexOf("CheckJNI") == -1) && (name.indexOf("JNI") >= 0)) {
//我们不能要checkJNI(这个是手机开启check的时候才会开启),其就一般不会走这个路,所以等于-1
if (name.indexOf("GetStringUTFChars") >= 0) {
console.log(name);
addr_GetStringUTFChars = symbols[i].address;
break;
}
}
}
}我们开始寻找

最后找到
function hook_libart() {
var module_libart = Process.findModuleByName("libart.so");
var symbols = module_libart.enumerateSymbols();
//console.log(symbols[15].name);
for(var i = 0; i < symbols.length ; i++){
//console.log(symbols[i].name);
}
var addr_GetStringUTFChars = null;
for (var i = 0; i < symbols.length; i++) {
var name = symbols[i].name;
if (name.indexOf("art") >= 0) {//先找到这个
if ((name.indexOf("CheckJNI") == -1) && (name.indexOf("JNI") >= 0)) {
//我们不能要checkJNI(这个是手机开启check的时候才会开启),其就一般不会走这个路,所以等于-1
if (name.indexOf("GetStringUTFChars") >= 0) {
//console.log(name);
addr_GetStringUTFChars = symbols[i].address;
//break;
}
}
}
}
if(addr_GetStringUTFChars) {
//console.log('11111');
Interceptor.attach(addr_GetStringUTFChars, {
onEnter: function (args) {
}, onLeave: function (retval) {
// retval const char*
console.log("addr_GetStringUTFChars onLeave:", ptr(retval).readCString(), "\r\n");
}
});
}
}我们使用这个来看:

那么说明v7就那一行就是被传入NKCTF
接着就是这个so文件,我们看到他创建了一个文件,我们去看看

(文件我这里不太会看)
再回到jadx里面

我们要找到m的值
我们在so文件中去看其他几个函数


我们依然修改其类型值
对所有进行hook
function hook_java() {
Java.perform(function (){
var MyApp = Java.use("com.gdufs.xman.MyApp");
MyApp.saveSN.implementation = function (str) {
console.log("MyApp.saveSN:", str);
this.saveSN(str);
};
var Process = Java.use("android.os.Process");
Process.killProcess.implementation = function (pid) {
//这里不使用this就不会调用原来的函数
console.log("Process.killProcess:", pid);
};
});
}
function hook_native() {
var base_myjni = Module.findBaseAddress("libmyjni.so");
if(base_myjni) {
var n2 = Module.findExportByName("libmyjni.so", "n2");
console.log("base_myjni:", base_myjni, "n2:", n2);
Interceptor.attach(n2, {
onEnter: function (args) {
console.log("n2 onEnter:", args[0], args[1], args[2]);
}, onLeave: function (retval) {
}
});
}
}
function hook_libart() {
var module_libart = Process.findModuleByName("libart.so");
var symbols = module_libart.enumerateSymbols();
//console.log(symbols[15].name);
for(var i = 0; i < symbols.length ; i++){
//console.log(symbols[i].name);
}
var addr_GetStringUTFChars = null;
var addr_FindClass = null;
var addr_GetStaticFieldID = null;
var addr_SetStaticIntField = null;
for (var i = 0; i < symbols.length; i++) {
var name = symbols[i].name;
if (name.indexOf("art") >= 0) {
if ((name.indexOf("CheckJNI") == -1) && (name.indexOf("JNI") >= 0)) {
if (name.indexOf("GetStringUTFChars") >= 0) {
console.log(name);
addr_GetStringUTFChars = symbols[i].address;
} else if (name.indexOf("FindClass") >= 0) {
console.log(name);
addr_FindClass = symbols[i].address;
} else if (name.indexOf("GetStaticFieldID") >= 0) {
console.log(name);
addr_GetStaticFieldID = symbols[i].address;
} else if (name.indexOf("SetStaticIntField") >= 0) {
console.log(name);
addr_SetStaticIntField = symbols[i].address;
}
}
}
}
if(addr_GetStringUTFChars) {
Interceptor.attach(addr_GetStringUTFChars, {
onEnter: function (args) {
}, onLeave: function (retval) {
console.log("addr_GetStringUTFChars onLeave:", ptr(retval).readCString());
}
});
}
if (addr_FindClass) {
Interceptor.attach(addr_FindClass, {
onEnter: function (args) {
console.log("addr_FindClass:", ptr(args[1]).readCString());
}, onLeave: function (retval) {
}
});
}
if (addr_GetStaticFieldID) {
Interceptor.attach(addr_GetStaticFieldID, {
onEnter: function (args) {
console.log("addr_GetStaticFieldID:", ptr(args[2]).readCString(), ptr(args[3]).readCString());
}, onLeave: function (retval) {
}
});
}
if (addr_SetStaticIntField) {
Interceptor.attach(addr_SetStaticIntField, {
onEnter: function (args) {
console.log("addr_SetStaticIntField:", args[3]);
}, onLeave: function (retval) {
}
});
}
}
function main() {
hook_java();
hook_native();
hook_libart();
}
setImmediate(main);(但我这里调试不通,因为要--no-pause)
但大概意思是,我们输入的东西,如果让m=1就可以通过验证,


我们继续看的话就是知道这个v6是啥就行了

当然也可以hook
function hook_libc() {
//hook libc的函数
var strcmp = Module.findExportByName("libc.so", "strcmp");
console.log("strcmp:", strcmp);
Interceptor.attach(strcmp, {
onEnter: function (args) {
var str_2 = ptr(args[1]).readCString();
if (str_2 == "EoPAoY62@ElRD") {
console.log("strcmp:", ptr(args[0]).readCString(),
ptr(args[1]).readCString());
}
}, onLeave: function (retval) {
}
});
}(还是老样子,没有--no-pause)
function hook_java() {
Java.perform(function (){
var MyApp = Java.use("com.gdufs.xman.MyApp");
MyApp.saveSN.implementation = function (str) {
console.log("MyApp.saveSN:", str);
this.saveSN(str);
};
var Process = Java.use("android.os.Process");
Process.killProcess.implementation = function (pid) {
//这里不使用this就不会调用原来的函数
console.log("Process.killProcess:", pid);
};
});
}
function hook_native() {
var base_myjni = Module.findBaseAddress("libmyjni.so");
if(base_myjni) {
var n2 = Module.findExportByName("libmyjni.so", "n2");
console.log("base_myjni:", base_myjni, "n2:", n2);
Interceptor.attach(n2, {
onEnter: function (args) {
console.log("n2 onEnter:", args[0], args[1], args[2]);
}, onLeave: function (retval) {
}
});
}
}
function hook_libart() {
var module_libart = Process.findModuleByName("libart.so");
var symbols = module_libart.enumerateSymbols();
//console.log(symbols[15].name);
for(var i = 0; i < symbols.length ; i++){
//console.log(symbols[i].name);
}
var addr_GetStringUTFChars = null;
var addr_FindClass = null;
var addr_GetStaticFieldID = null;
var addr_SetStaticIntField = null;
for (var i = 0; i < symbols.length; i++) {
var name = symbols[i].name;
if (name.indexOf("art") >= 0) {
if ((name.indexOf("CheckJNI") == -1) && (name.indexOf("JNI") >= 0)) {
if (name.indexOf("GetStringUTFChars") >= 0) {
console.log(name);
addr_GetStringUTFChars = symbols[i].address;
} else if (name.indexOf("FindClass") >= 0) {
console.log(name);
addr_FindClass = symbols[i].address;
} else if (name.indexOf("GetStaticFieldID") >= 0) {
console.log(name);
addr_GetStaticFieldID = symbols[i].address;
} else if (name.indexOf("SetStaticIntField") >= 0) {
console.log(name);
addr_SetStaticIntField = symbols[i].address;
}
}
}
}
if(addr_GetStringUTFChars) {
Interceptor.attach(addr_GetStringUTFChars, {
onEnter: function (args) {
}, onLeave: function (retval) {
console.log("addr_GetStringUTFChars onLeave:", ptr(retval).readCString(), "\r\n");
}
});
}
if (addr_FindClass) {
Interceptor.attach(addr_FindClass, {
onEnter: function (args) {
console.log("addr_FindClass:", ptr(args[1]).readCString());
}, onLeave: function (retval) {
}
});
}
if (addr_GetStaticFieldID) {
Interceptor.attach(addr_GetStaticFieldID, {
onEnter: function (args) {
console.log("addr_GetStaticFieldID:", ptr(args[2]).readCString(), ptr(args[3]).readCString());
}, onLeave: function (retval) {
}
});
}
if (addr_SetStaticIntField) {
Interceptor.attach(addr_SetStaticIntField, {
onEnter: function (args) {
console.log("addr_SetStaticIntField:", args[3]);
}, onLeave: function (retval) {
}
});
}
}
function hook_libc() {
//hook libc的函数
var strcmp = Module.findExportByName("libc.so", "strcmp");
console.log("strcmp:", strcmp);
Interceptor.attach(strcmp, {
onEnter: function (args) {
var str_2 = ptr(args[1]).readCString();
if (str_2 == "EoPAoY62@ElRD") {
console.log("strcmp:", ptr(args[0]).readCString(),
ptr(args[1]).readCString());
}
}, onLeave: function (retval) {
}
});
}
function main() {
hook_java();
hook_native();
hook_libart();
hook_libc();
}
setImmediate(main);frida -U -f com.gdufs.xman -l ./1.js
使用上面这个命令可以看到

但还是没有strcmp
最后他的解密还是很简单的
这道题目就到这里
[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!