📄 util.cpp
字号:
/*++
Copyright (c) 2002 Sten
Contact information:
mail: stenri@mail.ru
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Module Name:
util.cpp
Abstract: Some helper commands.
Revision History:
Sten 05/06/2002
Initial release
--*/
extern "C"{
#pragma warning ( push, 3 )
#include <ntddk.h>
#pragma warning ( pop )
}
#pragma warning ( disable: 4514 ) // unreferenced inline function has been removed
#include "defs.h"
#include "intel.h"
#include "multicpu.h"
static DWORD MmSystemPteBase=0xc0000000;
////////////////////////////////////////////////////////////////////////////
//
// IsAddressValid
// Return TRUE if I can safely access this address. Maybe I'll better
// write my own version using _MmSystemPteBase & so on...
//
////////////////////////////////////////////////////////////////////////////
BOOLEAN IsAddressValid(void* Addr)
{
return MmIsAddressValid(Addr);
}
////////////////////////////////////////////////////////////////////////////
//
// Hooks interrupt via IDT patching
//
// Arguments:
// IntNo - interrupt number to hook
// Ptr - pointer to interrupt function
// Return Value:
// STATUS_SUCCESS - ?
//
////////////////////////////////////////////////////////////////////////////
void* SetInterruptHandler(int IntNo, void *HandlerPtr, BYTE flags)
{
__asm
{
pushad
mov eax, IntNo
mov dl, flags
mov edi, HandlerPtr
mov bx, cs
cli ; TO DO: StopSecondCPUs()
call mp_HookInterrupt
sti
popad
}
return (void*)mp_OldHandler;
}
////////////////////////////////////////////////////////////////////////////
//
// Get interrupt vector via IDT
//
// Arguments:
// IntNo - interrupt number
// Return Value:
// Ptr to interrupt handler, -1 if error.
//
////////////////////////////////////////////////////////////////////////////
void* GetInterruptHandler(DWORD IntNo, DWORD IdtNum)
{
DWORD IDTBase=0;
DWORD OldIntr;
WORD *IdtEntry;
IDTBase = mp_GetIDTBase(IdtNum);
IdtEntry=(WORD*)(IDTBase+IntNo*8);
OldIntr=IdtEntry[0]+(IdtEntry[3]<<16);
return (void*)OldIntr;
}
////////////////////////////////////////////////////////////////////////////
//
// GetIDTLimit
//
// Arguments:
// None
// Return Value:
// IDT limit
//
////////////////////////////////////////////////////////////////////////////
DWORD __declspec(naked) GetIDTLimit(void)
{
__asm
{
sub esp , 8
sidt [esp]
movzx eax , word ptr [esp]
add esp , 8
ret
}
}
////////////////////////////////////////////////////////////////////////////
//
// Set flags of given interrupt
//
// IntNo - interrupt number to hook
// flags -
//
////////////////////////////////////////////////////////////////////////////
void SetInterruptFlags(int IntNo, WORD flags)
{
DWORD IDTBase=0;
WORD *IdtEntry;
EnableWrite();
for (DWORD i = 0; i < mp_NumOfCPUs; i++)
{
IDTBase = mp_GetIDTBase(i);
IdtEntry=(WORD*)(IDTBase+IntNo*8);
IdtEntry[2]=flags;
}
DisableWrite();
}
////////////////////////////////////////////////////////////////////////////
//
// GetIDTEntry
//
// Arguments:
// Interrupt number
// Pointer to IdtEntry_t structure
// Return Value:
// IdtEntry_t structure
//
////////////////////////////////////////////////////////////////////////////
void GetIDTEntry(DWORD IntNo, PIdtEntry_t entry, DWORD IdtNum)
{
DWORD IDTBase=0;
void *IdtEntry;
IDTBase = mp_GetIDTBase(IdtNum);
IdtEntry=(void*)(IDTBase+IntNo*8);
RtlMoveMemory(entry, IdtEntry, sizeof(IdtEntry_t));
return;
}
////////////////////////////////////////////////////////////////////////////
//
// GetPde
// Returns pointer to PDE for the given page
// See MiGetPdeAddress in HAL.DLL
//
////////////////////////////////////////////////////////////////////////////
DWORD* GetPde(void *Address)
{
return (DWORD*)(MmSystemPteBase + ( ((DWORD)Address>>20) & 0xFFC) + ((DWORD)MmSystemPteBase>>10));
}
////////////////////////////////////////////////////////////////////////////
//
// GetPte
// Returns pointer to PTE entry for the given address.
// If this is a 4Mbyte page - return PDE
//
////////////////////////////////////////////////////////////////////////////
DWORD* GetPte(void *Address)
{
DWORD *p=GetPde(Address);
if ((*p&0x81) == 0x81) // PDE is 4MByte && present
return p;
return (DWORD*)(MmSystemPteBase + ( ((DWORD)Address>>10) & 0x3FFFFC) );
}
////////////////////////////////////////////////////////////////////////////
//
// Enable write
// Clears write-protect bit in CR0 register.
// Enables write access to system pages
// RETURNS: old CR0 register value
//
////////////////////////////////////////////////////////////////////////////
DWORD __declspec(naked) EnableWrite()
{
__asm
{
mov eax, cr0
push eax
and eax, 11111111111111101111111111111111b
mov cr0, eax
pop eax
ret
}
}
////////////////////////////////////////////////////////////////////////////
//
// Disable write
// Sets write-protect bit in CR0 register.
// Disables write access to system pages
//
////////////////////////////////////////////////////////////////////////////
void __declspec(naked) DisableWrite()
{
__asm
{
push eax
mov eax, cr0
or eax, not 11111111111111101111111111111111b
mov cr0, eax
pop eax
ret
}
}
////////////////////////////////////////////////////////////////////////////
//
// Set CR0 register value
// Sets write-protect bit in CR0 register.
// Disables write access to system pages
//
////////////////////////////////////////////////////////////////////////////
void SetCR0(DWORD dwValue)
{
__asm
{
push eax
mov eax, dwValue
mov cr0, eax
pop eax
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -