有没有高手见过这段代码并能给出解释,小弟看不懂????????????????????????
__declspec(naked) void Ring0ModifyPageProtection()
{
_asm
{
Mov EAX, ECX
Shr EAX, 22
Test DWORD PTR [0FFBFE000h + EAX * 4], 1
Jz Fail
Mov EAX, ECX
Shr EAX, 12
Mov EBX, EAX
Mov EAX, DWORD PTR [0FF800000h + EAX * 4]
Test EAX, 1
Jz Fail
Mov EAX, 1
Cmp EDX, PAGE_READWRITE
Je PageReadWrite
And DWORD PTR [0FF800000h + EBX * 4], 0xFFFFFFFD
Jmp Done
PageReadWrite:
Or DWORD PTR [0FF800000h + EBX * 4], 2
Jmp Done
Fail:
Xor EAX, EAX
Done:
Retf
}
}
bool CallRing0(PVOID pvRing0FuncAddr, PVOID pvAddr, DWORD dwPageProtection)
{
GDT_DESCRIPTOR *pGDTDescriptor;
GDTR gdtr;
bool Result;
_asm Sgdt [gdtr]
// Skip the null descriptor
pGDTDescriptor = (GDT_DESCRIPTOR *)(gdtr.dwGDTBase + 8);
// Search for a free GDT descriptor
for (WORD wGDTIndex = 1; wGDTIndex < (gdtr.wGDTLimit / 8); wGDTIndex++)
{
if (pGDTDescriptor->Type == 0 &&
pGDTDescriptor->System == 0 &&
pGDTDescriptor->DPL == 0 &&
pGDTDescriptor->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).
CALLGATE_DESCRIPTOR *pCallgate;
pCallgate = (CALLGATE_DESCRIPTOR *) pGDTDescriptor;
pCallgate->Offset_0_15 = LOWORD(pvRing0FuncAddr);
pCallgate->Selector = 0x28;
pCallgate->ParamCount = 0;
pCallgate->Unused = 0;
pCallgate->Type = 0xc;
pCallgate->System = 0;
pCallgate->DPL = 3;
pCallgate->Present = 1;
pCallgate->Offset_16_31 = HIWORD(pvRing0FuncAddr);
// Prepare the far call parameters
WORD CallgateAddr[3];
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
{
Mov ECX, [pvAddr]
Mov EDX, [dwPageProtection]
Cli
Call FWORD PTR [CallgateAddr]
Sti
Mov DWORD PTR [Result], EAX
}
// Now free the GDT descriptor
memset(pGDTDescriptor, 0, 8);
return Result;
}
// Advance to the next GDT descriptor
pGDTDescriptor++;
}
// Whoops, the GDT is full
return false;
}