Frida - Windows 本机应用程序 - 读取 Wininet.h 公开的结构
Frida - Windows native app - Read a structure exposed by Wininet.h
我使用 Frida 挂钩了本机 Windows 应用程序的 HttpSendRequestExA 函数,但我无法读取结构 INTERNET_BUFFERSA 通过此函数的参数 lpBuffersIn 传递:
函数签名HttpSendRequestExA:
BOOLAPI HttpSendRequestExA(
HINTERNET hRequest,
LPINTERNET_BUFFERSA lpBuffersIn,
LPINTERNET_BUFFERSA lpBuffersOut,
DWORD dwFlags,
DWORD_PTR dwContext
);
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 上搜索过,但没有找到如何读取指针并将其关联到预期结构。
非常感谢您的帮助或提示:)
由于未指定体系结构,以下答案适用于 32 位进程,但解释了 64 位更改。
结构体_INTERNET_BUFFERSA
表示为LPINTERNET_BUFFERSA
,它是一个指针。 args[1]
持有指向 _INTERNET_BUFFERSA
结构的指针,当用 .readPointer
读取时,返回的是 dwStructSize
的值,即 40对于 32 位进程,52 对于 64 位进程。
每个成员的偏移量是:
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.pointerSize
是 4 对于 32 位进程和 8 对于 64 位进程,这允许解析偏移量正确。
我使用 Frida 挂钩了本机 Windows 应用程序的 HttpSendRequestExA 函数,但我无法读取结构 INTERNET_BUFFERSA 通过此函数的参数 lpBuffersIn 传递:
函数签名HttpSendRequestExA:
BOOLAPI HttpSendRequestExA(
HINTERNET hRequest,
LPINTERNET_BUFFERSA lpBuffersIn,
LPINTERNET_BUFFERSA lpBuffersOut,
DWORD dwFlags,
DWORD_PTR dwContext
);
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 上搜索过,但没有找到如何读取指针并将其关联到预期结构。
非常感谢您的帮助或提示:)
由于未指定体系结构,以下答案适用于 32 位进程,但解释了 64 位更改。
结构体_INTERNET_BUFFERSA
表示为LPINTERNET_BUFFERSA
,它是一个指针。 args[1]
持有指向 _INTERNET_BUFFERSA
结构的指针,当用 .readPointer
读取时,返回的是 dwStructSize
的值,即 40对于 32 位进程,52 对于 64 位进程。
每个成员的偏移量是:
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.pointerSize
是 4 对于 32 位进程和 8 对于 64 位进程,这允许解析偏移量正确。