首页
社区
课程
招聘
[原创]安卓FRIDA2
发表于: 3天前 292

[原创]安卓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实战!

最后于 3天前 被H1m编辑 ,原因:
收藏
免费 3
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回