type
_SECURITY_ATTRIBUTES =
record
nLength: DWord;
lpSecurityDescriptor: Pointer;
bInheritHandle: Boolean;
end;
SECURITY_ATTRIBUTES = _SECURITY_ATTRIBUTES;
PSECURITY_ATTRIBUTES = ^_SECURITY_ATTRIBUTES;
LPSECURITY_ATTRIBUTES = ^_SECURITY_ATTRIBUTES;
type
LPTHREAD_START_ROUTINE = Pointer;
type
_UNICODE_STRING =
record
Length: Word;
MaximumLength: Word;
Buffer: PWideChar;
end;
UNICODE_STRING = _UNICODE_STRING;
PUNICODE_STRING = ^_UNICODE_STRING;
type
_OBJECT_ATTRIBUTES =
record
Length: ULONG;
RootDirectory: Cardinal;
ObjectName: PUNICODE_STRING;
Attributes: ULONG;
SecurityDescriptor: Pointer;
SecurityQualityOfService: Pointer;
end;
OBJECT_ATTRIBUTES = _OBJECT_ATTRIBUTES;
POBJECT_ATTRIBUTES = ^_OBJECT_ATTRIBUTES;
type
_CLIENT_ID =
record
UniqueProcess: Cardinal;
UniqueThread: Cardinal;
end;
CLIENT_ID = _CLIENT_ID;
type
_INITIAL_TEB =
record
StackCommit: ULong;
StackReserve: ULong;
StackBase: Pointer;
StackLimit: Pointer;
StackAllocate: Pointer;
end;
INITIAL_TEB = _INITIAL_TEB;
type
PLIST_ENTRY = ^_LIST_ENTRY;
type
_LDR_MODULE =
record
InLoadOrderModuleList: LIST_ENTRY;
InOrderModuleList: LIST_ENTRY;
InInitializationOrderModuleList: LIST_ENTRY;
BaseAddress: Pointer;
EntryPoint: ULong;
SizeOfImage: ULong;
FullDllName: UNICODE_STRING;
BaseDllName: UNICODE_STRING;
Flags: ULong;
LoadCount: Word;
TlsIndex: Word;
SectionHandle: Cardinal;
CheckSum: ULong;
TimeDateStamp: ULong;
end;
PLDR_MODULE = ^_LDR_MODULE;
type
_DLLMAIN_FUNC =
function(hInst: Cardinal; ul_reason_for_call: ULong;
lpReserved: Pointer): BOOl;
stdcall;
PDLLMAIN_FUNC = ^_DLLMAIN_FUNC;
type
PRTL_CRITICAL_SECTION = ^RTL_CRITICAL_SECTION;
type
_STRING =
record
Length: Word;
MaximumLength: Word;
Buffer: PCHAR;
end;
type
// =================================================================
// PROCESS ENVIRONMENT BLOCK (PEB)
// =================================================================
// Verified in XP using WinDbg
_LDR_DATA_TABLE_ENTRY =
record // not packed!
case Integer
of
(* *)0: (
(*000*)InLoadOrderLinks: LIST_ENTRY
);
(* *)1: (
(*000*)InMemoryOrderLinks: LIST_ENTRY
);
(* *)2: (
(*000*)InInitializationOrderLinks: LIST_ENTRY;
(*008*)DllBase: Pointer;
(*00c*)EntryPoint: Pointer;
(*010*)SizeOfImage: ULONG;
(*014*)FullDllName: UNICODE_STRING;
(*01c*)BaseDllName: UNICODE_STRING;
(*024*)Flags: ULONG;
(*028*)LoadCount: Word;
(*02a*)TlsIndex: Word;
(*02c*)HashLinks: LIST_ENTRY;
(*034*)SectionPointer: Pointer;
(*038*)CheckSum: ULONG;
(*03C*)TimeDateStamp: ULONG;
(*040*)LoadedImports: Pointer;
(*044*)EntryPointActivationContext: Pointer;
// PACTIVATION_CONTEXT
(*048*)PatchInformation: Pointer;
)
end;
LDR_DATA_TABLE_ENTRY = _LDR_DATA_TABLE_ENTRY;
PLDR_DATA_TABLE_ENTRY = ^_LDR_DATA_TABLE_ENTRY;
PPLDR_DATA_TABLE_ENTRY = ^PLDR_DATA_TABLE_ENTRY;
TLdrDataTableEntry = _LDR_DATA_TABLE_ENTRY;
PLdrDataTableEntry = ^_LDR_DATA_TABLE_ENTRY;
// Verified in XP using WinDbg
_PEB_LDR_DATA =
record // not packed!
(*000*)Length: ULONG;
(*004*)Initialized: BOOLEAN;
(*008*)SsHandle: Pointer;
(*00c*)InLoadOrderModuleList: LIST_ENTRY;
(*014*)InMemoryOrderModuleList: LIST_ENTRY;
(*01c*)InInitializationOrderModuleList: LIST_ENTRY;
(*024*)EntryInProgress: Pointer;
end;
PEB_LDR_DATA = _PEB_LDR_DATA;
PPEB_LDR_DATA = ^_PEB_LDR_DATA;
PPPEB_LDR_DATA = ^PPEB_LDR_DATA;
TPebLdrData = _PEB_LDR_DATA;
PPebLdrData = ^_PEB_LDR_DATA;
// Verified in XP using WinDbg
_RTL_DRIVE_LETTER_CURDIR =
record // not packed!
(*000*)Flags: Word;
(*002*)Length: Word;
(*004*)TimeStamp: ULONG;
(*008*)DosPath: _STRING;
end;
RTL_DRIVE_LETTER_CURDIR = _RTL_DRIVE_LETTER_CURDIR;
PRTL_DRIVE_LETTER_CURDIR = ^_RTL_DRIVE_LETTER_CURDIR;
PPRTL_DRIVE_LETTER_CURDIR = ^PRTL_DRIVE_LETTER_CURDIR;
TRtlDriveLetterCurdir = _RTL_DRIVE_LETTER_CURDIR;
PRtlDriveLetterCurdir = ^_RTL_DRIVE_LETTER_CURDIR;
_CURDIR =
record // not packed!
(*000*)DosPath: UNICODE_STRING;
(*008*)Handle: Cardinal;
end;
CURDIR = _CURDIR;
PCURDIR = ^_CURDIR;
PPCURDIR = ^PCURDIR;
TCurdir = _CURDIR;
// PCurdir = ^_CURDIR; // <--- Pascal is case-insensitive
// Verified in XP using WinDbg
_RTL_USER_PROCESS_PARAMETERS =
record // not packed!
(*000*)MaximumLength: ULONG;
(*004*)Length: ULONG;
(*008*)Flags: ULONG;
// Bit 0: all pointers normalized
(*00c*)DebugFlags: ULONG;
(*010*)ConsoleHandle: Cardinal;
(*014*)ConsoleFlags: ULONG;
(*018*)StandardInput: Cardinal;
(*01c*)StandardOutput: Cardinal;
(*020*)StandardError: Cardinal;
(*024*)CurrentDirectory: CURDIR;
(*030*)DllPath: UNICODE_STRING;
(*038*)ImagePathName: UNICODE_STRING;
(*040*)CommandLine: UNICODE_STRING;
(*048*)Environment: Pointer;
(*04c*)StartingX: ULONG;
(*050*)StartingY: ULONG;
(*054*)CountX: ULONG;
(*058*)CountY: ULONG;
(*05c*)CountCharsX: ULONG;
(*060*)CountCharsY: ULONG;
(*064*)FillAttribute: ULONG;
(*068*)WindowFlags: ULONG;
(*06c*)ShowWindowFlags: ULONG;
(*070*)WindowTitle: UNICODE_STRING;
(*078*)DesktopInfo: UNICODE_STRING;
(*080*)ShellInfo: UNICODE_STRING;
(*088*)RuntimeData: UNICODE_STRING;
(*090*)CurrentDirectories:
array[0..31]
of RTL_DRIVE_LETTER_CURDIR;
end;
RTL_USER_PROCESS_PARAMETERS = _RTL_USER_PROCESS_PARAMETERS;
PRTL_USER_PROCESS_PARAMETERS = ^_RTL_USER_PROCESS_PARAMETERS;
PPRTL_USER_PROCESS_PARAMETERS = ^PRTL_USER_PROCESS_PARAMETERS;
TRtlUserProcessParameters = _RTL_USER_PROCESS_PARAMETERS;
PRtlUserProcessParameters = ^_RTL_USER_PROCESS_PARAMETERS;
TProcessParameters = _RTL_USER_PROCESS_PARAMETERS;
PProcessParameters = ^_RTL_USER_PROCESS_PARAMETERS;
_SYSTEM_STRINGS =
record // not packed!
(*000*)SystemRoot: UNICODE_STRING;
// %SystemRoot%
(*008*)System32Root: UNICODE_STRING;
// %SystemRoot%\System32
(*010*)BaseNamedObjects: UNICODE_STRING;
// \BaseNamedObjects
end;
SYSTEM_STRINGS = _SYSTEM_STRINGS;
PSYSTEM_STRINGS = ^_SYSTEM_STRINGS;
PPSYSTEM_STRINGS = ^PSYSTEM_STRINGS;
TSystemStrings = _SYSTEM_STRINGS;
PSystemStrings = ^_SYSTEM_STRINGS;
// Verified in XP using WinDbg
_TEXT_INFO =
record // not packed!
(*000*)Reserved: Pointer;
(*004*)SystemStrings: PSYSTEM_STRINGS;
end;
TEXT_INFO = _TEXT_INFO;
PTEXT_INFO = ^_TEXT_INFO;
PPTEXT_INFO = ^PTEXT_INFO;
TTextInfo = _TEXT_INFO;
PTextInfo = ^_TEXT_INFO;
// Verified in XP using WinDbg
PPEB_FREE_BLOCK = ^_PEB_FREE_BLOCK;
_PEB_FREE_BLOCK =
record // not packed!
(*000*)Next: PPEB_FREE_BLOCK;
(*004*)Size: ULONG;
end;
PEB_FREE_BLOCK = _PEB_FREE_BLOCK;
PPPEB_FREE_BLOCK = ^PPEB_FREE_BLOCK;
TPebFreeBlock = _PEB_FREE_BLOCK;
PPebFreeBlock = ^_PEB_FREE_BLOCK;
// Verified in W2K, WXP and W2K3 using WinDbg
_PEB_W2K =
packed record // packed!
(*000*)InheritedAddressSpace: BOOLEAN;
(*001*)ReadImageFileExecOptions: BOOLEAN;
(*002*)BeingDebugged: BOOLEAN;
(*003*)SpareBool: BOOLEAN;
(*004*)Mutant: Pointer;
(*008*)ImageBaseAddress: Pointer;
(*00c*)Ldr: PPEB_LDR_DATA;
(*010*)ProcessParameters: PRTL_USER_PROCESS_PARAMETERS;
(*014*)SubSystemData: Pointer;
(*018*)ProcessHeap: Pointer;
(*01c*)FastPebLock: PRTL_CRITICAL_SECTION;
(*020*)FastPebLockRoutine: Pointer;
// RtlEnterCriticalSection
(*024*)FastPebUnlockRoutine: Pointer;
// RtlLeaveCriticalSection
(*028*)EnvironmentUpdateCount: ULONG;
(*02c*)KernelCallbackTable: Pointer;
// List of callback functions
(*030*)SystemReserved:
array[0..0]
of ULONG;
(*034*)d034: ULONG;
(*038*)FreeList: PPEB_FREE_BLOCK;
(*03c*)TlsExpansionCounter: ULONG;
(*040*)TlsBitmap: Pointer;
// ntdll!TlsBitMap of type PRTL_BITMAP
(*044*)TlsBitmapBits:
array[0..1]
of ULONG;
// 64 bits
(*04c*)ReadOnlySharedMemoryBase: Pointer;
(*050*)ReadOnlySharedMemoryHeap: Pointer;
(*054*)ReadOnlyStaticServerData: PTEXT_INFO;
(*058*)AnsiCodePageData: Pointer;
(*05c*)OemCodePageData: Pointer;
(*060*)UnicodeCaseTableData: Pointer;
(*064*)NumberOfProcessors: ULONG;
(*068*)NtGlobalFlag: ULONG;
(*06C*)Unknown01: ULONG;
// Padding or something
(*070*)CriticalSectionTimeout: LARGE_INTEGER;
(*078*)HeapSegmentReserve: ULONG;
(*07c*)HeapSegmentCommit: ULONG;
(*080*)HeapDeCommitTotalFreeThreshold: ULONG;
(*084*)HeapDeCommitFreeBlockThreshold: ULONG;
(*088*)NumberOfHeaps: ULONG;
(*08c*)MaximumNumberOfHeaps: ULONG;
(*090*)ProcessHeaps: Pointer;
(*094*)GdiSharedHandleTable: Pointer;
(*098*)ProcessStarterHelper: Pointer;
(*09c*)GdiDCAttributeList: ULONG;
(*0a0*)LoaderLock: PRTL_CRITICAL_SECTION;
(*0a4*)OSMajorVersion: ULONG;
(*0a8*)OSMinorVersion: ULONG;
(*0ac*)OSBuildNumber: Word;
(*0ae*)OSCSDVersion: Word;
(*0b0*)OSPlatformId: ULONG;
(*0b4*)ImageSubsystem: ULONG;
(*0b8*)ImageSubsystemMajorVersion: ULONG;
(*0bc*)ImageSubsystemMinorVersion: ULONG;
(*0c0*)ImageProcessAffinityMask: ULONG;
(*0c4*)GdiHandleBuffer:
array[0..33]
of Cardinal;
(*14c*)PostProcessInitRoutine: Pointer;
(*150*)TlsExpansionBitmap: Pointer;
(*154*)TlsExpansionBitmapBits:
array[0..31]
of ULONG;
(*1d4*)SessionId: ULONG;
// Windows 2000
(*1d8*)AppCompatInfo: Pointer;
(*1dc*)CSDVersion: UNICODE_STRING;
end;
// Verified in W2K, WXP and W2K3 using WinDbg
_PEB_WXP =
packed record // packed!
(*000*)InheritedAddressSpace: BOOLEAN;
(*001*)ReadImageFileExecOptions: BOOLEAN;
(*002*)BeingDebugged: BOOLEAN;
(*003*)SpareBool: BOOLEAN;
(*004*)Mutant: Pointer;
(*008*)ImageBaseAddress: Pointer;
(*00c*)Ldr: PPEB_LDR_DATA;
(*010*)ProcessParameters: PRTL_USER_PROCESS_PARAMETERS;
(*014*)SubSystemData: Pointer;
(*018*)ProcessHeap: Pointer;
(*01c*)FastPebLock: PRTL_CRITICAL_SECTION;
(*020*)FastPebLockRoutine: Pointer;
// RtlEnterCriticalSection
(*024*)FastPebUnlockRoutine: Pointer;
// RtlLeaveCriticalSection
(*028*)EnvironmentUpdateCount: ULONG;
(*02c*)KernelCallbackTable: Pointer;
// List of callback functions
(*030*)SystemReserved:
array[0..0]
of ULONG;
(*034*)AtlThunkSListPtr32: Pointer;
// (Windows XP)
(*038*)FreeList: PPEB_FREE_BLOCK;
(*03c*)TlsExpansionCounter: ULONG;
(*040*)TlsBitmap: Pointer;
// ntdll!TlsBitMap of type PRTL_BITMAP
(*044*)TlsBitmapBits:
array[0..1]
of ULONG;
// 64 bits
(*04c*)ReadOnlySharedMemoryBase: Pointer;
(*050*)ReadOnlySharedMemoryHeap: Pointer;
(*054*)ReadOnlyStaticServerData: PTEXT_INFO;
(*058*)AnsiCodePageData: Pointer;
(*05c*)OemCodePageData: Pointer;
(*060*)UnicodeCaseTableData: Pointer;
(*064*)NumberOfProcessors: ULONG;
(*068*)NtGlobalFlag: ULONG;
(*06C*)Unknown01: ULONG;
// Padding or something
(*070*)CriticalSectionTimeout: LARGE_INTEGER;
(*078*)HeapSegmentReserve: ULONG;
(*07c*)HeapSegmentCommit: ULONG;
(*080*)HeapDeCommitTotalFreeThreshold: ULONG;
(*084*)HeapDeCommitFreeBlockThreshold: ULONG;
(*088*)NumberOfHeaps: ULONG;
(*08c*)MaximumNumberOfHeaps: ULONG;
(*090*)ProcessHeaps: Pointer;
(*094*)GdiSharedHandleTable: Pointer;
(*098*)ProcessStarterHelper: Pointer;
(*09c*)GdiDCAttributeList: ULONG;
(*0a0*)LoaderLock: PRTL_CRITICAL_SECTION;
(*0a4*)OSMajorVersion: ULONG;
(*0a8*)OSMinorVersion: ULONG;
(*0ac*)OSBuildNumber: Word;
(*0ae*)OSCSDVersion: Word;
(*0b0*)OSPlatformId: ULONG;
(*0b4*)ImageSubsystem: ULONG;
(*0b8*)ImageSubsystemMajorVersion: ULONG;
(*0bc*)ImageSubsystemMinorVersion: ULONG;
(*0c0*)ImageProcessAffinityMask: ULONG;
(*0c4*)GdiHandleBuffer:
array[0..33]
of Cardinal;
(*14c*)PostProcessInitRoutine: Pointer;
(*150*)TlsExpansionBitmap: Pointer;
(*154*)TlsExpansionBitmapBits:
array[0..31]
of ULONG;
(*1d4*)SessionId: ULONG;
// Windows XP
(*1d8*)AppCompatFlags: ULARGE_INTEGER;
(*1e0*)AppCompatFlagsUser: ULARGE_INTEGER;
(*1e8*)pShimData: Pointer;
(*1ec*)AppCompatInfo: Pointer;
(*1f0*)CSDVersion: UNICODE_STRING;
(*1f8*)ActivationContextData: Pointer;
// PACTIVATION_CONTEXT_DATA
(*1fc*)ProcessAssemblyStorageMap: Pointer;
// PASSEMBLY_STORAGE_MAP
(*200*)SystemDefaultActivationContextData: Pointer;
// PACTIVATION_CONTEXT_DATA
(*204*)SystemAssemblyStorageMap: Pointer;
// PASSEMBLY_STORAGE_MAP
(*208*)MinimumStackCommit: ULONG;
end;
// Verified in W2K, WXP and W2K3 using WinDbg
_PEB_2K3 =
packed record // packed!
(*000*)InheritedAddressSpace: BOOLEAN;
(*001*)ReadImageFileExecOptions: BOOLEAN;
(*002*)BeingDebugged: BOOLEAN;
(*003*)SpareBool: BOOLEAN;
(*004*)Mutant: Pointer;
(*008*)ImageBaseAddress: Pointer;
(*00c*)Ldr: PPEB_LDR_DATA;
(*010*)ProcessParameters: PRTL_USER_PROCESS_PARAMETERS;
(*014*)SubSystemData: Pointer;
(*018*)ProcessHeap: Pointer;
(*01c*)FastPebLock: PRTL_CRITICAL_SECTION;
(*020*)FastPebLockRoutine: Pointer;
// RtlEnterCriticalSection
(*024*)FastPebUnlockRoutine: Pointer;
// RtlLeaveCriticalSection
(*028*)EnvironmentUpdateCount: ULONG;
(*02c*)KernelCallbackTable: Pointer;
// List of callback functions
(*030*)SystemReserved:
array[0..0]
of ULONG;
(*034*)ExecuteOptions: ULONG;
// 2 Bits used (Windows 2003)
(*038*)FreeList: PPEB_FREE_BLOCK;
(*03c*)TlsExpansionCounter: ULONG;
(*040*)TlsBitmap: Pointer;
// ntdll!TlsBitMap of type PRTL_BITMAP
(*044*)TlsBitmapBits:
array[0..1]
of ULONG;
// 64 bits
(*04c*)ReadOnlySharedMemoryBase: Pointer;
(*050*)ReadOnlySharedMemoryHeap: Pointer;
(*054*)ReadOnlyStaticServerData: PTEXT_INFO;
(*058*)AnsiCodePageData: Pointer;
(*05c*)OemCodePageData: Pointer;
(*060*)UnicodeCaseTableData: Pointer;
(*064*)NumberOfProcessors: ULONG;
(*068*)NtGlobalFlag: ULONG;
(*06C*)Unknown01: ULONG;
// Padding or something
(*070*)CriticalSectionTimeout: LARGE_INTEGER;
(*078*)HeapSegmentReserve: ULONG;
(*07c*)HeapSegmentCommit: ULONG;
(*080*)HeapDeCommitTotalFreeThreshold: ULONG;
(*084*)HeapDeCommitFreeBlockThreshold: ULONG;
(*088*)NumberOfHeaps: ULONG;
(*08c*)MaximumNumberOfHeaps: ULONG;
(*090*)ProcessHeaps: Pointer;
(*094*)GdiSharedHandleTable: Pointer;
(*098*)ProcessStarterHelper: Pointer;
(*09c*)GdiDCAttributeList: ULONG;
(*0a0*)LoaderLock: PRTL_CRITICAL_SECTION;
(*0a4*)OSMajorVersion: ULONG;
(*0a8*)OSMinorVersion: ULONG;
(*0ac*)OSBuildNumber: Word;
(*0ae*)OSCSDVersion: Word;
(*0b0*)OSPlatformId: ULONG;
(*0b4*)ImageSubsystem: ULONG;
(*0b8*)ImageSubsystemMajorVersion: ULONG;
(*0bc*)ImageSubsystemMinorVersion: ULONG;
(*0c0*)ImageProcessAffinityMask: ULONG;
(*0c4*)GdiHandleBuffer:
array[0..33]
of Cardinal;
(*14c*)PostProcessInitRoutine: Pointer;
(*150*)TlsExpansionBitmap: Pointer;
(*154*)TlsExpansionBitmapBits:
array[0..31]
of ULONG;
(*1d4*)SessionId: ULONG;
// Windows XP
(*1d8*)AppCompatFlags: ULARGE_INTEGER;
(*1e0*)AppCompatFlagsUser: ULARGE_INTEGER;
(*1e8*)pShimData: Pointer;
(*1ec*)AppCompatInfo: Pointer;
(*1f0*)CSDVersion: UNICODE_STRING;
(*1f8*)ActivationContextData: Pointer;
// PACTIVATION_CONTEXT_DATA
(*1fc*)ProcessAssemblyStorageMap: Pointer;
// PASSEMBLY_STORAGE_MAP
(*200*)SystemDefaultActivationContextData: Pointer;
// PACTIVATION_CONTEXT_DATA
(*204*)SystemAssemblyStorageMap: Pointer;
// PASSEMBLY_STORAGE_MAP
(*208*)MinimumStackCommit: ULONG;
// New members in Windows 2003
(*20c*)FlsCallback: Pointer;
(*210*)FlsListHead: LIST_ENTRY;
(*218*)FlsBitmap: Pointer;
(*21c*)FlsBitmapBits:
array[0..3]
of ULONG;
(*22c*)FlsHighIndex: ULONG;
end;
(*{$IFDEF WINNT4}
_PEB = _PEB_W2K; // Exact layout for NT4 unknown
{$ENDIF}
{$IFDEF WIN2000}
_PEB = _PEB_W2K;
{$ENDIF}
{$IFDEF WINXP} *)
_PEB = _PEB_WXP;
(*{$ENDIF}
{$IFDEF WIN2003}
_PEB = _PEB_2K3;
{$ENDIF} *)
PEB = _PEB;
PPEB = ^_PEB;
PPPEB = ^PPEB;
function CreateRemoteThread(hProcess: Cardinal;
lpThreadAttributes: LPSECURITY_ATTRIBUTES; dwStackSize: DWord;
lpStartAddress: LPTHREAD_START_ROUTINE; lpParameter: Pointer;
dwCreationFlags: DWord;
var lpThreadId: LPDWord): Cardinal;
implementation
function NT_SUCCESS(Status: Longint): Boolean;
begin
Result := Status >= 0;
end;
function NtCurrentPEB: PPEB;
asm
mov EAX, FS:[018h]
mov EAX, [EAX+030h]
end;
function NtAllocateVirtualMemory(
ProcessHandle: Cardinal;
BaseAddress: Pointer;
ZeroBits: ULong;
AllocationSize: PULong;
AllocationType: ULong;
Protect: ULong
): Longint;
stdcall;
external '
ntdll.dll';
function NtFreeVirtualMemory(
ProcessHandle: Cardinal;
BaseAddress: Pointer;
FreeSize: PULong;
FreeType: ULong
): Longint;
stdcall;
external '
ntdll.dll';
function NtProtectVirtualMemory(
ProcessHandle: Cardinal;
BaseAddress: Pointer;
ProtectSize: PULong;
NewProtect: ULong;
OldProtect: PULong
): Longint;
stdcall;
external '
ntdll.dll';
procedure RtlEnterCriticalSection(
lpCriticalSection : PRTL_CRITICAL_SECTION
);
stdcall;
external '
ntdll.dll';
function CreateRemoteThread(hProcess: Cardinal;
lpThreadAttributes: LPSECURITY_ATTRIBUTES; dwStackSize: DWord;
lpStartAddress: LPTHREAD_START_ROUTINE; lpParameter: Pointer;
dwCreationFlags: DWord;
var lpThreadId: LPDWord): Cardinal;
procedure ThreadAttachDlls;
var
ModuleListHead: PLISTENTRY;
Entry: PLISTENTRY;
Module: PLDR_MODULE;
EntryPointer: PDLLMAIN_FUNC;
begin
RtlEnterCriticalSection(NtCurrentPeb.LoaderLock);
ModuleListHead := @NtCurrentPeb.Ldr.InInitializationOrderModuleList;
Entry := ModuleListHead.Blink;
while (Entry <> ModuleListHead)
do
begin
Module := CONTAINING_RECORD(Entry, LDR_MODULE, InInitializationOrderModuleList);
if (Module.EntryPoint <> 0)
then
begin
Entrypoint := PDLLMAIN_FUNC(Module.EntryPoint);
Entrypoint(Module.BaseAddress, DLL_THREAD_ATTACH,
nil);
end;
Entry := Entry.Blink;
end;
RtlLeaveCriticalSection(NtCurrentPeb.LoaderLock);
end;
procedure ThreadStartup(lpStartAddress: LPTHREAD_START_ROUTINE;
lpParameter: Pointer);
stdcall;
var
uExitCode: UInt;
begin
ThreadAttachDlls;
uExitCode := (lpStartAddress)(lpParameter);
ExitThread(uExitCode);
end;
var
ThreadHandle: Cardinal;
ObjectAttributes: OBJECT_ATTRIBUTES;
ClientId: CLIENT_ID;
ThreadContext: CONTEXT;
InitialTeb: INITIAL_TEB;
CreateSuspended: Boolean;
BaseAddress: Pointer;
OldPageProtection: ULong;
Status: Cardinal;
begin
ObjectAttributes.Length := sizeof(OBJECT_ATTRIBUTES);
ObjectAttributes.RootDirectory := 0;
ObjectAttributes.ObjectName :=
nil;
ObjectAttributes.Attributes := 0;
if (Assigned(lpThreadAttributes))
then
begin
if (lpThreadAttributes.bInheritHandle)
then
begin
ObjectAttributes.Attributes := $00000002;
end;
ObjectAttributes.SecurityDescriptor :=
lpThreadAttributes.lpSecurityDescriptor;
end;
ObjectAttributes.SecurityQualityOfService :=
nil;
{ 1 } if ((dwCreationFlags
or CREATE_SUSPENDED) = CREATE_SUSPENDED)
then
begin
CreateSuspended := true;
end
else
begin
CreateSuspended := false;
end;
{InitialTeb.StackReserve = 0x100000; /* 1MByte */
/* FIXME: use correct commit size */
#if 0
InitialTeb.StackCommit = (dwStackSize == 0) ? PAGESIZE : dwStackSize;
#endif
InitialTeb.StackCommit = InitialTeb.StackReserve - PAGESIZE;
/* size of guard page */
InitialTeb.StackCommit += PAGESIZE;}
InitialTeb.StackAllocate :=
nil;
Status := NtAllocateVirtualMemory(hProcess, @InitialTeb.StackAllocate, 0,
@InitialTeb.StackReserve, MEM_RESERVE, PAGE_READWRITE);
if (
not NT_SUCCESS(Status))
then
begin
Result := 0;
Exit;
end;
{InitialTeb.StackBase = (PVOID)((ULONG)InitialTeb.StackAllocate + InitialTeb.StackReserve);
InitialTeb.StackLimit = (PVOID)((ULONG)InitialTeb.StackBase - InitialTeb.StackCommit);}
Status := NtAllocateVirtualMemory(hProcess, @InitialTeb.StackLimit, 0,
@InitialTeb.StackCommit, MEM_COMMIT, PAGE_READWRITE);
if (
not NT_SUCCESS(Status))
then
begin
NtFreeVirtualMemory(hProcess, InitialTeb.StackAllocate,
@InitialTeb.StackReserve, MEM_RELEASE);
Result := 0;
Exit;
end;
Status := NtProtectVirtualMemory(hProcess, InitialTeb.StackLimit,
PAGESIZE, PAGE_GUARD
or PAGE_READWRITE, @OldPageProtection);
if (
not NT_SUCCESS(Status))
then
begin
NtFreeVirtualMemory(hProcess, InitialTeb.StackAllocate,
@InitialTeb.StackReserve, MEM_RELEASE);
Result := 0;
Exit;
end;
memset(@ThreadContext, 0, sizeof(CONTEXT));
ThreadContext.Eip := Longint(ThreadStartup);
ThreadContext.SegGs := USER_DS;
ThreadContext.SegFs := TEB_SELECTOR;
ThreadContext.SegEs := USER_DS;
ThreadContext.SegDs := USER_DS;
ThreadContext.SegCs := USER_CS;
ThreadContext.SegSs := USER_DS;
{ThreadContext.Esp = (ULONG)InitialTeb.StackBase - 12;
ThreadContext.EFlags = (1<<1) + (1<<9);
*((PULONG)((ULONG)InitialTeb.StackBase - 4)) = (ULONG)lpParameter;
*((PULONG)((ULONG)InitialTeb.StackBase - 8)) = (ULONG)lpStartAddress;
*((PULONG)((ULONG)InitialTeb.StackBase - 12)) = 0xdeadbeef;}
Status := NtCreateThread(@ThreadHandle, THREAD_ALL_ACCESS,
@ObjectAttributes, hProcess, @ClientId, @ThreadContext,
@InitialTeb, CreateSuspended);
end;
(*
Status = NtCreateThread(&ThreadHandle,
THREAD_ALL_ACCESS,
&ObjectAttributes,
hProcess,
&ClientId,
&ThreadContext,
&InitialTeb,
CreateSuspended);
if (!NT_SUCCESS(Status))
{
NtFreeVirtualMemory(hProcess,
InitialTeb.StackAllocate,
&InitialTeb.StackReserve,
MEM_RELEASE);
DPRINT("NtCreateThread() failed!\n");
SetLastErrorByStatus(Status);
return(NULL);
}
if (lpThreadId != NULL)
memcpy(lpThreadId, &ClientId.UniqueThread,sizeof(ULONG));
return(ThreadHandle);
}
*)