起因

某日志系统使用c++编写,使用log4cplus 进行日志输出。现需要屏蔽带有某关键字的输出(有人盯着控制台看输出)。

程序不能结束,只能考虑动态注射,思来想去用firda比较方便,反正也没体积限制,直接打包上传就好。

分析

所有linux打印最后都要通过write(int fd, const void *buf, size_t count);输出。STDOUT_FILENO文件描述符输出到标准输出设备。

无论是printf或std::cout都要使用write,所以选择hook write(),将count参数改为0,屏蔽相关输出。

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/72cf4c70-cf6b-42cf-9314-5e9e6c6fd1b8/Untitled.png

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/46665cd3-429d-40c9-af07-d617e4bf803c/Untitled.png

可以看到带有test1字符串的显示已经被过滤,无法输出

/////test.js
var coutPtr = Module.findExportByName(null, "write");

console.log(coutPtr)
Interceptor.attach(coutPtr, {
    onEnter: function(args) {
        this.size = args[2].toInt32()
        var buffer = Memory.readByteArray(ptr(args[1]),args[2]-1);
        var content = args[1].readUtf8String().toString()
        console.log(content.length)
        console.log(buffer)
        if(content.indexOf("test1") != -1){
            console.log("[!]find string")
            args[2] = ptr(0)
        }else{
            console.log("[*]Not found")
        }
    },
    onLeave:function(retval) {
        console.log(this.size)
        retval.replace(this.size)
    }
});
import frida
import sys

session = frida.attach('test')

f = open("./test.js",'r')
js_test = f.read()
f.close()

script = session.create_script(js_test)
script.load()
sys.stdin.read()