用驱动遍历进程的IAT表

WIN7 X86

驱动

#include<ntifs.h>
#include <WinDef.h>

#define DEVICE_NAME L"\\Device\\wangliang"
#define SYM_NAME L"\\??\\wangliang"

#define _COMM_ID 0x12345678

typedef NTSTATUS(*QUERY_INFO_PROCESS)(
	__in HANDLE ProcessHandle,
	__in PROCESSINFOCLASS ProcessInformationClass,
	__out_bcount(ProcessInformationLength) PVOID ProcessInformation,
	__in ULONG ProcessInformationLength,
	__out_opt PULONG ReturnLength
);

typedef struct _SYSTEM_PROCESS_INFORMATION {
	ULONG NextEntryOffset;
	ULONG NumberOfThreads;
	LARGE_INTEGER Reserved[3];
	LARGE_INTEGER CreateTime;
	LARGE_INTEGER UserTime;
	LARGE_INTEGER KernelTime;
	UNICODE_STRING ImageName;
	ULONG BasePriority;
	HANDLE ProcessId;
	HANDLE InheritedFromProcessId;
} SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION;

QUERY_INFO_PROCESS ZwQueryInformationProcess;


typedef struct _CommPackage {
	ULONG64 id;
	ULONG64 pid;
	ULONG Handle;
	CHAR name[64];
}CommPackage, * PCommPackage;

typedef NTSTATUS(NTAPI* CommCallback)(PCommPackage package);
CommCallback gCommCallback = NULL;

NTSTATUS DefDispatch(DEVICE_OBJECT* DeviceObject, IRP* Irp)
{
	Irp->IoStatus.Status = STATUS_SUCCESS;
	IoCompleteRequest(Irp, 0);
	return STATUS_SUCCESS;
}

VOID DriverUnload(PDRIVER_OBJECT pDriver) {
	UNICODE_STRING symName = { 0 };
	RtlInitUnicodeString(&symName, SYM_NAME);
	IoDeleteSymbolicLink(&symName);

	IoDeleteDevice(pDriver->DeviceObject);

	DbgPrint("Driver UnLoad!");
}


NTSTATUS process_enum(DEVICE_OBJECT* DeviceObject, IRP* Irp) {

	PIO_STACK_LOCATION ioStack = IoGetCurrentIrpStackLocation(Irp);
	LARGE_INTEGER ByteOffset = ioStack->Parameters.Read.ByteOffset;
	int Length = ioStack->Parameters.Read.Length;
	PCommPackage package = Irp->UserBuffer;
	NTSTATUS status = STATUS_UNSUCCESSFUL;

	HANDLE hProc = NULL;
	PEPROCESS pEprocess = NULL;
	
	PVOID pBuf = NULL;
	ULONG ulSize = 1000;
	ANSI_STRING ansi_buffer_target = { 0 };


	pEprocess = PsGetCurrentProcess();
	if (pEprocess == NULL) {
		DbgPrintEx(77, 0, "GRT ERROR");
		return STATUS_SUCCESS;

	}
	
	if (package->pid > 1) {
		ULONG64 i = (ULONG64)1;
		for (; i < package->pid; i++) {
			pEprocess = (PEPROCESS)(*(ULONG*)((ULONG)pEprocess + 0xB8) - 0xB8);
		}
	}
	
	if (*(ULONG*)((ULONG)pEprocess + 0xB4) == NULL) {
		Irp->IoStatus.Information = 0;
		Irp->IoStatus.Status = status;
		IoCompleteRequest(Irp, 0);
		return STATUS_SUCCESS;
	}
	package->Handle = pEprocess;
	NTSTATUS NtStatus = ObOpenObjectByPointer(pEprocess, NULL, NULL, 0, NULL, KernelMode, &hProc);

	if (!NT_SUCCESS(NtStatus)) {
		ZwClose(hProc);
		Irp->IoStatus.Information = 0;
		Irp->IoStatus.Status = status;
		IoCompleteRequest(Irp, 0);
		return STATUS_SUCCESS;
	}
	
	pBuf = ExAllocatePool(PagedPool, ulSize);
	
	if (!pBuf) {
		ZwClose(hProc);
		Irp->IoStatus.Information = 0;
		Irp->IoStatus.Status = status;
		IoCompleteRequest(Irp, 0);
		return STATUS_SUCCESS;
	}
	RtlZeroMemory(pBuf, ulSize);
	
	if (NULL == ZwQueryInformationProcess) {

		UNICODE_STRING routineName;

		RtlInitUnicodeString(&routineName, L"ZwQueryInformationProcess");

		ZwQueryInformationProcess =(QUERY_INFO_PROCESS)MmGetSystemRoutineAddress(&routineName);

		if (NULL == ZwQueryInformationProcess) {
			DbgPrint("Cannot resolve ZwQueryInformationProcess\n");
		}
	}
	NtStatus = ZwQueryInformationProcess(hProc, ProcessImageFileName, pBuf, ulSize,NULL);
	if (!NT_SUCCESS(NtStatus)) {
		ZwClose(hProc);
		Irp->IoStatus.Information = 0;
		Irp->IoStatus.Status = status;
		IoCompleteRequest(Irp, 0);
		return STATUS_SUCCESS;
	}
	RtlUnicodeStringToAnsiString(&ansi_buffer_target, (PUNICODE_STRING)pBuf, TRUE);
	strcpy(package->name, ansi_buffer_target.Buffer);
	RtlFreeAnsiString(&ansi_buffer_target);
	


/*
	ulProcessName = (char*)((ULONG)pEprocess + 0x16C);
	ulProcessID = *(ULONG*)((ULONG)pEprocess + 0xB4);

	DbgPrintEx(77, 0, "PID=%d,process_name=%s\r\n", ulProcessID, ulProcessName);
	strcpy(package->name, ulProcessName);
*/
	Irp->IoStatus.Information = 0;
	Irp->IoStatus.Status = status;

	//APChangeThreadMode(EThread, PreviousMode);

	ZwClose(hProc);
	IoCompleteRequest(Irp, 0);

	return STATUS_SUCCESS;
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING registeryPat) {
	UNICODE_STRING unName = { 0 };
	RtlInitUnicodeString(&unName, DEVICE_NAME);

	UNICODE_STRING symName = { 0 };
	RtlInitUnicodeString(&symName, SYM_NAME);

	PDEVICE_OBJECT pDevice = NULL;

	NTSTATUS status = IoCreateDevice(pDriver, NULL, &unName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDevice);

	if (!NT_SUCCESS(status))
	{
		DbgPrint("[db]:%x\r\n", status);
		return status;
	}

	status = IoCreateSymbolicLink(&symName, &unName);

	if (!NT_SUCCESS(status))
	{
		IoDeleteDevice(pDevice);
		DbgPrint("[db]:%x\r\n", status);
		return status;
	}

	pDevice->Flags &= ~DO_DEVICE_INITIALIZING;
	pDevice->Flags |= DO_BUFFERED_IO;

	pDriver->MajorFunction[IRP_MJ_CREATE] = DefDispatch;
	pDriver->MajorFunction[IRP_MJ_CLOSE] = DefDispatch;
	pDriver->MajorFunction[IRP_MJ_READ] = process_enum;

	pDriver->DriverUnload = DriverUnload;

	return STATUS_SUCCESS;

}

R3

#include <stdio.h>
#include <Windows.h>
#include<psapi.h>

#pragma comment(lib,"psapi.lib")

#define SYM_NAME   "\\\\.\\wangliang"

typedef struct _CommPackage {
	ULONG64 id;
	ULONG64 pid;
	ULONG Handle;
	CHAR name[64];
}CommPackage, * PCommPackage;

#define _COMM_ID 0x12345678

int check_address(HANDLE hProcess, int Address) {
	MEMORY_BASIC_INFORMATION memInfo;
	SIZE_T size = VirtualQueryEx(hProcess, Address, &memInfo, sizeof(memInfo));
	int value = 0;
	DWORD oldProtect;
	if (size == sizeof(memInfo)) {
		// 检查memInfo保护位,如果包含PAGE_NOACCESS标志,则地址无效
		if ((memInfo.State != MEM_COMMIT) ||
			((memInfo.Protect & PAGE_GUARD) != 0) ||
			((memInfo.Protect & PAGE_NOACCESS) != 0)) {
			return 0;
		}
		else {
			if (Address >= (int)memInfo.BaseAddress && Address < (int)memInfo.BaseAddress + memInfo.RegionSize) {
				if (ReadProcessMemory(hProcess, Address, &value, sizeof(int), NULL) == FALSE) {
					return 0;
				}
				else {
					if (VirtualProtect(memInfo.BaseAddress, memInfo.RegionSize, PAGE_READONLY, &oldProtect)) {
						VirtualProtect(memInfo.BaseAddress, memInfo.RegionSize, oldProtect, &oldProtect);
						return 1;
					}
					else {
						return 0;
					}
				}
			}
			else {
				return 0;
			}
		}
	}

}

int main()
{
	HANDLE Handle;
	PIMAGE_DOS_HEADER pDosHeader;
	PIMAGE_NT_HEADERS pNTHeaders;
	PIMAGE_OPTIONAL_HEADER pOptHeader;
	PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor;
	HMODULE hMods[1024];
	DWORD cbNeeded;
	DWORD processID; // 目标进程 ID

	CommPackage packag;
	packag.id = _COMM_ID;
	packag.pid = (ULONG64)1;

	for (int i = 0; i < 64; i++) {
		packag.name[i] = 0;
	}
	HANDLE hDevice = CreateFileA(SYM_NAME, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);


	if (hDevice == NULL || hDevice == INVALID_HANDLE_VALUE)
	{
		printf("%d", hDevice);
		system("pause");
		return 0;
	}

	DWORD p = 0;

	int j = 0;

	ReadFile(hDevice, &packag, sizeof(CommPackage), &p, NULL);
	char First[64] = { 0 };
	strcpy_s(First, 64, packag.name);
	printf("%s\r\n", packag.name);

	DWORD dwProcessID[0x500] = { 0 };  //开始的预先分配较大的缓冲区,用来存放进程ID
	DWORD dwNeeded = 0;
	BOOL bEnumRes = EnumProcesses(dwProcessID, sizeof(dwProcessID), &dwNeeded);
	UINT uCount = dwNeeded / sizeof(DWORD); //获得枚举到进程的数量


	do {

		j = 0;

		for (int i = 0; i < 64; i++) {
			if (packag.name[i] == 92) {
				j = i;
			}
		}
		char name[64] = { 0 };
		for (int i = 0; i + j + 1 < 64; i++) {
			name[i] = packag.name[j + i + 1];
		}

		for (UINT x = 0; x < uCount; x++)
		{

			//只对进程进程枚举,所以申请QUERY权限,具体还得根据应用申请权限

			HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessID[x]);
			if (NULL != hProcess)
			{
				CHAR szProcessName[0x50] = { 0 };
				DWORD dwNameLen = 0x50;
				BOOL bRet = QueryFullProcessImageNameA(hProcess, 0, szProcessName, &dwNameLen);
				if (bRet)
				{
					//printf("ID:%4d\tprocessName(%s)\n", dwProcessID[i], szProcessName);
					j = 0;

					for (int i = 0; i < sizeof(szProcessName); i++) {
						if (szProcessName[i] == 92) {
							j = i;
						}
					}
					char name2[64] = { 0 };
					for (int i = 0; i + j + 1 < sizeof(szProcessName); i++) {
						name2[i] = szProcessName[j + i + 1];
					}

					if (strcmp(name2, name) == 0) {
						//_asm int 3;
						processID = dwProcessID[x];
					}
				}
			}
		}
		//DWORD processID; // 目标进程 ID
		//_asm int 3;
		HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID); // 打开目标进程句柄

		_asm int 3;
		if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) { // 枚举目标进程所有模块
			for (unsigned int i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
				TCHAR szModName[MAX_PATH];
				//_asm int 3;
				if (GetModuleBaseName(hProcess, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR))) { // 获取模块名和基址
					if (check_address(hProcess, hMods[i]) == 0) {
						goto new_Mods;
					}
					
					printf("Module base address:%s ", hMods[i]);
					printf("Module name: %s", szModName);
					pDosHeader = (PIMAGE_DOS_HEADER)hMods[i];

					pNTHeaders = (PIMAGE_NT_HEADERS)((BYTE*)hMods[i] + pDosHeader->e_lfanew);
					pOptHeader = (PIMAGE_OPTIONAL_HEADER) & (pNTHeaders->OptionalHeader);

					//获取本进程的函数导入表结构体
					pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((BYTE*)hMods[i] + pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);

					//循环遍历函数导入表的IMAGE_IMPORT_DESCRIPTOR结构体
					while (pImportDescriptor->FirstThunk && pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
					{
						//获取函数名地址IMAGE_THUNK_DATA结构体
						PIMAGE_THUNK_DATA pFuncNameAddr = (PIMAGE_THUNK_DATA)((BYTE*)hMods[i] + pImportDescriptor->OriginalFirstThunk);

						//获取函数在内存中的地址IMAGE_THUNK_DATA结构体
						PIMAGE_THUNK_DATA pFuncAddr = (PIMAGE_THUNK_DATA)((BYTE*)hMods[i] + pImportDescriptor->FirstThunk);
						//获取本导入dll的dll文件名
						char* pDllName = (char*)((BYTE*)hMods[i] + pImportDescriptor->Name);
						if (check_address(hProcess, pDllName) == 0) {
							goto new_DLL;
						}
						printf("%s\n", pDllName);

						//循环遍历函数导入表的函数名列表
						while (pFuncNameAddr->u1.Function)
						{
							//获取函数导入序号
							WORD* iNo = ((BYTE*)hMods[i] + (DWORD)pFuncNameAddr->u1.AddressOfData);

							//获取函数名
							char* pFuncName = (char*)((BYTE*)hMods[i] + (DWORD)pFuncNameAddr->u1.AddressOfData + 2);

							if (check_address(hProcess, pFuncName) == 0) {
								goto new_Fun;
							}
							
							//获取函数名对应的函数在内存中的地址
							PDWORD lpAddr = pFuncAddr->u1.AddressOfData;

							printf("%0 4X : %s    %#X\n", *iNo, pFuncName, lpAddr);

						new_Fun:
							//指向下一个函数
							pFuncNameAddr++;
							pFuncAddr++;
						}
						//_asm int 3;
						//getchar();

					new_DLL:				//指向下一个dll
						pImportDescriptor++;
					}
				new_Mods:

					;
				}
			}
		}
			packag.pid = packag.pid + 1;
			for (int i = 0; i < 64; i++) {
				packag.name[i] = 0;
			}
			ReadFile(hDevice, &packag, sizeof(CommPackage), &p, NULL);
			printf("%s\r\n", packag.name);
			Sleep(1000);
	}while (strcmp(First, packag.name) != NULL);

	CloseHandle(hDevice);

	system("pause");
	return 0;
}

效果

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值