导出表_eat_遍历

#include <ntifs.h>
#include <ntimage.h>
#define SystemModuleInformation 11
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef struct _SYSTEM_MODULE_INFORMATION  // 系统模块信息
{
	ULONG  Reserved[2];
	ULONG  Base;
	ULONG  Size;
	ULONG  Flags;
	USHORT Index;
	USHORT Unknown;
	USHORT LoadCount;
	USHORT ModuleNameOffset;
	CHAR   ImageName[256];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

typedef struct _tagSysModuleList {          //模块链结构
	ULONG ulCount;
	SYSTEM_MODULE_INFORMATION smi[1];
} MODULES, *PMODULES;

NTSTATUS __stdcall ZwQuerySystemInformation(
	ULONG_PTR SystemInformationClass,
	PVOID SystemInformation,//__in_out 
	ULONG SystemInformationLength,
	PULONG ReturnLength//__out_opt 
	);
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
	DbgPrint("卸载完成!\n");
}
BOOLEAN GetKernelModuleInfo(ULONG *ulSysModuleBase, ULONG *ulSize)
{
	NTSTATUS status;
	ULONG NeededSize, i;
	PMODULES pModuleList;
	BOOLEAN bRet = FALSE;
	pModuleList = NULL;
	__try
	{
		status = ZwQuerySystemInformation(SystemModuleInformation,NULL,0,&NeededSize);//简单说,即调用第11号功能,枚举一下内核中已加载的模块。 功能号为11,先获取所需的缓冲区大小
		if (status != STATUS_INFO_LENGTH_MISMATCH)
		{
			return bRet;
		}
		pModuleList = (PMODULES)ExAllocatePool(NonPagedPool, NeededSize);//申请内存
		if (pModuleList)
		{
			status = ZwQuerySystemInformation(SystemModuleInformation,pModuleList,NeededSize,&NeededSize);

			if (NT_SUCCESS(status))
			{
				__try
				{
					//ntoskrnl.exe总是第一个加载
					*ulSysModuleBase = pModuleList->smi[0].Base;//指向导出表的RVA地址(相对地址)
					*ulSize = pModuleList->smi[0].Size;
					bRet = TRUE;

				}
				__except (EXCEPTION_EXECUTE_HANDLER){

				}
			}
			ExFreePool(pModuleList);
			pModuleList = NULL;
		}
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		KdPrint(("%08x\r\n", GetExceptionCode()));
	}
	if (pModuleList)
		ExFreePool(pModuleList);

	return bRet;
}
BOOLEAN EunmEATTable(PVOID ulModuleBase)
{
	PIMAGE_DOS_HEADER pDosHeader;
	PIMAGE_NT_HEADERS NtDllHeader;
	IMAGE_OPTIONAL_HEADER opthdr;
	ULONG_PTR* arrayOfFunctionAddresses;
	ULONG_PTR* arrayOfFunctionNames;
	WORD* arrayOfFunctionOrdinals;
	ULONG_PTR functionOrdinal;
	ULONG_PTR Base, x, functionAddress;
	IMAGE_EXPORT_DIRECTORY *pExportTable;
	char *functionName;

	__try
	{
		pDosHeader = (PIMAGE_DOS_HEADER)ulModuleBase;//dos头
		if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
		{
			DbgPrint("IMAGE_DOS_SIGNATURE failed\r\n");
			return FALSE;
		}
		NtDllHeader = (PIMAGE_NT_HEADERS)(ULONG_PTR)((ULONG_PTR)pDosHeader + pDosHeader->e_lfanew);//nt头
		if (NtDllHeader->Signature != IMAGE_NT_SIGNATURE)
		{
			DbgPrint("IMAGE_NT_SIGNATURE failed\r\n");
			return FALSE;
		}
		opthdr = NtDllHeader->OptionalHeader;//pe可选镜像头
		pExportTable = (IMAGE_EXPORT_DIRECTORY*)((ULONG_PTR)ulModuleBase + opthdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); //得到导出表		//指向导出表的RVA地址(相对地址)
		arrayOfFunctionAddresses = (ULONG_PTR*)((ULONG_PTR)ulModuleBase + pExportTable->AddressOfFunctions);  //地址表
		arrayOfFunctionNames = (ULONG_PTR*)((BYTE*)ulModuleBase + pExportTable->AddressOfNames);         //函数名表
		arrayOfFunctionOrdinals = (WORD*)((BYTE*)ulModuleBase + pExportTable->AddressOfNameOrdinals);// 函数索引号RVA
		Base = pExportTable->Base;
		for (x = 0; x < pExportTable->NumberOfFunctions; x++) //在整个导出表里扫描
		{
			functionName = (char*)((BYTE*)ulModuleBase + arrayOfFunctionNames[x]);//函数名字
			functionOrdinal = arrayOfFunctionOrdinals[x] + Base - 1; //函数索引号RVA[x]
			functionAddress = (ULONG_PTR)((BYTE*)ulModuleBase + arrayOfFunctionAddresses[functionOrdinal]);//函数地址

			DbgPrint("%d %s:0x%08X\r\n", x, functionName, functionAddress);
		}
	}
	__except (EXCEPTION_EXECUTE_HANDLER){
	}
	return FALSE;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
	ULONG_PTR ulong_kernel_base;
	ULONG_PTR ulong_kernel_size;
	DriverObject->DriverUnload = DriverUnload;
	if (GetKernelModuleInfo(&ulong_kernel_base, &ulong_kernel_size))
	{
		EunmEATTable((PVOID)ulong_kernel_base);
	}
	return STATUS_SUCCESS;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值