0x01 项目说明
实现在内存中对dll的加载和卸载
0x02 软件展示
0x03 代码展示
// TestInjectProcess.cpp : Defines the entry point for the application. // #include "stdafx.h" #include "resource.h" #include <Windows.h> #include <Tlhelp32.h> #include <assert.h> #include <string.h> #include <tchar.h> #include <stdlib.h> #include <stdio.h> //提升进程权限 BOOL EnableDebugPrivilege(BOOL bEnable) { BOOL status=FALSE; HANDLE hToken; //打开当前进程的访问令牌 if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken)) { LUID uID; LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&uID); //调整特权级别 TOKEN_PRIVILEGES tp; tp.PrivilegeCount =1; tp.Privileges[0].Luid=uID; tp.Privileges[0].Attributes=bEnable?SE_PRIVILEGE_ENABLED:0; AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(tp),NULL,NULL); status =(GetLastError() ==ERROR_SUCCESS); CloseHandle(hToken); } return status; } //获取进程name的ID DWORD getPid(LPTSTR name) { HANDLE hProcSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//获取进程快照句柄 assert(hProcSnap!=INVALID_HANDLE_VALUE); PROCESSENTRY32 pe32; pe32.dwSize=sizeof(PROCESSENTRY32); BOOL flag=Process32First(hProcSnap,&pe32);//获取列表的第一个进程 while(flag) { if(!_tcscmp(pe32.szExeFile,name)) { CloseHandle(hProcSnap); return pe32.th32ProcessID;//pid } flag=Process32Next(hProcSnap,&pe32);//获取下一个进程 } CloseHandle(hProcSnap); return 0; } //卸载dll BOOL ExitDll(DWORD dwID, LPSTR szDllName) { HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, dwID); if ( !hProcess ) { return FALSE; } int cByte = (_tcslen(szDllName)+1) * sizeof(TCHAR); LPVOID pAddr = VirtualAllocEx(hProcess, NULL, cByte, MEM_COMMIT, PAGE_READWRITE); if ( !pAddr || !WriteProcessMemory(hProcess, pAddr, szDllName, cByte, NULL)) { return FALSE; } #ifdef _UNICODE PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)GetModuleHandleW; #else PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)GetModuleHandleA; #endif //Kernel32.dll总是被映射到相同的地址 if ( !pfnStartAddr ) { return FALSE; } DWORD dwThreadID = 0,dwFreeId=0,dwHandle; HANDLE hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, pfnStartAddr, pAddr, 0, &dwThreadID); if ( !hRemoteThread ) { return FALSE; } WaitForSingleObject(hRemoteThread,INFINITE); // 获得GetModuleHandle的返回值 GetExitCodeThread(hRemoteThread,&dwHandle); CloseHandle(hRemoteThread); // 使目标进程调用FreeLibrary,卸载DLL #ifdef _UNICODE PTHREAD_START_ROUTINE pfnFreeAddr = (PTHREAD_START_ROUTINE)FreeLibrary; #else PTHREAD_START_ROUTINE pfnFreeAddr = (PTHREAD_START_ROUTINE)FreeLibrary; #endif HANDLE hFreeThread = CreateRemoteThread(hProcess, NULL, 0, pfnFreeAddr,(LPVOID)dwHandle,0,&dwFreeId); if ( !hFreeThread ) { return FALSE; } WaitForSingleObject(hFreeThread,INFINITE); VirtualFreeEx(hProcess,pAddr,cByte,MEM_COMMIT); CloseHandle(hFreeThread); CloseHandle(hProcess); return TRUE; } // 向目标进程地址空间写入DLL名称 BOOL InjectDll(HANDLE hProcess, LPSTR lpszDll) { DWORD dwSize, dwWritten; //HANDLE hProcess = (HANDLE)hTProcess; dwSize = lstrlenA(lpszDll) + 1; LPVOID lpBuf = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE ); if (NULL == lpBuf) { CloseHandle(hProcess); return FALSE; } if (WriteProcessMemory(hProcess, lpBuf, (LPVOID)lpszDll, dwSize, &dwWritten)) { if(dwWritten!=dwSize) { VirtualFreeEx(hProcess, lpBuf, dwSize,MEM_DECOMMIT); CloseHandle(hProcess); // 失败处理 return FALSE; } } else { CloseHandle(hProcess); } // 使目标进程调用LoadLibrary,加载DLL DWORD dwID; LPVOID pFunc = LoadLibraryA; HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0,(LPTHREAD_START_ROUTINE)pFunc, lpBuf, 0, &dwID); if(hThread == NULL) { return FALSE; } //收尾工具 WaitForSingleObject(hThread,INFINITE); // 释放目标进程中申请的空间 VirtualFreeEx(hProcess,lpBuf,dwSize,MEM_DECOMMIT); CloseHandle(hThread); CloseHandle(hProcess); // 等待LoadLibrary加载完毕 return TRUE; } BOOL CALLBACK InjectDialogProc( HWND hwndDlg, // handle to dialog box UINT uMsg, // message WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ) { TCHAR szStrTemp[256]={0}; DWORD ProcessId=0; TCHAR szProcess[10]={0}; TCHAR szDllStr[256]={0}; TCHAR szExitDllStr[256]={0}; HANDLE hProcess; BOOL isInject; BOOL isExit; switch(uMsg) { case WM_INITDIALOG: break; case WM_CLOSE: EndDialog(hwndDlg,0); break; case WM_COMMAND: { switch(LOWORD(wParam)) { case IDC_BUTTON_INJECT: //MessageBox(0,"inject","注入",0); GetDlgItemText(hwndDlg,IDC_EDIT_PROCESSNAME,szStrTemp,256); ProcessId = getPid(szStrTemp); if(ProcessId == 0) { MessageBox(0,"没找到进程","错误1",0); return FALSE; } //打开目标进程 hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, ProcessId); if(hProcess == NULL) { MessageBox(0,"进程打开失败","错误2",0); return FALSE; } //sprintf(szProcess,"%d",ProcessId); //MessageBox(0,szProcess,"进程ID",MB_OK); //写入进程的内存中去 GetDlgItemText(hwndDlg,IDC_EDIT_DLLLOCATION,szDllStr,256); isInject =InjectDll(hProcess,szDllStr); if(!isInject) { MessageBox(0,"注入DLL失败","错误\3",0); return FALSE; } break; case IDC_BUTTON_EXITDLL: //EndDialog(hwndDlg,0); GetDlgItemText(hwndDlg,IDC_EDIT_PROCESSNAME,szStrTemp,256); ProcessId = getPid(szStrTemp); if(ProcessId == 0) { MessageBox(0,"没找到进程","错误1",0); return FALSE; } /* hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, ProcessId); if(hProcess == NULL) { MessageBox(0,"进程打开失败","错误2",0); return FALSE; } */ GetDlgItemText(hwndDlg,IDC_EDIT_DLLLOCATION,szExitDllStr,256); //MessageBox(0,szExitDllStr,"卸载测试",MB_OK); isExit = ExitDll(ProcessId,szExitDllStr); if(!isExit) { MessageBox(0,"卸载Dll失败","错误5",0); return FALSE; } break; } } } return FALSE; } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // TODO: Place code here. EnableDebugPrivilege(TRUE); DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG_MAIN),NULL,InjectDialogProc); return 0; }
0x04 分析
因为代码基本参考一些文章编写的
在写卸载dll的时候, 遇到了很多问题, 因为对几个函数还不是太熟悉
写下来,继续分析一下吧!!
错误代码一:
void CDllManageDlg::UnInjectDll(DWORD dwPid, char *szDllName) { // 使目标进程调用GetModuleHandle,获得DLL在目标进程中的句柄 DWORD dwHandle; HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid); LPVOID pFunc = GetModuleHandleA; char lpBuf[MAXBYTE]; HANDLE hThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, lpBuf, 0, &dwPid ); // 等待GetModuleHandle运行完毕 WaitForSingleObject( hThread, INFINITE ); // 获得GetModuleHandle的返回值 GetExitCodeThread( hThread, &dwHandle ); // 释放目标进程中申请的空间 int dwSize = strlen(szDllName) + sizeof(char); VirtualFreeEx( hProcess, lpBuf, dwSize, MEM_DECOMMIT ); CloseHandle( hThread ); // 使目标进程调用FreeLibrary,卸载DLL pFunc = FreeLibrary; hThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, (LPVOID)dwHandle, 0, &dwPid ); // 等待FreeLibrary卸载完毕 WaitForSingleObject( hThread, INFINITE ); CloseHandle( hThread ); CloseHandle( hProcess ); }
错误代码二:
// 使目标进程调用GetModuleHandle,获得DLL在目标进程中的句柄 DWORD dwHandle, dwID; LPVOID pFunc = GetModuleHandleA; HANDLE hThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, lpBuf, 0, &dwID ); // 等待GetModuleHandle运行完毕 WaitForSingleObject( hThread, INFINITE ); // 获得GetModuleHandle的返回值 GetExitCodeThread( hThread, &dwHandle ); // 释放目标进程中申请的空间 VirtualFreeEx( hProcess, lpBuf, dwSize, MEM_DECOMMIT ); CloseHandle( hThread ); // 使目标进程调用FreeLibrary,卸载DLL pFunc = FreeLibrary; hThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, (LPVOID)dwHandle, 0, &dwID ); // 等待FreeLibrary卸载完毕 WaitForSingleObject( hThread, INFINITE ); CloseHandle( hThread ); CloseHandle( hProcess );
这两端代码, 继续分析一下
睡觉, 明天早起, 继续分析,, LP在催了,,,
标注:20180123:
已经分析完毕, 第一段代码的
lpBuf 没有指定模块名字(没有进行任何模块的分配)第二段代码类似,
lpBuf 没有指定
流程的话我认为应该的执行顺序是
VirtualAllocEx
WriteProcessMemory
CreateRemoteThread
获取返回值:dwHandle
CreateRemoteThread - FreeLibrary
VirtualFreeEx
后面两个代码, 不太符合要求
这是我的理解, 后面测试成功!
完整项目代码,下载地址:
待分析, 明天继续!!
0则评论给“[实例]远程加载DLL, 远程卸载DLL”