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);
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);
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));
}
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()
{
}
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;
}
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
{
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());
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
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
stdafx.cpp
#include "stdafx.h"
targetver.h
#pragma once
#include <SDKDDKVer.h>
export.def
LIBRARY
EXPORTS
SH_DriverLoad
SH_UnDriverLoad
SH_GetModule
SH_ReadMemory
rwR3.cpp
#include "stdafx.h"
dllmain.cpp
#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");
DWORD pid = 1968;
ULONG64 module = SH_GetModule(pid, "explorer.exe");
printf("module = %llx\r\n", module);
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;
ULONG64 cmd;
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;
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;
}
}
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)
{
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;
UCHAR Initialized;
ULONG SsHandle;
LIST_ENTRY32 InLoadOrderModuleList;
LIST_ENTRY32 InMemoryOrderModuleList;
LIST_ENTRY32 InInitializationOrderModuleList;
ULONG EntryInProgress;
UCHAR ShutdownInProgress;
ULONG ShutdownThreadId;
}PEB_LDR_DATA32,*PPEB_LDR_DATA32;
typedef struct _PEB32
{
UCHAR InheritedAddressSpace;
UCHAR ReadImageFileExecOptions;
UCHAR BeingDebugged;
union
{
UCHAR BitField;
struct
{
UCHAR ImageUsesLargePages : 1;
UCHAR IsProtectedProcess : 1;
UCHAR IsLegacyProcess : 1;
UCHAR IsImageDynamicallyRelocated : 1;
UCHAR SkipPatchingUser32Forwarders : 1;
UCHAR SpareBits : 3;
};
};
ULONG Mutant;
ULONG ImageBaseAddress;
ULONG Ldr;
}PEB32,*PPEB32;
typedef struct _LDR_DATA_TABLE_ENTRY32
{
LIST_ENTRY32 InLoadOrderLinks;
LIST_ENTRY32 InMemoryOrderLinks;
LIST_ENTRY32 InInitializationOrderLinks;
ULONG DllBase;
ULONG EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING32 FullDllName;
UNICODE_STRING32 BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
union
{
LIST_ENTRY32 HashLinks;
struct
{
ULONG SectionPointer;
ULONG CheckSum;
};
};
union
{
ULONG TimeDateStamp;
ULONG LoadedImports;
};
ULONG EntryPointActivationContext;
ULONG PatchInformation;
LIST_ENTRY32 ForwarderLinks;
LIST_ENTRY32 ServiceTagLinks;
LIST_ENTRY32 StaticLinks;
ULONG ContextInformation;
ULONG OriginalBase;
LARGE_INTEGER LoadTime;
}LDR_DATA_TABLE_ENTRY32,*PLDR_DATA_TABLE_ENTRY32;
#pragma pack(0)
typedef struct _PEB_LDR_DATA
{
ULONG Length;
UCHAR Initialized;
VOID* SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
VOID* EntryInProgress;
UCHAR ShutdownInProgress;
VOID* ShutdownThreadId;
}PEB_LDR_DATA,*PPEB_LDR_DATA;
typedef struct _PEB
{
ULONG64 x;
VOID* Mutant;
VOID* ImageBaseAddress;
PEB_LDR_DATA* Ldr;
}PEB,*PPEB;
typedef struct _LDR_DATA_TABLE_ENTRY
{
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
VOID* DllBase;
VOID* EntryPoint;
ULONG64 SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
union
{
LIST_ENTRY HashLinks;
struct
{
VOID* SectionPointer;
ULONG CheckSum;
};
};
union
{
ULONG TimeDateStamp;
VOID* LoadedImports;
};
struct _ACTIVATION_CONTEXT* EntryPointActivationContext;
VOID* PatchInformation;
LIST_ENTRY ForwarderLinks;
LIST_ENTRY ServiceTagLinks;
LIST_ENTRY StaticLinks;
VOID* ContextInformation;
ULONGLONG OriginalBase;
LARGE_INTEGER LoadTime;
}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>
NTSTATUS ReadMemory1(HANDLE pid, PVOID TargetAddress, PVOID Buffer, SIZE_T size);
NTSTATUS ReadMemory2(HANDLE pid, PVOID TargetAddress, PVOID Buffer, SIZE_T size);
NTSTATUS ReadMemory3(HANDLE pid, PVOID TargetAddress, PVOID Buffer, SIZE_T size);
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,
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
} SYSTEM_INFORMATION_CLASS;
typedef struct _RTL_PROCESS_MODULE_INFORMATION {
HANDLE Section;
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)
{
RegisterComm(DispatchComm);
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;
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;
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;
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;
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;
}