逆向工程 - Frida - Hook Module Function (C++)



參考資訊:
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#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

1
2
3
4
5
6
7
8
9
10
11
12
13
#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

1
2
3
4
5
6
#include "test.h"
 
void Test::test(int v)
{
    std::cout << v << std::endl;
}

hook.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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}