看雪论坛作者ID:1900
1
简介
| ul_reason_for_call的值 | 代表的状态 |
| DLL_PROCESS_ATTACH | Dll刚刚映射到进程空间中 |
| DLL_THREAD_ATTACH | 进程中有新线程创建 |
| DLL_THREAD_DETACH | 进程中有新线程销毁 |
Dll从进程空间中接触映射 |
// dllmain.cpp : 定义 DLL 应用程序的入口点。#include <Windows.h>#include <Shlobj.h>#pragma comment(lib, "shell32.lib")#define FILE_NAME "result.txt"DWORD WINAPI ThreadProc(LPVOID lpParameter){HANDLE hFile = NULL;CHAR szDesktopFile[MAX_PATH] = { 0 }; //保存系统桌面路径CHAR szFullFilePath[MAX_PATH] = { 0 }; //保存完成的加载DLL文件的文件路径DWORD dwRetLen = 0, dwFileLen = 0;BOOL bRet = TRUE;//获取桌面路径bRet = SHGetSpecialFolderPath(NULL, szDesktopFile, CSIDL_DESKTOP, TRUE);if (bRet){strcat(szDesktopFile, "\\");strcat(szDesktopFile, FILE_NAME);while (TRUE){hFile = CreateFile( szDesktopFile,GENERIC_READ | GENERIC_WRITE,0, NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL, NULL);if (hFile == INVALID_HANDLE_VALUE) //打开文件错误{if (GetLastError() == 32) //错误码是不是其他进程正在使用这个文件,是的话等待一会在继续打开{Sleep(200);continue;}else break;}else{GetModuleFileName(NULL, szFullFilePath, MAX_PATH); //获取加载DLL的进程的完整路径dwFileLen = strlen(szFullFilePath);szFullFilePath[dwFileLen] = '\r'; //由于是在WIN7运行,换行符是\r\nszFullFilePath[dwFileLen + 1] = '\n';SetFilePointer(hFile, 0, NULL, FILE_END);WriteFile(hFile, szFullFilePath, dwFileLen + 2, &dwRetLen, NULL);if (hFile) CloseHandle(hFile);break;}}}return 0;}BOOL APIENTRY DllMain( HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved){switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:{HANDLE hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);if (hThread) CloseHandle(hThread);break;}case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:break;}return TRUE;}
2
代码框架
#include <cstdio>#include <Windows.h>#include <TlHelp32.h>#define PROCESS_NAME "taskmgr.exe" //要注入的进程名,这个是任务管理器的进程名#define DLL_NAME "InjectDll.dll" //要注入的DLL的名称BOOL InjectDll(DWORD dwPid, CHAR szDllName[]); //注入DLLDWORD GetPID(PCHAR pProName); //根据进程名获取PIDVOID ShowError(PCHAR msg); //打印错误信息BOOL EnbalePrivileges(HANDLE hProcess, char *pszPrivilegesName); //提升进程权限int main(){CHAR szDllPath[MAX_PATH] = { 0 }; //保存要注入的DLL的路径DWORD dwPID = 0; //保存要注入的进程的PID// 提升当前进程令牌权限if (!EnbalePrivileges(GetCurrentProcess(), SE_DEBUG_NAME)){printf("权限提升失败\n");}dwPID = GetPID(PROCESS_NAME);if (dwPID == 0){printf("没有找到要注入的进程\n");goto exit;}GetCurrentDirectory(MAX_PATH, szDllPath); //获取程序的目录strcat(szDllPath, "\\");strcat(szDllPath, DLL_NAME); //与DLL名字拼接得到DLL的完整路径printf("要注入的进程名:%s PID:%d\n", PROCESS_NAME, dwPID);printf("要注入的DLL的完整路径%s\n", szDllPath);if (InjectDll(dwPID, szDllPath)){printf("Dll注入成功\n");}exit:system("pause");return 0;}BOOL InjectDll(DWORD dwPid, CHAR szDllName[]){BOOL bRet = TRUE;return bRet;}DWORD GetPID(PCHAR pProName){PROCESSENTRY32 pe32 = { 0 };HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);BOOL bRet = FALSE;DWORD dwPID = 0;if (hSnap == INVALID_HANDLE_VALUE){printf("CreateToolhelp32Snapshot process %d\n", GetLastError());goto exit;}pe32.dwSize = sizeof(pe32);bRet = Process32First(hSnap, &pe32);while (bRet){if (lstrcmp(pe32.szExeFile, pProName) == 0){dwPID = pe32.th32ProcessID;break;}bRet = Process32Next(hSnap, &pe32);}CloseHandle(hSnap);exit:return dwPID;}VOID ShowError(PCHAR msg){printf("%s Error %d\n", msg, GetLastError());}BOOL EnbalePrivileges(HANDLE hProcess, char *pszPrivilegesName){HANDLE hToken = NULL;LUID luidValue = { 0 };TOKEN_PRIVILEGES tokenPrivileges = { 0 };BOOL bRet = FALSE;DWORD dwRet = 0;// 打开进程令牌并获取具有 TOKEN_ADJUST_PRIVILEGES 权限的进程令牌句柄if (!OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken)){ShowError("OpenProcessToken");goto exit;}// 获取本地系统的 pszPrivilegesName 特权的LUID值if (!LookupPrivilegeValue(NULL, pszPrivilegesName, &luidValue)){ShowError("LookupPrivilegeValue");goto exit;}// 设置提升权限信息tokenPrivileges.PrivilegeCount = 1;tokenPrivileges.Privileges[0].Luid = luidValue;tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;// 提升进程令牌访问权限if (!AdjustTokenPrivileges(hToken, FALSE, &tokenPrivileges, 0, NULL, NULL)){ShowError("AdjustTokenPrivileges");goto exit;}else{// 根据错误码判断是否特权都设置成功dwRet = ::GetLastError();if (ERROR_SUCCESS == dwRet){bRet = TRUE;goto exit;}else if (ERROR_NOT_ALL_ASSIGNED == dwRet){ShowError("ERROR_NOT_ALL_ASSIGNED");goto exit;}}exit:return bRet;}
3
远程线程注入
HANDLE WINAPI CreateRemoteThread(__in HANDLE hProcess,__in LPSECURITY_ATTRIBUTES lpThreadAttributes,__in SIZE_T dwStackSize,__in LPTHREAD_START_ROUTINE lpStartAddress,__in LPVOID lpParameter,__in DWORD dwCreationFlags,__out LPDWORD lpThreadId);
| 参数 | 说明 |
| hProcess | 要创建线程的进程句柄 |
| lpThreadAttributes | 新线程的安全描述符 |
| dwStackSize | 堆栈起始大小,为0表示默认大小 |
| lpStartAddress | 表示要运行线程的起始地址 |
| lpParameter | 保存要传递给线程参数的地址 |
| dwCreationFlags | 控制线程创建的标志,为0表示创建后立即执行 |
| lpThreadId | 指向接收线程标识符变量的指针。为NULL表示不返回线程标识符 |
(1)hProcess用来指定在哪个进程中创建新线程。
(2)lpStartAddress用来指定将进程中的哪个地址开始作为新线程运行的起始地址。
(3)lpParameter保存的也是一个地址,这个地址中保存的就是新线程要用到的参数。
HMODULE WINAPI LoadLibrary(__in LPCTSTR lpFileName);BOOL InjectDll(DWORD dwPid, CHAR szDllName[]){BOOL bRet = TRUE;HANDLE hProcess = NULL, hRemoteThread = NULL;HMODULE hKernel32 = NULL;DWORD dwSize = 0;LPVOID pDllPathAddr = NULL;PVOID pLoadLibraryAddr = NULL;// 打开注入进程,获取进程句柄hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);if (NULL == hProcess){ShowError("OpenProcess");bRet = FALSE;goto exit;}// 在注入进程中申请可以容纳DLL完成路径名的内存空间dwSize = 1 + strlen(szDllName);pDllPathAddr = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);if (!pDllPathAddr){ShowError("VirtualAllocEx");bRet = FALSE;goto exit;}// 把DLL完整路径名写入进程中if (!WriteProcessMemory(hProcess, pDllPathAddr, szDllName, dwSize, NULL)){ShowError("WriteProcessMemory");bRet = FALSE;goto exit;}hKernel32 = LoadLibrary("kernel32.dll");if (hKernel32 == NULL){ShowError("LoadLibrary");bRet = FALSE;goto exit;}// 获取LoadLibraryA函数地址pLoadLibraryAddr = GetProcAddress(hKernel32, "LoadLibraryA");if (pLoadLibraryAddr == NULL){ShowError("GetProcAddress ");bRet = FALSE;goto exit;}//创建远程线程进行DLL注入hRemoteThread = CreateRemoteThread(hProcess, NULL, 0,(LPTHREAD_START_ROUTINE)pLoadLibraryAddr,pDllPathAddr, 0, NULL);if (hRemoteThread == NULL){ShowError("CreateRemoteThread");bRet = FALSE;goto exit;}exit:if (hKernel32) FreeLibrary(hKernel32);if (hProcess) CloseHandle(hProcess);if (hRemoteThread) CloseHandle(hRemoteThread);return bRet;}
4
加强版远程线程注入
typedef DWORD(WINAPI *pFnZwCreateThreadEx)(PHANDLE ThreadHandle,ACCESS_MASK DesiredAccess,LPVOID ObjectAttributes,HANDLE ProcessHandle,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,BOOL CreateSuspended,DWORD dwStackSize,DWORD dw1,DWORD dw2,LPVOID pUnkown);
typedef DWORD(WINAPI *pFnZwCreateThreadEx)(PHANDLE ThreadHandle,ACCESS_MASK DesiredAccess,LPVOID ObjectAttributes,HANDLE ProcessHandle,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,ULONG CreateThreadFlags,SIZE_T ZeroBits,SIZE_T StackSize,SIZE_T MaximumStackSize,LPVOID pUnkown);
typedef DWORD(WINAPI *pFnZwCreateThreadEx)(PHANDLE, ACCESS_MASK, LPVOID,HANDLE, LPTHREAD_START_ROUTINE,LPVOID, BOOL, DWORD, DWORD, DWORD, LPVOID);BOOL InjectDll(DWORD dwPid, CHAR szDllName[]){BOOL bRet = TRUE;HANDLE hProcess = NULL, hRemoteThread = NULL;HMODULE hKernel32 = NULL, hNtDll = NULL;DWORD dwSize = 0;LPVOID pDllPathAddr = NULL;PVOID pLoadLibraryAddr = NULL;pFnZwCreateThreadEx ZwCreateThreadEx = NULL;// 打开注入进程,获取进程句柄hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);if (NULL == hProcess){ShowError("OpenProcess");bRet = FALSE;goto exit;}// 在注入进程中申请可以容纳DLL完成路径名的内存空间dwSize = 1 + strlen(szDllName);pDllPathAddr = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);if (!pDllPathAddr){ShowError("VirtualAllocEx");bRet = FALSE;goto exit;}// 把DLL完成路径名写入进程中if (!WriteProcessMemory(hProcess, pDllPathAddr, szDllName, dwSize, NULL)){ShowError("WriteProcessMemory");bRet = FALSE;goto exit;}hKernel32 = LoadLibrary("kernel32.dll");if (hKernel32 == NULL){ShowError("LoadLibrary kernel32");bRet = FALSE;goto exit;}// 获取LoadLibraryA函数地址pLoadLibraryAddr = GetProcAddress(hKernel32, "LoadLibraryA");if (pLoadLibraryAddr == NULL){ShowError("GetProcAddress LoadLibraryA");bRet = FALSE;goto exit;}hNtDll = LoadLibrary("ntdll.dll");if (hNtDll == NULL){ShowError("LoadLibrary ntdll");bRet = FALSE;goto exit;}ZwCreateThreadEx = (pFnZwCreateThreadEx)GetProcAddress(hNtDll, "ZwCreateThreadEx");if (!ZwCreateThreadEx){ShowError("GetProcAddress ZwCreateThreadEx");bRet = FALSE;goto exit;}ZwCreateThreadEx(&hRemoteThread, PROCESS_ALL_ACCESS, NULL,hProcess, (LPTHREAD_START_ROUTINE)pLoadLibraryAddr,pDllPathAddr, 0, 0, 0, 0, NULL);if (hRemoteThread == NULL){ShowError("ZwCreateThreadEx");bRet = FALSE;goto exit;}exit:if (hKernel32) FreeLibrary(hKernel32);if (hNtDll) FreeLibrary(hNtDll);if (hProcess) CloseHandle(hProcess);if (hRemoteThread) CloseHandle(hRemoteThread);return bRet;}
5
APC注入
DWORD WINAPI QueueUserAPC(__in PAPCFUNC pfnAPC,__in HANDLE hThread,__in ULONG_PTR dwData);
BOOL InjectDll(DWORD dwPid, CHAR szDllName[]){BOOL bRet = TRUE;HANDLE hProcess = NULL, hThread = NULL, hSnap = NULL;HMODULE hKernel32 = NULL;DWORD dwSize = 0;PVOID pDllPathAddr = NULL;PVOID pLoadLibraryAddr = NULL;THREADENTRY32 te32 = { 0 };// 打开注入进程,获取进程句柄hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);if (NULL == hProcess){ShowError("OpenProcess");bRet = FALSE;goto exit;}// 在注入进程中申请可以容纳DLL完成路径名的内存空间dwSize = 1 + strlen(szDllName);pDllPathAddr = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);if (!pDllPathAddr){ShowError("VirtualAllocEx");bRet = FALSE;goto exit;}// 把DLL完成路径名写入进程中if (!WriteProcessMemory(hProcess, pDllPathAddr, szDllName, dwSize, NULL)){ShowError("WriteProcessMemory");bRet = FALSE;goto exit;}hKernel32 = LoadLibrary("kernel32.dll");if (hKernel32 == NULL){ShowError("LoadLibrary");bRet = FALSE;goto exit;}// 获取LoadLibraryA函数地址pLoadLibraryAddr = GetProcAddress(hKernel32, "LoadLibraryA");if (pLoadLibraryAddr == NULL){ShowError("GetProcAddress");bRet = FALSE;goto exit;}//获得线程快照hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);if (!hSnap){ShowError("CreateToolhelp32Snapshot");bRet = FALSE;goto exit;}//遍历线程te32.dwSize = sizeof(te32);if (Thread32First(hSnap, &te32)){do{//这个线程的进程ID是不是要注入的进程的PIDif (te32.th32OwnerProcessID == dwPid){hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, te32.th32ThreadID);if (hThread){QueueUserAPC((PAPCFUNC)pLoadLibraryAddr, hThread, (ULONG_PTR)pDllPathAddr);CloseHandle(hThread);hThread = NULL;}else{ShowError("OpenThread");bRet = FALSE;goto exit;}}} while (Thread32Next(hSnap, &te32));}exit:if (hKernel32) FreeLibrary(hKernel32);if (hProcess) CloseHandle(hProcess);if (hThread) CloseHandle(hThread);return bRet;}
6
AppInit_DLLs注入
BOOL InjectDll(DWORD dwPid, CHAR szDllName[]){BOOL bRet = TRUE;HKEY hKey = NULL;CHAR szAppKeyName[] = { "AppInit_DLLs" };CHAR szLoadAppKeyName[] = { "LoadAppInit_DLLs" };DWORD dwLoadAppInit = 1; //设置LoadAppInit_DLLs的值//打开相应注册表键if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows",0, KEY_ALL_ACCESS, &hKey) != ERROR_SUCCESS){ShowError("RegOpenKeyEx");bRet = FALSE;goto exit;}//设置AppInit_DLLs为相应的DLL路径if (RegSetValueEx(hKey, szAppKeyName, 0, REG_SZ, (PBYTE)szDllName, strlen(szDllName) + 1) != ERROR_SUCCESS){ShowError("RegSetValueEx");bRet = FALSE;goto exit;}//将LoadAppInit_DLLs的值设为1if (RegSetValueEx(hKey, szLoadAppKeyName, 0, REG_DWORD, (PBYTE)&dwLoadAppInit, sizeof(dwLoadAppInit)) != ERROR_SUCCESS){ShowError("RegSetValueEx");bRet = FALSE;goto exit;}exit:return bRet;}
7
全局钩子注入
HHOOK SetWindowsHookEx(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId);extern HMODULE g_hDllModule;// 设置全局钩子BOOL SetGlobalHook(){g_hHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)GetMsgProc, g_hDllModule, 0);if (NULL == g_hHook){return FALSE;}return TRUE;}
// 钩子回调函数LRESULT GetMsgProc(int code,WPARAM wParam,LPARAM lParam){return CallNextHookEx(g_hHook, code, wParam, lParam);}
// 卸载钩子BOOL UnSetGlobalHook(){if (g_hHook){UnhookWindowsHookEx(g_hHook);}return TRUE;}
// 共享内存#pragma data_seg("mydata")HHOOK g_hHook = NULL;#pragma data_seg()#pragma comment(linker, "/SECTION:mydata,RWS")
BOOL InjectDll(DWORD dwPid, CHAR szDllName[]){BOOL bRet = TRUE;HMODULE hDll = NULL;pFnSetGlobalHook SetGlobalHook = NULL;pFnUnSetGlobalHook UnSetGlobalHook = NULL;hDll = LoadLibrary(szDllName);if (hDll == NULL){ShowError("LoadLibrary");bRet = FALSE;goto exit;}SetGlobalHook = (pFnSetGlobalHook)GetProcAddress(hDll, "SetGlobalHook");if (SetGlobalHook == NULL){ShowError("GetProcAddress SetGlobalHook");bRet = FALSE;goto exit;}if (!SetGlobalHook()){printf("钩子安装失败\n");bRet = FALSE;goto exit;}printf("钩子安装成功,按回车卸载钩子\n");system("pause");UnSetGlobalHook = (pFnUnSetGlobalHook)GetProcAddress(hDll, "UnSetGlobalHook");if (UnSetGlobalHook == NULL){ShowError("GetProcAddress UnSetGlobalHook");bRet = FALSE;goto exit;}if (UnSetGlobalHook()){printf("已将全局钩子卸载\n");}exit:return bRet;}
8
实验结果
看雪ID:1900
https://bbs.pediy.com/user-home-835440.htm
# 往期推荐
5.进程隐藏技术
球分享
球点赞
球在看
点击“阅读原文”,了解更多!