作者:vxk
#include "vx_main.h"
#include "mem.h"
#include <undoc.h>
#include <stdio.h>
void MySwapContextHook();
void MySwapContextEndHook();
static DWORD SwapContextPtr=0;
static DWORD SwapContextCnt=0;
extern HANDLE CurrentProcessId; // used in VXGetCurrentProcessId
NTSTATUS InitSwapContextHook()
{
// The code "mov byte ptr es:[esi+2Dh], 2" is near the start of
// SwitchContext function in NTOSKRNL.EXE. It is the only place we see
// these bytes in NT4 & 2K and the first place in XP
PULONG pOldAttr;
DisableWriteProtect(pOldAttr);
unsigned char SwapContextStart[]={0x26,(char)0xc6,0x46,0x2d,0x02};
SwapContextPtr=Search(VXGetModuleBase("ntoskrnl.exe"), SwapContextStart, sizeof(SwapContextStart));
if(SwapContextPtr<(DWORD)VXSystemRangeStart)
{
DbgPrint("VX: Unable to find SwapContext in NTOSKRNL.EXE!");
return STATUS_PROCEDURE_NOT_FOUND;
} else
DbgPrint("VX: SwapContext found at %08X/n",SwapContextPtr);
SwapContextCnt=SwapContextPtr+5;
__asm cli; // Disable task switching
DWORD Addr=(DWORD)MySwapContextHook-(SwapContextPtr+5);
*(char*)SwapContextPtr=(char)0xe9;
*(DWORD*)(SwapContextPtr+1)=Addr;
__asm sti;
EnableWriteProtect(pOldAttr);
return STATUS_SUCCESS;
}
void RemoveSwapContextHook()
{
PULONG pOldAttr;
DisableWriteProtect(pOldAttr);
if(SwapContextPtr)
{
__asm cli; // Disable task switching
memcpy((void*)SwapContextPtr,"/x26/xc6/x46/x2d/x02",5);
__asm sti;
SwapContextPtr=0;
}
EnableWriteProtect(pOldAttr);
}
void __stdcall
HandleContextSwap(ETHREAD *New, ETHREAD *Old)
{
PULONG pOldAttr;
DisableWriteProtect(pOldAttr);
CurrentProcessId=Old->Cid.UniqueProcess;
VXDeferAllUserModeBreakpoints(); // I don't disable kernel breaks to increase speed
CurrentProcessId=New->Cid.UniqueProcess;
// Now install hook in the new thread's context so I can do what I need...
DWORD* Stack=(DWORD*)New->Tcb.KernelStack;
// Stack of SwapContext in NT4-XP looks like:
// esp+8 -> return address │ Stack[2]
// esp+4 -> EFLAGS │ Stack[1]
// esp -> ECX │ Stack[0]
// I'll insert address of my hook function between EFLAGS and return address
New->Tcb.KernelStack=((char*)New->Tcb.KernelStack)-4;
memmove(New->Tcb.KernelStack,Stack,8);
Stack[1]=(DWORD)MySwapContextEndHook;
EnableWriteProtect(pOldAttr);
}
void __stdcall HandleContextSwapEnd()
{
VXActivateAllUserModeBreakpoints();
}
void __declspec(naked) MySwapContextHook()
{
__asm {
mov byte ptr es:[esi+2Dh], 2
pushfd
pushad
push edi
push esi
call HandleContextSwap
popad
popfd
jmp [SwapContextCnt]
}
}
void __declspec(naked) MySwapContextEndHook()
{
__asm {
pushfd
pushad
call HandleContextSwapEnd
popad
popfd
retn
}
}