286 lines
5.1 KiB
C
286 lines
5.1 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1999-2000 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
wowrap.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This module implements some wrapper (on wx86cpu) functions wow64 might call.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
24-Aug-1999 askhalid
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include <nt.h>
|
||
|
#include <ntrtl.h>
|
||
|
#include <nturtl.h>
|
||
|
#include <windows.h>
|
||
|
#include <stdio.h>
|
||
|
|
||
|
#define _WOW64CPUAPI_
|
||
|
#define _WX86CPUAPI_
|
||
|
#define __WOW64_WRAPPER__
|
||
|
|
||
|
#include "wx86.h"
|
||
|
#include "wow64.h"
|
||
|
#include "wx86nt.h"
|
||
|
#include "wx86cpu.h"
|
||
|
#include "cpuassrt.h"
|
||
|
#include "config.h"
|
||
|
#include "entrypt.h"
|
||
|
#include "instr.h"
|
||
|
#include "compiler.h"
|
||
|
#include "wow64cpu.h"
|
||
|
|
||
|
ASSERTNAME;
|
||
|
|
||
|
typedef struct _WowBopInstr {
|
||
|
BOPINSTR Wx86Bop;
|
||
|
BYTE Ret;
|
||
|
} WOWBOPINSTR;
|
||
|
|
||
|
WOWBOPINSTR Bop;
|
||
|
|
||
|
|
||
|
NTSTATUS
|
||
|
CpuProcessInit(PSIZE_T pCpuThreadDataSize)
|
||
|
{
|
||
|
NTSTATUS st;
|
||
|
|
||
|
memset ( (char *)&Bop, 0, sizeof (Bop) );
|
||
|
Bop.Wx86Bop.Instr1 = 0xc4;
|
||
|
Bop.Wx86Bop.Instr2 = 0xc4;
|
||
|
Bop.Ret = 0xc3; // ret
|
||
|
|
||
|
st = MsCpuProcessInit();
|
||
|
|
||
|
*pCpuThreadDataSize = sizeof(CPUCONTEXT);
|
||
|
|
||
|
return st;
|
||
|
|
||
|
}
|
||
|
|
||
|
NTSTATUS
|
||
|
CpuProcessTerm(VOID)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
NTSTATUS
|
||
|
CpuThreadInit(PVOID pPerThreadData)
|
||
|
{
|
||
|
PTEB32 Teb32 = NtCurrentTeb32();
|
||
|
|
||
|
//
|
||
|
// Initialize the pointer to the DoSystemService function.
|
||
|
Teb32->WOW32Reserved = (ULONG)(LONGLONG)&Bop;
|
||
|
|
||
|
if ( MsCpuThreadInit()) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return STATUS_SEVERITY_ERROR; //return right value
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Execution
|
||
|
//
|
||
|
VOID
|
||
|
CpuSimulate(VOID)
|
||
|
{
|
||
|
MsCpuSimulate(NULL);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Exception handling, context manipulation
|
||
|
//
|
||
|
/* already been defined
|
||
|
VOID
|
||
|
CpuResetToConsistentState(PEXCEPTION_POINTERS pExecptionPointers)
|
||
|
{
|
||
|
|
||
|
|
||
|
}*/
|
||
|
|
||
|
|
||
|
NTSTATUS
|
||
|
CpuGetContext(
|
||
|
IN HANDLE ThreadHandle,
|
||
|
IN HANDLE ProcessHandle,
|
||
|
IN PTEB Teb,
|
||
|
OUT PCONTEXT32 Context)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Extracts the cpu context of the specified thread. If the target thread isn't the currently
|
||
|
executing thread, then it should be guaranteed by the caller that the target thread
|
||
|
is suspended at a proper CPU state.
|
||
|
Context->ContextFlags decides which IA32 register-set to retreive.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
ThreadHandle - Target thread handle to retreive the context for
|
||
|
ProcessHandle - Open handle to the process that the thread runs in
|
||
|
Teb - Pointer to the target's thread TEB
|
||
|
Context - Context record to fill
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
NTSTATUS.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
//Context->ContextFlags = CONTEXT_FULL_WX86;
|
||
|
if (NtCurrentThread() == ThreadHandle)
|
||
|
{
|
||
|
return MsCpuGetContext(Context);
|
||
|
}
|
||
|
|
||
|
return MsCpuGetContextThread(ProcessHandle,
|
||
|
Teb,
|
||
|
Context);
|
||
|
}
|
||
|
|
||
|
|
||
|
NTSTATUS
|
||
|
CpuSetContext(
|
||
|
IN HANDLE ThreadHandle,
|
||
|
IN HANDLE ProcessHandle,
|
||
|
IN PTEB Teb,
|
||
|
PCONTEXT32 Context)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Sets the cpu context for the specified thread. If the target thread isn't the currently
|
||
|
executing thread, then it should be guaranteed by the caller that the target thread is
|
||
|
suspended at a proper CPU state.
|
||
|
Context->ContextFlags decides which IA32 register-set to be set.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
ThreadHandle - Target thread handle to retreive the context for
|
||
|
ProcessHandle - Open handle to the process that the thread runs in
|
||
|
Teb - Pointer to the target's thread TEB
|
||
|
Context - Context record to set
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
NTSTATUS.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
|
||
|
//Context->ContextFlags = CONTEXT_FULL_WX86; // make sure wow return the right flags
|
||
|
if (NtCurrentThread() == ThreadHandle)
|
||
|
{
|
||
|
return MsCpuSetContext(Context);
|
||
|
}
|
||
|
|
||
|
return MsCpuSetContextThread(ProcessHandle,
|
||
|
Teb,
|
||
|
Context);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
ULONG
|
||
|
CpuGetStackPointer ( )
|
||
|
// create a wrapper that calls the Wx86 CPU's GetEsp
|
||
|
{
|
||
|
DECLARE_CPU;
|
||
|
return GetEsp(cpu);
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
CpuNotifyDllLoad (
|
||
|
LPWSTR DllName,
|
||
|
PVOID DllBase,
|
||
|
ULONG DllSize
|
||
|
)
|
||
|
// - create a wrapper on the Wx86 CPU's CpuMapNotify
|
||
|
{
|
||
|
CpuMapNotify( DllBase, TRUE );
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
CpuNotifyDllUnload (
|
||
|
PVOID DllBase
|
||
|
)
|
||
|
// - create a wrapper on the Wx86 CPU's CpuMapNotify
|
||
|
{
|
||
|
CpuMapNotify( DllBase, FALSE );
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
CpuSetInstructionPointer (
|
||
|
ULONG Value
|
||
|
)
|
||
|
//- wrapper on SetEip
|
||
|
{
|
||
|
DECLARE_CPU;
|
||
|
|
||
|
SetEip( cpu, Value);
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
CpuSetStackPointer (
|
||
|
ULONG val
|
||
|
)
|
||
|
// - wrapper on SetEsp
|
||
|
{
|
||
|
DECLARE_CPU;
|
||
|
|
||
|
SetEsp(cpu, val);
|
||
|
}
|
||
|
|
||
|
NTSTATUS
|
||
|
CpuThreadTerm(VOID)
|
||
|
//- just create an empty stub function - the Wx86 CPU doesn't care about this
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
LONG
|
||
|
WOW64DLLAPI
|
||
|
Wow64SystemService(
|
||
|
IN ULONG ServiceNumber,
|
||
|
IN PCONTEXT32 Context32 //This is read only!
|
||
|
)
|
||
|
|
||
|
*/
|
||
|
|
||
|
DWORD
|
||
|
ProxyWowDispatchBop(
|
||
|
ULONG ServiceNumber,
|
||
|
PCONTEXT_WX86 px86Context,
|
||
|
PULONG ArgBase
|
||
|
)
|
||
|
{
|
||
|
LONG ret=0;
|
||
|
|
||
|
//CONTEXT32 _Context32;
|
||
|
//_Context32.Edx = (ULONG)(ULONGLONG)ArgBase; //this is the only field wow64 using
|
||
|
|
||
|
if ( px86Context != NULL )
|
||
|
ret = Wow64SystemService ( ServiceNumber, px86Context );
|
||
|
return ret;
|
||
|
|
||
|
//[bb] The wow64 equivalent is Wow64SystemService.
|
||
|
}
|