11111

r3

Api.h

#pragma once
#include <Windows.h>

EXTERN_C BOOLEAN WINAPI SH_DriverLoad();

EXTERN_C VOID WINAPI SH_UnDriverLoad();

EXTERN_C ULONG64 WINAPI SH_GetModule(DWORD pid,char * moduleName);

EXTERN_C BOOLEAN WINAPI SH_ReadMemory(DWORD pid, ULONG64 BaseAddress,PVOID Buffer,ULONG size);

Api.cpp

#include "Api.h"
#include "LoadDriver.h"
#include <time.h>
#include "../rw/comm/commStruct.h"
#include "CommR3.h"

char AZTable[62]=
{
	0,
};

void initTable()
{
	if (AZTable[0] != 0) return;
	int k = 0;
	for (char i = 'A'; i <= 'Z'; i++, k++)
	{
		AZTable[k] = i;
	}

	for (char i = 'a'; i <= 'z'; i++, k++)
	{
		AZTable[k] = i;
	}

	for (char i = '0'; i <= '9'; i++, k++)
	{
		AZTable[k] = i;
	}
}

char * GetRandName()
{
	static char * name = NULL;
	if (name) return name;

	initTable();

	name = (char *)malloc(20);

	memset(name, 0, 20);  //15 .sys 0

	time_t t = time(NULL);
	srand(t);
	
	int len = (rand() % 10) + 5;
	for (int i = 0; i < len; i++)
	{
		int index = rand() % sizeof(AZTable);
		name[i] = AZTable[index];
	}
	
	strcat(name, ".sys");

	return name;
}

char * GetRandServiceName()
{
	static char * name = NULL;
	if (name) return name;

	initTable();

	name = (char *)malloc(10);

	memset(name, 0, 10);  //15 .sys 0

	time_t t = time(NULL);
	srand(t);

	int len = (rand() % 4) + 5;
	for (int i = 0; i < len; i++)
	{
		int index = rand() % sizeof(AZTable);
		name[i] = AZTable[index];
	}

	return name;
}

EXTERN_C BOOLEAN WINAPI SH_Test()
{
	ULONG64 xx = 0;
	return DriverComm(CMD_TEST, &xx, sizeof(xx));

	
}

//cdcel __stdcall
EXTERN_C BOOLEAN WINAPI SH_DriverLoad()
{
	LoadDriver Load;
	
	if (SH_Test())
	{
		return TRUE;
	}
	
	char bufPath[MAX_PATH] = { 0 };
	GetTempPathA(MAX_PATH, bufPath);

	char * driverName = GetRandName();
	char * serviceName = GetRandServiceName();



	strcat(bufPath, driverName);

	return Load.installDriver(bufPath, serviceName);
}

EXTERN_C VOID WINAPI SH_UnDriverLoad()
{
	//LoadDriver Load;
	//
	//char * serviceName = GetRandServiceName();
	//
	//Load.unload(serviceName);
}


EXTERN_C ULONG64 WINAPI SH_GetModule(DWORD pid, char * moduleName)
{
	ModuleInfo info = {0};
	info.moduleName = (ULONG64)moduleName;
	info.pid = pid;
	DriverComm(CMD_GET_MODULE, &info, sizeof(ModuleInfo));

	return info.Module;
}


EXTERN_C BOOLEAN WINAPI SH_ReadMemory(DWORD pid, ULONG64 BaseAddress, PVOID Buffer, ULONG size)
{
	ReadWriteInfo info = {0};
	info.pid = pid;
	info.BaseAddress = BaseAddress;
	info.Buffer = (ULONG64)Buffer;
	info.size = size;

	return DriverComm(CMD_READ_MEMORY, &info, sizeof(ReadWriteInfo));
}

CommR3.h

#pragma once
#include <Windows.h>

BOOLEAN DriverComm(ULONG cmd, PVOID inData, SIZE_T size);

CommR3.cpp

#include "CommR3.h"
#include <intrin.h>
#include "../rw/comm/commStruct.h"
#include <stdio.h>

typedef struct _IO_STATUS_BLOCK {
	union {
		ULONG Status;
		PVOID Pointer;
	};

	ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;

typedef ULONG(WINAPI *NtQueryInformationFileProc)(
	__in HANDLE FileHandle,
	__out PIO_STATUS_BLOCK IoStatusBlock,
	__out_bcount(Length) PVOID FileInformation,
	__in ULONG Length,
	__in ULONG FileInformationClass);

typedef ULONG(WINAPI * NtConvertBetweenAuxiliaryCounterAndPerformanceCounterProc)(char a1, PVOID a2, PVOID a3, PVOID a4);

NtQueryInformationFileProc gNtQueryInformationFile = NULL;
HANDLE ghFile = NULL;

NtConvertBetweenAuxiliaryCounterAndPerformanceCounterProc gNtConvertBetweenAuxiliary = NULL;


USHORT MyGetVersion()
{
	static USHORT osBuildNumber = 0;
	if (osBuildNumber) return osBuildNumber;
#ifndef _WIN64
	DWORD peb = __readfsdword(0x30);
	osBuildNumber = *(PUSHORT)(peb + 0xac);
#else
	ULONG64 peb = __readgsqword(0x60);
	osBuildNumber = *(PUSHORT)(peb + 0x120);
#endif

	return osBuildNumber;
}

BOOLEAN DriverCommInit()
{

	if(gNtQueryInformationFile || gNtConvertBetweenAuxiliary) return TRUE;

	USHORT buildNumber = MyGetVersion();
	HMODULE h = GetModuleHandleA("ntdll.dll");
	if (buildNumber == 7600 || buildNumber == 7601)
	{
		gNtQueryInformationFile = (NtQueryInformationFileProc)GetProcAddress(h, "NtQueryInformationFile");
		char bufPath[MAX_PATH] = { 0 };
		
		GetTempPathA(MAX_PATH, bufPath);
		strcat_s(bufPath, "\\1.txt");
		ghFile = CreateFileA(bufPath, FILE_ALL_ACCESS, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
		if (ghFile == NULL || ghFile == INVALID_HANDLE_VALUE)
		{
			MessageBoxA(NULL, "通信初始化失败", "func", 0);
			return FALSE;
		}
	}
	else 
	{
		
		gNtConvertBetweenAuxiliary = (NtConvertBetweenAuxiliaryCounterAndPerformanceCounterProc)GetProcAddress(h, "NtConvertBetweenAuxiliaryCounterAndPerformanceCounter");
	}

	return TRUE;
}

BOOLEAN DriverComm7(ULONG cmd, PVOID inData, SIZE_T size)
{
	char buf[0xE0] = { 0 };

	PCommPackage package = (PCommPackage)buf;
	package->Id = 0x12345678;
	package->cmd = cmd;
	package->Size = size;
	package->Data = (ULONG64)inData;
	package->retStatus = -1;
	IO_STATUS_BLOCK is = { 0 };
	gNtQueryInformationFile(ghFile, &is, buf, sizeof(buf), 0x34);

	return package->retStatus == 0;
}


BOOLEAN DriverComm10(ULONG cmd, PVOID inData, SIZE_T size)
{

	CommPackage package;
	package.Id = 0x12345678;
	package.cmd = cmd;
	package.Data = (ULONG64)inData;
	package.Size = size;
	package.retStatus = -1;
	ULONG64 xxx = 0;
	PCommPackage data = &package;
	gNtConvertBetweenAuxiliary(1, (PVOID)&data, (PVOID)&xxx, NULL);

	printf("ret = %d\r\n", package.retStatus);
	return package.retStatus == 0;
}

//int x = DriverCommInit();

BOOLEAN DriverComm(ULONG cmd, PVOID inData, SIZE_T size)
{
	if (DriverCommInit())
	{
		USHORT buildNumber = MyGetVersion();
		if (buildNumber == 7600 || buildNumber == 7601)
		{
			return DriverComm7(cmd, inData, size);
		}
		else 
		{
			return DriverComm10(cmd, inData, size);
		}
	}

	return FALSE;
}

LoadDriver.h

#pragma once
#include <string>
#include <Windows.h>
using namespace std;

class LoadDriver
{
public:
	LoadDriver();
	~LoadDriver();
	bool load(std::string path,std::string serviceName);
	bool unload(std::string serviceName);
	bool installDriver(std::string path, std::string serviceName);
	static HMODULE getDllBase();
};


LoadDriver.cpp

#include "stdafx.h"
#include "LoadDriver.h"
#include <windows.h>
#include <Winsvc.h>
#include "dll.h"

LoadDriver::LoadDriver()
{
	
}


LoadDriver::~LoadDriver() 
{
} 


bool LoadDriver::load(std::string path, std::string serviceName)
{
	bool bRet = false;
	DWORD dwLastError;
	SC_HANDLE hSCManager;
	SC_HANDLE hService = NULL;

	if (hSCManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS))
	{
		hService = CreateServiceA(
			hSCManager, serviceName.c_str(),
			serviceName.c_str(), SERVICE_ALL_ACCESS,
			SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START,
			SERVICE_ERROR_IGNORE, path.c_str(),
			NULL, NULL, NULL, NULL, NULL
			);

		if (hService == NULL)
		{
			hService = OpenServiceA(hSCManager, serviceName.c_str(), SERVICE_ALL_ACCESS);
			
			if (!hService)
			{
				CloseServiceHandle(hSCManager);
				return false;
			}
			
		}

		bRet = StartServiceA(hService, 0, NULL);
		if (!bRet)
		{
			dwLastError = GetLastError();
			printf("%d\r\n", dwLastError);
		}
	
	}

	if (hService)
	{
		CloseServiceHandle(hService);
	}

	if (hSCManager)
	{
		CloseServiceHandle(hSCManager);
	}

	return bRet;
}



bool LoadDriver::unload(std::string serviceName)
{
	BOOL bRet = FALSE;
	SC_HANDLE hServiceMgr = NULL;
	SC_HANDLE hServiceDDK = NULL;
	SERVICE_STATUS SvrSta;

	do
	{
		//
		// 打开SCM管理器
		//
		hServiceMgr = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);

		if (hServiceMgr == NULL)
		{
			break;
		}

		//
		// 打开驱动所对应的服务
		//
		hServiceDDK = OpenServiceA(hServiceMgr, serviceName.c_str(), SERVICE_ALL_ACCESS);

		if (hServiceDDK == NULL)
		{
			break;
		}

		ControlService(hServiceDDK, SERVICE_CONTROL_STOP, &SvrSta);


		if (DeleteService(hServiceDDK))
		{
			bRet = TRUE;
		}

	} while (FALSE);

	if (hServiceDDK)
	{
		CloseServiceHandle(hServiceDDK);
	}

	if (hServiceMgr)
	{
		CloseServiceHandle(hServiceMgr);
	}

	return bRet;
}

HMODULE GetSelfModuleHandle()
{
	MEMORY_BASIC_INFORMATION mbi;

	return ((::VirtualQuery(GetSelfModuleHandle, &mbi, sizeof(mbi)) != 0)
		? (HMODULE)mbi.AllocationBase : NULL);
}

HMODULE LoadDriver::getDllBase()
{
	return GetSelfModuleHandle();
}

bool LoadDriver::installDriver(std::string path, std::string serviceName)
{
	HRSRC hResc;
	DWORD dwImageSize;
	HANDLE hFile;
	DWORD dwByteWrite;
	HGLOBAL	hResourecImage;
	CHAR str[512] = { 0 };

	//
	// 或许是上次由于未知错误, 导致驱动卸载
	// 不干净, 这里卸载一次.
	//
	this->unload(serviceName.c_str());

	//
	// 在自定义资源中释放出sys
	//


	dwImageSize = sizeof(sysData);
	unsigned char * pMemory = (unsigned char *)malloc(dwImageSize);
	memcpy(pMemory, sysData, dwImageSize);
	for (ULONG i = 0; i < dwImageSize; i++)
	{
		pMemory[i] ^= 0xd8;
		pMemory[i] ^= 0xcd;
	}


	hFile = CreateFileA(path.c_str(), GENERIC_WRITE, FILE_SHARE_READ,
		NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		OutputDebugStringA(path.c_str());
		return false;
	}

	if (!WriteFile(hFile, pMemory, dwImageSize, &dwByteWrite, NULL))
	{
		OutputDebugStringA(path.c_str());
		CloseHandle(hFile);
		return false;
	}

	if (dwByteWrite != dwImageSize)
	{
		OutputDebugStringA(path.c_str());
		CloseHandle(hFile);
		return false;
	}

	CloseHandle(hFile);

	//
	// 安装驱动
	//
	if (!this->load(path, serviceName))
	{
		DeleteFileA(path.c_str());
		return false;
	}

	DeleteFileA(path.c_str());

	return true;
}

stdafx.h

// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//

#pragma once

#include "targetver.h"

#define WIN32_LEAN_AND_MEAN             // 从 Windows 头中排除极少使用的资料
// Windows 头文件: 
#include <windows.h>



// TODO:  在此处引用程序需要的其他头文件

stdafx.cpp

// stdafx.cpp : 只包括标准包含文件的源文件
// rwR3.pch 将作为预编译头
// stdafx.obj 将包含预编译类型信息

#include "stdafx.h"

// TODO: 在 STDAFX.H 中引用任何所需的附加头文件,
//而不是在此文件中引用

targetver.h

#pragma once

// 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。

// 如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并将
// 将 _WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。

#include <SDKDDKVer.h>

export.def

 LIBRARY 
    EXPORTS
		SH_DriverLoad
		SH_UnDriverLoad
		SH_GetModule
		SH_ReadMemory

rwR3.cpp

// rwR3.cpp : 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"

dllmain.cpp

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "CommR3.h"
#include "Api.h"

int main(int argc, char * argv[])
{
	if (SH_DriverLoad())
	{
		printf("驱动加载成功\r\n");
		//HWND hwnd = NULL;
		//do
		//{
		//	hwnd = FindWindowA("地下城与勇士", "地下城与勇士");		//找到dnf的句柄
		//	
		//
		//} while (!hwnd);
		//
		//printf("hwnd = %llx\r\n", hwnd);
		//
		//DWORD pid = 0;
		//GetWindowThreadProcessId(hwnd, &pid);			//在三环下获取dnf的进程id
		DWORD pid = 1968;
		ULONG64 module = SH_GetModule(pid, "explorer.exe");			//获取到进程模块
		printf("module = %llx\r\n", module);
		//A4052D0;
		ULONG64 buffer = 0;
		ULONG startTime = GetTickCount();
		ULONG64 role = module;
		for (int i = 0; i < 1000000; i++)
		{
			SH_ReadMemory(pid, role, &buffer, sizeof(buffer));
		}
		
		ULONG EndTime = GetTickCount();
		
		printf("读100W次耗时 %d毫秒\r\n", EndTime - startTime);
		
		printf("role = %llx\r\n", buffer);
		
		system("pause");
		SH_UnDriverLoad();
	}
	else 
	{
		printf("驱动加载失败\r\n");
	}
	


	system("pause");
	return 0;
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}


r0

comm

Comm.h

#pragma once
#include <ntifs.h>
#include "commStruct.h"




NTSTATUS RegisterComm(CommCallbackProc callback);

VOID UnRegisterComm();

Comm.c

#include "comm.h"
#include "comm7.h"
#include "comm10.h"
#include "../Search.h"

NTSTATUS RegisterComm(CommCallbackProc callback)
{
	RTL_OSVERSIONINFOEXW version = {0};
	RtlGetVersion(&version);

	if (version.dwBuildNumber == 7600 || version.dwBuildNumber == 7601)
	{
		return RegisterCommWin7(callback);
	}

	return RegisterCommWin10(callback);
}



VOID UnRegisterComm()
{
	RTL_OSVERSIONINFOEXW version = { 0 };
	RtlGetVersion(&version);

	if (version.dwBuildNumber == 7600 || version.dwBuildNumber == 7601)
	{
		UnRegisterCommWin7();
		return;
	}

	UnRegisterCommWin10();
}

CommStruct.h

#pragma once

#ifndef _WINDOWS
#include <ntifs.h>
#else
#include <Windows.h>
#endif
typedef struct _CommPackage
{
	ULONG64 Id; // 1 2 3 4
	ULONG64 cmd; // 1 2 3 4
	ULONG64 Data;
	ULONG64 Size;
	ULONG64 retStatus;
}CommPackage, *PCommPackage;

typedef enum _CMD
{
	CMD_TEST,		//防止驱动隐藏之后 重复加载
	CMD_GET_MODULE, //获取模块
	CMD_READ_MEMORY //读内存
}CMD;


typedef struct _ModuleInfo 
{
	ULONG64 pid;
	ULONG64 moduleName;
	ULONG64 Module;
	ULONG64 ModuleSize;
}ModuleInfo,*PModuleInfo;

typedef struct _ReadWriteInfo 
{
	ULONG64 pid;
	ULONG64 BaseAddress;
	ULONG64 Buffer;
	ULONG64 size;
}ReadWriteInfo,*PReadWriteInfo;

typedef ULONG (NTAPI * CommCallbackProc)(PCommPackage package);

Comm7.h

#pragma once
#include <ntifs.h>
#include "commStruct.h"


NTSTATUS RegisterCommWin7(CommCallbackProc callback);

VOID UnRegisterCommWin

Comm7.c

#include "comm7.h"
#include "../Search.h"

CommCallbackProc gCommCallbackWin7 = NULL;


//----------------------------------------WIN7----------------------------
typedef NTSTATUS(*FileCallBack)(HANDLE FileHandle, PVOID info, PVOID un1, PVOID un2);

FileCallBack oldExpDisQueryAttributeInformationFunc = NULL;
FileCallBack oldExpDisSetAttributeInformationFunc = NULL;

PULONG64 gWin7CallbackVar = NULL;



typedef struct _RegisterCallback
{
	FileCallBack QueryFileCallback;
	FileCallBack SetFileCallBack;

}RegisterCallback, *PRegisterCallback;


typedef NTSTATUS(*ExRegisterAttributeInformationCallbackProc)(PRegisterCallback callbacks);

NTSTATUS QueryFileCallBack(HANDLE FileHandle, PVOID info, PVOID un1, PVOID un2)
{
	KdPrintEx((77,0,"QueryFileCallBack\r\n"));
	if (MmIsAddressValid(info))
	{
		
		PCommPackage package = (PCommPackage)info;
		if (package->Id == 0x12345678)
		{
			package->retStatus = gCommCallbackWin7(package);

		}
		else
		{
			if (oldExpDisQueryAttributeInformationFunc)
			{
				return oldExpDisQueryAttributeInformationFunc(FileHandle, info, un1, un2);
			}
		}
	}

	
	return STATUS_SUCCESS;
}

NTSTATUS SetFileCallBack(HANDLE FileHandle, PVOID info,PVOID un1,PVOID un2)
{
	KdPrintEx((77, 0, "SetFileCallBack\r\n"));
	if (MmIsAddressValid(info))
	{
		
		PCommPackage package = (PCommPackage)info;
		if (package->Id == 0x12345678)
		{
			package->retStatus = gCommCallbackWin7(package);
			
		}
		else 
		{
			if (oldExpDisSetAttributeInformationFunc)
			{
				return oldExpDisSetAttributeInformationFunc(FileHandle, info, un1, un2);
			}
		}

	}
	
	return STATUS_SUCCESS;
}

NTSTATUS RegisterCommWin7(CommCallbackProc callback)
{
	UNICODE_STRING unName = {0};
	RtlInitUnicodeString(&unName, L"ExRegisterAttributeInformationCallback");
	PUCHAR pFunc = MmGetSystemRoutineAddress(&unName);

	ULONG64 offset = *(PLONG)(pFunc + 0xd + 3);
	PULONG64 ExpDisQueryAttributeInformation = (PULONG64)((pFunc + 0xd + 7) + offset);

	oldExpDisQueryAttributeInformationFunc = (FileCallBack)ExpDisQueryAttributeInformation[0];
	oldExpDisSetAttributeInformationFunc = (FileCallBack)ExpDisQueryAttributeInformation[1];

	ExpDisQueryAttributeInformation[0] = 0;
	ExpDisQueryAttributeInformation[1] = 0;
	
	RegisterCallback rcb = {0};
	rcb.SetFileCallBack = SetFileCallBack;
	rcb.QueryFileCallback = QueryFileCallBack;

	ExRegisterAttributeInformationCallbackProc callFunc = (ExRegisterAttributeInformationCallbackProc)pFunc;

	NTSTATUS status = callFunc(&rcb);
	if (NT_SUCCESS(status))
	{
		gCommCallbackWin7 = callback;
		gWin7CallbackVar = ExpDisQueryAttributeInformation;
	}
	
	
	return status;
}

VOID UnRegisterCommWin7()
{
	if (gWin7CallbackVar)
	{
		gWin7CallbackVar[0] = oldExpDisQueryAttributeInformationFunc;
		gWin7CallbackVar[1] = oldExpDisSetAttributeInformationFunc;
	}

}

//----------------------------------------WIN7--END--------------------------

Comm10.h

#pragma once
#include <ntifs.h>
#include "commStruct.h"

NTSTATUS RegisterCommWin10(CommCallbackProc callback);

VOID UnRegisterCommWin10();

Comm10.c

#include "comm10.h"
#include "../Search.h"

CommCallbackProc gCommCallbackWin10 = NULL;

typedef NTSTATUS(NTAPI * NewKdEnumerateDebuggingDevicesProc)(PVOID un1, PVOID un2, PVOID un3);

NewKdEnumerateDebuggingDevicesProc gOldNewKdEnumerateDebuggingDevicesFunc = NULL;
PULONG64 gWin10HookPoint = NULL;

NTSTATUS NewKdEnumerateDebuggingDevices(PVOID info, PVOID un2, PVOID un3)
{
	KdPrintEx((77, 0, "NewKdEnumerateDebuggingDevices\r\n"));
	
	if (MmIsAddressValid(info))
	{	
		PCommPackage package = (PCommPackage)info;
		if (package->Id == 0x12345678)
		{
			package->retStatus = gCommCallbackWin10(package);

		}
		else
		{
			if (gOldNewKdEnumerateDebuggingDevicesFunc)
			{
				return gOldNewKdEnumerateDebuggingDevicesFunc(info, un2, un3);
			}
		}

	}

	return STATUS_SUCCESS;
}

NTSTATUS RegisterCommWin10(CommCallbackProc callback)
{
	
	//NtConvertBetweenAuxiliaryCounterAndPerformanceCounter					 
	PUCHAR func = searchCode("ntoskrnl.exe", "PAGE", "488B05****75*488B05****E8", 0);
	if (func)
	{
		ULONG64 offset = *(PLONG)(func + 3);
		PULONG64 RepFunc = (PULONG64)((func +  7) + offset);

		gWin10HookPoint = RepFunc;

		gOldNewKdEnumerateDebuggingDevicesFunc = RepFunc[0];
		
		RepFunc[0] = NewKdEnumerateDebuggingDevices;

		gCommCallbackWin10 = callback;
	}


	

	return STATUS_SUCCESS;
}




VOID UnRegisterCommWin10()
{
	if (gOldNewKdEnumerateDebuggingDevicesFunc)
	{
		gWin10HookPoint[0] = gOldNewKdEnumerateDebuggingDevicesFunc;
	}

	gOldNewKdEnumerateDebuggingDevicesFunc = NULL;
}

Header Files

ExportFunc.h

#pragma once
#include <ntifs.h>

EXTERN_C void  * NTAPI PsGetProcessWow64Process(PEPROCESS Process);

EXTERN_C PVOID NTAPI PsGetProcessPeb(PEPROCESS Process);

NTSTATUS MmCopyVirtualMemory(
	IN PEPROCESS FromProcess,
	IN CONST VOID *FromAddress,
	IN PEPROCESS ToProcess,
	OUT PVOID ToAddress,
	IN SIZE_T BufferSize,
	IN KPROCESSOR_MODE PreviousMode,
	OUT PSIZE_T NumberOfBytesCopied
);

Module.h

#pragma once
#include <ntifs.h>
#include "ExportFunc.h"


#pragma pack(4)
typedef struct _PEB_LDR_DATA32
{
	ULONG Length;                                                           //0x0
	UCHAR Initialized;                                                      //0x4
	ULONG SsHandle;                                                         //0x8
	LIST_ENTRY32 InLoadOrderModuleList;                               //0xc
	LIST_ENTRY32 InMemoryOrderModuleList;                             //0x14
	LIST_ENTRY32 InInitializationOrderModuleList;                     //0x1c
	ULONG EntryInProgress;                                                  //0x24
	UCHAR ShutdownInProgress;                                               //0x28
	ULONG ShutdownThreadId;                                                 //0x2c
}PEB_LDR_DATA32,*PPEB_LDR_DATA32;



//0x248 bytes (sizeof)
typedef struct _PEB32
{
	UCHAR InheritedAddressSpace;                                            //0x0
	UCHAR ReadImageFileExecOptions;                                         //0x1
	UCHAR BeingDebugged;                                                    //0x2
	union
	{
		UCHAR BitField;                                                     //0x3
		struct
		{
			UCHAR ImageUsesLargePages : 1;                                    //0x3
			UCHAR IsProtectedProcess : 1;                                     //0x3
			UCHAR IsLegacyProcess : 1;                                        //0x3
			UCHAR IsImageDynamicallyRelocated : 1;                            //0x3
			UCHAR SkipPatchingUser32Forwarders : 1;                           //0x3
			UCHAR SpareBits : 3;                                              //0x3
		};
	};
	ULONG Mutant;                                                           //0x4
	ULONG ImageBaseAddress;                                                 //0x8
	ULONG Ldr;																//0xc

}PEB32,*PPEB32;

typedef struct _LDR_DATA_TABLE_ENTRY32
{
	LIST_ENTRY32 InLoadOrderLinks;                                    //0x0
	LIST_ENTRY32 InMemoryOrderLinks;                                  //0x8
	LIST_ENTRY32 InInitializationOrderLinks;                          //0x10
	ULONG DllBase;                                                          //0x18
	ULONG EntryPoint;                                                       //0x1c
	ULONG SizeOfImage;                                                      //0x20
	UNICODE_STRING32 FullDllName;                                     //0x24
	UNICODE_STRING32 BaseDllName;                                     //0x2c
	ULONG Flags;                                                            //0x34
	USHORT LoadCount;                                                       //0x38
	USHORT TlsIndex;                                                        //0x3a
	union
	{
		LIST_ENTRY32 HashLinks;                                       //0x3c
		struct
		{
			ULONG SectionPointer;                                           //0x3c
			ULONG CheckSum;                                                 //0x40
		};
	};
	union
	{
		ULONG TimeDateStamp;                                                //0x44
		ULONG LoadedImports;                                                //0x44
	};
	ULONG EntryPointActivationContext;                //0x48
	ULONG PatchInformation;                                                 //0x4c
	LIST_ENTRY32 ForwarderLinks;                                      //0x50
	LIST_ENTRY32 ServiceTagLinks;                                     //0x58
	LIST_ENTRY32 StaticLinks;                                         //0x60
	ULONG ContextInformation;                                               //0x68
	ULONG OriginalBase;                                                     //0x6c
	LARGE_INTEGER LoadTime;                                          //0x70
}LDR_DATA_TABLE_ENTRY32,*PLDR_DATA_TABLE_ENTRY32;

#pragma pack(0)

typedef struct _PEB_LDR_DATA
{
	
	ULONG Length;                                                           //0x0
	UCHAR Initialized;                                                      //0x4
	VOID* SsHandle;                                                         //0x8
	LIST_ENTRY InLoadOrderModuleList;                               //0x10
	LIST_ENTRY InMemoryOrderModuleList;                             //0x20
	LIST_ENTRY InInitializationOrderModuleList;                     //0x30
	VOID* EntryInProgress;                                                  //0x40
	UCHAR ShutdownInProgress;                                               //0x48
	VOID* ShutdownThreadId;                                                 //0x50
}PEB_LDR_DATA,*PPEB_LDR_DATA;

typedef struct _PEB
{
	ULONG64 x;
	VOID* Mutant;                                                           //0x8
	VOID* ImageBaseAddress;                                                 //0x10
	PEB_LDR_DATA* Ldr;														 //0x18

}PEB,*PPEB;

typedef struct _LDR_DATA_TABLE_ENTRY
{
	LIST_ENTRY InLoadOrderLinks;                                    //0x0
	LIST_ENTRY InMemoryOrderLinks;                                  //0x10
	LIST_ENTRY InInitializationOrderLinks;                          //0x20
	VOID* DllBase;                                                          //0x30
	VOID* EntryPoint;                                                       //0x38
	ULONG64 SizeOfImage;                                                      //0x40
	UNICODE_STRING FullDllName;                                     //0x48
	UNICODE_STRING BaseDllName;                                     //0x58
	ULONG Flags;                                                            //0x68
	USHORT LoadCount;                                                       //0x6c
	USHORT TlsIndex;                                                        //0x6e
	union
	{
		LIST_ENTRY HashLinks;                                       //0x70
		struct
		{
			VOID* SectionPointer;                                           //0x70
			ULONG CheckSum;                                                 //0x78
		};
	};
	union
	{
		ULONG TimeDateStamp;                                                //0x80
		VOID* LoadedImports;                                                //0x80
	};
	struct _ACTIVATION_CONTEXT* EntryPointActivationContext;                //0x88
	VOID* PatchInformation;                                                 //0x90
	LIST_ENTRY ForwarderLinks;                                      //0x98
	LIST_ENTRY ServiceTagLinks;                                     //0xa8
	LIST_ENTRY StaticLinks;                                         //0xb8
	VOID* ContextInformation;                                               //0xc8
	ULONGLONG OriginalBase;                                                 //0xd0
	LARGE_INTEGER LoadTime;                                          //0xd8
}LDR_DATA_TABLE_ENTRY,*PLDR_DATA_TABLE_ENTRY;





ULONG_PTR GetModuleR3(HANDLE pid, char *moduleName, PULONG_PTR sizeImage);

RW.h

#pragma once
#include <ntifs.h>

//直接memcpy读写 附加
NTSTATUS ReadMemory1(HANDLE pid, PVOID TargetAddress, PVOID Buffer, SIZE_T size);


// MmCopyVirtualMemory
NTSTATUS ReadMemory2(HANDLE pid, PVOID TargetAddress, PVOID Buffer, SIZE_T size);


//MDL
NTSTATUS ReadMemory3(HANDLE pid, PVOID TargetAddress, PVOID Buffer, SIZE_T size);

//直接切CR3
NTSTATUS ReadMemory4(HANDLE pid, PVOID TargetAddress, PVOID Buffer, SIZE_T size);

Search.h

#pragma once
#include <ntifs.h>


typedef enum _SYSTEM_INFORMATION_CLASS {
	SystemBasicInformation,
	SystemProcessorInformation,             // obsolete...delete
	SystemPerformanceInformation,
	SystemTimeOfDayInformation,
	SystemPathInformation,
	SystemProcessInformation,
	SystemCallCountInformation,
	SystemDeviceInformation,
	SystemProcessorPerformanceInformation,
	SystemFlagsInformation,
	SystemCallTimeInformation,
	SystemModuleInformation,
	SystemLocksInformation,
	SystemStackTraceInformation,
	SystemPagedPoolInformation,
	SystemNonPagedPoolInformation,
	SystemHandleInformation,
	SystemObjectInformation,
	SystemPageFileInformation,
	SystemVdmInstemulInformation,
	SystemVdmBopInformation,
	SystemFileCacheInformation,
	SystemPoolTagInformation,
	SystemInterruptInformation,
	SystemDpcBehaviorInformation,
	SystemFullMemoryInformation,
	SystemLoadGdiDriverInformation,
	SystemUnloadGdiDriverInformation,
	SystemTimeAdjustmentInformation,
	SystemSummaryMemoryInformation,
	SystemMirrorMemoryInformation,
	SystemPerformanceTraceInformation,
	SystemObsolete0,
	SystemExceptionInformation,
	SystemCrashDumpStateInformation,
	SystemKernelDebuggerInformation,
	SystemContextSwitchInformation,
	SystemRegistryQuotaInformation,
	SystemExtendServiceTableInformation,
	SystemPrioritySeperation,
	SystemVerifierAddDriverInformation,
	SystemVerifierRemoveDriverInformation,
	SystemProcessorIdleInformation,
	SystemLegacyDriverInformation,
	SystemCurrentTimeZoneInformation,
	SystemLookasideInformation,
	SystemTimeSlipNotification,
	SystemSessionCreate,
	SystemSessionDetach,
	SystemSessionInformation,
	SystemRangeStartInformation,
	SystemVerifierInformation,
	SystemVerifierThunkExtend,
	SystemSessionProcessInformation,
	SystemLoadGdiDriverInSystemSpace,
	SystemNumaProcessorMap,
	SystemPrefetcherInformation,
	SystemExtendedProcessInformation,
	SystemRecommendedSharedDataAlignment,
	SystemComPlusPackage,
	SystemNumaAvailableMemory,
	SystemProcessorPowerInformation,
	SystemEmulationBasicInformation,
	SystemEmulationProcessorInformation,
	SystemExtendedHandleInformation,
	SystemLostDelayedWriteInformation,
	SystemBigPoolInformation,
	SystemSessionPoolTagInformation,
	SystemSessionMappedViewInformation,
	SystemHotpatchInformation,
	SystemObjectSecurityMode,
	SystemWatchdogTimerHandler,
	SystemWatchdogTimerInformation,
	SystemLogicalProcessorInformation,
	SystemWow64SharedInformation,
	SystemRegisterFirmwareTableInformationHandler,
	SystemFirmwareTableInformation,
	SystemModuleInformationEx,
	SystemVerifierTriageInformation,
	SystemSuperfetchInformation,
	SystemMemoryListInformation,
	SystemFileCacheInformationEx,
	MaxSystemInfoClass  // MaxSystemInfoClass should always be the last enum
} SYSTEM_INFORMATION_CLASS;

typedef struct _RTL_PROCESS_MODULE_INFORMATION {
	HANDLE Section;                 // Not filled in
	PVOID MappedBase;
	PVOID ImageBase;
	ULONG ImageSize;
	ULONG Flags;
	USHORT LoadOrderIndex;
	USHORT InitOrderIndex;
	USHORT LoadCount;
	USHORT OffsetToFileName;
	UCHAR  FullPathName[256];
} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION;

typedef struct _RTL_PROCESS_MODULES {
	ULONG NumberOfModules;
	RTL_PROCESS_MODULE_INFORMATION Modules[1];
} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES;


NTSTATUS NTAPI ZwQuerySystemInformation(
	__in SYSTEM_INFORMATION_CLASS SystemInformationClass,
	__out_bcount_opt(SystemInformationLength) PVOID SystemInformation,
	__in ULONG SystemInformationLength,
	__out_opt PULONG ReturnLength
);



typedef struct _FindCode
{
	UCHAR code[0x200];
	ULONG len;
	int offset;
	ULONG lastAddressOffset;
}FindCode, *PFindCode;


void initFindCodeStruct(PFindCode findCode, PCHAR code, ULONG_PTR offset, ULONG_PTR lastAddrOffset);

ULONG_PTR findAddressByCode(ULONG_PTR beginAddr, ULONG_PTR endAddr, PFindCode  findCode, ULONG numbers);

ULONG_PTR QuerySysModule(char * MoudleName, _Out_opt_ ULONG_PTR * module);

ULONG_PTR searchNtCode(char * code, int offset);

ULONG_PTR searchCode(char * moduleName, char * segmentName, char * code, int offset);

Source Files

DriverMain.c

#include <ntifs.h>
#include "Module.h"
#include "comm\comm.h"
#include "comm\commStruct.h"
#include "RW.h"

NTSTATUS NTAPI DispatchComm(PCommPackage package)
{
	PVOID data = package->Data;
	NTSTATUS status = STATUS_UNSUCCESSFUL;
	DbgPrintEx(77, 0, "[db]:%llx,%llx\r\n", package->Id, package->cmd);
	switch (package->cmd)
	{
	case CMD_TEST:
		status = STATUS_SUCCESS;
		break;
	
	case CMD_GET_MODULE:
	{
		
		PModuleInfo info = (PModuleInfo)data;
		if (info)
		{
			ULONG64 imageSize = 0;
			info->Module = GetModuleR3(info->pid, info->moduleName,&imageSize);
			info->ModuleSize = imageSize;
			status = STATUS_SUCCESS;
		}

		
	}
		break;

	case CMD_READ_MEMORY:
	{
		PReadWriteInfo info = (PReadWriteInfo)data;
		if (info)
		{
			status = ReadMemory2(info->pid, info->BaseAddress, info->Buffer, info->size);
		}
	}
	break;

	default:
		status = STATUS_NOT_IMPLEMENTED;
		break;
	}
	
	return status;
}

VOID DriverUnload(PDRIVER_OBJECT pDriver)
{
	UnRegisterComm();
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)
{
	//DbgBreakPoint();
	//ULONG_PTR moudleBase = GetModuleR3(1332, "kernel32.dll", NULL);
	RegisterComm(DispatchComm);

	//1.直接读写 memcpy   直接切CR3 不附加了  调用附加函数

	//隐藏内存的时候 不会蓝屏
	//2.MmCopyVirtualMemory  ReadProcessMemory

	//3.MDL

	//4.直接映射物理页  第一个效率慢,第二个换页的时候 不是很精确,必须做跨页处理
	// 效率慢的原因 每层地址都自己转化 2 9 9 12   cr3 PDE PTE  10 10 12 2  9 9 9 9 12 4
	

	//5.APC读写 

	//6.队列读写   DXF system->线程下 父进程

	//DXF WIN7 0E异常 验证进程的白名单   PTE

	//CF  替换PML4 中 PDPTE

	//X64 CF 注入的  CR3 VAD  SXG // 

	//VT

	pDriver->DriverUnload = DriverUnload;
	return STATUS_SUCCESS;
}

Module.c

#include "Module.h"


ULONG_PTR GetModuleX86(PEPROCESS Process,PPEB32 peb32,PUNICODE_STRING moudleName,PULONG_PTR sizeImage)
{
	SIZE_T retSize = 0;
	MmCopyVirtualMemory(Process, peb32, Process, peb32, 0x1, UserMode, &retSize);
	PPEB_LDR_DATA32 pebldr = UlongToPtr(peb32->Ldr);

	PLIST_ENTRY32 pList32  = (PLIST_ENTRY32)&pebldr->InLoadOrderModuleList;
	PLDR_DATA_TABLE_ENTRY32 plistNext = (PLDR_DATA_TABLE_ENTRY32)UlongToPtr(pList32->Flink);
	
	ULONG_PTR module = 0;

	while (pList32 != plistNext)
	{

		PWCH baseDllName = plistNext->BaseDllName.Buffer;

		UNICODE_STRING uBaseName = {0};
		RtlInitUnicodeString(&uBaseName, baseDllName);

		if (RtlCompareUnicodeString(&uBaseName, moudleName, TRUE) == 0)
		{
			DbgPrintEx(77, 0, "[hotge]:imageBase = %llx,sizeofimage = %llx,%wZ\r\n", plistNext->DllBase, plistNext->SizeOfImage, &uBaseName);
			module = plistNext->DllBase;
			if (sizeImage) *sizeImage = plistNext->SizeOfImage;
			break;
		}


		plistNext = (PLDR_DATA_TABLE_ENTRY32)UlongToPtr(plistNext->InLoadOrderLinks.Flink);
	}

	return module;
}

ULONG_PTR GetModuleX64(PEPROCESS Process, PPEB peb, PUNICODE_STRING moudleName, PULONG_PTR sizeImage)
{
	SIZE_T retSize = 0;
	MmCopyVirtualMemory(Process, peb, Process, peb, 0x1, UserMode, &retSize);
	PPEB_LDR_DATA pebldr = peb->Ldr;

	PLIST_ENTRY pList = (PLIST_ENTRY)&pebldr->InLoadOrderModuleList;
	PLDR_DATA_TABLE_ENTRY plistNext = (PLDR_DATA_TABLE_ENTRY)(pList->Flink);

	ULONG_PTR module = 0;
	
	while (pList != plistNext)
	{
		if (RtlCompareUnicodeString(&plistNext->BaseDllName, moudleName, TRUE) == 0)
		{
			DbgPrintEx(77, 0, "[hotge]:imageBase = %llx,sizeofimage = %llx,%wZ\r\n", plistNext->DllBase, plistNext->SizeOfImage, &plistNext->BaseDllName);
			module = plistNext->DllBase;
			if (sizeImage) *sizeImage = plistNext->SizeOfImage;
			break;
		}


		plistNext = (PLDR_DATA_TABLE_ENTRY)plistNext->InLoadOrderLinks.Flink;
	}

	return module;
}

ULONG_PTR GetModuleR3(HANDLE pid, char *moduleName, PULONG_PTR sizeImage)
{
	if (!moduleName) return 0;

	PEPROCESS Process = NULL;
	KAPC_STATE kApcState = {0};
	ULONG_PTR moudule = 0;

	NTSTATUS status = PsLookupProcessByProcessId(pid, &Process);
	if (!NT_SUCCESS(status))
	{
		return 0;
	}

	STRING aModuleName = {0};
	RtlInitAnsiString(&aModuleName, moduleName);

	UNICODE_STRING uModuleName = {0};
	status = RtlAnsiStringToUnicodeString(&uModuleName, &aModuleName, TRUE);

	if (!NT_SUCCESS(status))
	{
		return 0;
	}

	
	_wcsupr(uModuleName.Buffer);

	

	KeStackAttachProcess(Process, &kApcState);

	PPEB peb = PsGetProcessPeb(Process);

	PPEB32 peb32 = (PPEB32)PsGetProcessWow64Process(Process);



	if (peb32)
	{
		moudule = GetModuleX86(Process, peb32, &uModuleName, sizeImage);
	}
	else
	{
		moudule = GetModuleX64(Process, peb, &uModuleName, sizeImage);
	}


	KeUnstackDetachProcess(&kApcState);

	RtlFreeUnicodeString(&uModuleName);

	return moudule;
}

RW.c

#include "RW.h"
#include "ExportFunc.h"
#include <intrin.h>

PVOID MdlMapMemory(PMDL * mdl, PVOID TargetAddress, SIZE_T size, MODE preMode)
{
	PMDL pMdl = IoAllocateMdl(TargetAddress, size, FALSE, FALSE, NULL);
	PVOID mapAddr = NULL;
	if (!pMdl)
	{
		return NULL;
	}

	BOOLEAN isLock = FALSE;
	__try 
	{
		MmProbeAndLockPages(pMdl, preMode, IoReadAccess);
		isLock = TRUE;
		//这个API 映射失败就会蓝屏
		//MmMapLockedPages
		mapAddr = MmMapLockedPagesSpecifyCache(pMdl, KernelMode, MmCached, NULL, FALSE, NormalPagePriority);
	}
	__except(1)
	{
	
		if (isLock)
		{
			MmUnlockPages(pMdl);
		}
		IoFreeMdl(pMdl);
		return;
	}
	
	*mdl = pMdl;

	return mapAddr;

}

VOID MdlUnMapMemory(PMDL mdl, PVOID mapBase)
{
	__try
	{
		MmUnmapLockedPages(mapBase, mdl);

		MmUnlockPages(mdl);
	
		IoFreeMdl(mdl);
	}
	__except (1)
	{
		return;
	}
}

NTSTATUS ReadMemory1(HANDLE pid, PVOID TargetAddress, PVOID Buffer, SIZE_T size)
{
	if ((ULONG64)TargetAddress >= MmHighestUserAddress
		|| ((ULONG64)TargetAddress + size) >= MmHighestUserAddress
		|| ((ULONG64)TargetAddress + size) < (ULONG64)TargetAddress)
	{
		return STATUS_ACCESS_VIOLATION;
	}

	if (Buffer == NULL) return STATUS_INVALID_PARAMETER_3;
	
	PEPROCESS Process;
	KAPC_STATE kApcState = {0};
	
	NTSTATUS status = PsLookupProcessByProcessId(pid, &Process);

	if (!NT_SUCCESS(status))
	{
		return status;
	}

	if (PsGetProcessExitStatus(Process) != 0x103)
	{
		ObDereferenceObject(Process);
		return STATUS_INVALID_PARAMETER_1;
	}

	PVOID mem = ExAllocatePool(NonPagedPool, size);
	memset(mem, 0, size);

	KeStackAttachProcess(Process, &kApcState);
	status = STATUS_UNSUCCESSFUL;
	//64K
	if (MmIsAddressValid(TargetAddress) && MmIsAddressValid((PVOID)((ULONG64)TargetAddress + size)))
	{
		memcpy(mem, TargetAddress, size);
		status = STATUS_SUCCESS;
	}

	KeUnstackDetachProcess(&kApcState);

	if (NT_SUCCESS(status))
	{
		memcpy(Buffer, mem, size);
	}

	ObDereferenceObject(Process);
	ExFreePool(mem);
	return status;
}

NTSTATUS ReadMemory4(HANDLE pid, PVOID TargetAddress, PVOID Buffer, SIZE_T size)
{
	if ((ULONG64)TargetAddress >= MmHighestUserAddress
		|| ((ULONG64)TargetAddress + size) >= MmHighestUserAddress
		|| ((ULONG64)TargetAddress + size) < (ULONG64)TargetAddress)
	{
		return STATUS_ACCESS_VIOLATION;
	}

	if (Buffer == NULL) return STATUS_INVALID_PARAMETER_3;

	PEPROCESS Process;
	

	NTSTATUS status = PsLookupProcessByProcessId(pid, &Process);

	if (!NT_SUCCESS(status))
	{
		return status;
	}

	if (PsGetProcessExitStatus(Process) != 0x103)
	{
		ObDereferenceObject(Process);
		return STATUS_INVALID_PARAMETER_1;
	}

	PVOID mem = ExAllocatePool(NonPagedPool, size);
	memset(mem, 0, size);

	
	status = STATUS_UNSUCCESSFUL;
	//64K
	ULONG64 newCr3 = *(PULONG64)((PUCHAR)Process + 0x18);

	ULONG64 oldCr3 = __readcr3();
	
	KeEnterCriticalRegion();
	
	_disable();
	
	__writecr3(newCr3);
	
	if (MmIsAddressValid(TargetAddress) && MmIsAddressValid((PVOID)((ULONG64)TargetAddress + size)))
	{
		memcpy(mem, TargetAddress, size);
		
		status = STATUS_SUCCESS;
	}

	_enable();

	__writecr3(oldCr3);

	KeLeaveCriticalRegion();

	if (NT_SUCCESS(status))
	{
		memcpy(Buffer, mem, size);
	}

	ObDereferenceObject(Process);
	ExFreePool(mem);
	return status;
}

NTSTATUS ReadMemory2(HANDLE pid, PVOID TargetAddress, PVOID Buffer, SIZE_T size)
{
	if ((ULONG64)TargetAddress >= MmHighestUserAddress
		|| ((ULONG64)TargetAddress + size) >= MmHighestUserAddress
		|| ((ULONG64)TargetAddress + size) < (ULONG64)TargetAddress)
	{
		return STATUS_ACCESS_VIOLATION;
	}

	if (Buffer == NULL) return STATUS_INVALID_PARAMETER_3;

	PEPROCESS Process;
	KAPC_STATE kApcState = { 0 };

	NTSTATUS status = PsLookupProcessByProcessId(pid, &Process);

	if (!NT_SUCCESS(status))
	{
		return status;
	}

	if (PsGetProcessExitStatus(Process) != 0x103)
	{
		ObDereferenceObject(Process);
		return STATUS_INVALID_PARAMETER_1;
	}

	SIZE_T pro = NULL;
	status = MmCopyVirtualMemory(Process, TargetAddress, IoGetCurrentProcess(), Buffer, size, UserMode, &pro);
	ObDereferenceObject(Process);
	return status;
}

NTSTATUS ReadMemory3(HANDLE pid, PVOID TargetAddress, PVOID Buffer, SIZE_T size)
{
	if ((ULONG64)TargetAddress >= MmHighestUserAddress
		|| ((ULONG64)TargetAddress + size) >= MmHighestUserAddress
		|| ((ULONG64)TargetAddress + size) < (ULONG64)TargetAddress)
	{
		return STATUS_ACCESS_VIOLATION;
	}

	if (Buffer == NULL) return STATUS_INVALID_PARAMETER_3;

	PEPROCESS Process;
	KAPC_STATE kApcState = { 0 };

	NTSTATUS status = PsLookupProcessByProcessId(pid, &Process);

	if (!NT_SUCCESS(status))
	{
		return status;
	}

	if (PsGetProcessExitStatus(Process) != 0x103)
	{
		ObDereferenceObject(Process);
		return STATUS_INVALID_PARAMETER_1;
	}

	PVOID mem = ExAllocatePool(NonPagedPool, size);
	memset(mem, 0, size);

	KeStackAttachProcess(Process, &kApcState);
	status = STATUS_UNSUCCESSFUL;
	//64K
	if (MmIsAddressValid(TargetAddress) && MmIsAddressValid((PVOID)((ULONG64)TargetAddress + size)))
	{
		PMDL mdl = NULL;
		PVOID map = MdlMapMemory(&mdl, TargetAddress, size, UserMode);
		if (map)
		{
			memcpy(mem, map, size);
			MdlUnMapMemory(mdl, map);
		}
		
		status = STATUS_SUCCESS;
	}

	KeUnstackDetachProcess(&kApcState);

	if (NT_SUCCESS(status))
	{
		memcpy(Buffer, mem, size);
	}

	ObDereferenceObject(Process);
	ExFreePool(mem);
	return status;
}

Search.c

#include "Search.h"
#include <ntimage.h>
#include "ExportFunc.h"

UCHAR charToHex(UCHAR * ch)
{
	unsigned char temps[2] = { 0 };
	for (int i = 0; i < 2; i++)
	{
		if (ch[i] >= '0' && ch[i] <= '9')
		{
			temps[i] = (ch[i] - '0');
		}
		else if (ch[i] >= 'A' && ch[i] <= 'F')
		{
			temps[i] = (ch[i] - 'A') + 0xA;
		}
		else if (ch[i] >= 'a' && ch[i] <= 'f')
		{
			temps[i] = (ch[i] - 'a') + 0xA;
		}
	}
	return ((temps[0] << 4) & 0xf0) | (temps[1] & 0xf);
}



void initFindCodeStruct(PFindCode findCode, PCHAR code, ULONG_PTR offset, ULONG_PTR lastAddrOffset)
{

	memset(findCode, 0, sizeof(FindCode));

	findCode->lastAddressOffset = lastAddrOffset;
	findCode->offset = offset;

	PCHAR pTemp = code;
	ULONG_PTR i = 0;
	for (i = 0; *pTemp != '\0'; i++)
	{
		if (*pTemp == '*' || *pTemp == '?')
		{
			findCode->code[i] = *pTemp;
			pTemp++;
			continue;
		}

		findCode->code[i] = charToHex(pTemp);
		pTemp += 2;

	}

	findCode->len = i;
}


ULONG_PTR findAddressByCode(ULONG_PTR beginAddr, ULONG_PTR endAddr, PFindCode  findCode, ULONG numbers)
{
	ULONG64 j = 0;
	LARGE_INTEGER rtna = { 0 };

	for (ULONG_PTR i = beginAddr; i <= endAddr; i++)
	{
		if (!MmIsAddressValid((PVOID)i))
		{
			i = i & (~0xfff) + PAGE_SIZE - 1;
			continue;
		}

		

		for (j = 0; j < numbers; j++)
		{
			FindCode  fc = findCode[j];
			ULONG_PTR tempAddress = i;

			UCHAR * code = (UCHAR *)(tempAddress + fc.offset);
			BOOLEAN isFlags = FALSE;

			for (ULONG_PTR k = 0; k < fc.len; k++)
			{
				if (!MmIsAddressValid((PVOID)(code + k)))
				{
					isFlags = TRUE;
					break;
				}

				if (fc.code[k] == '*' || fc.code[k] == '?') continue;

				if (code[k] != fc.code[k])
				{
					isFlags = TRUE;
					break;
				}
			}

			if (isFlags) break;

		}

		//找到了
		if (j == numbers)
		{
			rtna.QuadPart = i;
			rtna.LowPart += findCode[0].lastAddressOffset;
			break;
		}

	}

	return rtna.QuadPart;
}

char * CharToUper(char * wstr, BOOLEAN isAllocateMemory)
{
	char * ret = NULL;

	if (isAllocateMemory)
	{
		int len = strlen(wstr) + 2;
		ret = ExAllocatePool(PagedPool, len);
		memset(ret, 0, len);
		memcpy(ret, wstr, len - 2);
	}
	else
	{
		ret = wstr;
	}

	_strupr(ret);

	return ret;
}

//返回值为模块的大小
ULONG_PTR QuerySysModule(char * MoudleName, _Out_opt_ ULONG_PTR * module)
{
	RTL_PROCESS_MODULES info;
	ULONG retPro = NULL;
	ULONG_PTR moduleSize = 0;



	NTSTATUS ststas = ZwQuerySystemInformation(SystemModuleInformation, &info, sizeof(info), &retPro);
	char * moduleUper = CharToUper(MoudleName, TRUE);

	if (ststas == STATUS_INFO_LENGTH_MISMATCH)
	{
		//申请长度
		ULONG len = retPro + sizeof(RTL_PROCESS_MODULES);
		PRTL_PROCESS_MODULES mem = (PRTL_PROCESS_MODULES)ExAllocatePool(PagedPool, len);
		memset(mem, 0, len);
		ststas = ZwQuerySystemInformation(SystemModuleInformation, mem, len, &retPro);

		if (!NT_SUCCESS(ststas))
		{
			ExFreePool(moduleUper);
			ExFreePool(mem);
			return 0;
		}

		//开始查询

		if (strstr(MoudleName, "ntkrnlpa.exe") || strstr(MoudleName, "ntoskrnl.exe"))
		{
			PRTL_PROCESS_MODULE_INFORMATION ModuleInfo = &(mem->Modules[0]);
			*module = ModuleInfo->ImageBase;
			moduleSize = ModuleInfo->ImageSize;
		}
		else
		{
			for (int i = 0; i < mem->NumberOfModules; i++)
			{
				PRTL_PROCESS_MODULE_INFORMATION processModule = &mem->Modules[i];
				CharToUper(processModule->FullPathName, FALSE);
				if (strstr(processModule->FullPathName, moduleUper))
				{
					if (module)
					{
						*module = processModule->ImageBase;

					}

					moduleSize = processModule->ImageSize;

					break;
				}

			}
		}




		ExFreePool(mem);
	}


	ExFreePool(moduleUper);
	return moduleSize;
}


ULONG_PTR searchNtCode(char * code,int offset)
{
	FindCode fs[1] = { 0 };
	initFindCodeStruct(&fs[0], code, 0, offset);


	SIZE_T moduleBase = 0;
	ULONG size = QuerySysModule("ntoskrnl.exe", &moduleBase);


	ULONG_PTR func = findAddressByCode(moduleBase, size + moduleBase, fs, 1);

	return func;
}

ULONG_PTR searchCode(char * moduleName, char * segmentName, char * code, int offset)
{
	FindCode fs[1] = { 0 };
	initFindCodeStruct(&fs[0], code, 0, offset);
	SIZE_T moduleBase = 0;
	ULONG size = QuerySysModule(moduleName, &moduleBase);

	if (!moduleBase)
	{
		return 0;
	}


	PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)moduleBase;

	PIMAGE_NT_HEADERS pNts = (PIMAGE_NT_HEADERS)((PUCHAR)moduleBase + pDos->e_lfanew);

	PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNts);

	PIMAGE_SECTION_HEADER pTemp = NULL;

	for (int i = 0; i < pNts->FileHeader.NumberOfSections; i++)
	{
		char bufName[9] = {0};
		memcpy(bufName, pSection->Name, 8);
		if (_stricmp(bufName, segmentName) == 0)
		{
			pTemp = pSection;
			break;
		}
		pSection++;
	}

	if (pTemp)
	{
		moduleBase = pSection->VirtualAddress + moduleBase;
		size = pSection->SizeOfRawData;
	}

	PVOID mem = ExAllocatePool(NonPagedPool, size);
	SIZE_T retSize = 0;
	MmCopyVirtualMemory(IoGetCurrentProcess(), moduleBase, IoGetCurrentProcess(), mem, size, KernelMode, &retSize);
	
	ULONG_PTR func = findAddressByCode(moduleBase, size + moduleBase, fs, 1);
	ExFreePool(mem);
	return func;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值