494 lines
11 KiB
C
494 lines
11 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1998-2000 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
wow64.h
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Public header for wow64.dll
|
||
|
|
||
|
Author:
|
||
|
|
||
|
11-May-1998 BarryBo
|
||
|
|
||
|
Revision History:
|
||
|
9-Aug-1999 [askhalid] added WOW64IsCurrentProcess
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#ifndef _WOW64_INCLUDE
|
||
|
#define _WOW64_INCLUDE
|
||
|
|
||
|
//
|
||
|
// Make wow64.dll exports __declspec(dllimport) when this header is included
|
||
|
// by non-wow64 components
|
||
|
//
|
||
|
#if !defined(_WOW64DLLAPI_)
|
||
|
#define WOW64DLLAPI DECLSPEC_IMPORT
|
||
|
#else
|
||
|
#define WOW64DLLAPI
|
||
|
#endif
|
||
|
|
||
|
// crank down some warnings
|
||
|
#pragma warning(4:4312) // conversion to type of greater size
|
||
|
|
||
|
|
||
|
// pull in typedefs for TEB32, PEB32, etc.
|
||
|
#include "wow64t.h"
|
||
|
|
||
|
#include <setjmp.h>
|
||
|
#include <windef.h>
|
||
|
|
||
|
// wow64log constatns
|
||
|
#include "wow64log.h"
|
||
|
|
||
|
//wow64 regremaping
|
||
|
#include "regremap.h"
|
||
|
|
||
|
//
|
||
|
// Enable the wow64 history mechanism
|
||
|
// Eventually, this may only be enabled for debug builds, but for
|
||
|
// now, enable all the time
|
||
|
//
|
||
|
#define WOW64_HISTORY
|
||
|
|
||
|
//
|
||
|
// define a datatype corresponding to the 32-bit machine's CONTEXT
|
||
|
//
|
||
|
#include "wx86nt.h"
|
||
|
#define CONTEXT32 CONTEXT_WX86
|
||
|
#define PCONTEXT32 PCONTEXT_WX86
|
||
|
#define CONTEXT32_CONTROL CONTEXT_CONTROL_WX86
|
||
|
#define CONTEXT32_INTEGER CONTEXT_INTEGER_WX86
|
||
|
#define CONTEXT32_SEGMENTS CONTEXT_SEGMENTS_WX86
|
||
|
#define CONTEXT32_FLOATING_POINT CONTEXT_FLOATING_POINT_WX86
|
||
|
#define CONTEXT32_EXTENDED_REGISTERS CONTEXT_EXTENDED_REGISTERS_WX86
|
||
|
#define CONTEXT32_DEBUG_REGISTERS CONTEXT_DEBUG_REGISTERS_WX86
|
||
|
#define CONTEXT32_FULL CONTEXT_FULL_WX86
|
||
|
#define CONTEXT32_FULLFLOAT (CONTEXT_FULL_WX86|CONTEXT32_FLOATING_POINT|CONTEXT32_EXTENDED_REGISTERS)
|
||
|
|
||
|
#if defined(_AXP64_)
|
||
|
// Enable 4k page emulation in software. IA64 does it in h/w with OS support.
|
||
|
#define SOFTWARE_4K_PAGESIZE 1
|
||
|
#endif
|
||
|
|
||
|
typedef enum _WOW64_API_ERROR_ACTION {
|
||
|
ApiErrorNTSTATUS, //Return exception code as return value
|
||
|
ApiErrorNTSTATUSTebCode, //Some as above with SetLastError on exception code
|
||
|
ApiErrorRetval, //Return a constant parameter
|
||
|
ApiErrorRetvalTebCode //Some as above with SetLastError on exception code
|
||
|
} WOW64_API_ERROR_ACTION, *PWOW64_API_ERROR_ACTION;
|
||
|
|
||
|
// This structure describes what action should occure when thunks hit an unhandled exception.
|
||
|
typedef struct _WOW64_SERVICE_ERROR_CASE {
|
||
|
WOW64_API_ERROR_ACTION ErrorAction;
|
||
|
LONG ErrorActionParam;
|
||
|
} WOW64_SERVICE_ERROR_CASE, *PWOW64_SERVICE_ERROR_CASE;
|
||
|
|
||
|
// This is an extension of KSERVICE_TABLE_DESCRIPTOR
|
||
|
typedef struct _WOW64SERVICE_TABLE_DESCRIPTOR {
|
||
|
PULONG_PTR Base;
|
||
|
PULONG Count;
|
||
|
ULONG Limit;
|
||
|
#if defined(_IA64_)
|
||
|
LONG TableBaseGpOffset;
|
||
|
#endif
|
||
|
PUCHAR Number;
|
||
|
WOW64_API_ERROR_ACTION DefaultErrorAction; //Action if ErrorCases is NULL.
|
||
|
LONG DefaultErrorActionParam; //Action parameter if ErrorCases is NULL.
|
||
|
PWOW64_SERVICE_ERROR_CASE ErrorCases;
|
||
|
} WOW64SERVICE_TABLE_DESCRIPTOR, *PWOW64SERVICE_TABLE_DESCRIPTOR;
|
||
|
|
||
|
// Used to log hit counts for APIs.
|
||
|
typedef struct _WOW64SERVICE_PROFILE_TABLE WOW64SERVICE_PROFILE_TABLE;
|
||
|
typedef struct _WOW64SERVICE_PROFILE_TABLE *PWOW64SERVICE_PROFILE_TABLE;
|
||
|
|
||
|
typedef struct _WOW64SERVICE_PROFILE_TABLE_ELEMENT {
|
||
|
PWSTR ApiName;
|
||
|
SIZE_T HitCount;
|
||
|
PWOW64SERVICE_PROFILE_TABLE SubTable;
|
||
|
BOOLEAN ApiEnabled;
|
||
|
} WOW64SERVICE_PROFILE_TABLE_ELEMENT, *PWOW64SERVICE_PROFILE_TABLE_ELEMENT;
|
||
|
|
||
|
typedef struct _WOW64SERVICE_PROFILE_TABLE {
|
||
|
PWSTR TableName; //OPTIONAL
|
||
|
PWSTR FriendlyTableName; //OPTIONAL
|
||
|
CONST PWOW64SERVICE_PROFILE_TABLE_ELEMENT ProfileTableElements;
|
||
|
SIZE_T NumberProfileTableElements;
|
||
|
} WOW64SERVICE_PROFILE_TABLE, *PWOW64SERVICE_PROFILE_TABLE;
|
||
|
|
||
|
typedef struct _WOW64_SYSTEM_INFORMATION {
|
||
|
SYSTEM_BASIC_INFORMATION BasicInfo;
|
||
|
SYSTEM_PROCESSOR_INFORMATION ProcessorInfo;
|
||
|
ULONG_PTR RangeInfo;
|
||
|
} WOW64_SYSTEM_INFORMATION, *PWOW64_SYSTEM_INFORMATION;
|
||
|
|
||
|
//
|
||
|
// Indices for API thunks.
|
||
|
//
|
||
|
#define WHNT32_INDEX 0 // ntoskrnl
|
||
|
#define WHCON_INDEX 1 // console (replaces LPC calls)
|
||
|
#define WHWIN32_INDEX 2 // win32k
|
||
|
#define WHBASE_INDEX 3 // base/nls (replaces LPC calls)
|
||
|
#define MAX_TABLE_INDEX 4
|
||
|
|
||
|
|
||
|
//
|
||
|
// Logging mechanism. Usage:
|
||
|
// LOGPRINT((verbosity, format, ...))
|
||
|
//
|
||
|
#define LOGPRINT(args) Wow64LogPrint args
|
||
|
#define ERRORLOG LF_ERROR // Always output to debugger. Use for *unexpected*
|
||
|
// errors only
|
||
|
#define TRACELOG LF_TRACE // application trace information
|
||
|
#define INFOLOG LF_TRACE // misc. informational log
|
||
|
#define VERBOSELOG LF_NONE // practically never output to debugger
|
||
|
|
||
|
#if DBG
|
||
|
#define WOW64DOPROFILE
|
||
|
#endif
|
||
|
|
||
|
void
|
||
|
WOW64DLLAPI
|
||
|
Wow64LogPrint(
|
||
|
UCHAR LogLevel,
|
||
|
char *format,
|
||
|
...
|
||
|
);
|
||
|
|
||
|
|
||
|
|
||
|
//
|
||
|
// WOW64 Assertion Mechanism. Usage:
|
||
|
// - put an ASSERTNAME macro at the top of each .C file
|
||
|
// - WOW64ASSERT(expression)
|
||
|
// - WOW64ASSERTMSG(expression, message)
|
||
|
//
|
||
|
//
|
||
|
|
||
|
VOID
|
||
|
WOW64DLLAPI
|
||
|
Wow64Assert(
|
||
|
IN CONST PSZ exp,
|
||
|
OPTIONAL IN CONST PSZ msg,
|
||
|
IN CONST PSZ mod,
|
||
|
IN LONG LINE
|
||
|
);
|
||
|
|
||
|
#if DBG
|
||
|
|
||
|
#undef ASSERTNAME
|
||
|
#define ASSERTNAME static CONST PSZ szModule = __FILE__;
|
||
|
|
||
|
#define WOWASSERT(exp) \
|
||
|
if (!(exp)) { \
|
||
|
Wow64Assert( #exp, NULL, szModule, __LINE__); \
|
||
|
}
|
||
|
|
||
|
#define WOWASSERTMSG(exp, msg) \
|
||
|
if (!(exp)) { \
|
||
|
Wow64Assert( #exp, msg, szModule, __LINE__); \
|
||
|
}
|
||
|
|
||
|
#else // !DBG
|
||
|
|
||
|
#define WOWASSERT(exp)
|
||
|
#define WOWASSERTMSG(exp, msg)
|
||
|
|
||
|
#endif // !DBG
|
||
|
|
||
|
#define WOWASSERT_PTR32(ptr) WOWASSERT((ULONGLONG)ptr < 0xFFFFFFFF)
|
||
|
|
||
|
WOW64DLLAPI
|
||
|
PVOID
|
||
|
Wow64AllocateHeap(
|
||
|
SIZE_T Size
|
||
|
);
|
||
|
|
||
|
WOW64DLLAPI
|
||
|
VOID
|
||
|
Wow64FreeHeap(
|
||
|
PVOID BaseAddress
|
||
|
);
|
||
|
|
||
|
|
||
|
//
|
||
|
// 64-to-32 callback support for usermode APCs
|
||
|
//
|
||
|
|
||
|
// A list of these sits inside WOW64_TLS_APCLIST
|
||
|
typedef struct tagUserApcList {
|
||
|
struct tagUserApcList *Next;
|
||
|
jmp_buf JumpBuffer;
|
||
|
PCONTEXT32 pContext32;
|
||
|
} USER_APC_ENTRY, *PUSER_APC_ENTRY;
|
||
|
|
||
|
BOOL
|
||
|
WOW64DLLAPI
|
||
|
WOW64IsCurrentProcess (
|
||
|
HANDLE hProcess
|
||
|
);
|
||
|
|
||
|
NTSTATUS
|
||
|
Wow64WrapApcProc(
|
||
|
IN OUT PVOID *pApcProc,
|
||
|
IN OUT PVOID *pApcContext
|
||
|
);
|
||
|
|
||
|
|
||
|
typedef struct UserCallbackData {
|
||
|
jmp_buf JumpBuffer;
|
||
|
PVOID PreviousUserCallbackData;
|
||
|
PVOID OutputBuffer;
|
||
|
ULONG OutputLength;
|
||
|
NTSTATUS Status;
|
||
|
PVOID UserBuffer;
|
||
|
} USERCALLBACKDATA, *PUSERCALLBACKDATA;
|
||
|
|
||
|
ULONG
|
||
|
Wow64KiUserCallbackDispatcher(
|
||
|
PUSERCALLBACKDATA pUserCallbackData,
|
||
|
ULONG ApiNumber,
|
||
|
ULONG ApiArgument,
|
||
|
ULONG ApiSize
|
||
|
);
|
||
|
|
||
|
NTSTATUS
|
||
|
Wow64NtCallbackReturn(
|
||
|
PVOID OutputBuffer,
|
||
|
ULONG OutputLength,
|
||
|
NTSTATUS Status
|
||
|
);
|
||
|
|
||
|
BOOL
|
||
|
Wow64IsModule32bitHelper(
|
||
|
HANDLE ProcessHandle,
|
||
|
IN ULONG64 DllBase);
|
||
|
|
||
|
BOOL
|
||
|
Wow64IsModule32bit(
|
||
|
IN PCLIENT_ID ClientId,
|
||
|
IN ULONG64 DllBase);
|
||
|
|
||
|
NTSTATUS
|
||
|
Wow64SkipOverBreakPoint(
|
||
|
IN PCLIENT_ID ClientId,
|
||
|
IN PEXCEPTION_RECORD ExceptionRecord);
|
||
|
|
||
|
NTSTATUS
|
||
|
Wow64GetThreadSelectorEntry(
|
||
|
IN HANDLE ThreadHandle,
|
||
|
IN OUT PVOID DescriptorTableEntry,
|
||
|
IN ULONG Length,
|
||
|
OUT PULONG ReturnLength OPTIONAL);
|
||
|
|
||
|
//
|
||
|
// Thread Local Storage (TLS) support. TLS slots are statically allocated.
|
||
|
//
|
||
|
#define WOW64_TLS_STACKPTR64 0 // contains 64-bit stack ptr when simulating 32-bit code
|
||
|
#define WOW64_TLS_CPURESERVED 1 // per-thread data for the CPU simulator
|
||
|
#define WOW64_TLS_INCPUSIMULATION 2 // Set when inside the CPU
|
||
|
#define WOW64_TLS_TEMPLIST 3 // List of memory allocated in thunk call.
|
||
|
#define WOW64_TLS_EXCEPTIONADDR 4 // 32-bit exception address (used during exception unwinds)
|
||
|
#define WOW64_TLS_USERCALLBACKDATA 5 // Used by win32k callbacks
|
||
|
#define WOW64_TLS_EXTENDED_FLOAT 6 // Used in ia64 to pass in floating point
|
||
|
#define WOW64_TLS_APCLIST 7 // List of outstanding usermode APCs
|
||
|
#define WOW64_TLS_FILESYSREDIR 8 // Used to enable/disable the filesystem redirector
|
||
|
#define WOW64_TLS_LASTWOWCALL 9 // Pointer to the last wow call struct (Used when wowhistory is enabled)
|
||
|
#define WOW64_TLS_WOW64INFO 10 // Wow64Info address (structure shared between 32-bit and 64-bit code inside Wow64).
|
||
|
|
||
|
// VOID Wow64TlsSetValue(DWORD dwIndex, LPVOID lpTlsValue);
|
||
|
#define Wow64TlsSetValue(dwIndex, lpTlsValue) \
|
||
|
NtCurrentTeb()->TlsSlots[dwIndex] = lpTlsValue;
|
||
|
|
||
|
// LPVOID Wow64TlsGetValue(DWORD dwIndex);
|
||
|
#define Wow64TlsGetValue(dwIndex) \
|
||
|
(NtCurrentTeb()->TlsSlots[dwIndex])
|
||
|
|
||
|
//
|
||
|
// 32-to-64 thunk routine
|
||
|
//
|
||
|
LONG
|
||
|
WOW64DLLAPI
|
||
|
Wow64SystemService(
|
||
|
IN ULONG ServiceNumber,
|
||
|
IN PCONTEXT32 Context32
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// Wow64RaiseException
|
||
|
//
|
||
|
WOW64DLLAPI
|
||
|
NTSTATUS
|
||
|
Wow64RaiseException(
|
||
|
IN DWORD InterruptNumber,
|
||
|
IN OUT PEXCEPTION_RECORD ExceptionRecord);
|
||
|
|
||
|
|
||
|
//
|
||
|
// Helper routines, called from the thunks
|
||
|
//
|
||
|
|
||
|
#define CHILD_PROCESS_SIGNATURE 0xff00ff0011001100
|
||
|
typedef struct _ChildProcessInfo {
|
||
|
ULONG_PTR Signature;
|
||
|
PPEB32 pPeb32;
|
||
|
SECTION_IMAGE_INFORMATION ImageInformation;
|
||
|
ULONG_PTR TailSignature;
|
||
|
} CHILD_PROCESS_INFO, *PCHILD_PROCESS_INFO;
|
||
|
|
||
|
PVOID
|
||
|
WOW64DLLAPI
|
||
|
Wow64AllocateTemp(
|
||
|
SIZE_T Size
|
||
|
);
|
||
|
|
||
|
NTSTATUS
|
||
|
WOW64DLLAPI
|
||
|
Wow64QueryBasicInformationThread(
|
||
|
IN HANDLE Thread,
|
||
|
OUT PTHREAD_BASIC_INFORMATION ThreadInfo
|
||
|
);
|
||
|
|
||
|
WOW64DLLAPI
|
||
|
NTSTATUS
|
||
|
Wow64NtCreateThread(
|
||
|
OUT PHANDLE ThreadHandle,
|
||
|
IN ACCESS_MASK DesiredAccess,
|
||
|
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
||
|
IN HANDLE ProcessHandle,
|
||
|
OUT PCLIENT_ID ClientId,
|
||
|
IN PCONTEXT ThreadContext,
|
||
|
IN PINITIAL_TEB InitialTeb,
|
||
|
IN BOOLEAN CreateSuspended
|
||
|
);
|
||
|
|
||
|
WOW64DLLAPI
|
||
|
NTSTATUS
|
||
|
Wow64NtTerminateThread(
|
||
|
HANDLE ThreadHandle,
|
||
|
NTSTATUS ExitStatus
|
||
|
);
|
||
|
|
||
|
NTSTATUS
|
||
|
Wow64ExitThread(
|
||
|
HANDLE ThreadHandle,
|
||
|
NTSTATUS ExitStatus
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
Wow64BaseFreeStackAndTerminate(
|
||
|
IN PVOID OldStack,
|
||
|
IN ULONG ExitCode
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
Wow64BaseSwitchStackThenTerminate (
|
||
|
IN PVOID StackLimit,
|
||
|
IN PVOID NewStack,
|
||
|
IN ULONG ExitCode
|
||
|
);
|
||
|
|
||
|
NTSTATUS
|
||
|
Wow64NtContinue(
|
||
|
IN PCONTEXT ContextRecord, // really a PCONTEXT32
|
||
|
IN BOOLEAN TestAlert
|
||
|
);
|
||
|
|
||
|
NTSTATUS
|
||
|
WOW64DLLAPI
|
||
|
Wow64SuspendThread(
|
||
|
IN HANDLE ThreadHandle,
|
||
|
OUT PULONG PreviousSuspendCount OPTIONAL
|
||
|
);
|
||
|
|
||
|
NTSTATUS
|
||
|
WOW64DLLAPI
|
||
|
Wow64GetContextThread(
|
||
|
IN HANDLE ThreadHandle,
|
||
|
IN OUT PCONTEXT ThreadContext // really a PCONTEXT32
|
||
|
);
|
||
|
|
||
|
NTSTATUS
|
||
|
WOW64DLLAPI
|
||
|
Wow64SetContextThread(
|
||
|
IN HANDLE ThreadHandle,
|
||
|
IN PCONTEXT ThreadContext // really a PCONTEXT32
|
||
|
);
|
||
|
|
||
|
NTSTATUS
|
||
|
Wow64KiRaiseException(
|
||
|
IN PEXCEPTION_RECORD ExceptionRecord,
|
||
|
IN PCONTEXT ContextRecord,
|
||
|
IN BOOLEAN FirstChance
|
||
|
);
|
||
|
|
||
|
ULONG
|
||
|
Wow64SetupApcCall(
|
||
|
IN ULONG NormalRoutine,
|
||
|
IN PCONTEXT32 NormalContext,
|
||
|
IN ULONG Arg1,
|
||
|
IN ULONG Arg2
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
ThunkExceptionRecord64To32(
|
||
|
IN PEXCEPTION_RECORD pRecord64,
|
||
|
OUT PEXCEPTION_RECORD32 pRecord32
|
||
|
);
|
||
|
|
||
|
BOOLEAN
|
||
|
Wow64NotifyDebugger(
|
||
|
IN PEXCEPTION_RECORD ExceptionRecord,
|
||
|
IN BOOLEAN FirstChance
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
Wow64SetupExceptionDispatch(
|
||
|
IN PEXCEPTION_RECORD32 pRecord32,
|
||
|
IN PCONTEXT32 pContext32
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
Wow64NotifyDebuggerHelper(
|
||
|
IN PEXCEPTION_RECORD ExceptionRecord,
|
||
|
IN BOOLEAN FirstChance
|
||
|
);
|
||
|
|
||
|
NTSTATUS
|
||
|
Wow64InitializeEmulatedSystemInformation(
|
||
|
VOID
|
||
|
);
|
||
|
|
||
|
PWOW64_SYSTEM_INFORMATION
|
||
|
Wow64GetEmulatedSystemInformation(
|
||
|
VOID
|
||
|
);
|
||
|
|
||
|
PWOW64_SYSTEM_INFORMATION
|
||
|
Wow64GetRealSystemInformation(
|
||
|
VOID
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
Wow64Shutdown(
|
||
|
HANDLE ProcessHandle
|
||
|
);
|
||
|
|
||
|
// Defines the argsize of the emulated machine
|
||
|
#define ARGSIZE 4
|
||
|
|
||
|
VOID
|
||
|
ThunkPeb64ToPeb32(
|
||
|
IN PPEB Peb64,
|
||
|
OUT PPEB32 Peb32
|
||
|
);
|
||
|
|
||
|
|
||
|
extern RTL_CRITICAL_SECTION HandleDataCriticalSection;
|
||
|
|
||
|
#endif // _WOW64_INCLUDE
|