-
-
[分享]导出表_eat_遍历_函数名_源码
-
发表于:
2017-5-27 10:29
4332
-
#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;
}
可用 发出来分享 大家传播
[课程]FART 脱壳王!加量不加价!FART作者讲授!