blob: 00e884a59a333bf51f194b7e33aa9b2fa4097d6a [file] [log] [blame]
/* **********************************************************
* Copyright (c) 2011-2014 Google, Inc. All rights reserved.
* Copyright (c) 2003-2010 VMware, Inc. All rights reserved.
* **********************************************************/
/*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of VMware, Inc. nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
/* Copyright (c) 2003-2007 Determina Corp. */
/*
* ntdll.h
* Routines for calling Windows system calls via the ntdll.dll wrappers.
* We return a bool instead of NTSTATUS, for most cases.
*
* New routines however should return the raw NTSTATUS and leave to
* the callers to report or act on some specific failure. Should use
* NT_SUCCESS to verify success, luckily here 0 indicates success, so
* misuse as a bool will be caught easily.
*/
#ifndef _NTDLL_H_
#define _NTDLL_H_ 1
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stddef.h> /* for offsetof */
#include "ntdll_types.h"
#include "globals_shared.h" /* for reg_t */
#pragma warning(disable : 4214) /* allow short-sized bitfields for TEB */
/* Current method is to statically link with ntdll.lib obtained from the DDK */
/* We cannot call get_module_handle at arbitrary points.
* Some syscalls are at certain points in win32 API internal state
* such that doing so causes problems.
*/
/* We used to dynamically get the proc address but that led to some untimely
* loader lock acquisitions by kernel32.GetProcAddress (Bug 411).
* This should serve as an example why using kernel32 functions is not safe.
*/
/* A simple wrapper to define ntdll entry points used inside our functions.
Since there is no official header file exporting these,
we encapsulate signatures obtained from other sources.
*/
#define GET_NTDLL(NtFunction, signature) \
NTSYSAPI NTSTATUS NTAPI NtFunction signature
/***************************************************************************
* Structs and defines.
* Mostly from either Windows NT/2000 Native API Reference's ntdll.h
* or from the ddk's header files.
* These were generated from such headers to make
* information necessary for userspace to call into the Windows
* kernel available to DynamoRIO. They include only constants,
* structures, and macros generated from the original headers, and
* thus, contain no copyrightable information.
*/
#define NT_CURRENT_PROCESS ( (HANDLE) PTR_UINT_MINUS_1 )
#define NT_CURRENT_THREAD ( (HANDLE) (ptr_uint_t)-2 )
/* This macro is defined in wincon.h, but requires _WIN32_WINNT be XP+. _WIN32_WINNT is
* defined in globals.h to _WIN32_WINNT_NT4, thus the need for this re-definition.
*/
#ifndef ATTACH_PARENT_PROCESS
# define ATTACH_PARENT_PROCESS ((DWORD)-1)
#endif
#ifndef X64
typedef struct ALIGN_VAR(8) _UNICODE_STRING_64 {
/* Length field is size in bytes not counting final 0 */
USHORT Length;
USHORT MaximumLength;
int padding;
PWSTR Buffer;
uint Buffer_hi;
} UNICODE_STRING_64;
#endif
/* from DDK2003SP1/3790.1830/inc/ddk/wnet/ntddk.h */
#define DIRECTORY_QUERY (0x0001)
#define DIRECTORY_TRAVERSE (0x0002)
#define DIRECTORY_CREATE_OBJECT (0x0004)
#define DIRECTORY_CREATE_SUBDIRECTORY (0x0008)
#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0xF)
/* module information filled by the loader */
typedef struct _PEB_LDR_DATA {
ULONG Length;
BOOLEAN Initialized;
PVOID SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;
typedef struct _RTL_BALANCED_NODE {
union {
struct _RTL_BALANCED_NODE *Children[2];
struct {
struct _RTL_BALANCED_NODE *Left;
struct _RTL_BALANCED_NODE *Right;
};
};
union {
UCHAR Red : 1;
UCHAR Balance : 2;
ULONG_PTR ParentValue;
};
} RTL_BALANCED_NODE, *PRTL_BALANCED_NODE;
/* The ParentValue field should have the bottom 2 bits masked off */
#define RTL_BALANCED_NODE_PARENT_VALUE(rbn) \
((PRTL_BALANCED_NODE)((rbn)->ParentValue & (~3)))
typedef struct _RTL_RB_TREE {
PRTL_BALANCED_NODE Root;
PRTL_BALANCED_NODE Min;
} RTL_RB_TREE, *PRTL_RB_TREE;
/* Used for Windows 8 ntdll!_LDR_DATA_TABLE_ENTRY.LoadReason */
typedef enum _LDR_DLL_LOAD_REASON {
LoadReasonStaticDependency = 0,
LoadReasonStaticForwarderDependency = 1,
LoadReasonDynamicForwarderDependency = 2,
LoadReasonDelayloadDependency = 3,
LoadReasonDynamicLoad = 4,
LoadReasonAsImageLoad = 5,
LoadReasonAsDataLoad = 6,
LoadReasonUnknown = -1,
} LDR_DLL_LOAD_REASON;
/* Note that these lists are walked through corresponding LIST_ENTRY pointers
* i.e., for InInit*Order*, Flink points 16 bytes into the LDR_MODULE structure.
* The MS symbols refer to this data struct as ntdll!_LDR_DATA_TABLE_ENTRY
*/
typedef struct _LDR_MODULE { /* offset: 32bit / 64bit */
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
PVOID BaseAddress;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags; /* 0x034 / 0x068 */
SHORT LoadCount; /* 0x038 / 0x06c */
SHORT TlsIndex; /* 0x03a / 0x06e */
union {
struct {
HANDLE SectionHandle; /* 0x03c / 0x070 */
ULONG CheckSum; /* 0x040 / 0x078 */
};
LIST_ENTRY HashLinks; /* 0x03c / 0x070 */
};
ULONG TimeDateStamp; /* 0x044 / 0x080 */
PVOID/*ACTIVATION_CONTEXT*/ EntryPointActivationContext; /* 0x048 / 0x088 */
PVOID PatchInformation; /* 0x04c / 0x090 */
/* ----------------------------------------------------------------------
* Below here is Win8-only. Win7 has some different, incompatible
* fields. We only need to access things below here on Win8.
*/
PVOID DdagNode; /* 0x050 / 0x098 */
LIST_ENTRY NodeModuleLink; /* 0x054 / 0x0a0 */
PVOID SnapContext; /* 0x05c / 0x0b0 */
PVOID ParentDllBase; /* 0x060 / 0x0b8 */
PVOID SwitchBackContext; /* 0x064 / 0x0c0 */
RTL_BALANCED_NODE BaseAddressIndexNode; /* 0x068 / 0x0c8 */
RTL_BALANCED_NODE MappingInfoIndexNode; /* 0x074 / 0x0e0 */
ULONG_PTR OriginalBase; /* 0x080 / 0x0f8 */
LARGE_INTEGER LoadTime; /* 0x088 / 0x100 */
ULONG BaseNameHashValue; /* 0x090 / 0x108 */
LDR_DLL_LOAD_REASON LoadReason; /* 0x094 / 0x10c */
} LDR_MODULE, *PLDR_MODULE;
/* This macro is defined so that 32-bit dlls can be handled in 64-bit DR.
* Not all IMAGE_OPTIONAL_HEADER fields are affected, only ImageBase,
* LoaderFlags, NumberOfRvaAndSizes, SizeOf{Stack,Heap}{Commit,Reserve},
* and DataDirectory, of which we use only ImageBase and DataDirectory.
* All other fields happen to have the same offsets and sizes in both
* IMAGE_OPTIONAL_HEADER32 and IMAGE_OPTIONAL_HEADER64.
*/
#ifdef X64
/* Don't need to use module_is_32bit() here as that is heavyweight. Also, as
* it is used directly in process_image() just when the module processing
* begins, we don't have to do all the checks here.
*/
# define OPT_HDR(nt_hdr_p, field) OPT_HDR_BASE(nt_hdr_p, field, )
# define OPT_HDR_P(nt_hdr_p, field) OPT_HDR_BASE(nt_hdr_p, field, (app_pc)&)
# define OPT_HDR_BASE(nt_hdr_p, field, amp) \
((nt_hdr_p)->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC ? \
amp(((IMAGE_OPTIONAL_HEADER32 *)&((nt_hdr_p)->OptionalHeader))->field) : \
amp(((IMAGE_OPTIONAL_HEADER64 *)&((nt_hdr_p)->OptionalHeader))->field))
#else
# define OPT_HDR(nt_hdr_p, field) ((nt_hdr_p)->OptionalHeader.field)
# define OPT_HDR_P(nt_hdr_p, field) (&((nt_hdr_p)->OptionalHeader.field))
#endif
/* For use by routines that walk the module lists. */
enum {MAX_MODULE_LIST_INFINITE_LOOP_THRESHOLD = 2048};
/* Originally from winternl.h from wine (thus not official),
* these defines are (some of the) regular LDR_MODULE.Flags values.
* Windows 8 has these as named bitfields so we now have official
* confirmation.
*/
#define LDR_PROCESS_STATIC_IMPORT 0x00000020
#define LDR_IMAGE_IS_DLL 0x00000004
#define LDR_LOAD_IN_PROGRESS 0x00001000
#define LDR_UNLOAD_IN_PROGRESS 0x00002000
#define LDR_NO_DLL_CALLS 0x00040000
#define LDR_PROCESS_ATTACHED 0x00080000
#define LDR_MODULE_REBASED 0x00200000
typedef struct _PEBLOCKROUTINE *PPEBLOCKROUTINE;
typedef struct _PEB_FREE_BLOCK *PPEB_FREE_BLOCK;
typedef PVOID *PPVOID;
typedef struct _RTL_BITMAP {
ULONG SizeOfBitMap; /* Number of bits in the bitmap */
LPBYTE BitMapBuffer; /* Bitmap data, assumed sized to a DWORD boundary */
} RTL_BITMAP, *PRTL_BITMAP;
typedef const RTL_BITMAP *PCRTL_BITMAP;
/* The layout here is from ntdll pdb on x64 xpsp2, though we
* changed some PVOID types to more specific types.
* Later updated to win8 pdb info.
*/
typedef struct _PEB { /* offset: 32bit / 64bit */
BOOLEAN InheritedAddressSpace; /* 0x000 / 0x000 */
BOOLEAN ReadImageFileExecOptions; /* 0x001 / 0x001 */
BOOLEAN BeingDebugged; /* 0x002 / 0x002 */
#if 0
/* x64 xpsp2 lists this as a bitfield but compiler only accepts int bitfields: */
BOOLEAN ImageUsesLargePages:1; /* 0x003 / 0x003 */
BOOLEAN SpareBits:7; /* 0x003 / 0x003 */
#else
BOOLEAN ImageUsesLargePages; /* 0x003 / 0x003 */
#endif
HANDLE Mutant; /* 0x004 / 0x008 */
PVOID ImageBaseAddress; /* 0x008 / 0x010 */
PPEB_LDR_DATA LoaderData; /* 0x00c / 0x018 */
PRTL_USER_PROCESS_PARAMETERS ProcessParameters; /* 0x010 / 0x020 */
PVOID SubSystemData; /* 0x014 / 0x028 */
PVOID ProcessHeap; /* 0x018 / 0x030 */
PRTL_CRITICAL_SECTION FastPebLock; /* 0x01c / 0x038 */
#if 0
/* x64 xpsp2 lists these fields as: */
PVOID AtlThunkSListPtr; /* 0x020 / 0x040 */
PVOID SparePtr2; /* 0x024 / 0x048 */
#else
/* xpsp2 and earlier */
PPEBLOCKROUTINE FastPebLockRoutine; /* 0x020 / 0x040 */
PPEBLOCKROUTINE FastPebUnlockRoutine; /* 0x024 / 0x048 */
#endif
DWORD EnvironmentUpdateCount; /* 0x028 / 0x050 */
PVOID KernelCallbackTable; /* 0x02c / 0x058 */
#if 0
/* x64 xpsp2 lists these fields as: */
DWORD SystemReserved[1]; /* 0x030 / 0x060 */
DWORD SpareUlong; /* 0x034 / 0x064 */
#else
/* xpsp2 and earlier */
DWORD EvengLogSection; /* 0x030 / 0x060 */
DWORD EventLog; /* 0x034 / 0x064 */
#endif
PPEB_FREE_BLOCK FreeList; /* 0x038 / 0x068 */
DWORD TlsExpansionCounter; /* 0x03c / 0x070 */
PRTL_BITMAP TlsBitmap; /* 0x040 / 0x078 */
DWORD TlsBitmapBits[2]; /* 0x044 / 0x080 */
PVOID ReadOnlySharedMemoryBase; /* 0x04c / 0x088 */
PVOID ReadOnlySharedMemoryHeap; /* 0x050 / 0x090 */
PPVOID ReadOnlyStaticServerData; /* 0x054 / 0x098 */
PVOID AnsiCodePageData; /* 0x058 / 0x0a0 */
PVOID OemCodePageData; /* 0x05c / 0x0a8 */
PVOID UnicodeCaseTableData; /* 0x060 / 0x0b0 */
DWORD NumberOfProcessors; /* 0x064 / 0x0b8 */
DWORD NtGlobalFlag; /* 0x068 / 0x0bc */
LARGE_INTEGER CriticalSectionTimeout; /* 0x070 / 0x0c0 */
ptr_uint_t HeapSegmentReserve; /* 0x078 / 0x0c8 */
ptr_uint_t HeapSegmentCommit; /* 0x07c / 0x0d0 */
ptr_uint_t HeapDeCommitTotalFreeThreshold; /* 0x080 / 0x0d8 */
ptr_uint_t HeapDeCommitFreeBlockThreshold; /* 0x084 / 0x0e0 */
DWORD NumberOfHeaps; /* 0x088 / 0x0e8 */
DWORD MaximumNumberOfHeaps; /* 0x08c / 0x0ec */
PPVOID ProcessHeaps; /* 0x090 / 0x0f0 */
PVOID GdiSharedHandleTable; /* 0x094 / 0x0f8 */
PVOID ProcessStarterHelper; /* 0x098 / 0x100 */
DWORD GdiDCAttributeList; /* 0x09c / 0x108 */
PRTL_CRITICAL_SECTION LoaderLock; /* 0x0a0 / 0x110 */
DWORD OSMajorVersion; /* 0x0a4 / 0x118 */
DWORD OSMinorVersion; /* 0x0a8 / 0x11c */
WORD OSBuildNumber; /* 0x0ac / 0x120 */
WORD OSCSDVersion; /* 0x0ae / 0x122 */
DWORD OSPlatformId; /* 0x0b0 / 0x124 */
DWORD ImageSubsystem; /* 0x0b4 / 0x128 */
DWORD ImageSubsystemMajorVersion; /* 0x0b8 / 0x12c */
DWORD ImageSubsystemMinorVersion; /* 0x0bc / 0x130 */
ptr_uint_t ImageProcessAffinityMask; /* 0x0c0 / 0x138 */
#ifdef X64
DWORD GdiHandleBuffer[60]; /* 0x0c4 / 0x140 */
#else
DWORD GdiHandleBuffer[34]; /* 0x0c4 / 0x140 */
#endif
PVOID PostProcessInitRoutine; /* 0x14c / 0x230 */
PVOID TlsExpansionBitmap; /* 0x150 / 0x238 */
DWORD TlsExpansionBitmapBits[32]; /* 0x154 / 0x240 */
DWORD SessionId; /* 0x1d4 / 0x2c0 */
ULARGE_INTEGER AppCompatFlags; /* 0x1d8 / 0x2c8 */
ULARGE_INTEGER AppCompatFlagsUser; /* 0x1e0 / 0x2d0 */
PVOID pShimData; /* 0x1e8 / 0x2d8 */
PVOID AppCompatInfo; /* 0x1ec / 0x2e0 */
UNICODE_STRING CSDVersion; /* 0x1f0 / 0x2e8 */
PVOID ActivationContextData; /* 0x1f8 / 0x2f8 */
PVOID ProcessAssemblyStorageMap; /* 0x1fc / 0x300 */
PVOID SystemDefaultActivationContextData;/* 0x200 / 0x308 */
PVOID SystemAssemblyStorageMap; /* 0x204 / 0x310 */
ptr_uint_t MinimumStackCommit; /* 0x208 / 0x318 */
PPVOID FlsCallback; /* 0x20c / 0x320 */
LIST_ENTRY FlsListHead; /* 0x210 / 0x328 */
PRTL_BITMAP FlsBitmap; /* 0x218 / 0x338 */
DWORD FlsBitmapBits[4]; /* 0x21c / 0x340 */
DWORD FlsHighIndex; /* 0x22c / 0x350 */
PVOID WerRegistrationData; /* 0x230 / 0x358 */
PVOID WerShipAssertPtr; /* 0x234 / 0x360 */
PVOID pUnused; /* 0x238 / 0x368 */
PVOID pImageHeaderHash; /* 0x23c / 0x370 */
union {
ULONG TracingFlags; /* 0x240 / 0x378 */
struct {
ULONG HeapTracingEnabled:1; /* 0x240 / 0x378 */
ULONG CritSecTracingEnabled:1; /* 0x240 / 0x378 */
ULONG LibLoaderTracingEnabled:1; /* 0x240 / 0x378 */
ULONG SpareTracingBits:29; /* 0x240 / 0x378 */
};
};
ULONG64 CsrServerReadOnlySharedMemoryBase;/*0x248 / 0x380 */
} PEB, *PPEB;
#ifndef _W64
# define _W64
#endif
#ifndef X64
typedef _W64 long LONG_PTR, *PLONG_PTR;
typedef _W64 unsigned long ULONG_PTR, *PULONG_PTR;
typedef ULONG KAFFINITY;
#endif
typedef LONG KPRIORITY;
typedef struct _KERNEL_USER_TIMES {
LARGE_INTEGER CreateTime;
LARGE_INTEGER ExitTime;
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
} KERNEL_USER_TIMES;
/* Process Information Structures */
typedef struct _PROCESS_BASIC_INFORMATION {
NTSTATUS ExitStatus;
PPEB PebBaseAddress;
ULONG_PTR AffinityMask;
KPRIORITY BasePriority;
ULONG_PTR UniqueProcessId;
ULONG_PTR InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION;
typedef PROCESS_BASIC_INFORMATION *PPROCESS_BASIC_INFORMATION;
typedef struct _DESCRIPTOR_TABLE_ENTRY {
ULONG Selector;
LDT_ENTRY Descriptor;
} DESCRIPTOR_TABLE_ENTRY, *PDESCRIPTOR_TABLE_ENTRY;
/* format of data returned by QueryInformationProcess ProcessVmCounters */
typedef struct _VM_COUNTERS {
SIZE_T PeakVirtualSize;
SIZE_T VirtualSize;
ULONG PageFaultCount;
SIZE_T PeakWorkingSetSize;
SIZE_T WorkingSetSize;
SIZE_T QuotaPeakPagedPoolUsage;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaPeakNonPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
} VM_COUNTERS;
/* format of data returned by QueryInformationProcess ProcessDeviceMap */
typedef struct _PROCESS_DEVICEMAP_INFORMATION {
union {
struct {
HANDLE DirectoryHandle;
} Set;
struct {
ULONG DriveMap;
UCHAR DriveType[32];
} Query;
};
#ifdef X64
ULONG Flags;
#endif
} PROCESS_DEVICEMAP_INFORMATION, *PPROCESS_DEVICEMAP_INFORMATION;
#if defined(NOT_DYNAMORIO_CORE)
# ifndef bool
typedef char bool;
# endif /* bool */
typedef unsigned __int64 uint64;
#endif /* NOT_DYNAMORIO_CORE */
/* Case 7395: mmcgui build fails with redefinition of
* _JOBOBJECT_EXTENDED_LIMIT_INFORMATION and _IO_COUNTERS
*/
#if !defined(NOT_DYNAMORIO_CORE) && !defined(NOT_DYNAMORIO_CORE_PROPER)
/* For NtQueryInformationProcess using ProcessQuotaLimits or
* ProcessPooledQuotaLimits or for NtSetInformationProcess using
* ProcessQuotaLimits */
/* QUOTA_LIMITS defined in VC98/Include/WINNT.H - from WinNT+ */
/* note for NtSetInformationProcess when setting can set either
* working set or the other values: only when both
* MinimumWorkingSetSize and MaximumWorkingSetSize are non-zero
* working set is adjusted, and the other values are ignored.
* (Nebbett p.141)
*
* Job and working set note from MSDN "Processes can still empty their
* working sets using the SetProcessWorkingSetSize function, even when
* JOB_OBJECT_LIMIT_WORKINGSET is used. However, you cannot use
* SetProcessWorkingSetSize to change the minimum or maximum working
* set size."
*/
/* PageFaultHistory Information
* NtQueryInformationProcess ProcessWorkingSetWatch
*/
typedef struct _PROCESS_WS_WATCH_INFORMATION {
PVOID FaultingPc;
PVOID FaultingVa;
} PROCESS_WS_WATCH_INFORMATION, *PPROCESS_WS_WATCH_INFORMATION;
/* NtQueryInformationProcess ProcessPooledUsageAndLimits */
typedef struct _POOLED_USAGE_AND_LIMITS {
SIZE_T PeakPagedPoolUsage;
SIZE_T PagedPoolUsage;
SIZE_T PagedPoolLimit;
SIZE_T PeakNonPagedPoolUsage;
SIZE_T NonPagedPoolUsage;
SIZE_T NonPagedPoolLimit;
SIZE_T PeakPagefileUsage;
SIZE_T PagefileUsage;
SIZE_T PagefileLimit;
} POOLED_USAGE_AND_LIMITS;
typedef POOLED_USAGE_AND_LIMITS *PPOOLED_USAGE_AND_LIMITS;
/* Process Security Context Information
* NtSetInformationProcess ProcessAccessToken
* PROCESS_SET_ACCESS_TOKEN access needed to use
*/
typedef struct _PROCESS_ACCESS_TOKEN {
//
// Handle to Primary token to assign to the process.
// TOKEN_ASSIGN_PRIMARY access to this token is needed.
//
HANDLE Token;
//
// Handle to the initial thread of the process.
// A process's access token can only be changed if the process has
// no threads or one thread. If the process has no threads, this
// field must be set to NULL. Otherwise, it must contain a handle
// open to the process's only thread. THREAD_QUERY_INFORMATION access
// is needed via this handle.
HANDLE Thread;
} PROCESS_ACCESS_TOKEN, *PPROCESS_ACCESS_TOKEN;
/* End of Process Information Structures */
/* Basic Job Limit flags, specified in JOBOBJECT_BASIC_LIMIT_INFORMATION */
#define JOB_OBJECT_LIMIT_WORKINGSET 0x00000001
#define JOB_OBJECT_LIMIT_PROCESS_TIME 0x00000002
#define JOB_OBJECT_LIMIT_JOB_TIME 0x00000004
#define JOB_OBJECT_LIMIT_ACTIVE_PROCESS 0x00000008
#define JOB_OBJECT_LIMIT_AFFINITY 0x00000010
#define JOB_OBJECT_LIMIT_PRIORITY_CLASS 0x00000020
#define JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME 0x00000040
#define JOB_OBJECT_LIMIT_SCHEDULING_CLASS 0x00000080
/* Extended Job Limit flags, specified in JOBOBJECT_EXTENDED_LIMIT_INFORMATION */
#define JOB_OBJECT_LIMIT_PROCESS_MEMORY 0x00000100
#define JOB_OBJECT_LIMIT_JOB_MEMORY 0x00000200
#define JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION 0x00000400
#define JOB_OBJECT_LIMIT_BREAKAWAY_OK 0x00000800
#define JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK 0x00001000
#define JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE 0x00002000
/* End of Job Limits */
#endif /* !NOT_DYNAMORIO_CORE && !NOT_DYNAMORIO_CORE_PROPER */
/* OS dependent SEH frame supported by ntdll.dll
referred to in WINNT.H as _EXCEPTION_REGISTRATION_RECORD */
typedef struct _EXCEPTION_REGISTRATION {
struct _EXCEPTION_REGISTRATION* prev;
PVOID handler;
} EXCEPTION_REGISTRATION, *PEXCEPTION_REGISTRATION;
typedef struct _GDI_TEB_BATCH
{
ULONG Offset;
HANDLE HDC;
ULONG Buffer[0x136];
} GDI_TEB_BATCH;
/* The layout here is from ntdll pdb on x64 xpsp2,
* later updated to win8 pdb info.
*/
typedef struct _TEB { /* offset: 32bit / 64bit */
/* We lay out NT_TIB, which is declared in winnt.h */
PEXCEPTION_REGISTRATION ExceptionList; /* 0x000 / 0x000 */
PVOID StackBase; /* 0x004 / 0x008 */
PVOID StackLimit; /* 0x008 / 0x010 */
PVOID SubSystemTib; /* 0x00c / 0x018 */
union {
PVOID FiberData; /* 0x010 / 0x020 */
DWORD Version; /* 0x010 / 0x020 */
};
PVOID ArbitraryUserPointer; /* 0x014 / 0x028 */
struct _TEB* Self; /* 0x018 / 0x030 */
PVOID EnvironmentPointer; /* 0x01c / 0x038 */
CLIENT_ID ClientId; /* 0x020 / 0x040 */
PVOID ActiveRpcHandle; /* 0x028 / 0x050 */
PVOID ThreadLocalStoragePointer; /* 0x02c / 0x058 */
PEB* ProcessEnvironmentBlock; /* 0x030 / 0x060 */
DWORD LastErrorValue; /* 0x034 / 0x068 */
DWORD CountOfOwnedCriticalSections; /* 0x038 / 0x06c */
PVOID CsrClientThread; /* 0x03c / 0x070 */
PVOID Win32ThreadInfo; /* 0x040 / 0x078 */
DWORD User32Reserved[26]; /* 0x044 / 0x080 */
DWORD UserReserved[5]; /* 0x0ac / 0x0e8 */
PVOID WOW32Reserved; /* 0x0c0 / 0x100 */
DWORD CurrentLocale; /* 0x0c4 / 0x108 */
DWORD FpSoftwareStatusRegister; /* 0x0c8 / 0x10c */
PVOID /* kernel32 data */ SystemReserved1[54]; /* 0x0cc / 0x110 */
LONG ExceptionCode; /* 0x1a4 / 0x2c0 */
PVOID ActivationContextStackPointer;/* 0x1a8 / 0x2c8 */
/* Pre-Vista has no TxFsContext with its 4 bytes in SpareBytes1[] */
#ifdef X64
byte SpareBytes1[24]; /* 0x1ac / 0x2d0 */
#else
byte SpareBytes1[36]; /* 0x1ac / 0x2d0 */
#endif
DWORD TxFsContext; /* 0x1d0 / 0x2e8 */
GDI_TEB_BATCH GdiTebBatch; /* 0x1d4 / 0x2f0 */
CLIENT_ID RealClientId; /* 0x6b4 / 0x7d8 */
PVOID GdiCachedProcessHandle; /* 0x6bc / 0x7e8 */
DWORD GdiClientPID; /* 0x6c0 / 0x7f0 */
DWORD GdiClientTID; /* 0x6c4 / 0x7f4 */
PVOID GdiThreadLocalInfo; /* 0x6c8 / 0x7f8 */
ptr_uint_t Win32ClientInfo[62]; /* 0x6cc / 0x800 */
PVOID glDispatchTable[233]; /* 0x7c4 / 0x9f0 */
ptr_uint_t glReserved1[29]; /* 0xb68 / 0x1138 */
PVOID glReserved2; /* 0xbdc / 0x1220 */
PVOID glSectionInfo; /* 0xbe0 / 0x1228 */
PVOID glSection; /* 0xbe4 / 0x1230 */
PVOID glTable; /* 0xbe8 / 0x1238 */
PVOID glCurrentRC; /* 0xbec / 0x1240 */
PVOID glContext; /* 0xbf0 / 0x1248 */
DWORD LastStatusValue; /* 0xbf4 / 0x1250 */
UNICODE_STRING StaticUnicodeString; /* 0xbf8 / 0x1258 */
WORD StaticUnicodeBuffer[261]; /* 0xc00 / 0x1268 */
PVOID DeallocationStack; /* 0xe0c / 0x1478 */
PVOID TlsSlots[64]; /* 0xe10 / 0x1480 */
LIST_ENTRY TlsLinks; /* 0xf10 / 0x1680 */
PVOID Vdm; /* 0xf18 / 0x1690 */
PVOID ReservedForNtRpc; /* 0xf1c / 0x1698 */
PVOID DbgSsReserved[2]; /* 0xf20 / 0x16a0 */
DWORD HardErrorMode; /* 0xf28 / 0x16b0 */
PVOID Instrumentation[14]; /* 0xf2c / 0x16b8 */
PVOID SubProcessTag; /* 0xf64 / 0x1728 */
PVOID EtwTraceData; /* 0xf68 / 0x1730 */
PVOID WinSockData; /* 0xf6c / 0x1738 */
DWORD GdiBatchCount; /* 0xf70 / 0x1740 */
byte InDbgPrint; /* 0xf74 / 0x1744 */
byte FreeStackOnTermination; /* 0xf75 / 0x1745 */
byte HasFiberData; /* 0xf76 / 0x1746 */
byte IdealProcessor; /* 0xf77 / 0x1747 */
DWORD GuaranteedStackBytes; /* 0xf78 / 0x1748 */
PVOID ReservedForPerf; /* 0xf7c / 0x1750 */
PVOID ReservedForOle; /* 0xf80 / 0x1758 */
DWORD WaitingOnLoaderLock; /* 0xf84 / 0x1760 */
ptr_uint_t SparePointer1; /* 0xf88 / 0x1768 */
ptr_uint_t SoftPatchPtr1; /* 0xf8c / 0x1770 */
ptr_uint_t SoftPatchPtr2; /* 0xf90 / 0x1778 */
PPVOID TlsExpansionSlots; /* 0xf94 / 0x1780 */
#ifdef X64
PVOID DeallocationBStore; /* ----- / 0x1788 */
PVOID BStoreLimit; /* ----- / 0x1790 */
#endif
DWORD ImpersonationLocale; /* 0xf98 / 0x1798 */
DWORD IsImpersonating; /* 0xf9c / 0x179c */
PVOID NlsCache; /* 0xfa0 / 0x17a0 */
PVOID pShimData; /* 0xfa4 / 0x17a8 */
DWORD HeapVirtualAffinity; /* 0xfa8 / 0x17b0 */
PVOID CurrentTransactionHandle; /* 0xfac / 0x17b8 */
PVOID ActiveFrame; /* 0xfb0 / 0x17c0 */
PPVOID FlsData; /* 0xfb4 / 0x17c8 */
#ifndef PRE_VISTA_TEB /* pre-vs-post-Vista: we'll have to make a union if we care */
PVOID PreferredLanguages; /* 0xfb8 / 0x17d0 */
PVOID UserPrefLanguages; /* 0xfbc / 0x17d8 */
PVOID MergedPrefLanguages; /* 0xfc0 / 0x17e0 */
ULONG MuiImpersonation; /* 0xfc4 / 0x17e8 */
union {
USHORT CrossTebFlags; /* 0xfc8 / 0x17ec */
USHORT SpareCrossTebFlags:16; /* 0xfc8 / 0x17ec */
};
union
{
USHORT SameTebFlags; /* 0xfca / 0x17ee */
struct {
USHORT SafeThunkCall:1; /* 0xfca / 0x17ee */
USHORT InDebugPrint:1; /* 0xfca / 0x17ee */
USHORT HasFiberData2:1; /* 0xfca / 0x17ee */
USHORT SkipThreadAttach:1; /* 0xfca / 0x17ee */
USHORT WerInShipAssertCode:1; /* 0xfca / 0x17ee */
USHORT RanProcessInit:1; /* 0xfca / 0x17ee */
USHORT ClonedThread:1; /* 0xfca / 0x17ee */
USHORT SuppressDebugMsg:1; /* 0xfca / 0x17ee */
USHORT DisableUserStackWalk:1; /* 0xfca / 0x17ee */
USHORT RtlExceptionAttached:1; /* 0xfca / 0x17ee */
USHORT InitialThread:1; /* 0xfca / 0x17ee */
USHORT SessionAware:1; /* 0xfca / 0x17ee */
USHORT SpareSameTebBits:4; /* 0xfca / 0x17ee */
};
};
PVOID TxnScopeEntercallback; /* 0xfcc / 0x17f0 */
PVOID TxnScopeExitCAllback; /* 0xfd0 / 0x17f8 */
PVOID TxnScopeContext; /* 0xfd4 / 0x1800 */
ULONG LockCount; /* 0xfd8 / 0x1808 */
ULONG SpareUlong0; /* 0xfdc / 0x180c */
PVOID ResourceRetValue; /* 0xfe0 / 0x1810 */
PVOID ReservedForWdf; /* 0xfe4 / 0x1818 */
#else /* pre-Vista: */
byte SafeThunkCall; /* 0xfb8 / 0x17d0 */
byte BooleanSpare[3]; /* 0xfb9 / 0x17d1 */
#endif
} TEB;
typedef struct _THREAD_BASIC_INFORMATION { // Information Class 0
NTSTATUS ExitStatus;
PNT_TIB TebBaseAddress;
CLIENT_ID ClientId;
KAFFINITY AffinityMask;
KPRIORITY Priority;
KPRIORITY BasePriority;
} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
typedef struct _SYSTEM_BASIC_INFORMATION {
ULONG Unknown;
ULONG MaximumIncrement;
ULONG PhysicalPageSize;
ULONG NumberOfPhysicalPages;
ULONG LowestPhysicalPage;
ULONG HighestPhysicalPage;
ULONG AllocationGranularity;
PVOID LowestUserAddress;
PVOID HighestUserAddress;
ULONG_PTR ActiveProcessors;
UCHAR NumberProcessors;
#ifdef X64
ULONG Unknown2; /* set to 0: probably just padding to 8-byte max field align */
#endif
} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;
typedef struct _SYSTEM_PROCESSOR_INFORMATION {
USHORT ProcessorArchitecture;
USHORT ProcessorLevel;
USHORT ProcessorRevision;
USHORT Unknown;
ULONG FeatureBits;
} SYSTEM_PROCESSOR_INFORMATION, *PSYSTEM_PROCESSOR_INFORMATION;
typedef struct _SYSTEM_PERFORMANCE_INFORMATION {
LARGE_INTEGER IdleTime;
LARGE_INTEGER ReadTransferCount;
LARGE_INTEGER WriteTransferCount;
LARGE_INTEGER OtherTransferCount;
ULONG ReadOperationCount;
ULONG WriteOperationCount;
ULONG OtherOperationCount;
ULONG AvailablePages;
ULONG TotalCommittedPages;
ULONG TotalCommitLimit;
ULONG PeakCommitment;
ULONG PageFaults;
ULONG WriteCopyFaults;
ULONG TranstitionFaults;
ULONG Reserved1;
ULONG DemandZeroFaults;
ULONG PagesRead;
ULONG PageReadIos;
ULONG Reserved2[2];
ULONG PageFilePagesWritten;
ULONG PageFilePagesWriteIos;
ULONG MappedFilePagesWritten;
ULONG PagedPoolUsage;
ULONG NonPagedPoolUsage;
ULONG PagedPoolAllocs;
ULONG PagedPoolFrees;
ULONG NonPagedPoolAllocs;
ULONG NonPagedPoolFrees;
ULONG TotalFreeSystemPtes;
ULONG SystemCodePage;
ULONG TotalSystemDriverPages;
ULONG TotalSystemCodePages;
ULONG SmallNonPagedLookasideListAllocateHits;
ULONG SmallPagedLookasieListAllocateHits;
ULONG Reserved3;
ULONG MmSystemCachePage;
ULONG PagedPoolPage;
ULONG SystemDriverPage;
ULONG FastReadNoWait;
ULONG FastReadWait;
ULONG FastReadResourceMiss;
ULONG FastReadNotPossible;
ULONG FastMdlReadNoWait;
ULONG FastMdlReadWait;
ULONG FastMdlReadResourceMiss;
ULONG FastMdlReadNotPossible;
ULONG MapDataNoWait;
ULONG MapDataWait;
ULONG MapDataNoWaitMiss;
ULONG MapDataWaitMiss;
ULONG PinMappedDataCount;
ULONG PinReadNoWait;
ULONG PinReadWait;
ULONG PinReadNoWaitMiss;
ULONG PinReadWaitMiss;
ULONG CopyReadNoWait;
ULONG CopyReadWait;
ULONG CopyReadNoWaitMiss;
ULONG CopyReadWaitMiss;
ULONG MdlReadNoWait;
ULONG MdlReadWait;
ULONG MdlReadNoWaitMiss;
ULONG MdlReadWaitMiss;
ULONG ReadAheadIos;
ULONG LazyWriteIos;
ULONG LazyWritePages;
ULONG DataFlushes;
ULONG DataPages;
ULONG ContextSwitches;
ULONG FirstLevelTbFills;
ULONG SecondLevelTbFills;
ULONG SystemCalls;
/* Fields added in Windows 7 */
ULONG Unknown[4];
} SYSTEM_PERFORMANCE_INFORMATION, *PSYSTEM_PERFORMANCE_INFORMATION;
typedef struct _SYSTEM_TIME_OF_DAY_INFORMATION {
LARGE_INTEGER BootTime;
LARGE_INTEGER CurrentTime;
LARGE_INTEGER TimeZoneBias;
ULONG CurrentTimeZoneId;
} SYSTEM_TIME_OF_DAY_INFORMATION, *PSYSTEM_TIME_OF_DAY_INFORMATION;
typedef struct _SYSTEM_PROCESSOR_TIMES {
LARGE_INTEGER IdleTime;
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER DpcTime;
LARGE_INTEGER InterruptTime;
ULONG InterruptCount;
} SYSTEM_PROCESSOR_TIMES, *PSYSTEM_PROCESSOR_TIMES;
typedef struct _IO_COUNTERSEX {
LARGE_INTEGER ReadOperationCount;
LARGE_INTEGER WriteOperationCount;
LARGE_INTEGER OtherOperationCount;
LARGE_INTEGER ReadTransferCount;
LARGE_INTEGER WriteTransferCount;
LARGE_INTEGER OtherTransferCount;
} IO_COUNTERSEX, *PIO_COUNTERSEX;
typedef enum _THREAD_STATE {
StateInitialized,
StateReady,
StateRunning,
StateStandby,
StateTerminated,
StateWait,
StateTransition,
StateUnknown
} THREAD_STATE;
typedef enum _KWAIT_REASON {
Executive,
FreePage,
PageIn,
PoolAllocation,
DelayExecution,
Suspended,
UserRequest,
WrExecutive,
WrFreePage,
WrPageIn,
WrPoolAllocation,
WrDelayExecution,
WrSuspended,
WrUserRequest,
WrEventPair,
WrQueue,
WrLpcReceive,
WrVirtualMemory,
WrPageOut,
WrRendevous,
WrSpare2,
WrSpare3,
WrSpare4,
WrSpare5,
WrSpare6,
WrKernel
} KWAIT_REASON;
typedef struct _SYSTEM_THREADS {
/* XXX: are Create and Kernel swapped? */
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId;
KPRIORITY Priority;
KPRIORITY BasePriority;
ULONG ContextSwitchCount;
THREAD_STATE ThreadState;
KWAIT_REASON WaitReason;
ULONG Padding;
} SYSTEM_THREADS, *PSYSTEM_THREADS;
typedef struct _SYSTEM_PROCESSES {
ULONG NextEntryDelta;
ULONG ThreadCount;
LARGE_INTEGER WorkingSetPrivateSize; /* Vista+ */
ULONG HardFaultCount; /* Win7+ */
ULONG NumberOfThreadsHighWatermark; /* Win7+ */
ULONGLONG CycleTime; /* Win7+ */
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ProcessName;
KPRIORITY BasePriority;
HANDLE ProcessId;
HANDLE InheritedFromProcessId;
ULONG HandleCount;
ULONG SessionId;
ULONG_PTR PageDirectoryFrame;
VM_COUNTERS VmCounters;
SIZE_T PrivatePageCount; /* Windows 2000+: end of VM_COUNTERS_EX */
IO_COUNTERSEX IoCounters; /* Windows 2000+ only */
SYSTEM_THREADS Threads[1]; /* Variable size */
} SYSTEM_PROCESSES, *PSYSTEM_PROCESSES;
typedef struct _SYSTEM_GLOBAL_FLAG {
ULONG GlobalFlag;
} SYSTEM_GLOBAL_FLAG, *PSYSTEM_GLOBAL_FLAG;
typedef struct _MEMORY_SECTION_NAME {
UNICODE_STRING SectionFileName;
} MEMORY_SECTION_NAME, *PMEMORY_SECTION_NAME;
#define SYMBOLIC_LINK_QUERY (0x1)
#define SYMBOLIC_LINK_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYMBOLIC_LINK_QUERY)
/* Speculated arg 10 to NtCreateUserProcess.
* Note the similarities to CreateThreadEx arg 11 below. Struct starts with size then
* after that looks kind of like an array of 16 byte (32 on 64-bit) elements corresponding
* to the IN and OUT informational ptrs. Each array elment consists of a ?flags? then
* the sizeof of the IN/OUT ptr buffer then the ptr itself then 0.
*/
typedef enum { /* NOTE - these are speculative */
THREAD_INFO_ELEMENT_BUFFER_IS_INOUT = 0x00000, /* buffer is ??IN/OUT?? */
THREAD_INFO_ELEMENT_BUFFER_IS_OUT = 0x10000, /* buffer is IN (?) */
THREAD_INFO_ELEMENT_BUFFER_IS_IN = 0x20000, /* buffer is OUT (?) */
} thread_info_elm_buf_access_t;
typedef enum { /* NOTE - these are speculative */
THREAD_INFO_ELEMENT_CLIENT_ID = 0x3, /* buffer is CLIENT_ID - OUT */
THREAD_INFO_ELEMENT_TEB = 0x4, /* buffer is TEB * - OUT */
THREAD_INFO_ELEMENT_NT_PATH_TO_EXE = 0x5, /* buffer is wchar * path to exe
* [ i.e. L"\??\c:\foo.exe" ] - IN */
THREAD_INFO_ELEMENT_EXE_STUFF = 0x6, /* buffer is exe_stuff_t (see above)
* - INOUT */
THREAD_INFO_ELEMENT_UNKNOWN_1 = 0x9, /* Unknown - ptr_uint_t sized
* [ observed 1 ] - IN */
} thread_info_elm_buf_type_t;
typedef struct _thread_info_element_t { /* NOTE - this is speculative */
ptr_uint_t flags; /* thread_info_elm_buf_access_t | thread_info_elm_buf_type_t */
size_t buffer_size; /* sizeof of buffer, in bytes */
void *buffer; /* flags determine disposition, could be IN or OUT or both */
ptr_uint_t unknown; /* [ observed always 0 ] */
} thread_info_elm_t;
typedef struct _exe_stuff_t { /* NOTE - this is speculative */
OUT void *exe_entrypoint_addr; /* Entry point to the exe being started. */
// ratio of uint32 to ptr_uint_t assumes no larger changes between 32 and 64-bit
ptr_uint_t unknown1[3]; // possibly intermixed with uint32s below IN? OUT?
uint32 unknown2[8]; // possible intermixed with ptr_uint_ts above IN? OUT?
} exe_stuff_t;
typedef struct _create_proc_thread_info_t { /* NOTE - this is speculative */
size_t struct_size; /* observed 0x34 or 0x44 (0x68 on 64-bit) = sizeof(this struct) */
/* Observed - first thread_info_elm_t always
* flags = 0x20005
* buffer_size = varies (sizeof buffer string in bytes)
* buffer = wchar * : nt path to executable i.e. "\??\c:\foo.exe" - IN */
thread_info_elm_t nt_path_to_exe;
/* Observed - second thread_info_elm_t always
* flags = 0x10003
* buffer_size = sizeof(CLIENT_ID)
* buffer = PCLIENT_ID : OUT */
thread_info_elm_t client_id;
/* Observed - third thread_info_elm_t always
* flags = 0x6
* buffer_size = 0x30 (or 0x40 on 64-bit) == sizeof(exe_stuff_t)
* buffer = exe_stuff_t * : IN/OUT */
thread_info_elm_t exe_stuff;
/* While the first three thread_info_elm_t have been present in every call I've seen
* (and attempts to remove or re-arrange them caused the system call to fail,
* assuming I managed to do it right), there's more variation in the later fields
* (sometimes present, sometimes not) - most commonly there'll be nothing or just the
* TEB * info field (flags = 0x10003) which I've seen here a lot on 32bit. */
#if 0 /* 0 sized array is non-standard extension */
thread_info_elm_t info[];
#endif
} create_proc_thread_info_t;
/* Speculated arg 11 to NtCreateThreadEx. See the similar arg 10 of
* NtCreateUserProcess above. */
typedef struct _create_thread_info_t { /* NOTE - this is speculative */
size_t struct_size; /* observed 0x24 (0x48 on 64-bit) == sizeof(this struct) */
/* Note kernel32!CreateThread hardcodes all the values in this structure and
* I've never seen any variation elsewhere. Trying to swap the order caused the
* system call to fail when I tried it (assuming I did it right). */
/* Observed - always
* flags = 0x10003
* buffer_size = sizeof(CLIENT_ID)
* buffer = PCLIENT_ID : OUT */
thread_info_elm_t client_id;
/* Observed - always
* flags = 0x10004
* buffer_size = sizeof(CLIENT_ID)
* buffer = TEB ** : OUT */
thread_info_elm_t teb;
} create_thread_info_t;
/* PEB.ReadOnlyStaticServerData has an array of pointers sized to match the
* kernel (so 64-bit for WOW64). The second pointer points at this structure.
* However, be careful b/c the UNICODE_STRING structs are really UNICODE_STRING_64
* for WOW64.
*/
typedef struct _BASE_STATIC_SERVER_DATA
{
UNICODE_STRING WindowsDirectory;
UNICODE_STRING WindowsSystemDirectory;
UNICODE_STRING NamedObjectDirectory;
USHORT WindowsMajorVersion;
USHORT WindowsMinorVersion;
USHORT BuildNumber;
/* rest we don't care about */
} BASE_STATIC_SERVER_DATA, *PBASE_STATIC_SERVER_DATA;
#ifndef X64
typedef struct _BASE_STATIC_SERVER_DATA_64
{
UNICODE_STRING_64 WindowsDirectory;
UNICODE_STRING_64 WindowsSystemDirectory;
UNICODE_STRING_64 NamedObjectDirectory;
USHORT WindowsMajorVersion;
USHORT WindowsMinorVersion;
USHORT BuildNumber;
/* rest we don't care about */
} BASE_STATIC_SERVER_DATA_64, *PBASE_STATIC_SERVER_DATA_64;
#endif
/* NtQueryDirectoryFile information, from ntifs.h */
typedef struct _FILE_BOTH_DIR_INFORMATION {
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaSize;
CCHAR ShortNameLength;
WCHAR ShortName[12];
WCHAR FileName[1];
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;
/* from ntdef.h */
typedef enum _NT_PRODUCT_TYPE {
NtProductWinNt = 1,
NtProductLanManNt,
NtProductServer
} NT_PRODUCT_TYPE, *PNT_PRODUCT_TYPE;
/* from ntdkk.h */
typedef enum _ALTERNATIVE_ARCHITECTURE_TYPE {
StandardDesign, // None == 0 == standard design
NEC98x86, // NEC PC98xx series on X86
EndAlternatives // past end of known alternatives
} ALTERNATIVE_ARCHITECTURE_TYPE;
typedef struct _KSYSTEM_TIME {
ULONG LowPart;
LONG High1Time;
LONG High2Time;
} KSYSTEM_TIME, *PKSYSTEM_TIME;
#define PROCESSOR_FEATURE_MAX 64
typedef struct _KUSER_SHARED_DATA {
//
// Current low 32-bit of tick count and tick count multiplier.
//
// N.B. The tick count is updated each time the clock ticks.
//
ULONG TickCountLowDeprecated;
ULONG TickCountMultiplier;
//
// Current 64-bit interrupt time in 100ns units.
//
volatile KSYSTEM_TIME InterruptTime;
//
// Current 64-bit system time in 100ns units.
//
volatile KSYSTEM_TIME SystemTime;
//
// Current 64-bit time zone bias.
//
volatile KSYSTEM_TIME TimeZoneBias;
//
// Support image magic number range for the host system.
//
// N.B. This is an inclusive range.
//
USHORT ImageNumberLow;
USHORT ImageNumberHigh;
//
// Copy of system root in Unicode
//
WCHAR NtSystemRoot[ 260 ];
//
// Maximum stack trace depth if tracing enabled.
//
ULONG MaxStackTraceDepth;
//
// Crypto Exponent
//
ULONG CryptoExponent;
//
// TimeZoneId
//
ULONG TimeZoneId;
ULONG LargePageMinimum;
ULONG Reserved2[ 7 ];
//
// product type
//
NT_PRODUCT_TYPE NtProductType;
BOOLEAN ProductTypeIsValid;
//
// NT Version. Note that each process sees a version from its PEB, but
// if the process is running with an altered view of the system version,
// the following two fields are used to correctly identify the version
//
ULONG NtMajorVersion;
ULONG NtMinorVersion;
//
// Processor Feature Bits
//
BOOLEAN ProcessorFeatures[PROCESSOR_FEATURE_MAX];
//
// Reserved fields - do not use
//
ULONG Reserved1;
ULONG Reserved3;
//
// Time slippage while in debugger
//
volatile ULONG TimeSlip;
//
// Alternative system architecture. Example: NEC PC98xx on x86
//
ALTERNATIVE_ARCHITECTURE_TYPE AlternativeArchitecture;
//
// If the system is an evaluation unit, the following field contains the
// date and time that the evaluation unit expires. A value of 0 indicates
// that there is no expiration. A non-zero value is the UTC absolute time
// that the system expires.
//
LARGE_INTEGER SystemExpirationDate;
//
// Suite Support
//
ULONG SuiteMask;
//
// TRUE if a kernel debugger is connected/enabled
//
BOOLEAN KdDebuggerEnabled;
//
// Current console session Id. Always zero on non-TS systems
//
volatile ULONG ActiveConsoleId;
//
// Force-dismounts cause handles to become invalid. Rather than
// always probe handles, we maintain a serial number of
// dismounts that clients can use to see if they need to probe
// handles.
//
volatile ULONG DismountCount;
//
// This field indicates the status of the 64-bit COM+ package on the system.
// It indicates whether the Itermediate Language (IL) COM+ images need to
// use the 64-bit COM+ runtime or the 32-bit COM+ runtime.
//
ULONG ComPlusPackage;
//
// Time in tick count for system-wide last user input across all
// terminal sessions. For MP performance, it is not updated all
// the time (e.g. once a minute per session). It is used for idle
// detection.
//
ULONG LastSystemRITEventTickCount;
//
// Number of physical pages in the system. This can dynamically
// change as physical memory can be added or removed from a running
// system.
//
ULONG NumberOfPhysicalPages;
//
// True if the system was booted in safe boot mode.
//
BOOLEAN SafeBootMode;
//
// The following field is used for Heap and CritSec Tracing
// The last bit is set for Critical Sec Collision tracing and
// second Last bit is for Heap Tracing
// Also the first 16 bits are used as counter.
//
ULONG TraceLogging;
//
// Depending on the processor, the code for fast system call
// will differ, the following buffer is filled with the appropriate
// code sequence and user mode code will branch through it.
//
// (32 bytes, using ULONGLONG for alignment).
//
// N.B. The following two fields are only used on 32-bit systems.
//
ULONGLONG Fill0; // alignment
ULONGLONG SystemCall[4];
//
// The 64-bit tick count.
//
union {
volatile KSYSTEM_TIME TickCount;
volatile ULONG64 TickCountQuad;
};
/* XXX: Vista+ have added more fields */
} KUSER_SHARED_DATA;
/* We only rely on this up through Windows XP */
#define KUSER_SHARED_DATA_ADDRESS ((ULONG_PTR)0x7ffe0000)
/***************************************************************************
* convenience enums
*/
typedef enum {MEMORY_RESERVE_ONLY = MEM_RESERVE,
MEMORY_COMMIT = MEM_RESERVE|MEM_COMMIT
} memory_commit_status_t;
/***************************************************************************
* function declarations
*/
void
ntdll_init(void);
void
ntdll_exit(void);
NTSTATUS
nt_raw_close(HANDLE h);
bool
close_handle(HANDLE h);
/* from winddk.h used by cygwin */
#define DUPLICATE_SAME_ATTRIBUTES 0x00000004
NTSTATUS
duplicate_handle(HANDLE source_process, HANDLE source, HANDLE target_process,
HANDLE *target, ACCESS_MASK access, uint attributes,
uint options);
ACCESS_MASK
nt_get_handle_access_rights(HANDLE handle);
typedef enum {THREAD_EXITED, THREAD_NOT_EXITED, THREAD_EXIT_ERROR} thread_exited_status_t;
thread_exited_status_t
is_thread_exited(HANDLE hthread);
thread_id_t
thread_id_from_handle(HANDLE h);
process_id_t
process_id_from_handle(HANDLE h);
process_id_t
process_id_from_thread_handle(HANDLE h);
HANDLE
process_handle_from_id(process_id_t pid);
HANDLE
thread_handle_from_id(thread_id_t tid);
PEB *
get_peb(HANDLE h);
PEB *
get_own_peb(void);
TEB *
get_teb(HANDLE h);
void *
get_ntdll_base(void);
#if !defined(NOT_DYNAMORIO_CORE_PROPER) && !defined(NOT_DYNAMORIO_CORE)
bool
is_in_ntdll(app_pc pc);
#endif
NTSTATUS
nt_remote_query_virtual_memory(HANDLE process, const byte *pc,
MEMORY_BASIC_INFORMATION *mbi, size_t mbilen, size_t *got);
/* replacement for API call VirtualQuery */
size_t
query_virtual_memory(const byte *pc, MEMORY_BASIC_INFORMATION *mbi, size_t mbilen);
NTSTATUS
get_mapped_file_name(const byte *pc, PWSTR buf, USHORT buf_bytes);
/* for allocating in another process,
* keep in mind base is now IN/OUT value, a NULL value means no preference
* will bump size up to PAGE_SIZE multiple */
NTSTATUS
nt_remote_allocate_virtual_memory(HANDLE process, void **base, size_t size,
uint prot, memory_commit_status_t commit);
NTSTATUS
nt_remote_free_virtual_memory(HANDLE process, void *base);
/* will bump size up to PAGE_SIZE multiple
* keep in mind base is now IN/OUT value, a NULL value means no preference
*/
NTSTATUS
nt_allocate_virtual_memory(void **base, size_t size, uint prot,
memory_commit_status_t commit);
NTSTATUS
nt_commit_virtual_memory(void *base, size_t size, uint prot);
NTSTATUS
nt_decommit_virtual_memory(void *base, size_t size);
NTSTATUS
nt_free_virtual_memory(void *base);
bool
protect_virtual_memory(void *base, size_t size, uint prot, uint *old_prot);
bool
nt_remote_protect_virtual_memory(HANDLE process,
void *base, size_t size, uint prot, uint *old_prot);
bool
nt_read_virtual_memory(HANDLE process, const void *base, void *buffer,
size_t buffer_length, size_t *bytes_read);
bool
nt_write_virtual_memory(HANDLE process, void *base, const void *buffer,
size_t buffer_length, size_t *bytes_written);
/* returns raw NTSTATUS */
NTSTATUS
nt_raw_read_virtual_memory(HANDLE process, const void *base, void *buffer,
size_t buffer_length, size_t *bytes_read);
/* returns raw NTSTATUS */
NTSTATUS
nt_raw_write_virtual_memory(HANDLE process, void *base, const void *buffer,
size_t buffer_length, size_t *bytes_written);
void
nt_continue(CONTEXT *cxt);
NTSTATUS
nt_get_context(HANDLE hthread, CONTEXT *cxt);
NTSTATUS
nt_set_context(HANDLE hthread, CONTEXT *cxt);
bool
nt_thread_suspend(HANDLE hthread, int *previous_suspend_count);
bool
nt_thread_resume(HANDLE hthread, int *previous_suspend_count);
#if !defined(NOT_DYNAMORIO_CORE_PROPER) && !defined(NOT_DYNAMORIO_CORE)
/* Returns STATUS_NOT_IMPLEMENTED on pre-Vista */
NTSTATUS
nt_thread_iterator_next(HANDLE hprocess, HANDLE cur_thread, HANDLE *next_thread,
ACCESS_MASK access);
#endif
bool
nt_terminate_thread(HANDLE hthread, NTSTATUS exit_code);
bool
nt_terminate_process(HANDLE hprocess, NTSTATUS exit_code);
NTSTATUS
nt_terminate_process_for_app(HANDLE hprocess, NTSTATUS exit_code);
bool
am_I_sole_thread(HANDLE hthread, int *amI /*OUT*/);
/* checks current thread, and turns errors into false */
bool
check_sole_thread(void);
/* creates a waitable timer */
HANDLE
nt_create_and_set_timer(PLARGE_INTEGER due_time, LONG period);
/* thread sleeps for given relative or absolute time */
bool
nt_sleep(PLARGE_INTEGER due_time);
void
nt_yield(void);
bool
nt_raise_exception(EXCEPTION_RECORD* pexcrec, CONTEXT* pcontext);
bool
nt_messagebox(const wchar_t *msg, const wchar_t *title);
bool
tls_alloc(int synch, uint *teb_offs /* OUT */);
/* Allocates num tls slots aligned with alignment align */
bool
tls_calloc(int synch, uint *teb_offs /* OUT */, int num, uint alignment);
bool
tls_free(int synch, uint teb_offs);
bool
tls_cfree(int synch, uint teb_offs, int num);
/* RTL_BITMAP routines exported to drwinapi */
int
bitmap_find_free_sequence(byte *rtl_bitmap, int bitmap_size,
int num_requested_slots, bool top_down,
int align_which_slot, /* 0 based index */
uint alignment);
void
bitmap_mark_taken_sequence(byte *rtl_bitmap, int bitmap_size,
int first_slot, int last_slot_open_end);
void
bitmap_mark_freed_sequence(byte *rtl_bitmap, int bitmap_size,
int first_slot, int num_slots);
bool
get_process_mem_stats(HANDLE h, VM_COUNTERS *info);
NTSTATUS
get_process_mem_quota(HANDLE h, QUOTA_LIMITS *qlimits);
NTSTATUS
get_process_handle_count(HANDLE ph, ULONG *handle_count);
int
get_process_load(HANDLE h);
bool
is_wow64_process(HANDLE h);
NTSTATUS
nt_get_drive_map(HANDLE process, PROCESS_DEVICEMAP_INFORMATION *map OUT);
void *
get_section_address(HANDLE h);
/* Section attributes as described in Nebbett, p. 105.
* Some are documented in the SDK CreateFileMapping */
/* from wnet/winnt.h, new in Win2003 */
#define SEC_LARGE_PAGES 0x80000000
/* SEC_VLM in VC98/winnt.h but in DDK, apparently not implemented on x86 */
#ifndef SEC_VLM /* not defined in VC8 headers */
# define SEC_VLM 0x02000000
#endif
/* Similarly these may have existed in earlier windows versions as well */
#define SEC_BASED_UNSUPPORTED 0x00200000
#define SEC_NO_CHANGE_UNSUPPORTED 0x00400000
bool
get_section_attributes(HANDLE h, uint *section_attributes /* OUT */,
LARGE_INTEGER* section_size /* OUT OPTIONAL */);
/* This is a low-level interface. Use the reg_* routines below if possible. */
NTSTATUS
nt_query_value_key(IN HANDLE key,
IN PUNICODE_STRING value_name,
IN KEY_VALUE_INFORMATION_CLASS class,
OUT PVOID info,
IN ULONG info_length,
OUT PULONG res_length);
HANDLE
reg_create_key(HANDLE parent, PCWSTR keyname, ACCESS_MASK rights);
HANDLE
reg_open_key(PCWSTR keyname, ACCESS_MASK rights);
bool
reg_close_key(HANDLE hkey);
bool
reg_delete_key(HANDLE hkey);
typedef enum _reg_query_value_result {
REG_QUERY_FAILURE,
REG_QUERY_BUFFER_TOO_SMALL,
REG_QUERY_SUCCESS
} reg_query_value_result_t;
reg_query_value_result_t
reg_query_value(PCWSTR hkey, PCWSTR subkey,
KEY_VALUE_INFORMATION_CLASS key_class, PVOID info, ULONG info_size,
ACCESS_MASK rights);
bool
reg_set_key_value(HANDLE hkey, PCWSTR subkey, PCWSTR val);
bool
reg_set_dword_key_value(HANDLE hkey, PCWSTR subkey, DWORD val);
bool
reg_flush_key(HANDLE hkey);
bool
reg_enum_key(PCWSTR keyname, ULONG index, KEY_INFORMATION_CLASS info_class,
PVOID key_info, ULONG key_info_size);
bool
reg_enum_value(PCWSTR keyname, ULONG index, KEY_VALUE_INFORMATION_CLASS key_class,
PVOID key_info, ULONG key_info_length);
bool
env_get_value(PCWSTR var, wchar_t *val, size_t valsz);
#define LengthRequiredSID(subauthorities) \
(sizeof(SID) - (ANYSIZE_ARRAY * sizeof(DWORD)) /* SID.SubAuthority */ \
+ ((subauthorities) * sizeof(DWORD)))
#ifndef SECURITY_MAX_SID_SIZE
/* see DDK2003SP1/3790.1830/inc/wnet/winnt.h */
# define SECURITY_MAX_SID_SIZE \
(LengthRequiredSID(SID_MAX_SUB_AUTHORITIES))
#endif
/* Note: the above static SID size may change in future versions, so
* we need to keep track of winnt.h
*/
#define SECURITY_MAX_TOKEN_SIZE (SECURITY_MAX_SID_SIZE + sizeof(SID_AND_ATTRIBUTES))
NTSTATUS
get_primary_user_token(PTOKEN_USER ptoken, USHORT token_buffer_length);
NTSTATUS
get_current_user_token(PTOKEN_USER ptoken, USHORT token_buffer_length);
NTSTATUS
get_primary_owner_token(PTOKEN_OWNER powner, USHORT owner_buffer_length);
NTSTATUS
get_current_user_SID(PWSTR sid_string, USHORT buffer_length);
bool
get_owner_sd(PISECURITY_DESCRIPTOR SecurityDescriptor,
PSID* Owner);
void
initialize_security_descriptor(PISECURITY_DESCRIPTOR SecurityDescriptor);
/* use only on security descriptors created with initialize_security_descriptor() */
bool
set_owner_sd(PISECURITY_DESCRIPTOR SecurityDescriptor,
PSID Owner);
bool
equal_sid(IN PSID Sid1, IN PSID Sid2);
void
initialize_known_SID(PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
ULONG SubAuthority0,
SID *pSid);
NTSTATUS
query_seg_descriptor(HANDLE hthread, DESCRIPTOR_TABLE_ENTRY *entry);
NTSTATUS
query_win32_start_addr(HANDLE hthread, PVOID start_addr);
NTSTATUS
query_system_info(SYSTEM_INFORMATION_CLASS info_class, int info_size, PVOID info);
bool
query_full_attributes_file(PCWSTR filename,
PFILE_NETWORK_OPEN_INFORMATION info);
/* access mask flags, from ntddk.h rest are in winnt.h so no need to replicate
* them here */
#define FILE_ANY_ACCESS 0
#define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS)
#define FILE_READ_ACCESS ( 0x0001 ) // file & pipe
#define FILE_WRITE_ACCESS ( 0x0002 ) // file & pipe
/* share flags, from ntddk.h, rest are in winnt.h */
#define FILE_SHARE_VALID_FLAGS 0x00000007
/* attribute flags, from ntddk.h, rest are in winnt.h */
#define FILE_ATTRIBUTE_VALID_FLAGS 0x00007fb7
#define FILE_ATTRIBUTE_VALID_SET_FLAGS 0x000031a7
/* flags for NtCreateFile and NtOpenFile */
/* Create/Open options from ntddk.h */
#define FILE_DIRECTORY_FILE 0x00000001
#define FILE_WRITE_THROUGH 0x00000002
#define FILE_SEQUENTIAL_ONLY 0x00000004
#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
#define FILE_NON_DIRECTORY_FILE 0x00000040
#define FILE_CREATE_TREE_CONNECTION 0x00000080
#define FILE_COMPLETE_IF_OPLOCKED 0x00000100
#define FILE_NO_EA_KNOWLEDGE 0x00000200
#define FILE_OPEN_FOR_RECOVERY 0x00000400
#define FILE_OPEN_REMOTE_INSTANCE 0x00000400 /* alt name */
#define FILE_RANDOM_ACCESS 0x00000800
#define FILE_DELETE_ON_CLOSE 0x00001000
#define FILE_OPEN_BY_FILE_ID 0x00002000
#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000
#define FILE_NO_COMPRESSION 0x00008000
#define FILE_RESERVE_OPFILTER 0x00100000
#define FILE_OPEN_REPARSE_POINT 0x00200000
#define FILE_OPEN_NO_RECALL 0x00400000
#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000
#define FILE_COPY_STRUCTURED_STORAGE 0x00000041
#define FILE_STRUCTURED_STORAGE 0x00000441
#define FILE_VALID_OPTION_FLAGS 0x00ffffff
#define FILE_VALID_PIPE_OPTION_FLAGS 0x00000032
#define FILE_VALID_MAILSLOT_OPTION_FLAGS 0x00000032
#define FILE_VALID_SET_FLAGS 0x00000036
/* iob.Information for NtCreateFile or NtOpenFile */
#define FILE_SUPERSEDED 0x00000000
#define FILE_OPENED 0x00000001
#define FILE_CREATED 0x00000002
#define FILE_OVERWRITTEN 0x00000003
#define FILE_EXISTS 0x00000004
#define FILE_DOES_NOT_EXIST 0x00000005
/* CreateDisposition, from the ntddk.h */
#define FILE_SUPERSEDE 0x00000000
#define FILE_OPEN 0x00000001
#define FILE_CREATE 0x00000002
#define FILE_OPEN_IF 0x00000003
#define FILE_OVERWRITE 0x00000004
#define FILE_OVERWRITE_IF 0x00000005
#define FILE_MAXIMUM_DISPOSITION 0x00000005
/* note this is our own private flag, to explicitly set file owner */
#define FILE_DISPOSITION_SET_OWNER 0x10000000
/* from ntddk.h, special ByteOffset Parameters */
#define FILE_WRITE_TO_END_OF_FILE 0xffffffff
#define FILE_USE_FILE_POINTER_POSITION 0xfffffffe
#if _MSC_VER <= 1200
/* from ntstatus.h, NtFsControlFile typically returns this, if not using
* overlapped (i.e. asynch io) then TransactNamedPipe specifically checks for
* this value to determine whether or not it should wait on the pipe, this is
* the only return code it specifically checks for */
# define STATUS_PENDING 0x103
#endif
// Define the interesting device type values
#define FILE_DEVICE_FILE_SYSTEM 0x00000009
#define FILE_DEVICE_NAMED_PIPE 0x00000011
/* From NTSTATUS.H -- this shouldn't change, but you never know... */
/* DDK2003SP1/3790.1830/inc/wnet/ntstatus.h */
#define STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002L)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
/* The requested operation is not implemented. */
#define STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002L)
/* The file does not exist. */
#define STATUS_NO_SUCH_FILE ((NTSTATUS)0xC000000FL)
/* {Conflicting Address Range} The specified address range conflicts with the address space. */
#define STATUS_CONFLICTING_ADDRESSES ((NTSTATUS)0xC0000018L)
/* The end-of-file marker has been reached. There is no valid data in
* the file beyond this marker.
*/
#define STATUS_END_OF_FILE ((NTSTATUS)0xC0000011L)
/* "The address handle given to the transport was invalid." */
#define STATUS_INVALID_ADDRESS ((NTSTATUS)0xC0000141L)
/* "The data was too large to fit into the specified buffer." */
#define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005L)
/* No more files were found which match the file specification. */
#define STATUS_NO_MORE_FILES ((NTSTATUS)0x80000006L)
/* {Bad File} The attributes of the specified mapping file for a
* section of memory cannot be read. */
#define STATUS_INVALID_FILE_FOR_SECTION ((NTSTATUS)0xC0000020L)
/* {Access Denied} A process has requested access to an object, but
* has not been granted those access rights.*/
#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
/* "The buffer is too small to contain the entry. No information has been
* written to the buffer." */
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L)
/* There is a mismatch between the type of object required by the requested operation
* and the type of object that is specified in the request.
*/
#define STATUS_OBJECT_TYPE_MISMATCH ((NTSTATUS)0xC0000024L)
/* Object Name invalid. */
#define STATUS_OBJECT_NAME_INVALID ((NTSTATUS)0xC0000033L)
/* Object Name not found. */
#define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS)0xC0000034L)
/* Error: Object Name already exists */
#define STATUS_OBJECT_NAME_COLLISION ((NTSTATUS)0xC0000035L)
/* Object Path Component was not a directory object. */
#define STATUS_OBJECT_PATH_INVALID ((NTSTATUS)0xC0000039L)
/* The path does not exist. */
#define STATUS_OBJECT_PATH_NOT_FOUND ((NTSTATUS)0xC000003AL)
/* The specified section is too big to map the file. */
#define STATUS_SECTION_TOO_BIG ((NTSTATUS)0xC0000040L)
/* A file cannot be opened because the share access flags are incompatible. */
#define STATUS_SHARING_VIOLATION ((NTSTATUS)0xC0000043L)
/* The specified page protection was not valid. */
#define STATUS_INVALID_PAGE_PROTECTION ((NTSTATUS)0xC0000045L)
/* A requested read/write cannot be granted due to a conflicting file lock. */
#define STATUS_FILE_LOCK_CONFLICT ((NTSTATUS)0xC0000054L)
/* A non close operation has been requested of a file object with a delete pending. */
#define STATUS_DELETE_PENDING ((NTSTATUS)0xC0000056L)
/* The volume for a file has been externally altered such that the opened file
* is no longer valid.
*/
#define STATUS_FILE_INVALID ((NTSTATUS)0xC0000098L)
/* The file that was specified as a target is a directory and the
* caller specified that it could be anything but a directory.
*/
#define STATUS_FILE_IS_A_DIRECTORY ((NTSTATUS)0xC00000BAL)
/* Warning: An attempt was made to create an object and the object name already existed. */
#define STATUS_OBJECT_NAME_EXISTS ((NTSTATUS)0x40000000L)
/* Warning: Image Relocated
* "An image file could not be mapped at the address specified in the image file. "
* "Local fixups must be performed on this image."
*/
#define STATUS_IMAGE_NOT_AT_BASE ((NTSTATUS)0x40000003L)
#if !defined(STATUS_NO_MEMORY)
/* {Not Enough Quota} Not enough virtual memory or paging file quota
* is available to complete the specified operation. */
# define STATUS_NO_MEMORY ((NTSTATUS)0xC0000017L) /* winnt */
/* only seen on virtual memory reservation, maybe on NT it served multiple purposes */
#endif
/* Page file quota was exceeded. */
#define STATUS_PAGEFILE_QUOTA_EXCEEDED ((NTSTATUS)0xC000012CL)
/* not seen */
/* {Out of Virtual Memory} Your system is low on virtual memory. To
* ensure that Windows runs properly, increase the size of your
* virtual memory paging file. For more information, see Help.
*/
#define STATUS_COMMITMENT_LIMIT ((NTSTATUS)0xC000012DL)
/* Seen both when reaching the Commit limit (memory + page file size),
* as well as when a process in a Job reaches its ProcessMemoryLimit
*/
/* {Virtual Memory Minimum Too Low} Your system is low on virtual
* memory. Windows is increasing the size of your virtual memory
* paging file. During this process, memory requests for some
* applications may be denied. For more information, see Help.
*/
#define STATUS_COMMITMENT_MINIMUM ((NTSTATUS)0xC00002C8L)
/* This is the exception code microsoft uses for throw exception */
#define EXCEPTION_THROWN 0xe06d7363
/* Status to use with NtIsProcessInJob() on Win2003+ */
/* The specified process is not part of a job */
#define STATUS_PROCESS_NOT_IN_JOB ((NTSTATUS)0x00000123L)
/* The specified process is part of a job. */
#define STATUS_PROCESS_IN_JOB ((NTSTATUS)0x00000124L)
/* A specified privilege does not exist. */
#define STATUS_NO_SUCH_PRIVILEGE ((NTSTATUS)0xC0000060L)
/* A required privilege is not held by the client. */
#define STATUS_PRIVILEGE_NOT_HELD ((NTSTATUS)0xC0000061L)
/* Case 10579: pop but do not transfer control for NtCallbackReturn */
#define STATUS_CALLBACK_POP_STACK ((NTSTATUS)0xC0000423L)
/* needed for PR 233191 */
#define STATUS_INVALID_INFO_CLASS ((NTSTATUS)0xC0000003L)
/* An attempt was made to map a file of size zero with the maximum size specified as
* zero.
*/
#define STATUS_MAPPED_FILE_SIZE_ZERO ((NTSTATUS)0xC000011EL)
#define STATUS_PARTIAL_COPY ((NTSTATUS)0x8000000DL)
#ifndef STATUS_INVALID_PARAMETER
/* An invalid parameter was passed to a service or function. */
# define STATUS_INVALID_PARAMETER ((NTSTATUS)0xC000000DL)
#endif
/* Specified section to flush does not map a data file. */
#define STATUS_NOT_MAPPED_DATA ((NTSTATUS)0xC0000088L)
/* An invalid parameter was passed to a service or function as the first argument. */
#define STATUS_INVALID_PARAMETER_1 ((NTSTATUS)0xC00000EFL)
/* An invalid parameter was passed to a service or function as the second argument. */
#define STATUS_INVALID_PARAMETER_2 ((NTSTATUS)0xC00000F0L)
/* An invalid parameter was passed to a service or function as the third argument. */
#define STATUS_INVALID_PARAMETER_3 ((NTSTATUS)0xC00000F1L)
/* An invalid parameter was passed to a service or function as the fourth argument. */
#define STATUS_INVALID_PARAMETER_4 ((NTSTATUS)0xC00000F2L)
/* An invalid parameter was passed to a service or function as the fifth argument. */
#define STATUS_INVALID_PARAMETER_5 ((NTSTATUS)0xC00000F3L)
/* An invalid parameter was passed to a service or function as the sixth argument. */
#define STATUS_INVALID_PARAMETER_6 ((NTSTATUS)0xC00000F4L)
/* An invalid parameter was passed to a service or function as the seventh argument. */
#define STATUS_INVALID_PARAMETER_7 ((NTSTATUS)0xC00000F5L)
/* An invalid parameter was passed to a service or function as the eighth argument. */
#define STATUS_INVALID_PARAMETER_8 ((NTSTATUS)0xC00000F6L)
/* An invalid parameter was passed to a service or function as the ninth argument. */
#define STATUS_INVALID_PARAMETER_9 ((NTSTATUS)0xC00000F7L)
/* An invalid parameter was passed to a service or function as the tenth argument. */
#define STATUS_INVALID_PARAMETER_10 ((NTSTATUS)0xC00000F8L)
/* An invalid parameter was passed to a service or function as the eleventh argument. */
#define STATUS_INVALID_PARAMETER_11 ((NTSTATUS)0xC00000F9L)
/* An invalid parameter was passed to a service or function as the twelfth argument. */
#define STATUS_INVALID_PARAMETER_12 ((NTSTATUS)0xC00000FAL)
/* An attempt was made to access a thread that has begun termination. */
#define STATUS_THREAD_IS_TERMINATING ((NTSTATUS)0xC000004BL)
/* An attempt was made to access an exiting process. */
#define STATUS_PROCESS_IS_TERMINATING ((NTSTATUS)0xC000010AL)
/* The NTFS file or directory is not a reparse point. */
#define STATUS_NOT_A_REPARSE_POINT ((NTSTATUS)0xC0000275L)
/* This is in VS2005 winnt.h but not in SDK winnt.h */
#ifndef IMAGE_SIZEOF_BASE_RELOCATION
# define IMAGE_SIZEOF_BASE_RELOCATION 8
#endif
NTSTATUS
nt_create_file(OUT HANDLE *file_handle,
const wchar_t *filename, HANDLE dir_handle OPTIONAL,
size_t alloc_size, ACCESS_MASK rights, uint attributes, uint sharing,
uint create_disposition, uint create_options);
/* is_dir and synch are really bools */
/* note synch must be true if you are ever going to use read_file or write_file
* on the returned handle */
HANDLE
create_file(PCWSTR filename, bool is_dir, ACCESS_MASK rights, uint sharing,
uint create_disposition, bool synch);
#if !defined(NOT_DYNAMORIO_CORE_PROPER) && !defined(NOT_DYNAMORIO_CORE)
NTSTATUS
nt_open_file(HANDLE *handle OUT, PCWSTR filename, ACCESS_MASK rights, uint sharing,
uint options);
#endif
NTSTATUS
nt_delete_file(PCWSTR nt_filename);
NTSTATUS
nt_flush_file_buffers(HANDLE file_handle);
bool
read_file(HANDLE file_handle, void *buffer, uint num_bytes_to_read,
IN uint64* file_byte_offset OPTIONAL,
OUT size_t *num_bytes_read);
bool
write_file(HANDLE file_handle, const void *buffer, uint num_bytes_to_write,
OPTIONAL uint64* file_byte_offset,
OUT size_t *num_bytes_written);
bool
close_file(HANDLE hfile);
/* from DDK2003SP1/3790.1830/inc/ddk/wnet/ntddk.h */
typedef struct _FILE_STANDARD_INFORMATION {
LARGE_INTEGER AllocationSize;
LARGE_INTEGER EndOfFile;
ULONG NumberOfLinks;
BOOLEAN DeletePending;
BOOLEAN Directory;
} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
typedef struct _FILE_INTERNAL_INFORMATION {
LARGE_INTEGER IndexNumber;
} FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION;
typedef struct _FILE_POSITION_INFORMATION {
LARGE_INTEGER CurrentByteOffset;
} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;
typedef struct _FILE_ALIGNMENT_INFORMATION {
ULONG AlignmentRequirement;
} FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION;
#define MAX_FILE_NAME_LENGTH MAX_PATH
typedef struct _FILE_NAME_INFORMATION {
ULONG FileNameLength; /* length in _bytes_ */
WCHAR FileName[MAX_FILE_NAME_LENGTH];
/* NOTE that the official structure is FileName[1] so that
* callers control the length they are interested in */
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
typedef struct _FILE_RENAME_INFORMATION {
BOOLEAN ReplaceIfExists;
HANDLE RootDirectory;
ULONG FileNameLength;
WCHAR FileName[MAX_FILE_NAME_LENGTH];
} FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION;
typedef struct _FILE_ATTRIBUTE_TAG_INFORMATION {
ULONG FileAttributes;
ULONG ReparseTag;
} FILE_ATTRIBUTE_TAG_INFORMATION, *PFILE_ATTRIBUTE_TAG_INFORMATION;
typedef struct _FILE_DISPOSITION_INFORMATION {
BOOLEAN DeleteFile;
} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION;
typedef struct _FILE_END_OF_FILE_INFORMATION {
LARGE_INTEGER EndOfFile;
} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION;
typedef struct _FILE_VALID_DATA_LENGTH_INFORMATION {
LARGE_INTEGER ValidDataLength;
} FILE_VALID_DATA_LENGTH_INFORMATION, *PFILE_VALID_DATA_LENGTH_INFORMATION;
/* event synchronization, using both automatic and manual events */
HANDLE
nt_create_event(EVENT_TYPE event_type);
void
nt_close_event(HANDLE hevent);
typedef enum {WAIT_TIMEDOUT, WAIT_SIGNALED, WAIT_ERROR} wait_status_t;
#define INFINITE_WAIT ((PLARGE_INTEGER)NULL)
wait_status_t
nt_wait_event_with_timeout(HANDLE hevent, PLARGE_INTEGER timeout);
void
nt_set_event(HANDLE hevent);
/* should be used only for manual events (NotificationEvent) */
void
nt_clear_event(HANDLE hevent);
void
nt_signal_and_wait(HANDLE hevent_to_signal, HANDLE hevent_to_wait);
HANDLE
create_iocompletion(void);
HANDLE
open_pipe(PCWSTR pipename, HANDLE hsync);
size_t
nt_pipe_transceive(HANDLE hpipe, void *input, uint input_size,
void *output, uint output_size, uint timeout_ms);
#define TIMER_UNITS_PER_MILLISECOND (1000 * 10) /* 100ns intervals */
wchar_t *
get_process_param_buf(RTL_USER_PROCESS_PARAMETERS *params, wchar_t *buf);
/* uint query_time_seconds() declared in os_shared.h */
/* uint64 query_time_millis() declared in os_shared.h */
void
convert_100ns_to_system_time(uint64 time_in_100ns, SYSTEMTIME *st OUT);
void
convert_system_time_to_100ns(const SYSTEMTIME *st, uint64 *time_in_100ns OUT);
LONGLONG query_time_100ns(void);
void
query_system_time(SYSTEMTIME *st OUT);
void
nt_query_performance_counter(PLARGE_INTEGER counter, PLARGE_INTEGER frequency);
#ifdef WINDOWS_PC_SAMPLE
HANDLE
nt_create_profile(HANDLE process_handle, void *start, uint size, uint *buffer,
uint buffer_size, uint shift);
void
nt_set_profile_interval(uint nanoseconds);
int
nt_query_profile_interval(void);
void
nt_start_profile(HANDLE profile_handle);
void
nt_stop_profile(HANDLE profile_handle);
#endif
/* avoid needing x86_code.c from x86.asm from get_own_context_helper() */
#if !defined(NOT_DYNAMORIO_CORE) && !defined(NOT_DYNAMORIO_CORE_PROPER)
/* Executable name must be in kernel object name form
* (e.g., \SystemRoot\System32\notepad.exe, or \??\c:\foo\bar.exe)
* The executable name on the command line can be in any form.
* On success returns a handle for the child
* On failure returns INVALID_HANDLE_VALUE
*/
HANDLE
create_process(wchar_t *exe, wchar_t *cmdline);
/* NOTE see important usage information in ntdll.c, threads created with this
* function can NOT return from their start routine */
HANDLE
create_thread(HANDLE hProcess, bool target_64bit, void *start_addr,
void *arg, const void *arg_buf, size_t arg_buf_size,
uint stack_reserve, uint stack_commit, bool suspended, thread_id_t *tid);
HANDLE
create_thread_have_stack(HANDLE hProcess, bool target_64bit, void *start_addr,
void *arg, const void *arg_buf, size_t arg_buf_size,
byte *stack_base, size_t stack_size,
bool suspended, thread_id_t *tid);
/* NOTE : this isn't equivalent to nt_get_context(NT_CURRENT_THREAD, cxt)
* (where the returned context is undefined) so use this to get the context
* of the current thread */
/* FIXME : no support for float/mmx/sse/debug,
* also if integer or control does both
* Xref PR 264138 where we have to preserve xmm registers: however, no
* current uses need to get our own xmm registers, so we don't.
* PR 266070: If any future use uses this context to either set a
* priv_mcontext_t or passes it to nt_set_context() we'll have to add
* the xmm regs.
*/
/* NOTE : we use a macro so that we get the register state of the calling
* function (we don't want ebp/esp to point to a leaf routine's stack frame) */
#define GET_OWN_CONTEXT(cxt) { \
if (TESTANY(CONTEXT_CONTROL|CONTEXT_INTEGER, (cxt)->ContextFlags)) {\
byte *__get_own_context_cur_esp; \
get_own_context_helper((cxt)); \
GET_STACK_PTR(__get_own_context_cur_esp); \
(cxt)->CXT_XSP = (reg_t) __get_own_context_cur_esp; \
} \
get_own_context((cxt)); \
}
/* unstatic for use by GET_OWN_CONTEXT macro */
void
get_own_context_integer_control(CONTEXT *cxt, reg_t cs, reg_t ss,
priv_mcontext_t *mc);
/* don't call this directly, use GET_OWN_CONTEXT macro instead (it fills
* in CONTEXT_INTEGER and CONTEXT_CONTROL values, this fills the rest) */
void
get_own_context(CONTEXT *cxt);
#endif /* !defined(NOT_DYNAMORIO_CORE) && !defined(NOT_DYNAMORIO_CORE_PROPER) */
/***************************************************/
/* in module_shared.c */
enum { /* can't put w/ os_exports.h enum b/c needed for non-core */
/* for accessing x64 data from WOW64 */
X64_PEB_TIB_OFFSET = 0x060,
X64_LDR_PEB_OFFSET = 0x018,
};
LDR_MODULE *
get_ldr_module_by_name(wchar_t *name);;
bool
ldr_module_statically_linked(LDR_MODULE *mod);
#ifndef X64
void *
get_own_x64_peb(void);
/* caller must synchronize if not called during init */
HANDLE
load_library_64(const char *path);
bool
free_library_64(HANDLE lib);
HANDLE
get_module_handle_64(wchar_t *name);
void *
get_proc_address_64(HANDLE lib, const char *name);
#endif /* !X64 */
IMAGE_EXPORT_DIRECTORY*
get_module_exports_directory(app_pc base_addr, size_t *exports_size /* OPTIONAL OUT */);
IMAGE_EXPORT_DIRECTORY*
get_module_exports_directory_check(app_pc base_addr,
size_t *exports_size /*OPTIONAL OUT*/,
bool check_names);
/***************************************************/
/* Kernel32 uses HMODULE type for Load/FreeLibrary and GetModuleHandle. This
* is, at least in the platforms we've seen so far, just a pointer to the base
* address of the dll. We use separate types here to keep things neat.
* module_handle_t is a pointer to an opaque struct to improve type safety, but
* internally we use module_base_t which can be freely converted to HMODULE,
* HANDLE, byte*, and app_pc.
*/
/* FIXME: This duplicates the typedef in module_shared.h, but we can't include
* that into drpreinject or drinjectlib.
*/
struct _module_handle_t;
typedef struct _module_handle_t *module_handle_t;
typedef void *module_base_t;
module_handle_t
load_library(wchar_t *lib_name);
bool
free_library(module_handle_t lib);
module_handle_t
get_module_handle(wchar_t *lib_name);
/* From WINNT.H for .NET 2.0 (Visual Studio.NET VC7)
* Needed for IMAGE_COR20_HEADER
*/
#ifndef __IMAGE_COR20_HEADER_DEFINED__
#define __IMAGE_COR20_HEADER_DEFINED__
typedef enum replaces_cor_hdr_numeric_defines_t
{
// COM+ Header entry point flags.
COMIMAGE_FLAGS_ILONLY =0x00000001,
COMIMAGE_FLAGS_32BITREQUIRED =0x00000002,
COMIMAGE_FLAGS_IL_LIBRARY =0x00000004,
COMIMAGE_FLAGS_STRONGNAMESIGNED =0x00000008,
COMIMAGE_FLAGS_TRACKDEBUGDATA =0x00010000,
// Version flags for image.
COR_VERSION_MAJOR_V2 =2,
COR_VERSION_MAJOR =COR_VERSION_MAJOR_V2,
COR_VERSION_MINOR =0,
COR_DELETED_NAME_LENGTH =8,
COR_VTABLEGAP_NAME_LENGTH =8,
// Maximum size of a NativeType descriptor.
NATIVE_TYPE_MAX_CB =1,
COR_ILMETHOD_SECT_SMALL_MAX_DATASIZE=0xFF,
// #defines for the MIH FLAGS
IMAGE_COR_MIH_METHODRVA =0x01,
IMAGE_COR_MIH_EHRVA =0x02,
IMAGE_COR_MIH_BASICBLOCK =0x08,
// V-table constants
COR_VTABLE_32BIT =0x01, // V-table slots are 32-bits in size.
COR_VTABLE_64BIT =0x02, // V-table slots are 64-bits in size.
COR_VTABLE_FROM_UNMANAGED =0x04, // If set, transition from unmanaged.
COR_VTABLE_CALL_MOST_DERIVED =0x10, // Call most derived method described by
// EATJ constants
IMAGE_COR_EATJ_THUNK_SIZE =32, // Size of a jump thunk reserved range.
// Max name lengths
//@todo: Change to unlimited name lengths.
MAX_CLASS_NAME =1024,
MAX_PACKAGE_NAME =1024,
} replaces_cor_hdr_numeric_defines_t;
// COM+ 2.0 header structure.
typedef struct IMAGE_COR20_HEADER
{
// Header versioning
DWORD cb;
WORD MajorRuntimeVersion;
WORD MinorRuntimeVersion;
// Symbol table and startup information
IMAGE_DATA_DIRECTORY MetaData;
DWORD Flags;
DWORD EntryPointToken;
// Binding information
IMAGE_DATA_DIRECTORY Resources;
IMAGE_DATA_DIRECTORY StrongNameSignature;
// Regular fixup and binding information
IMAGE_DATA_DIRECTORY CodeManagerTable;
IMAGE_DATA_DIRECTORY VTableFixups;
IMAGE_DATA_DIRECTORY ExportAddressTableJumps;
// Precompiled image info (internal use only - set to zero)
IMAGE_DATA_DIRECTORY ManagedNativeHeader;
} IMAGE_COR20_HEADER, *PIMAGE_COR20_HEADER;
#endif // __IMAGE_COR20_HEADER_DEFINED__
#ifndef IMAGE_SCN_ALIGN_MASK
#define IMAGE_SCN_ALIGN_MASK 0x00F00000 /* from latest winnt.h */
#endif /* IMAGE_SCN_ALIGN_MASK */
NTSTATUS
nt_initialize_shared_directory(HANDLE *shared_directory /* OUT */, bool permanent);
NTSTATUS
nt_open_object_directory(HANDLE *shared_directory /* OUT */,
PCWSTR object_directory_name,
bool allow_creation);
void
nt_close_object_directory(HANDLE hobjdir);
NTSTATUS
nt_get_symlink_target(IN HANDLE directory_handle,
IN PCWSTR symlink_name,
IN OUT UNICODE_STRING* target_name,
OUT uint * returned_byte_length);
#define MAX_OBJECT_NAME_LENGTH MAX_PATH
typedef struct _OBJECT_NAME_INFORMATION {
UNICODE_STRING ObjectName;
/* note that the nt interface allows callers to specify any size,
* yet we do not expect needs for longer */
wchar_t object_name_buffer[MAX_OBJECT_NAME_LENGTH];
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
NTSTATUS
wchar_to_unicode(PUNICODE_STRING dst, PCWSTR src);
NTSTATUS
nt_get_object_name(HANDLE handle, OBJECT_NAME_INFORMATION* object_name /* OUT */,
uint byte_length, uint *returned_byte_length);
NTSTATUS
nt_create_section(OUT PHANDLE SectionHandle,
IN ACCESS_MASK DesiredAccess,
IN PLARGE_INTEGER SectionSize OPTIONAL,
IN ULONG Protect,
IN ULONG section_creation_attributes,
IN HANDLE FileHandle,
/* object name attributes */
IN PCWSTR new_section_name,
IN ULONG object_name_attributes,
IN HANDLE object_directory,
IN PSECURITY_DESCRIPTOR dacl
);
NTSTATUS
nt_open_section(OUT PHANDLE SectionHandle,
IN ACCESS_MASK DesiredAccess,
/* object name attributes */
IN PCWSTR section_name,
IN ULONG object_name_attributes,
IN HANDLE object_directory);
NTSTATUS
nt_create_module_file(OUT HANDLE* file_handle,
const wchar_t *file_path,
IN HANDLE root_directory_handle OPTIONAL,
ACCESS_MASK desired_access_rights,
uint file_special_attributes,
uint file_sharing_flags,
uint create_disposition,
size_t allocation_size);
NTSTATUS
nt_query_file_info(IN HANDLE FileHandle,
OUT PVOID FileInformation,
IN ULONG FileInformationLength,
IN FILE_INFORMATION_CLASS FileInformationClass);
NTSTATUS
nt_set_file_info(IN HANDLE FileHandle,
IN PVOID FileInformation,
IN ULONG FileInformationLength,
IN FILE_INFORMATION_CLASS FileInformationClass);
NTSTATUS
nt_query_volume_info(IN HANDLE FileHandle,
OUT PVOID FsInformation,
IN ULONG FsInformationLength,
IN FS_INFORMATION_CLASS FsInformationClass);
NTSTATUS
nt_query_security_object(IN HANDLE Handle,
IN SECURITY_INFORMATION RequestedInformation,
OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
IN ULONG SecurityDescriptorLength,
OUT PULONG ReturnLength);
/***************************************************************************
* SHARED NON-RAW NTDLL WRAPPERS
*
* These are ones for which there's no extra value we want to add in
* an nt_() routine of our own, but we want to share (typically between
* ntdll.c and drwinapi/).
*/
GET_NTDLL(RtlEnterCriticalSection, (IN OUT RTL_CRITICAL_SECTION *crit));
GET_NTDLL(RtlLeaveCriticalSection, (IN OUT RTL_CRITICAL_SECTION *crit));
GET_NTDLL(NtWaitForSingleObject, (IN HANDLE ObjectHandle,
IN BOOLEAN Alertable,
IN PLARGE_INTEGER TimeOut));
GET_NTDLL(NtFsControlFile, (IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG FsControlCode,
IN PVOID InputBuffer OPTIONAL,
IN ULONG InputBufferLength,
OUT PVOID OutputBuffer OPTIONAL,
IN ULONG OutputBufferLength));
GET_NTDLL(NtReadFile, (IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL));
GET_NTDLL(NtWriteFile, (IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN const void *Buffer, /* PVOID, but need const */
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL));
/***************************************************************************
* RAW WRAPPERS
*/
#if !defined(NOT_DYNAMORIO_CORE_PROPER) && !defined(NOT_DYNAMORIO_CORE)
NTSTATUS
nt_raw_CreateFile(PHANDLE file_handle,
ACCESS_MASK desired_access,
POBJECT_ATTRIBUTES object_attributes,
PIO_STATUS_BLOCK io_status_block,
PLARGE_INTEGER allocation_size,
ULONG file_attributes,
ULONG share_access,
ULONG create_disposition,
ULONG create_options,
PVOID ea_buffer,
ULONG ea_length);
NTSTATUS
nt_raw_OpenFile(PHANDLE file_handle,
ACCESS_MASK desired_access,
POBJECT_ATTRIBUTES object_attributes,
PIO_STATUS_BLOCK io_status_block,
ULONG share_access,
ULONG open_options);
NTSTATUS
nt_raw_OpenKey(PHANDLE key_handle,
ACCESS_MASK desired_access,
POBJECT_ATTRIBUTES object_attributes);
NTSTATUS
nt_raw_OpenKeyEx(PHANDLE key_handle,
ACCESS_MASK desired_access,
POBJECT_ATTRIBUTES object_attributes,
ULONG open_options);
NTSTATUS
nt_raw_OpenProcessTokenEx(HANDLE process_handle,
ACCESS_MASK desired_access,
ULONG handle_attributes,
PHANDLE token_handle);
NTSTATUS
nt_raw_OpenThread(PHANDLE thread_handle,
ACCESS_MASK desired_access,
POBJECT_ATTRIBUTES object_attributes,
PCLIENT_ID client_id);
NTSTATUS
nt_raw_OpenThreadTokenEx(HANDLE thread_handle,
ACCESS_MASK desired_access,
BOOLEAN open_as_self,
ULONG handle_attributes,
PHANDLE token_handle);
NTSTATUS
nt_raw_QueryAttributesFile(POBJECT_ATTRIBUTES object_attributes,
PFILE_BASIC_INFORMATION file_information);
NTSTATUS
nt_raw_SetInformationFile(HANDLE file_handle,
PIO_STATUS_BLOCK io_status_block,
PVOID file_information,
ULONG length,
FILE_INFORMATION_CLASS file_information_class);
NTSTATUS
nt_raw_SetInformationThread(HANDLE thread_handle,
THREADINFOCLASS thread_information_class,
PVOID thread_information,
ULONG thread_information_length);
NTSTATUS
nt_raw_UnmapViewOfSection(HANDLE process_handle,
PVOID base_address);
#endif /* !NOT_DYNAMORIO_CORE && !NOT_DYNAMORIO_CORE_PROPER */
NTSTATUS
nt_raw_OpenProcess(PHANDLE process_handle,
ACCESS_MASK desired_access,
POBJECT_ATTRIBUTES object_attributes,
PCLIENT_ID client_id);
NTSTATUS
nt_raw_MapViewOfSection(HANDLE section_handle,
HANDLE process_handle,
PVOID *base_address,
ULONG_PTR zero_bits,
SIZE_T commit_size,
PLARGE_INTEGER section_offset,
PSIZE_T view_size,
SECTION_INHERIT inherit_disposition,
ULONG allocation_type,
ULONG win32_protect);
NTSTATUS
nt_raw_QueryFullAttributesFile(POBJECT_ATTRIBUTES object_attributes,
PFILE_NETWORK_OPEN_INFORMATION file_information);
NTSTATUS
nt_raw_CreateKey(PHANDLE key_handle,
ACCESS_MASK desired_access,
POBJECT_ATTRIBUTES object_attributes,
ULONG title_index,
PUNICODE_STRING class,
ULONG create_options,
PULONG disposition);
NTSTATUS
nt_raw_OpenThreadToken(HANDLE thread_handle,
ACCESS_MASK desired_access,
BOOLEAN open_as_self,
PHANDLE token_handle);
NTSTATUS
nt_raw_OpenProcessToken(HANDLE process_handle,
ACCESS_MASK desired_access,
PHANDLE token_handle);
#define HEAP_CLASS_PRIVATE 0x00001000
#endif /* _NTDLL_H_ */