📄 mdx86.c
字号:
mov [ebp-16], eax // may overwrite CS value
mov [ebp-8], cs
pop eax // restore Eax
lea esp, [ebp-16] // (esp) = new stack (with Ebp & IRET frame pushed on)
pop ebp // (ebp) = original Ebp
iretd // continue at the desired address
}
}
void InitFPSaveArea (NK_PCR *pcr)
{
if (dwFPType == FPTYPE_HARDWARE) {
if (ProcessorFeatures & CPUID_FXSR) {
memcpy(&pcr->tcxExtended, &g_InitialFPUState,
sizeof(pcr->tcxExtended));
} else {
memcpy(&pcr->tcxFPU, &g_InitialFPUState, (sizeof(pcr->tcxFPU)+16));
}
} else if (dwFPType == FPTYPE_SOFTWARE)
memset(pcr->Emx87Data, 0, sizeof(pcr->Emx87Data));
}
//------------------------------------------------------------------------------
// normal thread stack: from top, TLS then args then free
//------------------------------------------------------------------------------
void
MDCreateThread(
PTHREAD pTh,
LPVOID lpStack,
DWORD cbStack,
LPVOID lpBase,
LPVOID lpStart,
BOOL kmode,
ulong param
)
{
ulong *args;
NK_PCR *pcr;
DEBUGCHK ((ulong)lpStack>>VA_SECTION);
// Allocate space for TLS & PCR info.
pcr = NCRPTR (lpStack, cbStack);
pTh->tlsPtr = pcr->tls;
// update stack base
KSTKBASE(pTh) = (DWORD)lpStack;
// Allocate space for arguments to the start function.
pTh->ctx.TcxEsp = (ulong)pcr - 3*4;
// update stackbound
KSTKBOUND(pTh) = pTh->ctx.TcxEsp & ~(PAGE_SIZE-1);
args = (ulong*)pTh->ctx.TcxEsp;
pcr->ExceptionList = 0;
// pcr->InitialStack = pTh->ctx.TcxEsp;
// pcr->StackLimit = (DWORD)lpStack;
args[1] = (ulong)lpStart;
args[2] = param;
args[0] = 0; // set return address to fault
pTh->ctx.TcxEip = (ULONG)lpBase;
pTh->ctx.TcxDs = KGDT_R3_DATA;
pTh->ctx.TcxEs = KGDT_R3_DATA;
pTh->ctx.TcxFs = KGDT_PCR;
pTh->ctx.TcxGs = 0;
pTh->ctx.TcxEFlags = 0x3200; // IOPL=3, IF=1
InitFPSaveArea (pcr);
if (kmode || bAllKMode) {
SetThreadMode (pTh, KERNEL_MODE);
KTHRDINFO (pTh) |= UTLS_INKMODE;
} else {
SetThreadMode (pTh, USER_MODE);
KTHRDINFO (pTh) &= ~UTLS_INKMODE;
}
}
// main thread stack: from top, PCR then buf then buf2 then buf2 (ascii) then args then free
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
MDSetupMainThread (
PTHREAD pTh,
LPBYTE pCurSP,
LPVOID lpBase,
LPVOID lpStart,
BOOL kmode,
ulong dwModCnt
)
{
ulong *args;
PPROCESS pprc = pTh->pOwnerProc;
// Allocate space for arguments to the start function.
pTh->ctx.TcxEsp = (ulong) pCurSP - 10*4; // 8 arguments + return address + 1 for Quad-word alignment
KSTKBOUND(pTh) = pTh->ctx.TcxEsp & ~(PAGE_SIZE-1);
args = (ulong*)pTh->ctx.TcxEsp;
args[1] = (ulong)lpStart;
args[2] = (ulong)pprc->hProc;
args[3] = dwModCnt;
args[4] = (ulong) pprc->pcmdline;
args[5] = (DWORD) hCoreDll;
args[6] = pprc->e32.e32_sect14rva;
args[7] = pprc->e32.e32_sect14size;
args[8] = (DWORD) pprc->BasePtr;
args[0] = 0; // set return address to fault
pTh->ctx.TcxEip = (ULONG)lpBase;
pTh->ctx.TcxDs = KGDT_R3_DATA;
pTh->ctx.TcxEs = KGDT_R3_DATA;
pTh->ctx.TcxFs = KGDT_PCR;
pTh->ctx.TcxGs = 0;
pTh->ctx.TcxEFlags = 0x3200; // IOPL=3, IF=1
InitFPSaveArea ((NK_PCR *) ((DWORD) pTh->tlsPtr - offsetof(NK_PCR, tls)));
if (kmode || bAllKMode) {
SetThreadMode (pTh, KERNEL_MODE);
KTHRDINFO (pTh) |= UTLS_INKMODE;
} else {
SetThreadMode (pTh, USER_MODE);
KTHRDINFO (pTh) &= ~UTLS_INKMODE;
}
}
void MDInitSecureStack (LPBYTE lpStack)
{
InitFPSaveArea (NCRPTR (lpStack, CNP_STACK_SIZE));
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
ZeroPage(
void *pvPage
)
{
_asm {
mov edi, pvPage
mov ecx, PAGE_SIZE/4
xor eax, eax
rep stosd
}
}
extern void FPUFlushContext(void);
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL
DoThreadGetContext(
HANDLE hTh,
LPCONTEXT lpContext
)
{
PTHREAD pth;
PFXSAVE_AREA FxArea;
PFLOATING_SAVE_AREA FnArea;
ACCESSKEY ulOldKey;
if (!(pth = HandleToThread(hTh))) {
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (lpContext->ContextFlags & ~(CONTEXT_FULL|CONTEXT_FLOATING_POINT|CONTEXT_DEBUG_REGISTERS)) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
SWITCHKEY(ulOldKey,0xffffffff);
if (pth->pThrdDbg && pth->pThrdDbg->psavedctx) {
if ((lpContext->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) {
lpContext->Ebp = pth->pThrdDbg->psavedctx->Ebp;
lpContext->Eip = pth->pThrdDbg->psavedctx->Eip;
lpContext->SegCs = pth->pThrdDbg->psavedctx->SegCs;
lpContext->EFlags = pth->pThrdDbg->psavedctx->EFlags;
lpContext->Esp = pth->pThrdDbg->psavedctx->Esp;
lpContext->SegSs = pth->pThrdDbg->psavedctx->SegSs;
}
if ((lpContext->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) {
lpContext->Edi = pth->pThrdDbg->psavedctx->Edi;
lpContext->Esi = pth->pThrdDbg->psavedctx->Esi;
lpContext->Ebx = pth->pThrdDbg->psavedctx->Ebx;
lpContext->Edx = pth->pThrdDbg->psavedctx->Edx;
lpContext->Ecx = pth->pThrdDbg->psavedctx->Ecx;
lpContext->Eax = pth->pThrdDbg->psavedctx->Eax;
}
if ((lpContext->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS) {
lpContext->SegGs = pth->pThrdDbg->psavedctx->SegGs;
lpContext->SegFs = pth->pThrdDbg->psavedctx->SegFs;
lpContext->SegEs = pth->pThrdDbg->psavedctx->SegEs;
lpContext->SegDs = pth->pThrdDbg->psavedctx->SegDs;
}
if ((lpContext->ContextFlags & CONTEXT_FLOATING_POINT) ==
CONTEXT_FLOATING_POINT) {
FPUFlushContext();
lpContext->FloatSave = pth->pThrdDbg->psavedctx->FloatSave;
}
if ((lpContext->ContextFlags & CONTEXT_DEBUG_REGISTERS) ==
CONTEXT_DEBUG_REGISTERS) {
}
} else {
if ((lpContext->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) {
lpContext->Ebp = pth->ctx.TcxEbp;
lpContext->Eip = pth->ctx.TcxEip;
lpContext->SegCs = pth->ctx.TcxCs;
lpContext->EFlags = pth->ctx.TcxEFlags;
lpContext->Esp = pth->ctx.TcxEsp;
lpContext->SegSs = pth->ctx.TcxSs;
}
if ((lpContext->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) {
lpContext->Edi = pth->ctx.TcxEdi;
lpContext->Esi = pth->ctx.TcxEsi;
lpContext->Ebx = pth->ctx.TcxEbx;
lpContext->Edx = pth->ctx.TcxEdx;
lpContext->Ecx = pth->ctx.TcxEcx;
lpContext->Eax = pth->ctx.TcxEax;
}
if ((lpContext->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS) {
lpContext->SegGs = pth->ctx.TcxGs;
lpContext->SegFs = pth->ctx.TcxFs;
lpContext->SegEs = pth->ctx.TcxEs;
lpContext->SegDs = pth->ctx.TcxDs;
}
if ((lpContext->ContextFlags & CONTEXT_FLOATING_POINT) ==
CONTEXT_FLOATING_POINT) {
if (ProcessorFeatures & CPUID_FXSR) {
FxArea = (PFXSAVE_AREA) PTH_TO_FLTSAVEAREAPTR(pth);
FnArea = &lpContext->FloatSave;
__asm {
// We won't get here if emulating FP, so CR0.EM will be 0
call FPUFlushContext // FPUFlushContext sets CR0.TS
clts
mov eax, FxArea
FXRESTOR_EAX // convert from fxsave format
mov eax, FnArea // in NK_PCR to fnsave format
fnsave [eax] // in CONTEXT structure
fwait
mov eax, cr0
or eax, TS_MASK
mov cr0, eax
}
} else {
FPUFlushContext();
lpContext->FloatSave = *(PTH_TO_FLTSAVEAREAPTR(pth));
}
}
if ((lpContext->ContextFlags & CONTEXT_DEBUG_REGISTERS) ==
CONTEXT_DEBUG_REGISTERS) {
}
}
SETCURKEY(ulOldKey);
return TRUE;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL
DoThreadSetContext(
HANDLE hTh,
const CONTEXT *lpContext
)
{
PTHREAD pth;
PFXSAVE_AREA FxArea;
DWORD i, j, TagWord;
ACCESSKEY ulOldKey;
if (!(pth = HandleToThread(hTh))) {
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (lpContext->ContextFlags & ~(CONTEXT_FULL|CONTEXT_FLOATING_POINT|CONTEXT_DEBUG_REGISTERS)) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
SWITCHKEY(ulOldKey,0xffffffff);
if (pth->pThrdDbg && pth->pThrdDbg->psavedctx) {
if ((lpContext->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) {
pth->pThrdDbg->psavedctx->Ebp = lpContext->Ebp;
pth->pThrdDbg->psavedctx->Eip = lpContext->Eip;
pth->pThrdDbg->psavedctx->SegCs = lpContext->SegCs;
pth->pThrdDbg->psavedctx->EFlags = (pth->pThrdDbg->psavedctx->EFlags & 0xfffff200) |
(lpContext->EFlags& 0x00000dff);
pth->pThrdDbg->psavedctx->Esp = lpContext->Esp;
pth->pThrdDbg->psavedctx->SegSs = lpContext->SegSs;
}
if ((lpContext->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) {
pth->pThrdDbg->psavedctx->Edi = lpContext->Edi;
pth->pThrdDbg->psavedctx->Esi = lpContext->Esi;
pth->pThrdDbg->psavedctx->Ebx = lpContext->Ebx;
pth->pThrdDbg->psavedctx->Edx = lpContext->Edx;
pth->pThrdDbg->psavedctx->Ecx = lpContext->Ecx;
pth->pThrdDbg->psavedctx->Eax = lpContext->Eax;
}
if ((lpContext->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS) {
pth->pThrdDbg->psavedctx->SegGs = lpContext->SegGs;
pth->pThrdDbg->psavedctx->SegFs = lpContext->SegFs;
pth->pThrdDbg->psavedctx->SegEs = lpContext->SegEs;
pth->pThrdDbg->psavedctx->SegDs = lpContext->SegDs;
}
if ((lpContext->ContextFlags & CONTEXT_FLOATING_POINT) ==
CONTEXT_FLOATING_POINT) {
FPUFlushContext();
pth->pThrdDbg->psavedctx->FloatSave = lpContext->FloatSave;
}
if ((lpContext->ContextFlags & CONTEXT_DEBUG_REGISTERS) ==
CONTEXT_DEBUG_REGISTERS) {
}
} else {
if ((lpContext->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) {
pth->ctx.TcxEbp = lpContext->Ebp;
pth->ctx.TcxEip = lpContext->Eip;
pth->ctx.TcxCs = lpContext->SegCs;
pth->ctx.TcxEFlags = (pth->ctx.TcxEFlags & 0xfffff200) |
(lpContext->EFlags& 0x00000dff);
pth->ctx.TcxEsp = lpContext->Esp;
pth->ctx.TcxSs = lpContext->SegSs;
}
if ((lpContext->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) {
pth->ctx.TcxEdi = lpContext->Edi;
pth->ctx.TcxEsi = lpContext->Esi;
pth->ctx.TcxEbx = lpContext->Ebx;
pth->ctx.TcxEdx = lpContext->Edx;
pth->ctx.TcxEcx = lpContext->Ecx;
pth->ctx.TcxEax = lpContext->Eax;
}
if ((lpContext->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS) {
pth->ctx.TcxGs = lpContext->SegGs;
pth->ctx.TcxFs = lpContext->SegFs;
pth->ctx.TcxEs = lpContext->SegEs;
pth->ctx.TcxDs = lpContext->SegDs;
}
if ((lpContext->ContextFlags & CONTEXT_FLOATING_POINT) ==
CONTEXT_FLOATING_POINT) {
FPUFlushContext();
if (ProcessorFeatures & CPUID_FXSR) {
// Convert from fnsave format in CONTEXT to fxsave format in PCR
FxArea = (PFXSAVE_AREA) PTH_TO_FLTSAVEAREAPTR(pth);
FxArea->ControlWord = (USHORT) lpContext->FloatSave.ControlWord;
FxArea->StatusWord = (USHORT) lpContext->FloatSave.StatusWord;
FxArea->TagWord = 0;
TagWord = lpContext->FloatSave.TagWord;
for (i = 0; i < FN_BITS_PER_TAGWORD; i+=2) {
if (((TagWord >> i) & FN_TAG_MASK) != FN_TAG_EMPTY)
FxArea->TagWord |= (FX_TAG_VALID << (i/2));
}
FxArea->ErrorOffset = lpContext->FloatSave.ErrorOffset;
FxArea->ErrorSelector = lpContext->FloatSave.ErrorSelector & 0xffff;
FxArea->ErrorOpcode = (USHORT)
((lpContext->FloatSave.ErrorSelector >> 16) & 0xFFFF);
FxArea->DataOffset = lpContext->FloatSave.DataOffset;
FxArea->DataSelector = lpContext->FloatSave.DataSelector;
memset(&FxArea->RegisterArea[0], 0, SIZE_OF_FX_REGISTERS);
for (i = 0; i < NUMBER_OF_FP_REGISTERS; i++) {
for (j = 0; j < BYTES_PER_FP_REGISTER; j++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -