Windows将TEB存储在FS(32位)或GS(64位)段寄存器中。在使用NtCurrentPeb()
的程序中,x86指令为mov rax, gs:60h
。 0x60
的值为offsetof(TEB, ProcessEnvironmentBlock)
。
要在程序中使用此文件,我必须同时包含Windows.h
和Winternl.h
头文件,该文件还有其他#define
一堆。正如问题所说,我想在没有这些头文件的情况下使用该函数,并直接访问段寄存器。我还用TEB和PEB结构制作了一个单独的头文件。那我该怎么办呢?我在考虑使用__asm
关键字和一个typedef NtCurrentTeb()
之类的东西。
答案 0 :(得分:1)
声明函数原型并链接到ntdll.dll。
答案 1 :(得分:1)
我真的不明白您为什么不完全回答自己的问题。这使更多的读者感到困惑,因为您没有为问题本身提供适当的答案。
您无需为此使用ASM,可以像这样使用intrinsic functions:
#ifdef _M_X64
auto pPEB = (PPEB)__readgsqword(0x60);
#elif _M_IX86
auto pPEB = (PPEB)__readfsdword(0x30);
#else
#error "PPEB Architecture Unsupported"
#endif
但是要回答实际问题,这是通过ASM进行的操作:
x64 ASM(TEB / PEB):
GetTEBAsm64 proc
push rbx
xor rbx,rbx
xor rax,rax
mov rbx, qword ptr gs:[00000030h]
mov rax, rbx
pop rbx
ret
GetTEBAsm64 endp
GetPEBAsm64 proc
push rbx
xor rbx,rbx
xor rax,rax
mov rbx, qword ptr gs:[00000060h]
mov rax, rbx
pop rbx
ret
GetPEBAsm64 endp
x86-PEB:
__asm
{
mov eax, dword ptr fs : [00000030h]
mov peb, eax
}
x86-TEB:
__asm
{
mov eax, dword ptr fs : [00000018h]
mov teb, eax
}
我强烈希望我的回答很清楚,希望将来有人能从中受益。
答案 2 :(得分:0)
要读取gs
或fs
段寄存器,我在Visual Studio中使用了此程序集。使用these settings enabled在Visual Studio中创建一个C / C ++空项目。 fs
或gs
段寄存器分别在32位和64位Windows中提供NT_TIB结构。在NT_TIB结构中,TEB在0x30
处偏移。因此,采用64位的程序集将是:mov rax, gs:[30h]
。
以下是获取可执行文件当前目录的示例源代码:
.code
ProcParam PROC
mov rax, gs:[30h] ; TEB from gs in 64 bit only
mov rax, [rax+60h] ; PEB
mov rax, [rax+20h] ; RTL_USER_PROCESS_PARAMETERS
ret
ProcParam ENDP
end
#include <stdio.h>
typedef struct _UNICODE_STRING {
unsigned short Length;
unsigned short MaximumLength;
wchar_t* Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _CURDIR {
UNICODE_STRING DosPath;
void* Handle;
} CURDIR, *PCURDIR;
/*Extracted from ntdll.pdb file*/
typedef struct _RTL_USER_PROCESS_PARAMETERS {
unsigned int MaximumLength;
unsigned int Length;
unsigned int Flags;
unsigned int DebugFlags;
void* ConsoleHandle;
unsigned int ConsoleFlags;
void* StandardInput;
void* StandardOutput;
void* StandardError;
CURDIR CurrentDirectory;
/*Many more*/
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
PRTL_USER_PROCESS_PARAMETERS ProcParam(void);
int main(void)
{
wprintf(L"%s\n", ProcParam()->CurrentDirectory.DosPath.Buffer);
}