题目来自看雪2020春季班10月份第一题和第三题。这两个题目本身难度不高,但是确实考察对源码的理解,同时也不失为一个frida的案例。
在HttpURLConnection的开发过程中,设置参数时会用到以下方法。分析并hook上这些方法,写出一两个参数的自吐。
具体在测试时可以自己写一个简单的demo并在APP中显示调用如下函数

测试app功能正常后,用Objection直接把以下两个类全都hook上:java.net.URLConnection以及java.net.HttpURLConnection
结果如图发现反复调用这几个函数,其他函数都没有调用:

怀疑底层是否真实使用这些类实现的,找到对应源码,发现其实HttpURLConnection类也是一个抽象类,就是说在Java中实际上是其Impl类去实现:
使用WallBreaker去搜索HttpURLConnection会发现确实有一个类com.android.okhttp.internal.huc.HttpURLConnectionImpl

去源码里搜了搜发现,确实这个类实现了这个函数
源码看HttpURLConnectionImpl

晕死,结果这个类也是okHttp做的底层???先hook一下这个类
会发现这个实现类确实实现了之前没有hook到的三个函数

那么最终脚本就直接写就是了
最终效果如下

在课时⑨中给出的init array的自吐 hook_linker,32位版本解决了,请分析64位版本,尝试给出解决方案并解决。
以8.1为例,查看源码后会发现
dlopen调用过程中最终是
目录/bionic/linker/linker_soinfo.cpp

这个函数是模版函数,把linker拷到IDA上一看,会发现这个函数是唯一的,且参数是4个,同时会发现64位的linker中是没有call_function这个函数的,这个函数被优化成了代码片段,插进call_constructors函数和call_array函数中了。
最终模仿这个函数直接写一个js版本就行了关键的代码如下
但是这样只是hook了so中init_array节中函数,还存在.init_proc的构造函数并未hook,和32位一样本来是继续去hook call_function函数,在脱出/system/lib64/libart.so后,发现call_function这个symbol无法找到,观察下图发现这个函数被inline了。


但是仔细观察.init_proc和.init_array函数调用前后,都会有一个log的判断,直接去hook这个_dl_async_safe_format_log函数吧
但是首先得_dl_g_ld_debug_verbosity这个值大于等于2这个函数才会执行,那么先使用frida去这个变量的地址,然后修改这个变量的值使其达到_dl_async_safe_format_log函数会执行的条件即可。
最终frida关键代码如下:
最终效果如下,
64位:

32位效果:

同样的完整代码已经上传github,看这里
一切答案都在源码中。
// URLConnection
httpUrlConnection.setDoOutput(true);
httpUrlConnection.setDoInput(true);
HttpUrlConnection.setUseCaches(false);
httpUrlConnection.setRequestProperty("Content-type", "application/x-java-serialized-object");
httpUrlConnection.connect();
// HttpURLConnection
httpUrlConnection.setRequestMethod("POST");
// URLConnection
httpUrlConnection.setDoOutput(true);
httpUrlConnection.setDoInput(true);
HttpUrlConnection.setUseCaches(false);
httpUrlConnection.setRequestProperty("Content-type", "application/x-java-serialized-object");
httpUrlConnection.connect();
// HttpURLConnection
httpUrlConnection.setRequestMethod("POST");
function hook_java(){
Java.perform(function(){
// httpUrlConnection.setDoOutput(true);
// httpUrlConnection.setDoInput(true);
// HttpUrlConnection.setUseCaches(false);
var URLConnection = Java.use("java.net.URLConnection")
URLConnection.setDoOutput.implementation = function(isOutput){
console.log("URLConnection.setDoOutput : ",isOutput);
return this.setDoOutput(isOutput);
}
URLConnection.setDoInput.implementation = function(isInput){
console.log("URLConnection.setDoInput : ",isInput);
return this.setDoInput(isInput);
}
URLConnection.setUseCaches.implementation = function(isUseCaches){
console.log("URLConnection.setUseCaches : ",isUseCaches);
return this.setUseCaches(isUseCaches);
}
// com.android.okhttp.internal.huc.HttpURLConnectionImpl
var HttpURLConnectionImpl = Java.use("com.android.okhttp.internal.huc.HttpURLConnectionImpl");
HttpURLConnectionImpl.setRequestProperty.implementation = function(name,value){
console.log("HttpURLConnectionImpl.setRequestProperty => ",name,": ",value);
return this.setRequestProperty(name,value);
}
HttpURLConnectionImpl.setRequestMethod.implementation = function(type){
console.log("HttpURLConnectionImpl.setRequestMethod : ",type);
return this.setRequestMethod(type);
}
HttpURLConnectionImpl.connect.implementation = function(){
console.log("HttpURLConnectionImpl.connect");
return this.connect();
}
});
}
function main(){
hook_java();
}
setImmediate(main);
function hook_java(){
Java.perform(function(){
// httpUrlConnection.setDoOutput(true);
// httpUrlConnection.setDoInput(true);
// HttpUrlConnection.setUseCaches(false);
var URLConnection = Java.use("java.net.URLConnection")
URLConnection.setDoOutput.implementation = function(isOutput){
console.log("URLConnection.setDoOutput : ",isOutput);
return this.setDoOutput(isOutput);
}
URLConnection.setDoInput.implementation = function(isInput){
console.log("URLConnection.setDoInput : ",isInput);
return this.setDoInput(isInput);
}
URLConnection.setUseCaches.implementation = function(isUseCaches){
console.log("URLConnection.setUseCaches : ",isUseCaches);
return this.setUseCaches(isUseCaches);
}
// com.android.okhttp.internal.huc.HttpURLConnectionImpl
var HttpURLConnectionImpl = Java.use("com.android.okhttp.internal.huc.HttpURLConnectionImpl");
HttpURLConnectionImpl.setRequestProperty.implementation = function(name,value){
console.log("HttpURLConnectionImpl.setRequestProperty => ",name,": ",value);
return this.setRequestProperty(name,value);
}
HttpURLConnectionImpl.setRequestMethod.implementation = function(type){
console.log("HttpURLConnectionImpl.setRequestMethod : ",type);
return this.setRequestMethod(type);
}
HttpURLConnectionImpl.connect.implementation = function(){
console.log("HttpURLConnectionImpl.connect");
return this.connect();
}
});
}
function main(){
hook_java();
}
setImmediate(main);
soinfo::call_constructors()
call_function("DT_INIT", init_func_, get_realpath());
call_array("DT_INIT_ARRAY", init_array_, init_array_count_, false, get_realpath());
------>循环调用了 call_function("function", functions[i], realpath);
soinfo::call_constructors()
call_function("DT_INIT", init_func_, get_realpath());
call_array("DT_INIT_ARRAY", init_array_, init_array_count_, false, get_realpath());
------>循环调用了 call_function("function", functions[i], realpath);
function hook_init_array() {
//console.log("hook_constructor",Process.pointerSize);
if (Process.pointerSize == 4) {
var linker = Process.findModuleByName("linker");
}else if (Process.pointerSize == 8) {
var linker = Process.findModuleByName("linker64");
}
var addr_call_array = null;
if (linker) {
var symbols = linker.enumerateSymbols();
for (var i = 0; i < symbols.length; i++) {
var name = symbols[i].name;
if (name.indexOf("call_array") >= 0) {
addr_call_array = symbols[i].address;
}
}
}
if (addr_call_array) {
Interceptor.attach(addr_call_array, {
onEnter: function (args) {
this.type = ptr(args[0]).readCString();
//console.log(this.type,args[1],args[2],args[3])
if (this.type == "DT_INIT_ARRAY") {
this.count = args[2];
//this.addrArray = new Array(this.count);
this.path = ptr(args[3]).readCString();
var strs = new Array(); //定义一数组
strs = this.path.split("/"); //字符分割
this.filename = strs.pop();
if(this.count > 0){
console.log("path : ", this.path);
console.log("filename : ", this.filename);
}
for (var i = 0; i < this.count; i++) {
console.log("offset : init_array["+i+"] = ", ptr(args[1]).add(Process.pointerSize*i).readPointer().sub(Module.findBaseAddress(this.filename)));
//插入hook init_array代码
}
}
},
onLeave: function (retval) {
}
});
}
}
function hook_init_array() {
//console.log("hook_constructor",Process.pointerSize);
if (Process.pointerSize == 4) {
var linker = Process.findModuleByName("linker");
}else if (Process.pointerSize == 8) {
var linker = Process.findModuleByName("linker64");
}
var addr_call_array = null;
[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!
最后于 2021-5-11 11:34
被Simp1er编辑
,原因: