⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 idt_guard.c

📁 IDT Hook 检测及恢复 此程序在 Ring3 下打开物理内存对象取得当前内存中的 IDT
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
    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 + -