1.
线程注入一注入的可行性
kernel32.dll
和
user32.dll
是两个在大部分程序上都会调用的 DLL 同一个
DLL
,在不同的进程中,不一定被映射(加载)在同一个内存地址下。但是 kernel32.dll和
user32.dll
例外。他们总是被映射到进程的内存首选地址因此,在所有使用这两个
DLL 的 进程中,这两个
DLL
的内存地址是相同的。我们在本进程获取的
kernel32.dli 中函数的地址, 在目标进程中也是一样的。
2.
涉及的
API
OpenProcess //
获取已知进程的句柄
VirtualAllocEx //
在进程申请空间
WriteProcessMemory //
向进程写入东西
GetProcAddress //
取得函数在
DLL
的地址
CreateRemoteThreadEx //
在其他进程中创建新线程
CloseHandle //
关闭句柄
3.
待注入dll项目testDll.dll的代码
// dllmain.cpp : 定义 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:
::MessageBox(NULL, L"if you see this, testDll.dll had been inject in this Process", L"hi", MB_ICONINFORMATION | MB_OK);
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
4. 注入代码
// RemoteInject.cpp : 定义应用程序的入口点。
//
#include "framework.h"
#include <shellapi.h>
#include <tlhelp32.h>
#include <string>
#include <thread>
DWORD processFind(LPCWSTR exeName)
{
HANDLE hProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if(!hProcess)
return 0;
PROCESSENTRY32 info;
info.dwSize = sizeof(PROCESSENTRY32);
if(!Process32First(hProcess, &info))
return 0;
while(true)
{
if(!wcscmp(info.szExeFile, exeName))
return info.th32ProcessID;
if(!Process32Next(hProcess, &info))
return 0;
}
return 0;
}
BOOL Inject(DWORD processId, LPCWSTR dllPath)
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, processId);
if(!hProcess)
return FALSE;
SIZE_T pathSize = (wcslen(dllPath) + 1) * sizeof(wchar_t);
LPVOID startAddr = VirtualAllocEx(hProcess, NULL, pathSize, MEM_COMMIT, PAGE_READWRITE);
if(!startAddr)
return FALSE;
if(!WriteProcessMemory(hProcess, startAddr, dllPath, pathSize, NULL))
return FALSE;
PTHREAD_START_ROUTINE pFuncStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");
if(!pFuncStartAddr)
return FALSE;
HANDLE hThread = CreateRemoteThreadEx(hProcess, NULL, NULL, pFuncStartAddr, startAddr, NULL, NULL, NULL);
if(!hThread)
return FALSE;
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
CloseHandle(hProcess);
return TRUE;
}
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
//运行windows自带的记事本程序
ShellExecute(0, L"open", L"notepad.exe", L"", L"", SW_SHOWNORMAL);
bool b = false;
std::thread th([&]() {
::Sleep(100);
DWORD id = processFind(L"notepad.exe");
if (!id)
{
b = true;
return;
}
wchar_t szPath[MAX_PATH];
if (!GetModuleFileNameW(NULL, szPath, MAX_PATH))
{
b = true;
return;
}
std::wstring str = szPath;
size_t pos = str.find_last_of(L"\\");
str = str.substr(0, pos + 1);
str += L"testDll.dll";
Inject(id, str.c_str());
b = true;
});
th.detach();
while (!b)
{
std::this_thread::yield();
}
return 0;
}
5. 界面显示
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)