逆向工程核心原理之dll加载和卸载(远程线程注入法)
2019-03-24 本文已影响0人
Sadmess
加载
加载主程序
#include <Windows.h>
#include <tchar.h>
//LPCTSTR用来表示你的字符是否使用UNICODE
BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath)
{
HANDLE hProcess = NULL, hThread = NULL;
HMODULE hMod = NULL;
LPVOID pRemoteBuf = NULL;
DWORD dwBufSize = (DWORD)(_tcslen(szDllPath) + 10) * sizeof(TCHAR);
//LPTHREAD_START_ROUTINE函数指针指向一个函数,该函数通知宿主某个线程已开始执行。.NET Framework 4 版 中已弃用此函数指针。
LPTHREAD_START_ROUTINE pThreadProc;
//1.使用dwPID获取目标进程句柄(notepad.exe)
if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
{
//printf的宽字符版
_tprintf(L"OpenProcess(%d) failed!!![%d]\n", dwPID, GetLastError());
return FALSE;
}
//2.在目标进程notepad.exe内存中分配szDllName大小的内存
if (!(pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE)))
{
_tprintf(L"分配地址失败!!![%d]\n", GetLastError());
}
//3.将myhack.dll路径写入分配的内存
if (!(WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllPath, dwBufSize, NULL)))
{
_tprintf(L"写入内存失败!!![%d]\n", GetLastError);
}
//4.获取LoadLibraryW的地址
hMod = GetModuleHandle(L"kernel32.dll");
if (!(pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW")))
{
_tprintf(L"获取LoadLibraryW地址失败!!![%d]\n", GetLastError);
}
//5.在notepad.exe进程中运行线程
if (!(hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL)))
{
_tprintf(L"运行线程失败!!![%d]\n", GetLastError);
}
// If dwMilliseconds is INFINITE, the function will return only when the object is signaled.
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
CloseHandle(hProcess);
return TRUE;
}
int _tmain(int argc, TCHAR* argv[])
{
if (argc != 3)
{
_tprintf(L"USAGE: %s pid dll_path\n", argv[0]);
return 1;
}
// change privilege
//if (!SetPrivilege(SE_DEBUG_NAME, TRUE))
// return 1;
//inject dll
if (InjectDll((DWORD)_tstol(argv[1]), argv[2]))
_tprintf(L"InjectDll(\"%s\")success!!!\n", argv[2]);
else
_tprintf(L"InjectDll(\"%s\")failed!!!\n", argv[2]);
return 0;
}
加载dll
#include <tchar.h>
#include<windows.h>
#pragma comment(lib,"urlmon.lib")
#define DEF_URL (L"http://www.naver.com/index.html")
#define DEF_FILE_NAME (L"\\index.html")
HMODULE g_hMod = NULL;
DWORD WINAPI ThreadProc(LPVOID lParam)
{
TCHAR szPath[_MAX_PATH] = { 0 };
GetModuleFileName(g_hMod, szPath, MAX_PATH);
TCHAR *p = _tcsrchr(szPath, '\\');
_tcscpy(p+1, DEF_FILE_NAME);
URLDownloadToFile(NULL, DEF_URL, szPath, 0, NULL);
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(L"myhack.dll Injection!!!");
hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
CloseHandle(hThread);
break;
}
return TRUE;
}
坑点_tcscpy_s函数报错runtime #2(数组越界),原因未知以后再补。。。
卸载
// EjectDll.exe
#include "windows.h"
#include "tlhelp32.h"
#include "tchar.h"
//由进程名找到进程id号
DWORD FindProcessID(LPCTSTR szProcessName) {
DWORD dwPID = 0xFFFFFFFF;
HANDLE hSnapShot = INVALID_HANDLE_VALUE;
PROCESSENTRY32 pe;
// 获得系统进程的快照
pe.dwSize = sizeof(PROCESSENTRY32);
hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
Process32First(hSnapShot, &pe);
do {
if (!_tcsicmp(szProcessName, (LPCTSTR)pe.szExeFile)) {
dwPID = pe.th32ProcessID;
break;
}
} while (Process32Next(hSnapShot, &pe));
CloseHandle(hSnapShot);
return dwPID;
}
BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) {
TOKEN_PRIVILEGES tp;
HANDLE hToken;
LUID luid;
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
return FALSE;
if (!LookupPrivilegeValue(NULL, // lookup privilege on local system
lpszPrivilege, // privilege to lookup
&luid)) // receives LUID of privilege
return FALSE;
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege)
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
tp.Privileges[0].Attributes = 0;
// Enable the privilege or disable all privileges.
if (!AdjustTokenPrivileges(hToken, FALSE, &tp,
sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL))
return FALSE;
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
return FALSE;
return TRUE;
}
BOOL EjectDll(DWORD dwPID, LPCTSTR szDllName) {
BOOL bMore = FALSE, bFound = FALSE;
HANDLE hSnapshot, hProcess, hThread;
HMODULE hModule = NULL;
MODULEENTRY32 me = { sizeof(me) };
LPTHREAD_START_ROUTINE pThreadProc;
// dwPID = notepad进程的id号
// 使用TH32CS_SNAPMODULE参数,获得加载到notepad进程地址空间的DLL信息
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
bMore = Module32First(hSnapshot, &me);
for (; bMore; bMore = Module32Next(hSnapshot, &me)) {
if (!_tcsicmp((LPCTSTR)me.szModule, szDllName) ||
!_tcsicmp((LPCTSTR)me.szExePath, szDllName)) {
bFound = TRUE;
break;
}
}
if (!bFound) {
CloseHandle(hSnapshot);
return FALSE;
}
if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
return FALSE;
hModule = GetModuleHandle(L"kernel32.dll");
pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hModule, "FreeLibrary");
hThread = CreateRemoteThread(hProcess, NULL, 0,
pThreadProc, me.modBaseAddr,
0, NULL);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
CloseHandle(hProcess);
CloseHandle(hSnapshot);
return TRUE;
}
int _tmain(int argc, TCHAR* argv[]) {
DWORD dwPID = 0xFFFFFFFF;
dwPID = FindProcessID(L"notepad.exe");
if (dwPID == 0xFFFFFFFF) //没有找到notepad进程
return 1;
// 更改特权
if (!SetPrivilege(SE_DEBUG_NAME, TRUE))
return 1;
// 卸载DLL
if (EjectDll(dwPID, L"myhack.dll"))
_tprintf(L"EjectDll(%d, \"%s\") success!!!\n", dwPID, L"myhack.dll");
else
_tprintf(L"EjectDll(%d, \"%s\") failed!!!\n", dwPID, L"myhack.dll");
return 0;
}
代码来源:逆向工程核心原理