文章详情
C++驱动层dll注入例子(APC注入)
Posted on 2021-01-21 19:06:13 by 主打一个C++
//此例子将注入于所有新创建的进程
//驱动层代码如下:
driver.h
#pragma once
#include <ntifs.h>
#include <ntdef.h>
#include <ntimage.h>
#pragma warning(disable : 4996)
#pragma warning(disable : 4703)
#pragma warning(disable : 4701)
#pragma warning(disable : 4533)
#define DbgPrintx(s,...) DbgPrint(DRIVER_PREFIX s "\n",__VA_ARGS__)
#define DbgPrintLine(s,...) DbgPrint(DRIVER_PREFIX "[%s]" s "\n",__FUNCTION__ ,__VA_ARGS__)
#define DbgError(s,...) DbgPrintLine("<Error>" s , __VA_ARGS__)
#define DbgInfo(s,...) DbgPrintLine("<Info>" s , __VA_ARGS__)
#define DRIVER_PREFIX "InjDriver: "
#define EDR_MEMORY_TAG ' rdE'
#define PROCESS_INFO_MEMORY_TAG ' crP'
//dll路径
#define DLL_PATH_X64 L"C:\\Users\\Win10\\Desktop\\HookDllx64.dll"
#define DLL_PATH_X86 L"C:\\Users\\Win10\\Desktop\\HookDllx86.dll"
//用于保存加载图像和状态信息的进程结构
typedef struct _PROCESS_INFO {
LIST_ENTRY ListEntry;
HANDLE ProcessId;
BOOLEAN IsInjected = FALSE;
BOOLEAN ForceUserApc;
ULONG LoadedDlls;
PVOID LdrLoadDllAddress = NULL;
PUNICODE_STRING DllPath;
} PROCESS_INFO, * PPROCESS_INFO;
typedef enum _SYSTEM_DLL
{
NOTHING_LOADED = 0x0000,
SYSTEM32_NTDLL_LOADED = 0x0001,
SYSTEM32_KERNEL32_LOADED = 0x0002,
SYSWOW64_NTDLL_LOADED = 0x0004,
SYSTEM32_WOW64_LOADED = 0x0008,
SYSTEM32_WOW64WIN_LOADED = 0x0010,
SYSTEM32_WOW64CPU_LOADED = 0x0020,
SYSTEM32_WOWARMHW_LOADED = 0x0040,
} SYSTEM_DLL, *PSYSTEM_DLL;
typedef struct _SYSTEM_DLL_DESCRIPTOR
{
UNICODE_STRING DllPath;
SYSTEM_DLL Flag;
} SYSTEM_DLL_DESCRIPTOR, * PSYSTEM_DLL_DESCRIPTOR;
SYSTEM_DLL_DESCRIPTOR g_pSystemDlls[] = {
{ RTL_CONSTANT_STRING(L"\\SysWow64\\ntdll.dll"), SYSWOW64_NTDLL_LOADED },
{ RTL_CONSTANT_STRING(L"\\System32\\ntdll.dll"), SYSTEM32_NTDLL_LOADED },
{ RTL_CONSTANT_STRING(L"\\System32\\kernel32.dll"), SYSTEM32_KERNEL32_LOADED },
{ RTL_CONSTANT_STRING(L"\\System32\\wow64.dll"), SYSTEM32_WOW64_LOADED },
{ RTL_CONSTANT_STRING(L"\\System32\\wow64win.dll"), SYSTEM32_WOW64WIN_LOADED },
{ RTL_CONSTANT_STRING(L"\\System32\\wow64cpu.dll"), SYSTEM32_WOW64CPU_LOADED },
};
VOID DriverUnload(PDRIVER_OBJECT DriverObject);
VOID DriverInitialize();
BOOLEAN AreAllDllsLoaded(PPROCESS_INFO ProcessInfo);
// 进程创建回调
VOID ProcessCreateNotifyCallback(
HANDLE ParentId,
HANDLE ProcessId,
BOOLEAN Create);
// 模块加载回调
VOID ImageLoadNotifyCallback(
PUNICODE_STRING FullImageName,
HANDLE ProcessId,
PIMAGE_INFO ImageInfo);
PPROCESS_INFO FindProcessInfo(HANDLE ProcessId);
VOID AddProcess(HANDLE ProcessId);
VOID RemoveProcess(HANDLE ProcessId);
//API流程函数
extern "C"
NTKERNELAPI
PVOID
NTAPI
PsGetProcessWow64Process(
_In_ PEPROCESS Process
);
extern "C"
NTKERNELAPI
PCHAR
NTAPI
PsGetProcessImageFileName(
_In_ PEPROCESS Process
);
extern "C"
NTKERNELAPI
BOOLEAN
NTAPI
PsIsProtectedProcess(
_In_ PEPROCESS Process
);
extern "C"
NTKERNELAPI
USHORT
NTAPI
PsWow64GetProcessMachine(
_In_ PEPROCESS Process
);
//函数地址解析
PVOID
NTAPI
RtlFindExportedRoutineByName(
_In_ PVOID DllBase,
_In_ PANSI_STRING ExportName
);
extern "C"
NTSYSAPI
PVOID
NTAPI
RtlImageDirectoryEntryToData(
_In_ PVOID BaseOfImage,
_In_ BOOLEAN MappedAsImage,
_In_ USHORT DirectoryEntry,
_Out_ PULONG Size
);
//APC相关代码
extern "C"
typedef enum _KAPC_ENVIRONMENT
{
OriginalApcEnvironment,
AttachedApcEnvironment,
CurrentApcEnvironment,
InsertApcEnvironment
} KAPC_ENVIRONMENT;
extern "C"
typedef
VOID
(NTAPI* PKNORMAL_ROUTINE)(
_In_ PVOID NormalContext,
_In_ PVOID SystemArgument1,
_In_ PVOID SystemArgument2
);
extern "C"
typedef
VOID
(NTAPI* PKKERNEL_ROUTINE)(
_In_ PKAPC Apc,
_Inout_ PKNORMAL_ROUTINE* NormalRoutine,
_Inout_ PVOID* NormalContext,
_Inout_ PVOID* SystemArgument1,
_Inout_ PVOID* SystemArgument2
);
extern "C"
typedef
VOID
(NTAPI* PKRUNDOWN_ROUTINE) (
_In_ PKAPC Apc
);
NTSTATUS
NTAPI
QueueInjectionApc(
_In_ KPROCESSOR_MODE ApcMode,
_In_ PKNORMAL_ROUTINE NormalRoutine,
_In_ PVOID NormalContext,
_In_ PVOID SystemArgument1,
_In_ PVOID SystemArgument2
);
extern "C"
NTKERNELAPI
VOID
NTAPI
KeInitializeApc(
_Out_ PRKAPC Apc,
_In_ PETHREAD Thread,
_In_ KAPC_ENVIRONMENT Environment,
_In_ PKKERNEL_ROUTINE KernelRoutine,
_In_opt_ PKRUNDOWN_ROUTINE RundownRoutine,
_In_opt_ PKNORMAL_ROUTINE NormalRoutine,
_In_opt_ KPROCESSOR_MODE ApcMode,
_In_opt_ PVOID NormalContext
);
extern "C"
NTKERNELAPI
BOOLEAN
NTAPI
KeInsertQueueApc(
_Inout_ PRKAPC Apc,
_In_opt_ PVOID SystemArgument1,
_In_opt_ PVOID SystemArgument2,
_In_ KPRIORITY Increment
);
VOID
NTAPI
InjectionApcKernelRoutine(
_In_ PKAPC Apc,
_Inout_ PKNORMAL_ROUTINE* NormalRoutine,
_Inout_ PVOID* NormalContext,
_Inout_ PVOID* SystemArgument1,
_Inout_ PVOID* SystemArgument2
);
VOID
NTAPI
InjectionApcNormalRoutine(
_In_ PVOID NormalContext,
_In_ PVOID SystemArgument1,
_In_ PVOID SystemArgument2
);
NTSTATUS
NTAPI
EdrInject(
_In_ PPROCESS_INFO pProcessInfo
);
extern "C"
BOOLEAN
NTAPI
KeTestAlertThread(
_In_ KPROCESSOR_MODE AlertMode
);
driver.cpp
#include "driver.h"
ANSI_STRING LdrLoadDllRoutineName = RTL_CONSTANT_STRING("LdrLoadDll");
LIST_ENTRY ProcessList;
FAST_MUTEX ProcessListLock;
UNICODE_STRING g_DllPath64;
UNICODE_STRING g_DllPath86;
static BOOLEAN gRegisteredForProcessCreation = FALSE;
static BOOLEAN gRegisteredForThreadCreation = FALSE;
static BOOLEAN gRegisteredForImageLoad = FALSE;
extern "C"
NTSTATUS DriverEntry(
PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath)
{
UNREFERENCED_PARAMETER(DriverObject);
UNREFERENCED_PARAMETER(RegistryPath);
DbgPrintx("Driver load (0x%p, %wZ)", DriverObject, RegistryPath);
NTSTATUS status = STATUS_SUCCESS;
do {
//注册回调
status = PsSetCreateProcessNotifyRoutine(ProcessCreateNotifyCallback, FALSE);
if (!NT_SUCCESS(status))
{
DbgPrintx("Failed to register process creation routine");
break;
}
gRegisteredForProcessCreation = TRUE;
status = PsSetLoadImageNotifyRoutine((PLOAD_IMAGE_NOTIFY_ROUTINE)ImageLoadNotifyCallback);
if (!NT_SUCCESS(status))
{
DbgPrintx("Failed to register image load routine");
PsSetCreateProcessNotifyRoutine(ProcessCreateNotifyCallback, TRUE);
break;
}
gRegisteredForImageLoad = TRUE;
} while (false);
if (!NT_SUCCESS(status))
{
DbgPrintx("Failed to start driver");
return status;
}
DriverInitialize();
DriverObject->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
VOID DriverUnload(PDRIVER_OBJECT DriverObject) {
UNREFERENCED_PARAMETER(DriverObject);
PsSetCreateProcessNotifyRoutine(ProcessCreateNotifyCallback, TRUE);
PsRemoveLoadImageNotifyRoutine((PLOAD_IMAGE_NOTIFY_ROUTINE)ImageLoadNotifyCallback);
//清理流程列表
ExAcquireFastMutex(&ProcessListLock);
PLIST_ENTRY entry, nextEntry;
for (entry = ProcessList.Flink; entry != &ProcessList; entry = nextEntry) {
nextEntry = entry->Flink;
RemoveProcess(CONTAINING_RECORD(entry, PROCESS_INFO, ListEntry)->ProcessId);
}
ExReleaseFastMutex(&ProcessListLock);
}
// 初始化进程列表并锁定
VOID DriverInitialize() {
InitializeListHead(&ProcessList);
ExInitializeFastMutex(&ProcessListLock);
RtlInitUnicodeString(&g_DllPath64, DLL_PATH_X64);
RtlInitUnicodeString(&g_DllPath86, DLL_PATH_X86);
}
//进程创建回调
VOID ProcessCreateNotifyCallback(
HANDLE ParentId,
HANDLE ProcessId,
BOOLEAN Create)
{
UNREFERENCED_PARAMETER(ParentId);
ExAcquireFastMutex(&ProcessListLock);
if (Create) {
AddProcess(ProcessId); //将进程添加到列表中
}
else {
RemoveProcess(ProcessId); // 进程终止时将其删除
}
ExReleaseFastMutex(&ProcessListLock);
}
BOOLEAN IsSuffixMatch(const CHAR* imageName, const CHAR* suffix) {
if (imageName == NULL || suffix == NULL) return FALSE;
size_t imageNameLen = strlen(imageName);
size_t suffixLen = strlen(suffix);
// 检查后缀是否长于图像名称。
if (suffixLen > imageNameLen) {
return FALSE;
}
// 将imageName的末尾与后缀进行比较
return _strnicmp(imageName + imageNameLen - suffixLen, suffix, suffixLen) == 0;
}
//图像加载回调
VOID ImageLoadNotifyCallback(
PUNICODE_STRING FullImageName,
HANDLE ProcessId,
PIMAGE_INFO ImageInfo)
{
ExAcquireFastMutex(&ProcessListLock);
PPROCESS_INFO ProcessInfo = FindProcessInfo(ProcessId);
DbgInfo("Loading image %wZ\nfor: [PID: %u, Name: '%s']", FullImageName, HandleToUlong(ProcessId), PsGetProcessImageFileName(PsGetCurrentProcess()));
if (!ProcessInfo)
{
DbgError("Could not find process: [PID: %u, Name: '%wZ'] In image load callback routine", HandleToUlong(ProcessId), PsGetProcessImageFileName(PsGetCurrentProcess()));
ExReleaseFastMutex(&ProcessListLock);
return;
}
if (ProcessInfo->IsInjected)
{
DbgInfo("Already injected to process: [PID: %u, Name: '%s']", HandleToUlong(ProcessId), PsGetProcessImageFileName(PsGetCurrentProcess()));
ExReleaseFastMutex(&ProcessListLock);
return;
}
if (PsIsProtectedProcess(PsGetCurrentProcess()))
{
DbgInfo("Its protected process [PID: %u, Name: '%s'] wont inject at this point", HandleToUlong(ProcessId), PsGetProcessImageFileName(PsGetCurrentProcess()));
ExReleaseFastMutex(&ProcessListLock);
return;
}
else {
DbgInfo("Found process: %s", PsGetProcessImageFileName(PsGetCurrentProcess()));
}
//如果加载了所有必要的DLL,则执行APC注入
if (AreAllDllsLoaded(ProcessInfo)) {
// 所有必要的dll都已加载
ProcessInfo->IsInjected = TRUE;
DbgInfo("All necessary dlls are loaded for process [PID:%u, Name: '%s', Wow64: %s], will queue apc injection ",
HandleToUlong(ProcessId),
PsGetProcessImageFileName(PsGetCurrentProcess()),
PsGetProcessWow64Process(PsGetCurrentProcess()) ? "True" : "False");
QueueInjectionApc(KernelMode,
(PKNORMAL_ROUTINE)&InjectionApcNormalRoutine,
ProcessInfo,
NULL,
NULL);
ExReleaseFastMutex(&ProcessListLock);
return;
}
//并非所有必需的dll都已加载。
for (ULONG Index = 0; Index < RTL_NUMBER_OF(g_pSystemDlls); Index++)
{
PUNICODE_STRING pSysDllPath = &g_pSystemDlls[Index].DllPath;
if (RtlSuffixUnicodeString(pSysDllPath, FullImageName, TRUE))
{
//当前dll是必不可少的dll之一
DbgInfo("The Process is loading essential image [PID: %u, Name: '%s' Iamge: '%wZ']",
HandleToUlong(ProcessId),
PsGetProcessImageFileName(PsGetCurrentProcess()),
FullImageName);
ProcessInfo->LoadedDlls |= g_pSystemDlls[Index].Flag;
if (g_pSystemDlls[Index].Flag == SYSTEM32_NTDLL_LOADED)
{
// 这是原生ntdll dll,我们需要获取LdrLoadDll地址
ProcessInfo->LdrLoadDllAddress = RtlFindExportedRoutineByName(ImageInfo->ImageBase, &LdrLoadDllRoutineName);
}
//找到了dll,跳出
break;
}
}
ExReleaseFastMutex(&ProcessListLock);
}
//检查是否加载了所有必需的DLL
BOOLEAN AreAllDllsLoaded(PPROCESS_INFO ProcessInfo) {
//我希望加载ntdll.dll,因为目前只将其注入x64
//还希望加载kernel32.dll,因为注入的dll使用了它。
ULONG RequiredDlls = SYSTEM32_NTDLL_LOADED | SYSTEM32_KERNEL32_LOADED;
#if defined (_M_AMD64)
if (PsGetProcessWow64Process(PsGetCurrentProcess()))
{
//将Wow64相关dll添加到所需dll中
RequiredDlls |= SYSTEM32_WOW64CPU_LOADED;
RequiredDlls |= SYSWOW64_NTDLL_LOADED;
}
#endif
BOOLEAN Ret = (ProcessInfo->LoadedDlls & RequiredDlls) == RequiredDlls;
return Ret;
}
//按进程ID查找进程信息
PPROCESS_INFO FindProcessInfo(HANDLE ProcessId) {
PLIST_ENTRY entry;
for (entry = ProcessList.Flink; entry != &ProcessList; entry = entry->Flink) {
PPROCESS_INFO ProcessInfo = CONTAINING_RECORD(entry, PROCESS_INFO, ListEntry);
if (ProcessInfo->ProcessId == ProcessId) {
return ProcessInfo;
}
}
return NULL;
}
//将流程添加到流程列表中
VOID AddProcess(HANDLE ProcessId) {
PPROCESS_INFO ProcessInfo = (PPROCESS_INFO)ExAllocatePoolWithTag(NonPagedPool, sizeof(PROCESS_INFO), PROCESS_INFO_MEMORY_TAG);
RtlZeroMemory(ProcessInfo, sizeof(PROCESS_INFO));
ProcessInfo->ProcessId = ProcessId;
ProcessInfo->ForceUserApc = TRUE;
InsertTailList(&ProcessList, &ProcessInfo->ListEntry);
}
//从进程列表中删除进程
VOID RemoveProcess(HANDLE ProcessId) {
PPROCESS_INFO ProcessInfo = FindProcessInfo(ProcessId);
if (ProcessInfo) {
RemoveEntryList(&ProcessInfo->ListEntry);
ExFreePoolWithTag(ProcessInfo, PROCESS_INFO_MEMORY_TAG);
}
}
// 函数地址解析
PVOID
NTAPI
RtlFindExportedRoutineByName(
_In_ PVOID DllBase,
_In_ PANSI_STRING ExportName
)
{
PULONG NameTable;
PUSHORT OrdinalTable;
PIMAGE_EXPORT_DIRECTORY ExportDirectory;
ULONG Index;
USHORT Ordinal;
PVOID Function;
ULONG ExportSize;
PULONG ExportTable;
LONG Ret;
BOOLEAN Found = FALSE;
ExportDirectory = (PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData(DllBase,
TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &ExportSize);
if (!ExportDirectory)
{
DbgError("RtlImageDirectoryEntryToData:: Failed to find ExportDirectory");
return NULL;
}
NameTable = (PULONG)((ULONG_PTR)DllBase + ExportDirectory->AddressOfNames);
OrdinalTable = ((PUSHORT)((ULONG_PTR)DllBase + ExportDirectory->AddressOfNameOrdinals));
Index = 0;
while (Index < ExportDirectory->NumberOfNames)
{
Ret = strcmp(ExportName->Buffer, (PCHAR)DllBase + NameTable[Index]);
if (Ret == 0)
{
Found = TRUE;
break;
}
Index++;
}
if (!Found)
{
DbgError("Could not find the function in export directory: %Z", ExportName);
return NULL;
}
Ordinal = OrdinalTable[Index];
if (Ordinal < 0 || Ordinal >= ExportDirectory->NumberOfFunctions)
{
DbgError("Ordinal out of bound for function: %Z", ExportName);
return NULL;
}
ExportTable = (PULONG)((ULONG_PTR)DllBase + ExportDirectory->AddressOfFunctions);
Function = (PVOID)((ULONG_PTR)DllBase + ExportTable[Ordinal]);
DbgInfo("Found LdrLoadDll at 0x%p", Function);
return Function;
}
//APC相关代码
NTSTATUS
NTAPI
QueueInjectionApc(
_In_ KPROCESSOR_MODE ApcMode,
_In_ PKNORMAL_ROUTINE NormalRoutine,
_In_ PVOID NormalContext,
_In_ PVOID SystemArgument1,
_In_ PVOID SystemArgument2
)
{
NTSTATUS Status = STATUS_SUCCESS;
PETHREAD pThread = PsGetCurrentThread();
HANDLE ThreadId = PsGetThreadId(pThread);
HANDLE ProcessId = PsGetThreadProcessId(pThread);
// 为KAPC分配内存
PKAPC Apc = (PKAPC)ExAllocatePoolWithTag(NonPagedPool,
sizeof(KAPC),
EDR_MEMORY_TAG);
if (!Apc)
{
DbgError("ExAllocatePoolWithTag:: Failed to allocate Apc ([P:T] :: [%u:%u])", HandleToUlong(ProcessId), HandleToUlong(ThreadId));
Status = STATUS_INSUFFICIENT_RESOURCES;
return Status;
}
//初始化Apc
KeInitializeApc(Apc,
pThread,
OriginalApcEnvironment,
&InjectionApcKernelRoutine,
NULL,
NormalRoutine,
ApcMode,
NormalContext);
BOOLEAN Inserted = KeInsertQueueApc(Apc,
SystemArgument1,
SystemArgument2,
0);
if (!Inserted)
{
DbgError("KeInsertQueueApc:: Failed inserting Apc ([P:T] :: [%u:%u])", HandleToUlong(ProcessId), HandleToUlong(ThreadId));
ExFreePoolWithTag(Apc, EDR_MEMORY_TAG);
return STATUS_UNSUCCESSFUL;
}
DbgInfo("Inserted injection APC for process [PID: %u, Name: '%s'] ", HandleToUlong(ProcessId), PsGetProcessImageFileName(PsGetCurrentProcess()));
return Status;
}
VOID
NTAPI
InjectionApcNormalRoutine(
_In_ PVOID NormalContext,
_In_ PVOID SystemArgument1,
_In_ PVOID SystemArgument2
)
{
UNREFERENCED_PARAMETER(SystemArgument1);
UNREFERENCED_PARAMETER(SystemArgument2);
PPROCESS_INFO InjectionContext = (PPROCESS_INFO)NormalContext;
EdrInject(InjectionContext);
}
NTSTATUS
NTAPI
EdrInject(
_In_ PPROCESS_INFO pProcessInfo
)
{
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
InitializeObjectAttributes(&ObjectAttributes,
NULL,
OBJ_KERNEL_HANDLE,
NULL,
NULL);
HANDLE hSection;
SIZE_T SectionSize = PAGE_SIZE;
LARGE_INTEGER MaximumSize;
MaximumSize.QuadPart = SectionSize;
Status = ZwCreateSection(&hSection,
GENERIC_READ | GENERIC_WRITE,
&ObjectAttributes,
&MaximumSize,
PAGE_READWRITE,
SEC_COMMIT,
NULL);
if (!NT_SUCCESS(Status))
{
DbgError("ZwCreateSection:: Failed to create section for process: %u", HandleToUlong(pProcessInfo->ProcessId));
goto End;
}
// Map
PVOID SectionMemoryAddress = NULL;
Status = ZwMapViewOfSection(hSection,
ZwCurrentProcess(),
&SectionMemoryAddress,
0,
SectionSize,
NULL,
&SectionSize,
ViewUnmap,
0,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
DbgError("ZwMapViewOfSection:: Failed to map view of section for process: %u", HandleToUlong(pProcessInfo->ProcessId));
goto End;
}
DbgInfo("Mapped section to process %u on address 0x%p", HandleToUlong(pProcessInfo->ProcessId), SectionMemoryAddress);
// 注入
PUNICODE_STRING pDllPath = (PUNICODE_STRING)(SectionMemoryAddress);
PWCHAR DllPathBuffer = (PWCHAR)((PUCHAR)pDllPath + sizeof(UNICODE_STRING));
PUNICODE_STRING pSourcDll;
if (PsGetProcessWow64Process(PsGetCurrentProcess()))
{
pSourcDll = &g_DllPath86;
}
else {
pSourcDll = &g_DllPath64;
}
//复制
RtlCopyMemory(DllPathBuffer,
pSourcDll->Buffer,
pSourcDll->Length+1);
RtlInitUnicodeString(pDllPath, DllPathBuffer);
Status = QueueInjectionApc(UserMode,
(PKNORMAL_ROUTINE)(ULONG_PTR)pProcessInfo->LdrLoadDllAddress,
NULL, // 转换为第一个参数。LdrLoadDll(搜索路径)
NULL, // 转换为第二个参数。LdrLoadDll(Dll特征)
pDllPath // 转换为第三个参数。LdrLoadDll(DllName)
);
End:
ZwClose(hSection);
if (NT_SUCCESS(Status)/* && pProcessInfo->ForceUserApc*/)
{
DbgInfo("Inserted LdrLoadDll APC for process %u \nThe section start at 0x%p", HandleToUlong(pProcessInfo->ProcessId), SectionMemoryAddress);
//KeTestAlertThread(UserMode); /*TODO: 找出为什么警报导致apc不执行 */
}
return Status;
}
VOID
NTAPI
InjectionApcKernelRoutine(
_In_ PKAPC Apc,
_Inout_ PKNORMAL_ROUTINE* NormalRoutine,
_Inout_ PVOID* NormalContext,
_Inout_ PVOID* SystemArgument1,
_Inout_ PVOID* SystemArgument2
)
{
UNREFERENCED_PARAMETER(NormalRoutine);
UNREFERENCED_PARAMETER(NormalContext);
UNREFERENCED_PARAMETER(SystemArgument1);
UNREFERENCED_PARAMETER(SystemArgument2);
ExFreePoolWithTag(Apc, EDR_MEMORY_TAG);
}
//编译加载驱动后,所有新启动的进程都将被注入一份定义的dll路径的dll文件。
//测试dll代码,简单的弹出一个提示框
#include "pch.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBoxA(nullptr, "APC注入成功!", "提示", MB_ICONASTERISK);
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
//bb: 如果想指定进程,可以修改驱动代码加以判断,或者直接从dll中判断进程,如若成功~卸载驱动即可。
*转载请注明出处:原文链接:https://cpp.vin/page/66.html