參考資訊:
https://github.com/frida/frida
https://frida.re/docs/functions/
https://frida.re/docs/installation/
https://mprtmma.medium.com/c-shared-library-dynamic-linking-eps-1-bacf2c95d54f
main.cpp
#include <thread>
#include <chrono>
#include "test.h"
int main(int argc, char *argv[])
{
Test t;
int cc = 0;
while (1) {
std::this_thread::sleep_for(std::chrono::seconds(1));
t.test(cc++);
}
return 0;
}
test.h
#include <string>
#include <iostream>
class Base {
public:
~Base() = default;
virtual void test(int v) = 0;
};
class Test : public Base {
public:
void test(int v) override;
};
test.cpp
#include "test.h"
void Test::test(int v)
{
std::cout << v << std::endl;
}
hook.py
import sys
import frida
def on_message(message, data):
print(message)
session = frida.attach("main")
script = session.create_script("""
const mylib = "test.so";
const myfun = "%s";
let pfun = 0;
let m = Process.enumerateModules();
for (let i = 0; i < m.length; i++) {
if (m[i]["name"] == mylib) {
let e = m[i].enumerateExports();
for (let j = 0; j < e.length; j++) {
if (e[j]["name"] == myfun) {
pfun = e[j]["address"]
}
}
}
}
Interceptor.attach(ptr(pfun), {
onEnter: function (args) {
send(args[1].toInt32());
}
});
""" % sys.argv[1])
script.on('message', on_message)
script.load()
sys.stdin.read()
編譯、執行
$ g++ test.cpp -o test.so -shared -fPIC
$ g++ main.cpp -o main test.so
$ LD_LIBRARY_PATH=. ./main&
0
1
2
3
4
5
$ nm -D test.so | grep "T "
000000000000113a T _ZN4Test4testEi
$ python3 hook.py _ZN4Test4testEi
{'type': 'send', 'payload': 6}
{'type': 'send', 'payload': 7}
{'type': 'send', 'payload': 8}
{'type': 'send', 'payload': 9}