C/C++Windows黑客编程系列——Dll注入与卸载

Dll注入与卸载

#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>

#ifndef MAX_LENGTH
#define MAX_LENGTH 20
#elif
#define MIN_LENGTH 10
#endif

void InjectDll(char *dllName, int pid) {
    if (strlen(dllName) == 0 || pid == 0) {
        printf("注入动态链接库和进程ID不能为空\n");
        return;
    }
    // 目的函数
    char *ptrAimFunc = "LoadLibraryA";
    // 打开进程
    HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (processHandle == INVALID_HANDLE_VALUE) {
        printf("打开进程句柄失败\n");
        return;
    }
    // dll需要的内存大小,末尾\0结束
    size_t dllNameLen = strlen(dllName) + sizeof(char);
    // 动态分配dll内存,设置内存页可读、可写,返回内存地址
    LPVOID dllAddr = VirtualAllocEx(processHandle, NULL, dllNameLen, MEM_COMMIT, PAGE_READWRITE);
    if (dllAddr == NULL) {
        printf("分配dll内存失败\n");
        return;
    }
    DWORD dwWrite = 0;
    // 将dll写入内存
    WriteProcessMemory(processHandle, dllAddr, dllName, dllNameLen, (SIZE_T *) &dwWrite);
    // 获取目标函数的地址
    FARPROC ptrFunAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), ptrAimFunc);
    if (ptrFunAddr == NULL) {
        printf("获取函数指针错误\n");
        return;
    }
    // 创建远程线程执行函数,触发dll的入口函数
    HANDLE hThread = CreateRemoteThread(processHandle, NULL, 0, (LPTHREAD_START_ROUTINE) ptrFunAddr, dllAddr, 0, NULL);
    // 等待线程执行完毕
    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);
    CloseHandle(processHandle);
}

void UnInjectDll(char *dllName, DWORD pid) {
    // 获取指定进程的快照
    HANDLE handle = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
    MODULEENTRY32 moduleEntry32 = {0};
    moduleEntry32.dwSize = sizeof(MODULEENTRY32);
    // 获取进程内部模块列表
    BOOL ret = Module32First(handle, &moduleEntry32);
    while (ret) {
        if (strcmp(moduleEntry32.szExePath,dllName) == 0) {
            break;
        }
        ret = Module32Next(handle, &moduleEntry32);
    }
    CloseHandle(handle);
    // 释放模块的函数名
    const char *pFuncName = "FreeLibrary";
    // 打开进程句柄
    HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    // 获取函数地址
    FARPROC pFunAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), (LPCSTR) pFuncName);
    // 创建远程线程
    HANDLE hThread = CreateRemoteThread(processHandle, NULL, 0, (LPTHREAD_START_ROUTINE) pFunAddr, moduleEntry32.hModule, 0, NULL);
    // 等待线程执行完毕
    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);
    CloseHandle(processHandle);
    printf("释放dll成功\n");
}

int main(int args, char *argv[]) {
    // 提升当前进程权限
    HANDLE token = NULL;
    BOOL ret = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token);
    if (ret) {
        TOKEN_PRIVILEGES privileges;
        privileges.PrivilegeCount = 1;
        LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &privileges.Privileges[0].Luid);
        privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        AdjustTokenPrivileges(token, FALSE, &privileges, sizeof(privileges), NULL, NULL);
        CloseHandle(token);
    }
    int pid = 10528;
    InjectDll("D:\libshare.dll", pid);
    // 卸载
    UnInjectDll("D:\libshare.dll",pid);
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
失色天空
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!