Windows:代码远程线程注入

DLL远程线程注入

Windows开发:DLL远程线程注入

代码远程线程注入

DLL远程线程注入,一言以蔽之:在被注入进程中创建一个线程,线程函数的作用是加载指定DLL。

代码远程线程注入,实质是自定义线程函数,然后将线程函数代码和线程函数中用到的数据分别注入到目标进程,最后将数据作为线程函数的参数创建远程线程,执行自定义操作。

示例

不依赖自定义dll,在被注入进程中创建线程实现弹窗,窗口标题为被注入进程的位置。

线程函数:

  1. 线程函数要做的事情是弹窗,弹窗需要得到MessageBoxA在被注入进程中的位置,因此需要加载user32.dll,还需要字符串"MessageBoxA"。加载要用到Kernel32.dll中的LoadLibraryGetProcAddress,还需要字符串"user32.dll",在标题显示被注入进程的位置需要Kernal32.dll中的GetModuleFileName获取进程当前的运行目录。
  2. 上述用到的数据,在注入函数创建线程函数时被封装为一个结构体作为参数传给线程函数。
  3. 线程函数获得数据,调用被注入进程中的MessageBoxA弹窗

注入函数:

  1. 获取线程函数要用到的Kernel32.dll中的导出函数地址,用函数指针存放其在本进程中的地址,Kernel32.dll在各进程中位置相同,所以可用其在本进程的地址代替在被注入进程中的地址
  2. 上述所有线程函数用到的函数地址、数据等,再加一个弹窗要显示的字符串,封装到一个结构体DATA中。
  3. 将结构体、线程函数的代码注入进程
  4. 创建远程线程,将结构体作为参数传给线程函数。

源码

__stdcall百度百科

// 不依赖dll的远程线程注入
#include <windows.h>
#include <stdio.h>

#define STRLEN 20

typedef struct _DATA{
    // 4字节指针,存放指向函数的内存地址
    FARPROC fpLoadLibrary;
    FARPROC fpGetProcAddress;
    FARPROC fpGetModuleFileName;

    char strUser32Dll[STRLEN];    // 保存"user32.dll"字符串
    char strMessageBox[STRLEN];    // 保存"MessageBoxA"字符串
    char showStr[STRLEN];    // 保存MessageBox弹出的字符串
} DATA, *PDATA;


// 远程线程函数
// 因为要在线程中调用MessageBox,而user32.dll在各进程中位置不同,所以需获得其在被注入进程中的地址
DWORD WINAPI RemoteThreadFunc(LPVOID lpParam){
    PDATA pData = (PDATA)lpParam;

    // 声明函数指针
    HMODULE (__stdcall *MyLoadLibrary)(LPCTSTR);
    FARPROC (__stdcall *MyGetProcAddress)(HMODULE, LPCTSTR);
    int (__stdcall *MyMessageBox)(HWND, LPCTSTR, LPCTSTR, UINT);
    DWORD (__stdcall *MyGetModuleFileName)(HMODULE, LPTSTR, DWORD);

    // Kernel32.dll在各进程中位置相同,所以可用其在本进程的地址代替在被注入进程中的地址
    MyLoadLibrary = (HMODULE (__stdcall *)(LPCTSTR))pData->fpLoadLibrary;
    MyGetProcAddress = (FARPROC (__stdcall *)(HMODULE, LPCTSTR))pData->fpGetProcAddress;
    MyGetModuleFileName = (DWORD (__stdcall *)(HMODULE, LPTSTR, DWORD))pData->fpGetModuleFileName;

    // 加载user32.dll
    HMODULE hModule = MyLoadLibrary(pData->strUser32Dll);
    // 获取user32.dll中MessageBoxA的地址
    MyMessageBox = (int (__stdcall *)(HWND, LPCTSTR, LPCTSTR, UINT))MyGetProcAddress(hModule, pData->strMessageBox);

    char szModuleFileName[MAX_PATH] = {0};
    MyGetModuleFileName(NULL, szModuleFileName, MAX_PATH);
    // 弹窗
    MyMessageBox(NULL, pData->showStr, szModuleFileName, MB_OK);

    return 0;

}


// 注入函数
VOID Inject(DWORD dwPid){
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
    if (hProcess == NULL){
        printf("failed to open process.\n");
        return ;
    }
    DATA myData = {0};

    // 获取Kernel32.dll中的导出函数,用函数指针存放其在本进程中的地址
    myData.fpLoadLibrary = (FARPROC)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
    myData.fpGetProcAddress = (FARPROC)GetProcAddress(GetModuleHandle("kernel32.dll"), "GetProcAddress");
    myData.fpGetModuleFileName = (FARPROC)GetProcAddress(GetModuleHandle("kernel32.dll"), "GetModuleFileNameA");

    // 存入所需字符串,线程函数将Load user32.dll,并获取MessageBoxA在被注入进程中的位置
    lstrcpy(myData.strUser32Dll, "user32.dll");
    lstrcpy(myData.strMessageBox, "MessageBoxA");
    lstrcpy(myData.showStr, "non dll inject success.");

    // 在目标进程中申请空间
    LPVOID lpData = VirtualAllocEx(hProcess, NULL, sizeof(myData), MEM_COMMIT, PAGE_READWRITE);
    if (!lpData){
        printf("alloc mem failed.\n");
        printf("%x", GetLastError());
        return;
    }
    // 将myData结构体写入目标进程
    if(!WriteProcessMemory(hProcess, lpData, &myData, sizeof(myData), NULL)){
        printf("write mem failed.\n");
        return;
    }

    // 远程线程函数代码大小
    DWORD dwThradFuncSize = 0x4000;
    // 为将被注入的线程函数代码申请空间
    LPVOID lpCode = VirtualAllocEx(hProcess, NULL, dwThradFuncSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if(!lpCode){
        printf("alloc mem failed 2.\n");
        return;
    }
    // 注入,注意C才能用&RemoteThreadFunc取线程函数地址,C++不能
    if(!WriteProcessMemory(hProcess, lpCode, &RemoteThreadFunc, dwThradFuncSize, NULL)){
        printf("write mem failed 2.\n");
        return;
    }
    // 创建远程线程
    HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpCode, lpData, 0, NULL);
    if (hThread){
        printf("non dll inject success.\n");
    }
    else{
        return;
    }

    WaitForSingleObject(hThread, INFINITE);

    CloseHandle(hThread);
    CloseHandle(hProcess);
}


int main() {
    Inject(19328);

    return 0;
}

演示

在这里插入图片描述

被注入进程delete.exe
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
看很多人说VC好像需要使用release方式,不过我的CLion用release和debug都可以成功注入
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 示例代码:#include <windows.h> #include <stdio.h> #include <tlhelp32.h> // 远程线程注入dll BOOL InjectDLL(DWORD dwPID, char *szDLLName); int main(int argc, char *argv[]) { printf("远程线程注入dll演示程序\n"); if (argc == 3) { DWORD dwPID = atoi(argv[1]); char *szDLLName = argv[2]; InjectDLL(dwPID, szDLLName); } else { printf("用法:InjectDLL.exe <PID> <DLLName>\n"); } return 0; } // 远程线程注入dll BOOL InjectDLL(DWORD dwPID, char *szDLLName) { HANDLE hProcess, hThread; LPVOID lpBaseAddress; LPTHREAD_START_ROUTINE lpStartAddress; DWORD dwSize, dwThreadId; char szPath[256]; char szBuffer[1024]; // 打开进程 hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID); if (hProcess == NULL) { printf("OpenProcess() Error: %d\n", GetLastError()); return FALSE; } // 获取DLL的完整路径 GetFullPathName(szDLLName, 256, szPath, NULL); // 在进程中申请虚拟内存 dwSize = strlen(szPath) + 1; lpBaseAddress = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE); if (lpBaseAddress == NULL) { printf("VirtualAllocEx() Error: %d\n", GetLastError()); return FALSE; } // 将DLL路径写入到虚拟内存 int nBytesWritten; WriteProcessMemory(hProcess, lpBaseAddress, szPath, dwSize, &nBytesWritten); if (nBytesWritten != dwSize) { printf("WriteProcessMemory() Error: %d\n", GetLastError()); return FALSE; } // 加载Kernel32.dll HMODULE hKernel32 = GetModuleHandle("Kernel32"); if (hKernel32 == NULL) { printf("GetModuleHandle() Error: %d\n", GetLastError()); return FALSE; } // 获取LoadLibraryA函数地址 lpStartAddress = GetProcAddress(hKernel32, "LoadLibraryA"); if (lpStartAddress == NULL) { printf("GetProcAddress() Error: %d\n", GetLastError()); return FALSE; } // 创建远程线程 hThread = CreateRemoteThread(hProcess, NULL, 0, lpStartAddress, lpBaseAddress, 0, &dwThreadId); if (hThread == NULL) { printf("CreateRemoteThread() Error: %d\n", GetLastError()); return FALSE; } // 等待远程线程结束 WaitForSingleObject(hThread, INFINITE); // 读取线程退出码 DWORD dwExitCode; GetExitCodeThread(hThread, &dwExitCode); if (dwExitCode == 0) { printf("LoadLibrary() Error: %d\n", GetLastError()); return FALSE; } // 关闭句柄 CloseHandle(hProcess); CloseHandle(hThread); return TRUE; }我不能帮助你编写代码,但是我可以提供一些参考资料,帮助你编写远程线程注入dll代码。 ### 回答2: 远程线程注入DLL是一种技术,用于在目标进程中注入自定义的动态链接库(DLL)并执行其中的代码。以下是一个使用C语言编写的远程线程注入DLL的代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <windows.h> int main() { // 目标进程的进程ID DWORD pid = 1234; // 加载要注入的DLL路径 char dllPath[] = "C:\\path_to_dll\\mydll.dll"; // 获取目标进程句柄 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); if (hProcess == NULL) { printf("无法打开目标进程"); return -1; } // 在目标进程中为DLL路径分配内存 LPVOID dllPathAddr = VirtualAllocEx(hProcess, NULL, sizeof(dllPath), MEM_COMMIT, PAGE_READWRITE); if (dllPathAddr == NULL) { printf("无法在目标进程中分配内存"); CloseHandle(hProcess); return -1; } // 在目标进程中写入DLL路径 if (!WriteProcessMemory(hProcess, dllPathAddr, dllPath, sizeof(dllPath), NULL)) { printf("无法写入DLL路径到目标进程"); VirtualFreeEx(hProcess, dllPathAddr, 0, MEM_RELEASE); CloseHandle(hProcess); return -1; } // 获取Kernel32.dll中LoadLibrary函数的地址 HMODULE kernel32 = GetModuleHandle("kernel32.dll"); FARPROC loadLibrary = GetProcAddress(kernel32, "LoadLibraryA"); // 创建远程线程在目标进程中执行LoadLibrary函数,将DLL路径作为参数 HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)loadLibrary, dllPathAddr, 0, NULL); if (hThread == NULL) { printf("无法在目标进程中创建远程线程"); VirtualFreeEx(hProcess, dllPathAddr, 0, MEM_RELEASE); CloseHandle(hProcess); return -1; } // 等待远程线程执行结束 WaitForSingleObject(hThread, INFINITE); // 清理资源 VirtualFreeEx(hProcess, dllPathAddr, 0, MEM_RELEASE); CloseHandle(hThread); CloseHandle(hProcess); printf("远程线程注入DLL成功"); return 0; } ``` 这段代码首先通过`OpenProcess`函数打开目标进程,然后使用`VirtualAllocEx`在目标进程中为DLL路径分配内存,并使用`WriteProcessMemory`将DLL路径写入目标进程内存。接着,使用`GetModuleHandle`和`GetProcAddress`获取`LoadLibrary`函数的地址,然后使用`CreateRemoteThread`在目标进程中创建一个远程线程,让其执行`LoadLibrary`函数,将DLL路径作为参数传递给它。最后,使用`WaitForSingleObject`等待远程线程执行完毕,并释放之前分配的资源。 ### 回答3: 使用C语言编写远程线程注入DLL的代码可以通过以下步骤实现: 1. 首先,需要创建一个目标进程的句柄。可以使用`OpenProcess`函数来打开目标进程,并获得进程的句柄。 2. 接下来,需要在目标进程中分配一块内存空间,用于存储DLL的路径和名称。可以使用`VirtualAllocEx`函数在目标进程内部分配内存。 3. 在分配的内存空间中写入DLL的路径和名称。可以使用`WriteProcessMemory`函数将DLL的路径和名称写入到目标进程的内存中。 4. 使用`GetProcAddress`函数获取`LoadLibraryA`函数的地址,该函数用于加载DLL。可以使用`GetModuleHandle`函数获取kernel32.dll的句柄,然后再调用`GetProcAddress`函数来获取`LoadLibraryA`函数的地址。 5. 使用`CreateRemoteThread`函数在目标进程中创建一个远程线程,将`LoadLibraryA`函数地址作为线程的入口点,将DLL的路径和名称作为线程的参数传递。这样,在目标进程中就会自动加载并执行DLL。 完整的代码示例如下: ```c #include <windows.h> int main() { // Step 1: 打开目标进程句柄 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PROCESS_ID); // Step 2: 分配内存空间 LPVOID lpRemoteBuffer = VirtualAllocEx(hProcess, NULL, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); // Step 3: 写入DLL路径和名称 char dllPath[] = "C:\\path\\to\\dll.dll"; WriteProcessMemory(hProcess, lpRemoteBuffer, (LPVOID)dllPath, sizeof(dllPath), NULL); // Step 4: 获取LoadLibraryA函数地址 HMODULE hKernel32 = GetModuleHandleA("kernel32.dll"); FARPROC lpLoadLibraryA = GetProcAddress(hKernel32, "LoadLibraryA"); // Step 5: 创建远程线程注入DLL HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpLoadLibraryA, lpRemoteBuffer, 0, NULL); // 关闭句柄 CloseHandle(hThread); CloseHandle(hProcess); return 0; } ``` 以上就是使用C语言编写远程线程注入DLL的代码。请注意,使用远程线程注入DLL可能存在一些安全风险,请谨慎使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值