Using Frida to hook Win API calls

python -m pip install frida-tools
Collecting frida-tools
  Downloading frida-tools-14.4.5.tar.gz (4.7 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.7/4.7 MB 2.8 MB/s  0:00:01
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... done
Requirement already satisfied: colorama<1.0.0,>=0.2.7 in c:\dev\tools\python313\lib\site-packages (from frida-tools) (0.4.6)
Collecting frida<18.0.0,>=17.2.8 (from frida-tools)
  Downloading frida-17.2.17-cp37-abi3-win_amd64.whl.metadata (2.3 kB)
Collecting prompt-toolkit<4.0.0,>=2.0.0 (from frida-tools)
  Downloading prompt_toolkit-3.0.52-py3-none-any.whl.metadata (6.4 kB)
Collecting pygments<3.0.0,>=2.0.2 (from frida-tools)
  Downloading pygments-2.19.2-py3-none-any.whl.metadata (2.5 kB)
Collecting websockets<14.0.0,>=13.0.0 (from frida-tools)
  Downloading websockets-13.1-cp313-cp313-win_amd64.whl.metadata (7.0 kB)
Collecting wcwidth (from prompt-toolkit<4.0.0,>=2.0.0->frida-tools)
  Downloading wcwidth-0.2.13-py2.py3-none-any.whl.metadata (14 kB)
Downloading frida-17.2.17-cp37-abi3-win_amd64.whl (41.8 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 41.8/41.8 MB 10.6 MB/s  0:00:04
Downloading prompt_toolkit-3.0.52-py3-none-any.whl (391 kB)
Downloading pygments-2.19.2-py3-none-any.whl (1.2 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.2/1.2 MB 10.4 MB/s  0:00:00
Downloading websockets-13.1-cp313-cp313-win_amd64.whl (159 kB)
Downloading wcwidth-0.2.13-py2.py3-none-any.whl (34 kB)
Building wheels for collected packages: frida-tools
  Building wheel for frida-tools (pyproject.toml) ... done
  Created wheel for frida-tools: filename=frida_tools-14.4.5-py3-none-any.whl size=4699595 sha256=115f2de0f912d70ee9eed25c26b0460f4fe24213359dd46a0ffec3e96e24c911
  Stored in directory: c:\users\dmitr\appdata\local\pip\cache\wheels\a6\b2\fb\eff238e22a7ceffee8c7a366ce7ff4011af13c77a103f870d4
Successfully built frida-tools
Installing collected packages: wcwidth, websockets, pygments, prompt-toolkit, frida, frida-tools
   ━━━━━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━ 2/6 [pygments]  WARNING: The script pygmentize.exe is installed in 'C:\dev\tools\Python313\Scripts' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╺━━━━━━ 5/6 [frida-tools]  WARNING: The scripts frida-apk.exe, frida-compile.exe, frida-create.exe, frida-discover.exe, frida-itrace.exe, frida-join.exe, frida-kill.exe, frida-ls-devices.exe, frida-ls.exe, frida-pm.exe, frida-ps.exe, frida-pull.exe, frida-push.exe, frida-rm.exe, frida-trace.exe and frida.exe are installed in 'C:\dev\tools\Python313\Scripts' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed frida-17.2.17 frida-tools-14.4.5 prompt-toolkit-3.0.52 pygments-2.19.2 wcwidth-0.2.13 websockets-13.1
Scripts\frida-trace.exe -f C:\Windows\System32\notepad.exe -i "CreateFile*"
Instrumenting...
CreateFileMoniker: Auto-generated handler at "C:\dev\tools\Python313\__handlers__\ole32.dll\CreateFileMoniker.js"
CreateFile2: Auto-generated handler at "C:\dev\tools\Python313\__handlers__\KERNEL32.DLL\CreateFile2.js"
CreateFileA: Auto-generated handler at "C:\dev\tools\Python313\__handlers__\KERNEL32.DLL\CreateFileA.js"
CreateFileW: Auto-generated handler at "C:\dev\tools\Python313\__handlers__\KERNEL32.DLL\CreateFileW.js"
CreateFileMappingA: Auto-generated handler at "C:\dev\tools\Python313\__handlers__\KERNEL32.DLL\CreateFileMappingA.js"
CreateFileTransactedA: Auto-generated handler at "C:\dev\tools\Python313\__handlers__\KERNEL32.DLL\CreateFileTransactedA.js"
CreateFileMappingNumaA: Auto-generated handler at "C:\dev\tools\Python313\__handlers__\KERNEL32.DLL\CreateFileMappingNumaA.js"
CreateFileMappingW: Auto-generated handler at "C:\dev\tools\Python313\__handlers__\KERNEL32.DLL\CreateFileMappingW.js"
CreateFileTransactedW: Auto-generated handler at "C:\dev\tools\Python313\__handlers__\KERNEL32.DLL\CreateFileTransactedW.js"
CreateFileMappingNumaW: Auto-generated handler at "C:\dev\tools\Python313\__handlers__\KERNEL32.DLL\CreateFileMappingNumaW.js"
CreateFileMappingFromApp: Auto-generated handler at "C:\dev\tools\Python313\__handlers__\KERNELBASE.dll\CreateFileMappingFromApp.js"
CreateFile2: Auto-generated handler at "C:\dev\tools\Python313\__handlers__\KERNELBASE.dll\CreateFile2.js"
CreateFileA: Auto-generated handler at "C:\dev\tools\Python313\__handlers__\KERNELBASE.dll\CreateFileA.js"
CreateFileMapping2: Auto-generated handler at "C:\dev\tools\Python313\__handlers__\KERNELBASE.dll\CreateFileMapping2.js"
CreateFileW: Auto-generated handler at "C:\dev\tools\Python313\__handlers__\KERNELBASE.dll\CreateFileW.js"
CreateFileMappingW: Auto-generated handler at "C:\dev\tools\Python313\__handlers__\KERNELBASE.dll\CreateFileMappingW.js"
CreateFileMappingNumaW: Auto-generated handler at "C:\dev\tools\Python313\__handlers__\KERNELBASE.dll\CreateFileMappingNumaW.js"
Started tracing 17 functions. Web UI available at http://localhost:60571/
           /* TID 0x32cd8 */
    29 ms  CreateFileW()
    29 ms     | CreateFileW()
    29 ms  CreateFileMappingW()
    29 ms     | CreateFileMappingW()
    29 ms     |    | CreateFileMappingNumaW()
    29 ms     |    |    | CreateFileMappingNumaW()
    34 ms  CreateFileW()
    34 ms     | CreateFileW()
    34 ms  CreateFileMappingW()
    34 ms     | CreateFileMappingW()
    34 ms     |    | CreateFileMappingNumaW()
    34 ms     |    |    | CreateFileMappingNumaW()
    43 ms  CreateFileW()
    43 ms     | CreateFileW()
    43 ms  CreateFileMappingNumaW()
    43 ms     | CreateFileMappingNumaW()
Process terminated
Scripts\frida-trace.exe -f C:\Windows\System32\ldp.exe -i "setsockopt"
Instrumenting...
setsockopt: Auto-generated handler at "C:\dev\tools\Python313\__handlers__\WS2_32.dll\setsockopt.js"
Started tracing 1 function. Web UI available at http://localhost:60022/
           /* TID 0x58080 */
  6548 ms  setsockopt()
 27587 ms  setsockopt()
 41039 ms  setsockopt()
 62076 ms  setsockopt()
Process terminated

Attaching by PID:

Scripts\frida-trace.exe -p 413100  -i "setsockopt"
Instrumenting...
setsockopt: Loaded handler at "C:\dev\tools\Python313\__handlers__\WS2_32.dll\setsockopt.js"
Started tracing 1 function. Web UI available at http://localhost:59950/
           /* TID 0x64db4 */
  5986 ms  setsockopt()
 13384 ms  setsockopt()

Using JavaScript

// int setsockopt(
//   SOCKET s,        // args[0] — дескриптор сокета
//   int level,       // args[1] — уровень (SOL_SOCKET, IPPROTO_TCP и т.д.)
//   int optname,     // args[2] — имя опции
//   const char *optval, // args[3] — указатель на значение
//   int optlen       // args[4] — длина значения
// );

function readOptVal(optvalPtr, optlen) {
    try {
        var len = optlen.toInt32();
        if (len <= 0) return "<empty>";
        // console.log("  val length:", len);
        var buf = optvalPtr.readByteArray(len);
        // console.log("  val buf:", buf);

        // как массив байт в hex
        var arr = new Uint8Array(buf);
        return Array.from(arr).map(b => b.toString(16).padStart(2, "0")).join(" ");
    } catch(e) {
        console.log("  Error:", e);
        return "<cannot-read>";
    }
}

var fn = Process.getModuleByName('ws2_32.dll').getExportByName('setsockopt');

if (!fn)
{
    console.log("setsockopt not found!");
}
else
{
    Interceptor.attach(fn, {
        onEnter: function(args) {
            var sock = args[0].toInt32();
            var level = args[1].toInt32();
            var optname = args[2];//.toInt32();
            var optval = args[3];
            var optlen = args[4];

            var val = readOptVal(optval, optlen);

            console.log("[setsockopt] called");
            console.log("  Socket:", sock);
            console.log("  Level :", level);
            console.log("  Opt   :", optname);
            console.log("  Val   :", val);
            console.log("  Len   :", optlen.toInt32());
        },
        onLeave: function(retval) {
            console.log("  Return:", retval.toInt32());
            console.log("------------------------------------");
        }
    });
}

Hooking ChannelTest.exe

frida -p 427684 -l hook_setsockopt.js

The output:

  Socket: 14356
  Level : 65535
  Opt   : 0xfffffffb
  Val   : 01 00 00 00
  Len   : 4
  Return: 0

0xfffffffb is 1111 1111 1111 1111 1111 1111 1111 1011 and SO_LINGER is 0x0080 that is 1000 0000.

The same result with ldp.exe:

frida -p 413100 -l hook_setsockopt.js

[setsockopt] called
  Socket: 1356
  Level : 65535
  Opt   : 0xfffffffb
  Val   : 01 00 00 00
  Len   : 4
  Return: 0

Sample Program in C++

#include <iostream>

#include <winsock2.h>

int main()
{
    std::cout << "Hello World!\n";

    struct linger lingerOpt;
    lingerOpt.l_onoff = 1;  // Включить ожидание
    lingerOpt.l_linger = 10; // Ожидать 10 секунд

    static_assert(sizeof(linger) == 4u);
    
    SOCKET socket = 0;

    setsockopt(socket, SOL_SOCKET, SO_LINGER, (char*)&lingerOpt, sizeof(lingerOpt));
}
frida -f C:\dev\repos\channelmeter\x64\Release\LingerSample.exe -l hook_setsockopt.js
[setsockopt] called
  Socket: 0
  Level : 65535
  Opt   : 0x80
  Val   : 01 00 0a 00
  Len   : 4
  Return: -1

1 Response to Using Frida to hook Win API calls

Leave a Reply

Your email address will not be published. Required fields are marked *