📄 idt_guard.c
字号:
/*
Interrupt Descriptor Table (IDT) Guard.
VERSiON 1.0 - (c) December, 2005 -
Copyright (C) 2005 Matthieu Suiche <msuiche@gmail.com> www.msuiche.net
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
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <memory.h>
#include <aclapi.h>
#include "header.h"
HANDLE hPhysMem;
BYTE KernelPath[LEN_PATH];
int main(int argc, char **argv) {
KIDTRAWENTRY IdtRaw[MAX_INTERRUPTION], IdtMem[MAX_INTERRUPTION];
BYTE lpCmd[12];
DWORD VirtualAddress, Counter, Status,
Index, pCmd;
printf("Interrupt Descriptor Table(IDT) Guard\n");
printf("Matthieu Suiche <matt@msuiche.net> www.msuiche.net\n");
printf("Version 0.1 - (c) December, 2005 - \n\n\n");
if(!CheckOsVersion())
{
printf("\nError: Bad OS Version\n");
return FALSE;
}
if(!UpdateAffinityMask())
{
printf("\nError: Affinity Mask\n");
return FALSE;
}
if(!GetNtdllFunction())
{
printf("\nError: Getting Ntdll's functions\n");
return FALSE;
}
if(!GetRawInterruption((PKIDTRAWENTRY)&IdtRaw))
{
printf("\nError: Getting Raw interruptions\n");
return FALSE;
}
if(!(VirtualAddress = StartUp()))
{
printf("\nError: Bad Virtual Address\n");
return FALSE;
}
if(!GetMemoryInterruption((PKIDTRAWENTRY)&IdtMem, VirtualAddress+0x400)) // IDT Offset = GDT Offset + 0x400
{
printf("\nError: Cannot get interruption. Is access to \\Device\\PhysicalMemory.\n");
return FALSE;
}
Counter = CompareInterruption((PKIDTRAWENTRY)&IdtRaw, (PKIDTRAWENTRY)&IdtMem);
printf("\n%d Interruptions have been modified.\n\n",Counter);
GetHelp();
Status = 1;
while(Status) {
printf("\ncmd>");
switch(getchar()) {
case 'q':
printf("I hope you like this tool ;)\n");
Status = 0;
break;
case 'h':
GetHelp();
break;
case 's':
getchar();
GetMemoryInterruption((PKIDTRAWENTRY)&IdtMem, VirtualAddress+0x400); // IDT Offset = GDT Offset + 0x400
CompareInterruption((PKIDTRAWENTRY)&IdtRaw, (PKIDTRAWENTRY)&IdtMem);
break;
case 'r':
memset(lpCmd,0,sizeof(lpCmd));
fgets(lpCmd,sizeof(lpCmd)-1,stdin);
pCmd = (DWORD)&lpCmd;
memset((PDWORD)(pCmd+5), 0, 1);
Index = strtol((PBYTE)pCmd+3,0,16);
printf("Are you sure that you want to restore the Interruption 0x%02X(%d)? (y/n)",Index,Index);
if(getchar() == 'y') {
getchar();
printf("\nLet's restore it !\n");
RestoreInterruptionByHandle(Index, IdtRaw, IdtMem, (PKIDTENTRY)(VirtualAddress+0x400));
GetMemoryInterruption((PKIDTRAWENTRY)&IdtMem, VirtualAddress+0x400);
} else getchar();
break;
default:
printf("Invalid Command\n");
break;
}
}
CleanUp(VirtualAddress);
return TRUE;
}
DWORD CheckOsVersion(void) {
OSVERSIONINFO OsVersion;
OsVersion.dwOSVersionInfoSize = sizeof(OsVersion);
GetVersionEx(&OsVersion);
if( (OsVersion.dwMajorVersion != 5) &&
(OsVersion.dwMinorVersion != 0) && (OsVersion.dwMinorVersion != 1)
){
printf("Sorry, but this tool works only with Win2K and WinXP.\n");
return FALSE;
}
return TRUE;
}
DWORD UpdateAffinityMask(void) {
DWORD lpProcessAffinityMask, lpSystemAffinityMask;
GetProcessAffinityMask((HANDLE)-1, &lpProcessAffinityMask, &lpSystemAffinityMask);
if(lpProcessAffinityMask == 0) {
lpProcessAffinityMask = 1;
if(!SetProcessAffinityMask((HANDLE)-1, lpProcessAffinityMask)) {
printf("Cannot update process affinity mask.\n");
return FALSE;
}
}
return TRUE;
}
DWORD RestoreInterruptionByHandle(DWORD Index, PKIDTRAWENTRY IdtRaw, PKIDTRAWENTRY IdtMem, PKIDTENTRY IdtEntry) {
BYTE TypeRaw[10], TypeMem[10];
if (IdtRaw[Index].Type == GATE_TASK_16) strcpy(TypeRaw, "TaskG16 ");
else if (IdtRaw[Index].Type == GATE_TASK_32) strcpy(TypeRaw, "TaskG32 ");
else if (IdtRaw[Index].Type == GATE_INTERRUPT_32) strcpy(TypeRaw, "IntG32 ");
else if (IdtRaw[Index].Type == GATE_INTERRUPT_16) strcpy(TypeRaw, "IntG16 ");
else if (IdtRaw[Index].Type == GATE_TRAP_32) strcpy(TypeRaw, "TrapG32 ");
else if (IdtRaw[Index].Type == GATE_TRAP_16) strcpy(TypeRaw, "TrapG16 ");
else strcpy(TypeRaw, "Reserved");
if (IdtMem[Index].Type == GATE_TASK_16) strcpy(TypeMem, "TaskG16 ");
else if (IdtMem[Index].Type == GATE_TASK_32) strcpy(TypeMem, "TaskG32 ");
else if (IdtMem[Index].Type == GATE_INTERRUPT_32) strcpy(TypeMem, "IntG32 ");
else if (IdtMem[Index].Type == GATE_INTERRUPT_16) strcpy(TypeMem, "IntG16 ");
else if (IdtMem[Index].Type == GATE_TRAP_32) strcpy(TypeMem, "TrapG32 ");
else if (IdtMem[Index].Type == GATE_TRAP_16) strcpy(TypeMem, "TrapG16 ");
else strcpy(TypeMem, "Reserved");
printf("I will do that : \n");
printf("\tOffset : 0x%08X => 0x%08X\n", IdtMem[Index].Offset,IdtRaw[Index].Offset);
printf("\tDpl : 0x%02X => 0x%02X\n", IdtMem[Index].Dpl,IdtRaw[Index].Dpl);
// printf("\tSelector : 0x%04X => 0x%04X\n", IdtMem[Index].Selector,IdtRaw[Index].Selector);
// printf("\tPresent : 0x%01d => 0x%01d\n", IdtMem[Index].Present,IdtRaw[Index].Present);
printf("\tType : %08s => %08s\n\n",TypeMem, TypeRaw);
if(
(IdtMem[Index].Offset == IdtRaw[Index].Offset)
&& (IdtMem[Index].Dpl == IdtRaw[Index].Dpl)
&& (IdtMem[Index].Type == IdtRaw[Index].Type)
// && (IdtMem[Index].Present == IdtRaw[Index].Present)
) return TRUE;
printf("Are you sure?(y/n)");
if(getchar() == 'y') {
getchar();
/*
Dpl: Descriptor Privilege Level
Offset: Offset To Procedure Entry Point
P: Segment Present Bit
Reserved: Do not use
Selector: Segment Selector For Destination Code Segment
*/
printf("\nReconstrution of the INT 0x%02X\n",Index);
printf("\tOffset value...");
IdtEntry[Index].OffsetLow = IdtRaw[Index].OffsetLow;
IdtEntry[Index].OffsetHigh = IdtRaw[Index].OffsetHigh;
printf("Done\n");
printf("\tDpl(Descriptor Privilege Level) value...");
IdtEntry[Index].Dpl = IdtRaw[Index].Dpl;
printf("Done\n");
printf("\tType value...");
IdtEntry[Index].Type = IdtRaw[Index].Type;
printf("Done\n");
printf("\nOKiE\n");
} else getchar();
return TRUE;
}
DWORD GetRawInterruption(PKIDTRAWENTRY IdtRaw) {
HANDLE hFile, hMapping, pMapping;
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS NTHeaders;
PIMAGE_SECTION_HEADER pSecHdr;
DWORD NumberOfSections, RawSize, IntAddr, ImageBase = 0;
DWORD INIT_Sex, KernelBaseAddr, i;
PKIDTRAWENTRY IDTr;
BYTE Type[10];
KernelBaseAddr = GetKernelInformation();
if(!KernelBaseAddr)
return FALSE;
//printf("%08X:%s\n",KernelBaseAddr,KernelPath);
hFile = CreateFile(KernelPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if(hFile == INVALID_HANDLE_VALUE) {
printf("\nCannot open the kernel. Please check if the file is correct\n");
return FALSE;
}
hMapping = CreateFileMapping(hFile, 0, PAGE_READONLY, 0, 0, 0);
if(!hMapping){
printf("Cannot create file mapping.\n");
CloseHandle(hFile);
return FALSE;
}
pMapping = MapViewOfFile(hMapping, FILE_MAP_READ , 0, 0, 0);
if(!pMapping){
printf("Cannot view mapping.\n");
CloseHandle(hMapping);
CloseHandle(hFile);
return FALSE;
}
DOSHeader = (PIMAGE_DOS_HEADER)pMapping;
if (DOSHeader->e_magic != IMAGE_DOS_SIGNATURE) {
printf("Bad DOS Signature.\n");
UnmapViewOfFile(pMapping);
CloseHandle(hMapping);
CloseHandle(hFile);
return FALSE;
}
NTHeaders = (PIMAGE_NT_HEADERS)((BYTE *)pMapping + DOSHeader->e_lfanew);
if (NTHeaders->Signature != IMAGE_NT_SIGNATURE){
printf("Bad PE Signature\n");
UnmapViewOfFile(pMapping);
CloseHandle(hMapping);
CloseHandle(hFile);
return FALSE;
}
ImageBase = NTHeaders->OptionalHeader.ImageBase;
KernelBaseAddr -= ImageBase;
pSecHdr = IMAGE_FIRST_SECTION(NTHeaders);
for(NumberOfSections = NTHeaders->FileHeader.NumberOfSections;
NumberOfSections;
(DWORD)pSecHdr += sizeof(IMAGE_SECTION_HEADER), NumberOfSections--
)
if(strcmp(pSecHdr->Name,"INIT") == 0)
break;
if(!NumberOfSections) {
printf("Cannot found the section \"INIT\".\n");
UnmapViewOfFile(pMapping);
CloseHandle(hMapping);
CloseHandle(hFile);
return FALSE;
}
INIT_Sex = (DWORD)((DWORD)pMapping + (DWORD)pSecHdr->PointerToRawData);
RawSize = pSecHdr->SizeOfRawData - 12;
while(RawSize) {
/*
INIT:00558B36 mov ecx, 800h
INIT:00558B3B shr ecx, 2
INIT:00558B3E rep movsd ; Copy To IDT !
*/
if(!memcmp((PBYTE)INIT_Sex,"\xB9\x00\x08\x00\x00\xC1\xE9\x02\xF3\xA5",10))
break; // Good Boy ;)
(DWORD)INIT_Sex += 1;
(DWORD)RawSize -= 1;
}
if(!RawSize) {
printf("Cannot found the magic part of code.\n");
UnmapViewOfFile(pMapping);
CloseHandle(hMapping);
CloseHandle(hFile);
return FALSE;
}
(DWORD)INIT_Sex -= 4; // INIT:00558B31 mov esi, offset xxxxx ; _IDT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -