流沙团
[转]注入小结
2018-1-24 流沙团



一.Windows消息钩取:SetWindowsHookEx



HHOOK SetWindowsHookEx(



intidHook,// hook type 就是HOOK的消息种类,如WH_KEYBOARD,WH_MOUSE....见MSDN



HOOKPROClpfn,// hook procedure 钩子过程,安装消息钩子时候,钩子过程一定要位于某个DLL内部



HINSTANCEhMod,// handle to application instance 钩子过程的DLL句柄(为NULL则是局部钩子)



DWORDdwThreadId // thread identifie想要挂上钩子的线程ID(为NULL则为全局钩子)



);   



把SetWindowsHookEx的钩子过程放在DLL中(SetWindowsHookEx本身可以放在DLL内部外部都可以)这样只要有消息事件发生,就会自动把Dll加载至目标进程,这样加载时候DllMain可以获取目标进程的句柄。



不用之后要卸载Hook,调用API,  UnhookWindowsHookEx(SetWindowsHookEx返回的句柄)



HookMain:








[cpp] view plain copy







  1. #include "stdio.h"  


  2. #include "conio.h"  


  3. #include "windows.h"  


  4.   


  5. #define DEF_DLL_NAME "KeyHook.dll"  


  6. #define DEF_HOOKSTART "HookStart"  


  7. #define DEF_HOOKSTOP "HookStop"  


  8.   


  9. typedef void(*PFN_HOOKSTART)();  


  10. typedef void(*PFN_HOOKSTOP)();  


  11.   


  12. void main()  


  13. {  


  14.     HMODULE hDll = NULL;  


  15.     PFN_HOOKSTART HookStart = NULL;  


  16.     PFN_HOOKSTOP HookStop = NULL;  


  17.     char ch = 0;  


  18.   


  19.     hDll = LoadLibraryA(DEF_DLL_NAME);  


  20.   


  21.     HookStart = (PFN_HOOKSTART)GetProcAddress(hDll, DEF_HOOKSTART);  


  22.     HookStop = (PFN_HOOKSTOP)GetProcAddress(hDll, DEF_HOOKSTOP);  


  23.   


  24.     HookStart();  


  25.   


  26.     printf("press 'q' to quit!\n");  


  27.     while (_getch() != 'q');  


  28.   


  29.     HookStop();  


  30.   


  31.     FreeLibrary(hDll);  


  32. }  






HookDll:





[cpp] view plain copy







  1. #include <stdio.h>  


  2. #include <windows.h>  


  3.   


  4. #define DEF_PROCESS_NAME "notepad.exe"  


  5.   


  6. HINSTANCE g_hInstance = NULL;  


  7. HHOOK g_hHook = NULL;  


  8. HWND g_hWnd = NULL;  


  9.   


  10. BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD dwReason, LPVOID lpvReserved)  


  11. {  


  12.     switch (dwReason)  


  13.     {  


  14.     case DLL_PROCESS_ATTACH:  


  15.         g_hInstance = hinstDll;  


  16.         break;  


  17.   


  18.     case DLL_PROCESS_DETACH:  


  19.         break;  


  20.     }  


  21.     return TRUE;  


  22. }  


  23.   


  24. LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)  


  25. {  


  26.     char szPath[MAX_PATH] = { 0 };  


  27.     char *p = NULL;  


  28.   


  29.     if (nCode >= 0)  


  30.     {  


  31.         if (!(lParam & 0x80000000))  


  32.         {  


  33.             GetModuleFileNameA(NULL, szPath, MAX_PATH);  


  34.             p = strrchr(szPath, '\\');  


  35.   


  36.             if (!_stricmp(p + 1, DEF_PROCESS_NAME))  


  37.                 return 1;  


  38.         }  


  39.     }  


  40.     return CallNextHookEx(g_hHook, nCode, wParam, lParam);  


  41. }  


  42.   


  43. #ifdef __cplusplus  


  44. extern "C" {  


  45. #endif  


  46.   


  47.     __declspec(dllexportvoid HookStart()  


  48.     {  


  49.         g_hHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hInstance, 0);  


  50.     }  


  51.     __declspec(dllexportvoid HookStop()  


  52.     {  


  53.         if (g_hHook)  


  54.         {  


  55.             UnhookWindowsHookEx(g_hHook);  


  56.             g_hHook = NULL;  


  57.         }  


  58.     }  


  59.   


  60. #ifdef __cplusplus  


  61. }  


  62. #endif  








二.创建远程线程注入Dll(CreateRemoteThread)



dll注入原理就是从外部使目标进程调用LoadLibrary()来加载Dll



      步骤:



1.OpenProcess来获取目标进程的进程句柄



2.VirtualAllocEx来在目标进程中分配要注入的DLL路径名长度大小的空间



3.WriteProcessMemory在目标进程分配的空间进行写入DLL路径(相当于)



4.GetModuleHandle + GetProcAddress获取LoadLibrary的地址(因为kernel32.dll加载的地址一样,所以目标进程一样可以加载)



5.CreateRemoteThread在目标进程运行LoadLibrary加载Dll,VirtualAllocEx分配空间为LoadLibrary的参数



6.DllMain中再CreateThread来创建线程干自己想干的事



注入Main程序:








[cpp] view plain copy







  1. #include<windows.h>  


  2. #include<stdio.h>  


  3. #include"tchar.h"  


  4.   


  5. BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath);  


  6.   


  7. int _tmain(int argc, TCHAR *argv[])  


  8. {  


  9.     if (argc != 3)  


  10.     {  


  11.         _tprintf(TEXT("%s参数不足"), argv[0]);  


  12.         getchar();  


  13.         return 1;  


  14.     }  


  15.       


  16.     if (InjectDll((DWORD)_tstol(argv[1]), argv[2]))  


  17.     {  


  18.         _tprintf(TEXT("InjectDll %s success!!!\n"), argv[2]);  


  19.     }  


  20.     else  


  21.     {  


  22.         _tprintf(TEXT("InjectDll %s failed!!!\n"), argv[2]);  


  23.     }  


  24.     getchar();  


  25.     return 0;  


  26. }  


  27.   


  28.   


  29. BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath)  


  30. {  


  31.     HANDLE hProcess = NULL, hThread = NULL;  


  32.     HMODULE hMod = NULL;  


  33.     LPVOID pRemoteBuf = NULL;  


  34.     DWORD dwBufSize = (DWORD)((_tcslen(szDllPath) + 1) * sizeof(TCHAR));  


  35.     LPTHREAD_START_ROUTINE pThreadProc;  


  36.   


  37.     if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))                        //以PROCESS_ALL_ACCESS打开进程获取句柄  


  38.     {  


  39.         _tprintf(TEXT("OpenProcess %d PID failed!!! [%d]\n"), dwPID,GetLastError());  


  40.         return FALSE;  


  41.     }  


  42.   


  43.     pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);     //在目标进程中分配dll路径长度的内存空间返回到pRemoteBuf  


  44.   


  45.     WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllPath, dwBufSize, NULL);           //在目标进程中写入进程的路径  


  46.   


  47.     hMod = GetModuleHandle(TEXT("kernel32.dll"));                                           //获取kernel32.dll的模块地址(每个进程这个地址都一样)  


  48.     pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, TEXT("LoadLibraryA"));       //LoadLibraryA  


  49.     if (NULL == pThreadProc)  


  50.     {  


  51.         _tprintf(TEXT("GetLastError = [%d]\n"), GetLastError());  


  52.         return FALSE;  


  53.     }  


  54.   


  55.     hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);      //用远程线程在目标进程创建出线程来调用LoadLibrary  


  56.     if (NULL == hThread)      


  57.     {  


  58.         _tprintf(TEXT("GetLastError = [%d]\n"), GetLastError());  


  59.     }  


  60.     WaitForSingleObject(hThread, INFINITE);  


  61.     CloseHandle(hThread);  


  62.     CloseHandle(hProcess);  


  63.   


  64.     return TRUE;  


  65. }  






注入的Dll:








[cpp] view plain copy







  1. #include<windows.h>  


  2. #include "tchar.h"  


  3.   


  4. #pragma comment(lib,"urlmon.lib")  


  5.   


  6. #define DEF_FILE_NAME (TEXT("index.html"))  


  7. #define DEF_URL (TEXT("http://www/naver.com/index.html"))  


  8.   


  9.   


  10. HMODULE g_hMod = NULL;  


  11.   


  12. DWORD WINAPI ThreadProc(LPVOID lParam)                                          //线程函数,实现功能  


  13. {  


  14.     TCHAR szPath[MAX_PATH] = { 0 };  


  15.     if (!GetModuleFileName(g_hMod, szPath, MAX_PATH))  


  16.         return FALSE;  


  17.   


  18.     TCHAR *p = _tcsrchr(szPath, '\\');  


  19.     if (!p)  


  20.         return FALSE;  


  21.   


  22.     _tcscpy_s(p + 1, MAX_PATH, DEF_FILE_NAME);  


  23.   


  24.     URLDownloadToFile(NULL, DEF_URL, szPath, 0, NULL);  


  25.   


  26.     return 0;  


  27. }  


  28.   


  29. BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)  


  30. {  


  31.     HANDLE hThread = NULL;  


  32.     g_hMod = (HMODULE)hinstDLL;  


  33.   


  34.     switch (fdwReason)  


  35.     {  


  36.     case DLL_PROCESS_ATTACH:  


  37.         MessageBox(NULL,TEXT("注入成功!"),TEXT("Success!"),NULL);  


  38.         hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);         //DLL中创建线程  


  39.         CloseHandle(hThread);  


  40.         break;  


  41.     }  


  42.   


  43.     return TRUE;  


  44. }  








三,使用注册表



   原理:User32.dll加载时候会读取AppInit_DLLs,若有值则会LoadLibrary加载用户DLL



在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows



1.要注入的DLL路径写入AppInit_DLLs中



2.把LoadAppInit_DLLs注册表项的值设为1








这样DLL就会注入到所有加载user32.dll的进程








四,Dll卸载(只适用于自己注入的DLL,PE记载的不能卸载)




原理:使目标去调用FreeLibrary去卸载DLL



过程:



1.遍历进程查找获得对应程序的PID(CreateToolhelp32Snapshot-》PROCESSENTRY32)



2.提高进程权限(获取进程访问的令牌句柄OpenProcessToken -> 获取对应权限的LUID(LookupPrivilegevalue)->改变令牌权限(AdjustTokenPrivileges))



3.查找目标进程的模板(CreateToolhelp32Snapshot-》MODULEENTRY32),获取对应的DLL的handle



4.用CreateRemoteThread来调用FreeLibrary去卸载注入DLL








[cpp] view plain copy







  1. #include<stdio.h>  


  2. #include<windows.h>  


  3. #include<tlhelp32.h>  


  4. #include<tchar.h>  


  5.   


  6. DWORD FindProcessID(LPCTSTR szProcessName);  


  7. BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege);  


  8. BOOL EjectDll(DWORD dwPID, LPCTSTR szDllName);  


  9. #define DEF_PROC_NAME (TEXT("notepad.exe"))  


  10. #define DEF_DLL_NAME (TEXT("myhack.dll"))  


  11.   


  12. int _tmain()  


  13. {  


  14.     DWORD dwPID = 0xFFFFFFFF;  


  15.       


  16.     dwPID = FindProcessID(DEF_PROC_NAME);  


  17.     if (dwPID == 0XFFFFFFFF)  


  18.     {  


  19.         _tprintf(TEXT("没有找到这个process"));  


  20.         getchar();  


  21.         return 1;  


  22.     }  


  23.   


  24.     _tprintf(TEXT("PID of \"%s\" is %d\n"), DEF_PROC_NAME, dwPID);  


  25.   


  26.     if (!SetPrivilege(SE_DEBUG_NAME, TRUE))  


  27.     {  


  28.         getchar();  


  29.         return 1;  


  30.     }  


  31.   


  32.     if (EjectDll(dwPID, DEF_DLL_NAME))  


  33.     {  


  34.         _tprintf(TEXT("EjectDll(%d  \"%s\") success!!!\n"), dwPID, DEF_DLL_NAME);  


  35.     }  


  36.     else  


  37.     {  


  38.         _tprintf(TEXT("EjectDll(%d  \"%s\") falied!!!\n"), dwPID, DEF_DLL_NAME);  


  39.     }  


  40.   


  41.     getchar();  


  42.     return 0;  


  43. }  


  44.   


  45.   


  46. DWORD FindProcessID(LPCTSTR szProcessName)                            


  47. {  


  48.     DWORD dwPID = 0XFFFFFFFF;  


  49.     HANDLE hSnapshot = INVALID_HANDLE_VALUE;  


  50.     PROCESSENTRY32 pe;  


  51.   


  52.     pe.dwSize = sizeof(PROCESSENTRY32);  


  53.     hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL,NULL);      //获取进程的句柄  


  54.   


  55.     Process32First(hSnapshot,&pe);                                  //获取指定进程名的PID  


  56.     do  


  57.     {  


  58.         if (!_tcsicmp(pe.szExeFile, DEF_PROC_NAME))  


  59.         {  


  60.             dwPID = pe.th32ProcessID;  


  61.             break;  


  62.         }  


  63.     } while (Process32Next(hSnapshot, &pe));  


  64.   


  65.     CloseHandle(hSnapshot);  


  66.   


  67.     return dwPID;  


  68.       


  69. }  


  70. BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)     //提升程序权限  


  71. {  


  72.     TOKEN_PRIVILEGES tp;  


  73.     HANDLE hToken;  


  74.     LUID luid;  


  75.   


  76.     if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))     //获取令牌句柄  


  77.     {  


  78.         _tprintf(TEXT("OpenProcessToken error : %u\n"), GetLastError());  


  79.         return FALSE;  


  80.     }  


  81.           


  82.     LookupPrivilegeValue(NULL,lpszPrivilege,&luid);                                                 //获取指定权限的LUID  


  83.   


  84.     tp.PrivilegeCount = 1;  


  85.     tp.Privileges[0].Luid = luid;  


  86.     if (bEnablePrivilege)  


  87.         tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;                                       


  88.     else  


  89.         tp.Privileges[0].Attributes = 0;  


  90.   


  91.     if (!AdjustTokenPrivileges(hToken,          //令牌句柄  


  92.                                 FALSE,          //FALSE则修改权限  


  93.                                   &tp,          //令牌权限的结构(包括LUID和tp中的数组个数吗)  


  94.              sizeof(TOKEN_PRIVILEGES),   


  95.               (PTOKEN_PRIVILEGES)NULL,    


  96.                         (PDWORD)NULL))  


  97.     {  


  98.         _tprintf(TEXT("AdjustTokenPrivileges error : %u\n"), GetLastError());  


  99.         return FALSE;  


  100.     }                                                                                           //调整进程的权限  


  101.   


  102.     if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)  


  103.     {  


  104.         _tprintf(TEXT("The Token does not have the specified privilege. \n"));  


  105.         return FALSE;  


  106.     }  


  107.   


  108.     return TRUE;  


  109. }  


  110.   


  111.   


  112. BOOL EjectDll(DWORD dwPID, LPCTSTR szDllName)  


  113. {  


  114.     BOOL bMore = FALSE, bFound = FALSE;  


  115.     HANDLE hSnapshot, hProcess, hThread;  


  116.     HMODULE hModule = NULL;  


  117.     MODULEENTRY32 me = { sizeof(me) };  


  118.     LPTHREAD_START_ROUTINE pThreadProc;  


  119.   


  120.     hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL,dwPID);         //获取寻找到的模块表的模块列表  


  121.     bMore = Module32First(hSnapshot, &me);                              //查找是否有myhack.dll这个dll模块,并且模块dll的名字保存在me结构体中  


  122.     for (; bMore; bMore = Module32Next(hSnapshot, &me))  


  123.     {  


  124.         if (!_tcsicmp((LPCTSTR)me.szExePath, szDllName) | !_tcsicmp((LPCTSTR)me.szModule, szDllName))  


  125.         {  


  126.             bFound = TRUE;  


  127.             break;  


  128.         }  


  129.     }  


  130.   


  131.     if (!bFound)  


  132.     {  


  133.         CloseHandle(hSnapshot);  


  134.         return FALSE;  


  135.     }  


  136.   


  137.     if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))                        //获得进程的句柄  


  138.     {  


  139.         _tprintf(TEXT("OpenProcess falied"));  


  140.         return FALSE;  


  141.     }     


  142.     hModule = GetModuleHandle(TEXT("kernel32.dll"));                                        //获得kernel.dll中的FreeLibrary函数地址  


  143.     pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hModule,TEXT("FreeLibrary"));      //找到ProcAddress  


  144.     hThread = CreateRemoteThread(hProcess,NULL,0,pThreadProc,me.modBaseAddr,0,NULL);          


  145.     WaitForSingleObject(hThread, INFINITE);  


  146.     CloseHandle(hThread);  


  147.     CloseHandle(hProcess);  


  148.     CloseHandle(hSnapshot);  


  149.   


  150.     return TRUE;  


  151. }  






五,修改PE来加载DLL



原理:修改导入表来实现加载DLL



   步骤:



1.查看IDT(IMPORT Directory Table)是否有足够空间来增加一个新的IID



2.有足够空间就直接新增一个IID并修改导入表的SIZE(没有足够空间就转移导入表并修改导入表的RVA以及SIZE)



3.将新增的IID的INT 和 IAT以及NAME都修改



4.删除BOUND IMPORT表



5.修改导入表的节区属性可写



6.不修改导入表节区属性可以将新增的IID的FirstThunk改为IAT的末尾地址



DLL代码:





[cpp] view plain copy







  1. #include<windows.h>  


  2. #include<string.h>  


  3. #include<tchar.h>  


  4.   


  5. BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)  


  6. {  


  7.     switch (fdwReason)  


  8.     {  


  9.     case DLL_PROCESS_ATTACH:  


  10.         MessageBox(NULL,TEXT("注入成功"),TEXT("Success!"),MB_OK);  


  11.         break;  


  12.   


  13.     default:  


  14.         break;  


  15.     }  


  16.     return TRUE;  


  17. }  


  18.   


  19. #ifdef __cplusplus  


  20. extern "C" {  


  21. #endif  


  22.     _declspec(dllexportvoid Fun()                     //无意义的函数只为了PE格式  


  23.     {  


  24.         return;  


  25.     }  


  26. #ifdef __cplusplus  


  27. }  


  28. #endif  






强行导入一个Fun是为了保存完整性,能够加载DLL













六,代码注入



与DLL注入不一样,代码注入仅向目标进程注入必要的代码而不是整个DLL



原理:用一个结构体来保存要注入代码使用的API地址(一般是user32.dll中的)以及所需要用到的数据(如MessageBoxA函数所需要的信息框名字和标题),并将这个结构体也注入进目标进程,再将线程过程代码都注入进目标进程。(一样利用OpenProcess -> VirtualAllocEx -> WriteProcessMemory -> CreateRemoteThread)











[cpp] view plain copy







  1. #include<windows.h>  


  2. #include<stdio.h>  


  3. #include<string.h>  


  4.   


  5. DWORD WINAPI ThreadProc(LPVOID lParam);  


  6. BOOL CodeInject(DWORD dwPID);  


  7. typedef struct _THREAD_PARAM  


  8. {  


  9.     FARPROC pFun[2];        //GetProcAddress() 和 LoadLibraryA()的地址  


  10.     char szBuf[4][128];     //二维数组,表示四个参数“user32.dll”,“MessageBoxA”,“内容”,“标题”  


  11. }THREAD_PARAM, *PTHREAD_PARAM;  


  12.   


  13. typedef HMODULE (WINAPI *PFAR_LOADLIBRARYA)  


  14. (  


  15.     LPCSTR lpLibFileName  


  16. );  


  17.   


  18. typedef HMODULE(WINAPI *PFAR_GETPROCADDRESS)  


  19. (  


  20.     HMODULE hModule,  


  21.     LPCSTR lpProcName  


  22. );  


  23.   


  24. typedef int (WINAPI *PFMESSAGEBOXA)  


  25. (  


  26.     HWND hWnd,  


  27.     LPCSTR lpText,  


  28.     LPCTSTR lpCaption,  


  29.     UINT type  


  30. );  


  31.   


  32. int main(int argc, char *argv[])  


  33. {  


  34.     DWORD dwPID = 0;  


  35.       


  36.     if (argc != 2)  


  37.     {  


  38.         printf("请输入要注入程序的PID!\n");  


  39.         getchar();  


  40.         return 1;  


  41.     }  


  42.   


  43.     dwPID = (DWORD)atol(argv[1]);  


  44.     CodeInject(dwPID);  


  45.   


  46.     return 0;  


  47. }  


  48.   


  49. DWORD WINAPI ThreadProc(LPVOID lParam)  


  50. {  


  51.     PTHREAD_PARAM pParam = (PTHREAD_PARAM)lParam;  


  52.     HMODULE hMod = NULL;  


  53.     FARPROC pFunc = NULL;  


  54.   


  55.     //pParam->pFun[0] 是 LoadLibraryA  


  56.     //pParam->szBuf[0] 是 "user32.dll"  


  57.     hMod = ((PFAR_LOADLIBRARYA)pParam->pFun[0])(pParam->szBuf[0]);  


  58.   


  59.     pFunc = (FARPROC)((PFAR_GETPROCADDRESS)pParam->pFun[1])(hMod,pParam->szBuf[1]);  


  60.   


  61.     ((PFMESSAGEBOXA)pFunc)(NULL, pParam->szBuf[2], pParam->szBuf[3], MB_OK);  


  62.   


  63.     return 0;  


  64. }  


  65.   


  66. BOOL CodeInject(DWORD dwPID)  


  67. {  


  68.      HMODULE hMod = NULL;  


  69.      HANDLE hProcess = NULL;  


  70.      HANDLE hThread = NULL;  


  71.      DWORD dwSIZE = 0;  


  72.      THREAD_PARAM param = {0};  


  73.      LPVOID pRemoteBuf[2] = {0};  


  74.       


  75.     hMod = GetModuleHandleA("kernel32.dll");  


  76.   


  77.     //初始化结构体pParam  


  78.     param.pFun[0] = GetProcAddress(hMod, "LoadLibraryA");  


  79.     param.pFun[1] = GetProcAddress(hMod, "GetProcAddress");  


  80.     strcpy_s(param.szBuf[0],sizeof("user32.dll"),"user32.dll");  


  81.     strcpy_s(param.szBuf[1], sizeof("MessageBoxA"),"MessageBoxA");  


  82.     strcpy_s(param.szBuf[2], sizeof("Inject Success!"),"Inject Success!");  


  83.     strcpy_s(param.szBuf[3], sizeof("Success!"),"Success!");  


  84.   


  85.   


  86.     //获取进程句柄  


  87.     hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwPID);  


  88.   


  89.     //分配内存空间  


  90.     dwSIZE = sizeof(THREAD_PARAM);  


  91.     pRemoteBuf[0] = VirtualAllocEx(hProcess,  


  92.                                     NULL,                   //为NULL不指定具体分配哪个地址  


  93.                                     dwSIZE,                 //分配空间的大小  


  94.                                     MEM_COMMIT,  


  95.                                     PAGE_READWRITE);  


  96.   


  97.     WriteProcessMemory(hProcess,  


  98.                        pRemoteBuf[0],  


  99.                        (LPVOID)¶m,  


  100.                        dwSIZE,  


  101.                         NULL);    //指定写入指定进程的字节数,为NULL则忽略  


  102.   


  103.     dwSIZE = (DWORD)CodeInject - (DWORD)ThreadProc;         //两个函数地址相减,一定要在Release下优化编译!!!!!!!  


  104.     pRemoteBuf[1] = VirtualAllocEx(hProcess,  


  105.                                     NULL,   


  106.                                     dwSIZE,  


  107.                                     MEM_COMMIT,   


  108.                                     PAGE_EXECUTE_READWRITE);  


  109.   


  110.     WriteProcessMemory(hProcess,pRemoteBuf[1],(LPVOID)ThreadProc,dwSIZE,NULL);  


  111.   


  112.     hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pRemoteBuf[1], pRemoteBuf[0], 0, NULL);  


  113.     WaitForSingleObject(hThread, INFINITE);  


  114.     CloseHandle(hThread);  


  115.     CloseHandle(hProcess);  


  116.   


  117.     return TRUE;  


  118. }  









七,汇编代码注入



原理:将汇编代码的注入部分(CreateRemoteThread的传入的过程代码)用十六进制保存,再传入一个结构体(CreateRemoteThread的传入的参数),结构体有LoadLibrary和GetProcAddress两个API的地址,再在汇编代码中进行调用这个结构体这两个地址。








[cpp] view plain copy







  1. #include<windows.h>  


  2. #include<stdio.h>  


  3.   


  4. BOOL InjectCode(DWORD dwPID);  


  5. BYTE g_InjectionCode[] = {  


  6.     0x55,0x8B,0xEC,0x8B,0x75,0x08,0x68,0x6C,  


  7.     0x6C,0x00,0x00,0x68,0x33,0x32,0x2E,0x64,  


  8.     0x68,0x75,0x73,0x65,0x72,0x54,0xFF,0x16,  


  9.     0x68,0x6F,0x78,0x41,0x00,0x68,0x61,0x67,  


  10.     0x65,0x42,0x68,0x4D,0x65,0x73,0x73,0x54,  


  11.     0x50,0xFF,0x56,0x04,0x6A,0x00,0xE8,0x0C,  


  12.     0x00,0x00,0x00,0x52,0x65,0x76,0x65,0x72,  


  13.     0x73,0x65,0x43,0x6F,0x72,0x65,0x00,0xE8,  


  14.     0x14,0x00,0x00,0x00,0x77,0x77,0x77,0x2E,  


  15.     0x72,0x65,0x76,0x65,0x72,0x73,0x65,0x63,  


  16.     0x6F,0x72,0x65,0x2E,0x63,0x6F,0x6D,0x00,  


  17.     0x6A,0x00,0xFF,0xD0,0x33,0xC0,0x8B,0xE5,  


  18.     0x5D,0xC3  


  19. };  


  20.   


  21. typedef struct _THREAD_PARAM  


  22. {  


  23.     FARPROC pFunc[2];  


  24. }THREAD_PARAM, *PTHREAD_PARAM;  


  25.   


  26. int main()  


  27. {  


  28.     DWORD dwPID = 12056;  


  29.   


  30.     InjectCode(dwPID);  


  31.     getchar();  


  32.     return 0;  


  33. }  


  34.   


  35. BOOL InjectCode(DWORD dwPID)  


  36. {  


  37.     HMODULE         hMod = NULL;  


  38.     THREAD_PARAM    param = { 0, };  


  39.     HANDLE          hProcess = NULL;  


  40.     HANDLE          hThread = NULL;  


  41.     LPVOID          pRemoteBuf[2] = { 0, };  


  42.   


  43.     hMod = GetModuleHandleA("kernel32.dll");  


  44.   


  45.     // set THREAD_PARAM  


  46.     param.pFunc[0] = GetProcAddress(hMod, "LoadLibraryA");  


  47.     param.pFunc[1] = GetProcAddress(hMod, "GetProcAddress");  


  48.   


  49.     // Open Process  


  50.     if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS,               // dwDesiredAccess  


  51.         FALSE,                            // bInheritHandle  


  52.         dwPID)))                         // dwProcessId  


  53.     {  


  54.         printf("OpenProcess() fail : err_code = %d\n", GetLastError());  


  55.         return FALSE;  


  56.     }  


  57.   


  58.     // Allocation for THREAD_PARAM  


  59.     if (!(pRemoteBuf[0] = VirtualAllocEx(hProcess,                  // hProcess  


  60.         NULL,                      // lpAddress  


  61.         sizeof(THREAD_PARAM),      // dwSize  


  62.         MEM_COMMIT,                // flAllocationType  


  63.         PAGE_READWRITE)))         // flProtect  


  64.     {  


  65.         printf("VirtualAllocEx() fail : err_code = %d\n", GetLastError());  


  66.         return FALSE;  


  67.     }  


  68.   


  69.     if (!WriteProcessMemory(hProcess,                               // hProcess  


  70.         pRemoteBuf[0],                          // lpBaseAddress  


  71.         (LPVOID)¶m,                         // lpBuffer  


  72.         sizeof(THREAD_PARAM),                   // nSize  


  73.         NULL))                                 // [out] lpNumberOfBytesWritten  


  74.     {  


  75.         printf("WriteProcessMemory() fail : err_code = %d\n", GetLastError());  


  76.         return FALSE;  


  77.     }  


  78.   


  79.     // Allocation for ThreadProc()  


  80.     if (!(pRemoteBuf[1] = VirtualAllocEx(hProcess,                  // hProcess  


  81.         NULL,                      // lpAddress  


  82.         sizeof(g_InjectionCode),   // dwSize  


  83.         MEM_COMMIT,                // flAllocationType  


  84.         PAGE_EXECUTE_READWRITE))) // flProtect  


  85.     {  


  86.         printf("VirtualAllocEx() fail : err_code = %d\n", GetLastError());  


  87.         return FALSE;  


  88.     }  


  89.   


  90.     if (!WriteProcessMemory(hProcess,                               // hProcess  


  91.         pRemoteBuf[1],                          // lpBaseAddress  


  92.         (LPVOID)&g_InjectionCode,               // lpBuffer  


  93.         sizeof(g_InjectionCode),                // nSize  


  94.         NULL))                                 // [out] lpNumberOfBytesWritten  


  95.     {  


  96.         printf("WriteProcessMemory() fail : err_code = %d\n", GetLastError());  


  97.         return FALSE;  


  98.     }  


  99.   


  100.     if (!(hThread = CreateRemoteThread(hProcess,                    // hProcess  


  101.         NULL,                        // lpThreadAttributes  


  102.         0,                           // dwStackSize  


  103.         (LPTHREAD_START_ROUTINE)pRemoteBuf[1],  


  104.         pRemoteBuf[0],               // lpParameter  


  105.         0,                           // dwCreationFlags  


  106.         NULL)))                     // lpThreadId  


  107.     {  


  108.         printf("CreateRemoteThread() fail : err_code = %d\n", GetLastError());  


  109.         return FALSE;  


  110.     }  


  111.   


  112.     WaitForSingleObject(hThread, INFINITE);  


  113.   


  114.     CloseHandle(hThread);  


  115.     CloseHandle(hProcess);  


  116.   


  117.     return TRUE;  


  118. }  






十六进制部分所代表的汇编代码:








[plain] view plain copy







  1. /*  


  2. 004010ED    55               PUSH EBP  


  3. 004010EE    8BEC             MOV EBP,ESP  


  4. 004010F0    8B75 08          MOV ESI,DWORD PTR SS:[EBP+8]       ; ESI = 结构体的地址,地址表示的是API所代表的地址             


  5. 004010F3    68 6C6C0000      PUSH 6C6C                        


  6. 004010F8    68 33322E64      PUSH 642E3233  


  7. 004010FD    68 75736572      PUSH 72657375<span style="white-space:pre">            </span>; 三行表示的是"user32.dll"逆序push  


  8. 00401102    54               PUSH ESP                           ; ESP表示的是 "user32.dll"字符串的首地址  


  9. 00401103    FF16             CALL DWORD PTR DS:[ESI]            ; 调用LoadLibraryA("user32.dll")  


  10. 00401105    68 6F784100      PUSH 41786F  


  11. 0040110A    68 61676542      PUSH 42656761  


  12. 0040110F    68 4D657373      PUSH 7373654D  


  13. 00401114    54               PUSH ESP                           ; - 字符串"MessageBoxA"的首地址  


  14. 00401115    50               PUSH EAX                           ; - 前面LoadLibrary所返回的hMod  


  15. 00401116    FF56 04          CALL DWORD PTR DS:[ESI+4]          ; - GetProcAddress(hMod, "MessageBoxA")  


  16. 00401119    6A 00            PUSH 0                             ; - MB_OK (0)  


  17. 0040111B    E8 0C000000      CALL 0040112C<span style="white-space:pre">            </span>; CALL后面的是ASCLL,CALL的意思是PUSH EIP,相当于PUSH了后面字符串的首地址  


  18. 00401120                     <ASCII>                            ; - "ReverseCore", 0  


  19. 0040112C    E8 14000000      CALL 00401145  


  20. 00401131                     <ASCII>                            ; - "www.reversecore.com", 0  


  21. 00401145    6A 00            PUSH 0                             ; - hWnd (0)  


  22. 00401147    FFD0             CALL EAX                           ; EAX是GetProcAddress所获得的地址存放在eax - MessageBoxA(0, "www.reversecore.com", "ReverseCore", 0)  


  23. 00401149    33C0             XOR EAX,EAX                      <span style="white-space:pre">    </span>; API结果要返回0 到EAX中   


  24. 0040114B    8BE5             MOV ESP,EBP  


  25. 0040114D    5D               POP EBP                            ; 清除堆栈  


  26. 0040114E    C3               RETN  


  27. */  









发表评论:
昵称

邮件地址 (选填)

个人主页 (选填)

内容