MRX271828
2021-09-15 15:50
采纳率: 100%
浏览 134

Winodws10系统下远程线程DLL注入

我是个初学者 最近学习Windows远程线程注入 照着书上理解了一遍 然后实现代码的时候 发现总是不成功
这个程序功能是让在用户在控制台上向程序输入两个参数 一个是notepad.exe的PID 一个是DLL路径 注入目标DLL后 出现弹窗
下面展示过程:
打开记事本

img


获取其PID:

img


打开控制台输入命令:

img


没看出什么错误:

img


但记事本进程被关闭 没有任何效果
请问代码的问题具体在哪里?
下面是代码

//InjectDll.cpp
#include "tchar.h"
#include <windows.h>
#include <stdio.h>
BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath)
{
    HANDLE hProcess = NULL, hTread = NULL;
    HMODULE hMod = NULL;//DLL模块
    LPVOID pRemoteBuf = NULL;//插入字符串的缓冲区
    DWORD dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR);//DLL路径字符串大小长度
    LPTHREAD_START_ROUTINE pThreadProc;//定义函数指针
    //使用dwPID获取目标进程(notepad.exe)句柄
    if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
    {
        _tprintf(TEXT("OpenProcess(%d) failed [%d]\n"), dwPID, GetLastError());
        return FALSE;
    }
    //在目标进程(notepad.exe)内存中分配szDllName大小的内存
    pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);
    //将myhack.dll路径写入分配的内存
    if (pRemoteBuf == NULL)
        return FALSE;
    //将DLL路径字符串写入内存地址
    WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllPath, dwBufSize, NULL);
    //获取LoadLibraryW() API的地址
    hMod = GetModuleHandleW(L"kernel.dll");
    pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW");
    //在notepad.exe进程中运行线程
    HANDLE hThread = CreateRemoteThread(
        hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL
    );
    if (hThread == NULL)
        return FALSE;
    WaitForSingleObject(hThread, INFINITE);
    VirtualFreeEx(hProcess, pRemoteBuf, dwBufSize, MEM_FREE);
    CloseHandle(hThread);
    CloseHandle(hProcess);
    return TRUE;
}

int _tmain(int argc, TCHAR *argv[])
{
    if (argc != 3)
    {
        _tprintf(TEXT("USAGE :%s pid dll_path\n"), argv[0]);
        return 1;
    }
    //inject DLL
    if (InjectDll((DWORD)_tstol(argv[1]), argv[2]))
        wprintf(L"InjectDll(%hs) success\n", argv[2]);
    else
        wprintf(L"InjectDll(%hs) failed\n", argv[2]);
    return 0;
}

//myhack.cpp 会生成一个DLL文件 用来注入
#include <stdlib.h>
#include "windows.h"
#include "tchar.h"
#include <stdio.h>

HMODULE g_hMod = NULL;
DWORD WINAPI ThreadProc(LPVOID lParam)
{
    MessageBox(NULL, TEXT("DLL injection SUCCESS"), TEXT("HaHa"), MB_OK);
    return 0;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    HANDLE hThread = NULL;
    g_hMod = (HMODULE)hinstDLL;
    switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
        OutputDebugString("Myhack.dll Injection\n");//输出字符串
        hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
        CloseHandle(hThread);
        break;
    }
    return TRUE;
}
  • 收藏

4条回答 默认 最新

  • 急速光粒 2021-09-17 15:40
    已采纳

    花了点时间改了一下,亲测成功了,希望采纳!
    没成功的问题有好几个,概括一下:
    1、你调用的库(L"kernel.dll"); 改为(L"kernel32.dll");
    2、hMod = GetModuleHandleW(L"kernel32.dll"); 需要改成hMod = GetRemoteHandle(dwPID, hProcess);,这是最大的问题,应该是从远程进程查找kernel32.dll,而不是从本进程查找;
    3、需要编译x64位版本(如果你是32位,你就编译32位);
    4、需要关闭360,这也是必须的,之前一直没出来,关闭了360 ,就出来了。应该是360禁止了进程注入。
    下面是成功的运行界面:

    img

    最后不说废话,上代码:
    //主程序

    #include "tchar.h"
    #include <windows.h>
    #include <stdio.h>
    #include <psapi.h>
    #include <string>
    
    HMODULE GetRemoteHandle(DWORD dwProcessId, HANDLE hProcess)
    {
        HMODULE* phMods = NULL;
        //HANDLE hProcess = NULL;
        HMODULE hRet = NULL;
        DWORD dwNeeded = 0;
        DWORD i = 0;
        TCHAR szModName[MAX_PATH] = {};
    
        //hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessId);
        /*if (NULL == hProcess)
        {
            printf("不能打开进程[ID:0x%x]句柄,错误码:0x%08x\n", dwProcessId);
            return;
        }*/
    
        EnumProcessModules(hProcess, NULL, 0, &dwNeeded);
        phMods = (HMODULE*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwProcessId);
    
        if (EnumProcessModules(hProcess, phMods, dwNeeded, &dwNeeded))
        {
            for (i = 0; i < (dwNeeded / sizeof(HMODULE)); i++)
            {
                ZeroMemory(szModName, MAX_PATH * sizeof(TCHAR));
                //在这如果使用GetModuleFileName,有的模块名称获取不到,函数返回无法找到该模块的错误
                if (GetModuleFileNameEx(hProcess, phMods[i], szModName, MAX_PATH))
                {
                    //printf("%ws\n", szModName);
    
                    std::wstring str(szModName);
                    int pos = str.find(_T("KERNEL32"));
                    if (pos > 0)
                    {
                        hRet = phMods[i];
                        break;
                    }
                }
            }
        }
        HeapFree(GetProcessHeap(), 0, phMods);
        //CloseHandle(hProcess);
    
        return NULL;
    }
    BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath)
    {
        HANDLE hProcess = NULL, hTread = NULL;
        HMODULE hMod = NULL;//DLL模块
        LPVOID pRemoteBuf = NULL;//插入字符串的缓冲区
        DWORD dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR);//DLL路径字符串大小长度
        LPTHREAD_START_ROUTINE pThreadProc;//定义函数指针
                                           //使用dwPID获取目标进程(notepad.exe)句柄
        if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
        {
            _tprintf(TEXT("OpenProcess(%d) failed [%d]\n"), dwPID, GetLastError());
            return FALSE;
        }
        //在目标进程(notepad.exe)内存中分配szDllName大小的内存
        pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);
        //将myhack.dll路径写入分配的内存
        if (pRemoteBuf == NULL)
            return FALSE;
        //将DLL路径字符串写入内存地址
        bool b=WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllPath, dwBufSize, NULL);
        //获取LoadLibraryW() API的地址
        //hMod = GetModuleHandleW(L"kernel32.dll"); 
        hMod = GetRemoteHandle(dwPID, hProcess);
        pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW");
        //在notepad.exe进程中运行线程
        HANDLE hThread = CreateRemoteThread(
            hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL
        );
        if (hThread == NULL)
            return FALSE;
        WaitForSingleObject(hThread, INFINITE);
        VirtualFreeEx(hProcess, pRemoteBuf, dwBufSize, MEM_FREE);
        CloseHandle(hThread);
        CloseHandle(hProcess);
        system("pause");
        return TRUE;
    }
    int _tmain(int argc, TCHAR *argv[])
    {
        if (argc != 3)
        {
            _tprintf(TEXT("USAGE :%s pid dll_path\n"), argv[0]);
            return 1;
        }
        //inject DLL
        if (InjectDll((DWORD)_tstol(argv[1]), argv[2]))
            wprintf(L"InjectDll(%hs) success\n", argv[2]);
        else
            wprintf(L"InjectDll(%hs) failed\n", argv[2]);
        system("pause");
        return 0;
    }
    

    //myhack.dll代码

    #include "stdafx.h"
    
    
    //myhack.cpp 会生成一个DLL文件 用来注入
    #include <stdlib.h>
    #include "windows.h"
    #include "tchar.h"
    #include <stdio.h>
    
    HMODULE g_hMod = NULL;
    DWORD WINAPI ThreadProc(LPVOID lParam)
    {
        MessageBox(NULL, TEXT("DLL injection SUCCESS"), TEXT("HaHa"), MB_OK);
        return 0;
    }
    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    {
        HANDLE hThread = NULL;
        g_hMod = (HMODULE)hinstDLL;
        switch (fdwReason)
        {
        case DLL_PROCESS_ATTACH:
            //OutputDebugString("Myhack.dll Injection\n");//输出字符串
            //MessageBox(NULL, TEXT("DLL injection SUCCESS"), TEXT("HaHa"), MB_OK);
    
            hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
            CloseHandle(hThread);
            break;
        }
        return TRUE;
    }
    
    已采纳该答案
    打赏 评论
  • 冰岛少年 2021-09-15 16:10

    建议你把杀毒软件关闭后再试一下,说不定就是它搞的

    打赏 评论
  • 急速光粒 2021-09-15 21:35

    myhack.dll文件没贴出来吗?

    打赏 评论
  • yangxinyue315 2021-09-16 13:16

    1、dll注入,需要确定exe是64位还是32位的;dll的位数要和exe对应
    2、注入前,要注意获得进程的权限,也就是网上说的很多的“提权”
    貌似下边的逻辑:

    
    HANDLE hToken;   
        TOKEN_PRIVILEGES tkp;
        if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))   
            return( FALSE );
        LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid);
        tkp.PrivilegeCount = 1;   
        tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
        if (GetLastError() != ERROR_SUCCESS)   
            return FALSE;   
    
        return TRUE; 
    

    3、借助工具CodeinEX,可以测试dll是否可以成功注入;先确定被注入的dll没有问题,然后再去看你自己写的注入逻辑。
    4、实在不行,找我。可以详细帮你解决,我在这个方面曾经踩坑不少。

    打赏 评论

相关推荐 更多相似问题