我是个初学者 最近学习Windows远程线程注入 照着书上理解了一遍 然后实现代码的时候 发现总是不成功
这个程序功能是让在用户在控制台上向程序输入两个参数 一个是notepad.exe的PID 一个是DLL路径 注入目标DLL后 出现弹窗
下面展示过程:
打开记事本
//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;
}
花了点时间改了一下,亲测成功了,希望采纳!
没成功的问题有好几个,概括一下:
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禁止了进程注入。
下面是成功的运行界面:
最后不说废话,上代码:
//主程序
#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;
}
建议你把杀毒软件关闭后再试一下,说不定就是它搞的
myhack.dll文件没贴出来吗?
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、实在不行,找我。可以详细帮你解决,我在这个方面曾经踩坑不少。