1

我使用 Frida 挂钩了本机 Windows 应用程序的函数HttpSendRequestExA,但我无法读取通过此函数的参数lpBuffersIn传递的结构INTERNET_BUFFERSA

函数HttpSendRequestExA的签名:

BOOLAPI HttpSendRequestExA(
HINTERNET           hRequest,
LPINTERNET_BUFFERSA lpBuffersIn,
LPINTERNET_BUFFERSA lpBuffersOut,
DWORD               dwFlags,
DWORD_PTR           dwContext
);

结构INTERNET_BUFFERSA

typedef struct _INTERNET_BUFFERSA {
DWORD                     dwStructSize;
struct _INTERNET_BUFFERSA *Next;
LPCSTR                    lpcszHeader;
DWORD                     dwHeadersLength;
DWORD                     dwHeadersTotal;
LPVOID                    lpvBuffer;
DWORD                     dwBufferLength;
DWORD                     dwBufferTotal;
DWORD                     dwOffsetLow;
DWORD                     dwOffsetHigh;
} INTERNET_BUFFERSA, *LPINTERNET_BUFFERSA;

这是挂钩脚本的功能:

  onEnter: function (log, args, state) {
  log('###### HttpSendRequestExA() ###################');
  log("lpBuffersIn  = " + args[1].readPointer());//I'm stuck here to reach the structure
  log('###############################################');       
 }

我在 Internet 上进行了搜索,但没有找到如何读取指针并将其与预期结构相关联。

非常感谢您的任何帮助或提示:)

4

1 回答 1

1

由于未指定体系结构,因此以下答案适用于 32 位进程,但解释了 64 位更改。

结构_INTERNET_BUFFERSA显示为LPINTERNET_BUFFERSAwhich 是一个指针。args[1]保存指向结构的指针,_INTERNET_BUFFERSA读取时.readPointer返回的值dwStructSize是32 位进程的40和 64 位进程的52

每个成员的偏移量是:

typedef struct _INTERNET_BUFFERSA {
DWORD                     dwStructSize; // Offset: 0
struct _INTERNET_BUFFERSA *Next; // Offset: 4
LPCSTR                    lpcszHeader; // Offset -> 32-bit: 8, 64-bit:12
DWORD                     dwHeadersLength; // Offset -> 32-bit: 12, 64-bit:20
DWORD                     dwHeadersTotal; // Offset -> 32-bit: 16, 64-bit 24
LPVOID                    lpvBuffer; // Offset -> 32-bit: 20, 64-bit 28
DWORD                     dwBufferLength; // Offset -> 32-bit: 24, 64-bit 36
DWORD                     dwBufferTotal; // Offset -> 32-bit: 28, 64-bit 40
DWORD                     dwOffsetLow; // Offset -> 32-bit: 32, 64-bit 44
DWORD                     dwOffsetHigh;// Offset -> 32-bit: 36, 64-bit 48
} INTERNET_BUFFERSA, *LPINTERNET_BUFFERSA;

考虑到这一点,以下 FRIDA 代码将检索 32 位进程的每个结构成员:

Interceptor.attach(Module.getExportByName(null, "HttpSendRequestExW"), {
    onEnter (args) {
        let internetBufferStruct = args[1];
        console.log("Struct size: " + internetBufferStruct.readPointer());
        console.log("*Next: " + internetBufferStruct.add(Process.pointerSize).readPointer());  
        console.log("lpcszHeader: " + internetBufferStruct.add(Process.pointerSize * 2).readPointer());  
        console.log("dwHeadersLength: " + internetBufferStruct.add(12).readPointer());  
        console.log("dwHeadersTotal: " + internetBufferStruct.add(16).readPointer());  
        let dwBufferLength = parseInt(internetBufferStruct.add(24).readPointer());
        console.log("lpvBuffer: " + internetBufferStruct.add(Process.pointerSize * 5).readCString(dwBufferLength));  
        console.log("dwBufferLength: " + dwBufferLength);  
        console.log("dwBufferTotal: " + internetBufferStruct.add(28).readPointer());  
        console.log("dwOffsetLow: " + internetBufferStruct.add(32).readPointer());  
        console.log("dwOffsetHigh: " + internetBufferStruct.add(36).readPointer());  
    }
});

Process.pointerSize32 位进程为 4,64 位进程为8 这允许正确解析偏移量。

于 2021-07-18T13:31:21.693 回答