本文主要是介绍DLL 动态注入---ImgWalk动态库,这个DLL用来检测被注入的进程中当前载入的各个模块名称---DLL程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
DLL 动态注入—ImgWalk动态库,这个DLL用来检测被注入的进程中当前载入的各个模块名称—exe程序
DLL 动态注入—ImgWalk动态库,这个DLL用来检测被注入的进程中当前载入的各个模块名称—exe程序
/*------------------------------------------------------------------------22-InjLib.cppImgWalk动态库,这个DLL用来检测被注入的进程中当前载入的各个模块名称---exe程序
-----------------------------------------------------------------------*/
#include "CmnHdr.h"
#include "Resource.h"
#include <malloc.h>
#include <strsafe.h>
#include <TlHelp32.h>
#include <windowsx.h>
#include <tchar.h>/
#ifdef UNICODE#define InjectLib InjectLibW#define EjectLib EjectLibW
#else#define InjectLib InjectLibA#define EjectLib EjectLibA
#endif/
BOOL WINAPI InjectLibW(DWORD dwProcessId, PCWSTR pszLibFile);//创建远程线程并注入DLL
BOOL WINAPI InjectLibA(DWORD dwProcessId, PCSTR pszLibFile);
BOOL WINAPI EjectLibW(DWORD dwProcessId, PCWSTR pszLibFile);//将DLL从进程地址空间中撤销
BOOL WINAPI EjectLibA(DWORD dwProcessId, PCSTR pszLibFile);
BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam);
void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtrl, UINT codeNotity);
INT_PTR WINAPI Dlg_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
//int WINAPI _tWinMain(HINSTANCE hInstance,HINSTANCE,PTSTR pszCmdLine,int)
{DialogBox(hInstance,MAKEINTRESOURCE(IDD_INJLIB),NULL,Dlg_Proc);return 0;
}
INT_PTR WINAPI Dlg_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{switch (uMsg){chHANDLE_DLGMSG(hWnd,WM_INITDIALOG,Dlg_OnInitDialog);chHANDLE_DLGMSG(hWnd,WM_COMMAND,Dlg_OnCommand);}return FALSE;
}/
BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{chSETDLGICONS(hwnd,IDI_INJLIB);return TRUE;
}/
void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtrl, UINT codeNotity)
{switch (id){case IDCANCEL:EndDialog(hwnd, id);break;case IDC_INJECT:DWORD dwProcessId = GetDlgItemInt(hwnd, IDC_PROCESSID, NULL, FALSE);if (dwProcessId == 0){//如果为0,表示注入本进程dwProcessId = GetCurrentProcessId();}TCHAR szLibFile[MAX_PATH];GetModuleFileName(NULL,szLibFile,_countof(szLibFile));//获得当前进程的完整路径PTSTR pFileName = _tcsrchr(szLibFile, TEXT('\\')) + 1;_tcscpy_s(pFileName,_countof(szLibFile) - (pFileName - szLibFile),TEXT("22-ImgWalk.DLL"));if (InjectLib(dwProcessId, szLibFile)){chVERIFY(EjectLib(dwProcessId,szLibFile));chMB("DLL注入/撤消成功!");} elsechMB("DLL注入/撤消失败!");break;}
}/
//创建远程线程注入DLL
//参数:dwProcessID --进程ID
// pszLibFile ---要注入的DLL路径(含名称)
BOOL WINAPI InjectLibW(DWORD dwProcessId, PCWSTR pszLibFile)
{BOOL bOk = FALSE;//假设注入失败HANDLE hProcess = NULL,hThread = NULL;PWSTR pszLibFileRemote = NULL;__try {//获得目标进程句柄hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | //需要检索有关进程的某些信息,例如其令牌、退出代码和优先级类PROCESS_CREATE_THREAD | //For CreateRemoteThreadPROCESS_VM_OPERATION| //For VirtualAllocEx/VirtualFreeExPROCESS_VM_WRITE, //For WriteProcessMemoryFALSE,dwProcessId);if (hProcess == NULL) __leave;//计算存储DLL路径所需字节数int cch = 1 + lstrlenW(pszLibFile);//字符个数,因strlen不含结尾\0,所以加1int cb = cch * sizeof(wchar_t);//为远程进程分配内存空间pszLibFileRemote = (PWSTR)VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);if (pszLibFileRemote == NULL) __leave;//复制DLL路径到远程进程的内存中if (!WriteProcessMemory(hProcess, pszLibFileRemote,(PVOID)pszLibFile, cb, NULL)) __leave;//获取LoadLibraryW在Kernel32.dll中的地址//LPTHREAD_START_ROUTINE 函数指针,该函数通知宿主某个线程已开始执行。PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)//指向一个函数,该函数通知宿主某个线程已开始执行GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");if (pfnThreadRtn == NULL) __leave;//创建远程线程调用LoadLibraryWhThread = CreateRemoteThread(hProcess, NULL, 0, pfnThreadRtn, //LoadLibraryW(远程进程地址空间中)pszLibFileRemote, //Dll路径名(远程进程地址空间中)0, NULL);//立即执行if (hThread == NULL) __leave;//等待远程线程结束WaitForSingleObject(hThread,INFINITE);bOk = TRUE; //注入成功}__finally {//释放用于保存Dll路径名称的内存if (pszLibFileRemote != NULL)VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE);if (hThread != NULL)CloseHandle(hThread);if (hProcess != NULL)CloseHandle(hProcess);}return (bOk);}BOOL WINAPI InjectLibA(DWORD dwProcessId, PCSTR pszLibFile)
{//分配一个栈内存(无需手动释放),用于存储Unicode版本的路径名SIZE_T cchSize = lstrlenA(pszLibFile) + 1;//字符个数,含'\0'PWSTR pszLibFileW = (PWSTR)_alloca(cchSize * sizeof(wchar_t));//将ANSI路径转换为等价的UNICODEStringCchPrintfW(pszLibFileW, cchSize, L"%s", pszLibFile);return InjectLibW(dwProcessId, pszLibFileW);
}///
//将DLL从进程地址空间中撤销
//先根据DLL文件名,在进程加载的模块中查找是否该DLL己被加载
//如果被加载,记下这个DLL的句柄。然后创建远程线程去调用FreeLibrary卸载
BOOL WINAPI EjectLibW(DWORD dwProcessId, PCWSTR pszLibFile)
{BOOL bOk = FALSE;//假定撤销失败HANDLE hthSnapshot = NULL;HANDLE hProcess = NULL, hThread = NULL;__try{//抓取进程快照hthSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,//指定进程中加载的所有模块dwProcessId);if (hthSnapshot == INVALID_HANDLE_VALUE) __leave;//获得Unicode版本的目标DLL库句柄MODULEENTRY32W me = {sizeof(me)};BOOL bFound = FALSE;BOOL bMoreMods = Module32FirstW(hthSnapshot, &me);//Unicode版本for (;bMoreMods;bMoreMods = Module32NextW(hthSnapshot,&me)){bFound = (_wcsicmp(me.szModule,pszLibFile) == 0) || (_wcsicmp(me.szExePath,pszLibFile) == 0);if(bFound)break;}if (!bFound) __leave;//获得目标进程的句柄hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |PROCESS_CREATE_THREAD |PROCESS_VM_OPERATION ,FALSE, dwProcessId);if (hProcess == NULL) __leave;//获取FreeLibraray在Kernel32.dll中的地址PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "FreeLibrary");if(pfnThreadRtn == NULL) __leave;//创建远程线程hThread = CreateRemoteThread(hProcess,NULL, 0,pfnThreadRtn,me.modBaseAddr,0, NULL);if (hThread == NULL) __leave;//等待远程线程结束WaitForSingleObject(hThread, INFINITE);bOk = TRUE; //撤销成功}__finally{if (hthSnapshot != NULL)CloseHandle(hthSnapshot);if (hThread != NULL)CloseHandle(hThread);if (hProcess != NULL)CloseHandle(hProcess);}return bOk;
}BOOL WINAPI EjectLibA(DWORD dwProcessId, PCSTR pszLibFile)
{//分配一个栈内存(无需手动释放),用于存储Unicode版本的路径名SIZE_T cchSize = lstrlenA(pszLibFile) + 1;//字符个数,含'\0'PWSTR pszLibFileW = (PWSTR)_alloca(cchSize * sizeof(wchar_t));//将ANSI路径转换为等价的UNICODEStringCchPrintfW(pszLibFileW, cchSize, L"%s", pszLibFile);return EjectLibW(dwProcessId, pszLibFileW);
}
这篇关于DLL 动态注入---ImgWalk动态库,这个DLL用来检测被注入的进程中当前载入的各个模块名称---DLL程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!