L o a d i n g . . .
主打一个C++
文章详情

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

作者近期文章
  • 随手笔记
  • 主打一个C++   2025-01-11 20:02:01
  • 都2000000025年了。还有不能随意访问guthub的,仔细看。在国内其实是可以正常访问的,gfw并没屏蔽。这里给出其中一个简单直接的方法稳定访问。1. 随便百度一个”dn
提示
×
确定
数据库执行: 8次 总耗时: 0.01s
页面加载耗时: 



wechat +447752296473
wechat cpp-blog