利用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;
}
}
{
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;
}
}
相关文章推荐
- 利用NTLDR进入RING0的方法及MGF病毒技术分析笔记
- 利用NtSystemDebugControl进入Ring0的源代码
- 进入TP-Link路由器之后利用快捷键F12查看星号路由密码的方法
- 浅谈NT下Ring3无驱进入Ring0的方法
- 利用python进入数据分析之全美婴儿姓名分析
- 利用socket转发和反弹端口技术突破防火墙进入内网
- 利用Theme自定义Activity进入退出动画
- 空草子·如何利用QT和opengl进入幻想乡
- 利用phpmyadmin修改mysql的root密码及如何进入修改密码后的phpmyadmin
- 利用phpmyadmin修改mysql的root密码及如何进入修改密码后的phpmyadmin
- 在XP-SP3下安装CentOS5,当Linux崩溃之后,如何利用Grub进入XP
- 浅谈NT下Ring3无驱进入Ring0的方法
- 利用Theme自定义Activity进入退出动画
- 利用dos进入mysql数据库操作数据
- 利用Win+R命令进入Win10安全模式以便对电脑全面检修
- 利用python进入数据分析之Numpy基础知识
- 突破重重防护获得进入同程邮箱(iPhone内置接口利用技巧)
- win2000下不用驱动进入ring0
- 利用python进入数据分析之usagov_bitly_data数据分析
- 利用phpmyadmin修改mysql的root密码及如何进入修改密码后的phpmyadmin