一.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 identifier 想要挂上钩子的线程ID(为NULL则为全局钩子)
);
把SetWindowsHookEx的钩子过程放在DLL中(SetWindowsHookEx本身可以放在DLL内部外部都可以),这样只要有消息事件发生,就会自动把Dll加载至目标进程,这样加载时候DllMain可以获取目标进程的句柄。
不用之后要卸载Hook,调用API, UnhookWindowsHookEx(SetWindowsHookEx返回的句柄)
HookMain:
- #include "stdio.h"
- #include "conio.h"
- #include "windows.h"
- #define DEF_DLL_NAME "KeyHook.dll"
- #define DEF_HOOKSTART "HookStart"
- #define DEF_HOOKSTOP "HookStop"
- typedef void(*PFN_HOOKSTART)();
- typedef void(*PFN_HOOKSTOP)();
- void main()
- {
- HMODULE hDll = NULL;
- PFN_HOOKSTART HookStart = NULL;
- PFN_HOOKSTOP HookStop = NULL;
- char ch = 0;
- hDll = LoadLibraryA(DEF_DLL_NAME);
- HookStart = (PFN_HOOKSTART)GetProcAddress(hDll, DEF_HOOKSTART);
- HookStop = (PFN_HOOKSTOP)GetProcAddress(hDll, DEF_HOOKSTOP);
- HookStart();
- printf("press 'q' to quit!\n");
- while (_getch() != 'q');
- HookStop();
- FreeLibrary(hDll);
- }
HookDll:
- #include <stdio.h>
- #include <windows.h>
- #define DEF_PROCESS_NAME "notepad.exe"
- HINSTANCE g_hInstance = NULL;
- HHOOK g_hHook = NULL;
- HWND g_hWnd = NULL;
- BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD dwReason, LPVOID lpvReserved)
- {
- switch (dwReason)
- {
- case DLL_PROCESS_ATTACH:
- g_hInstance = hinstDll;
- break;
- case DLL_PROCESS_DETACH:
- break;
- }
- return TRUE;
- }
- LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
- {
- char szPath[MAX_PATH] = { 0 };
- char *p = NULL;
- if (nCode >= 0)
- {
- if (!(lParam & 0x80000000))
- {
- GetModuleFileNameA(NULL, szPath, MAX_PATH);
- p = strrchr(szPath, '\\');
- if (!_stricmp(p + 1, DEF_PROCESS_NAME))
- return 1;
- }
- }
- return CallNextHookEx(g_hHook, nCode, wParam, lParam);
- }
- #ifdef __cplusplus
- extern "C" {
- #endif
- __declspec(dllexport) void HookStart()
- {
- g_hHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hInstance, 0);
- }
- __declspec(dllexport) void HookStop()
- {
- if (g_hHook)
- {
- UnhookWindowsHookEx(g_hHook);
- g_hHook = NULL;
- }
- }
- #ifdef __cplusplus
- }
- #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程序:
- #include<windows.h>
- #include<stdio.h>
- #include"tchar.h"
- BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath);
- int _tmain(int argc, TCHAR *argv[])
- {
- if (argc != 3)
- {
- _tprintf(TEXT("%s参数不足"), argv[0]);
- getchar();
- return 1;
- }
- if (InjectDll((DWORD)_tstol(argv[1]), argv[2]))
- {
- _tprintf(TEXT("InjectDll %s success!!!\n"), argv[2]);
- }
- else
- {
- _tprintf(TEXT("InjectDll %s failed!!!\n"), argv[2]);
- }
- getchar();
- return 0;
- }
- BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath)
- {
- HANDLE hProcess = NULL, hThread = NULL;
- HMODULE hMod = NULL;
- LPVOID pRemoteBuf = NULL;
- DWORD dwBufSize = (DWORD)((_tcslen(szDllPath) + 1) * sizeof(TCHAR));
- LPTHREAD_START_ROUTINE pThreadProc;
- if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID))) //以PROCESS_ALL_ACCESS打开进程获取句柄
- {
- _tprintf(TEXT("OpenProcess %d PID failed!!! [%d]\n"), dwPID,GetLastError());
- return FALSE;
- }
- pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE); //在目标进程中分配dll路径长度的内存空间返回到pRemoteBuf
- WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllPath, dwBufSize, NULL); //在目标进程中写入进程的路径
- hMod = GetModuleHandle(TEXT("kernel32.dll")); //获取kernel32.dll的模块地址(每个进程这个地址都一样)
- pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, TEXT("LoadLibraryA")); //LoadLibraryA
- if (NULL == pThreadProc)
- {
- _tprintf(TEXT("GetLastError = [%d]\n"), GetLastError());
- return FALSE;
- }
- hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL); //用远程线程在目标进程创建出线程来调用LoadLibrary
- if (NULL == hThread)
- {
- _tprintf(TEXT("GetLastError = [%d]\n"), GetLastError());
- }
- WaitForSingleObject(hThread, INFINITE);
- CloseHandle(hThread);
- CloseHandle(hProcess);
- return TRUE;
- }
注入的Dll:
- #include<windows.h>
- #include "tchar.h"
- #pragma comment(lib,"urlmon.lib")
- #define DEF_FILE_NAME (TEXT("index.html"))
- #define DEF_URL (TEXT("http://www/naver.com/index.html"))
- HMODULE g_hMod = NULL;
- DWORD WINAPI ThreadProc(LPVOID lParam) //线程函数,实现功能
- {
- TCHAR szPath[MAX_PATH] = { 0 };
- if (!GetModuleFileName(g_hMod, szPath, MAX_PATH))
- return FALSE;
- TCHAR *p = _tcsrchr(szPath, '\\');
- if (!p)
- return FALSE;
- _tcscpy_s(p + 1, MAX_PATH, 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:
- MessageBox(NULL,TEXT("注入成功!"),TEXT("Success!"),NULL);
- hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL); //DLL中创建线程
- CloseHandle(hThread);
- break;
- }
- return TRUE;
- }
三,使用注册表
原理: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
- #include<stdio.h>
- #include<windows.h>
- #include<tlhelp32.h>
- #include<tchar.h>
- DWORD FindProcessID(LPCTSTR szProcessName);
- BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege);
- BOOL EjectDll(DWORD dwPID, LPCTSTR szDllName);
- #define DEF_PROC_NAME (TEXT("notepad.exe"))
- #define DEF_DLL_NAME (TEXT("myhack.dll"))
- int _tmain()
- {
- DWORD dwPID = 0xFFFFFFFF;
- dwPID = FindProcessID(DEF_PROC_NAME);
- if (dwPID == 0XFFFFFFFF)
- {
- _tprintf(TEXT("没有找到这个process"));
- getchar();
- return 1;
- }
- _tprintf(TEXT("PID of \"%s\" is %d\n"), DEF_PROC_NAME, dwPID);
- if (!SetPrivilege(SE_DEBUG_NAME, TRUE))
- {
- getchar();
- return 1;
- }
- if (EjectDll(dwPID, DEF_DLL_NAME))
- {
- _tprintf(TEXT("EjectDll(%d \"%s\") success!!!\n"), dwPID, DEF_DLL_NAME);
- }
- else
- {
- _tprintf(TEXT("EjectDll(%d \"%s\") falied!!!\n"), dwPID, DEF_DLL_NAME);
- }
- getchar();
- return 0;
- }
- 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); //获取指定进程名的PID
- do
- {
- if (!_tcsicmp(pe.szExeFile, DEF_PROC_NAME))
- {
- 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)) //获取令牌句柄
- {
- _tprintf(TEXT("OpenProcessToken error : %u\n"), GetLastError());
- return FALSE;
- }
- LookupPrivilegeValue(NULL,lpszPrivilege,&luid); //获取指定权限的LUID
- tp.PrivilegeCount = 1;
- tp.Privileges[0].Luid = luid;
- if (bEnablePrivilege)
- tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- else
- tp.Privileges[0].Attributes = 0;
- if (!AdjustTokenPrivileges(hToken, //令牌句柄
- FALSE, //FALSE则修改权限
- &tp, //令牌权限的结构(包括LUID和tp中的数组个数吗)
- sizeof(TOKEN_PRIVILEGES),
- (PTOKEN_PRIVILEGES)NULL,
- (PDWORD)NULL))
- {
- _tprintf(TEXT("AdjustTokenPrivileges error : %u\n"), GetLastError());
- return FALSE;
- } //调整进程的权限
- if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
- {
- _tprintf(TEXT("The Token does not have the specified privilege. \n"));
- 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;
- hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL,dwPID); //获取寻找到的模块表的模块列表
- bMore = Module32First(hSnapshot, &me); //查找是否有myhack.dll这个dll模块,并且模块dll的名字保存在me结构体中
- for (; bMore; bMore = Module32Next(hSnapshot, &me))
- {
- if (!_tcsicmp((LPCTSTR)me.szExePath, szDllName) | !_tcsicmp((LPCTSTR)me.szModule, szDllName))
- {
- bFound = TRUE;
- break;
- }
- }
- if (!bFound)
- {
- CloseHandle(hSnapshot);
- return FALSE;
- }
- if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID))) //获得进程的句柄
- {
- _tprintf(TEXT("OpenProcess falied"));
- return FALSE;
- }
- hModule = GetModuleHandle(TEXT("kernel32.dll")); //获得kernel.dll中的FreeLibrary函数地址
- pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hModule,TEXT("FreeLibrary")); //找到ProcAddress
- hThread = CreateRemoteThread(hProcess,NULL,0,pThreadProc,me.modBaseAddr,0,NULL);
- WaitForSingleObject(hThread, INFINITE);
- CloseHandle(hThread);
- CloseHandle(hProcess);
- CloseHandle(hSnapshot);
- return TRUE;
- }
五,修改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代码:
- #include<windows.h>
- #include<string.h>
- #include<tchar.h>
- BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
- {
- switch (fdwReason)
- {
- case DLL_PROCESS_ATTACH:
- MessageBox(NULL,TEXT("注入成功"),TEXT("Success!"),MB_OK);
- break;
- default:
- break;
- }
- return TRUE;
- }
- #ifdef __cplusplus
- extern "C" {
- #endif
- _declspec(dllexport) void Fun() //无意义的函数只为了PE格式
- {
- return;
- }
- #ifdef __cplusplus
- }
- #endif
强行导入一个Fun是为了保存完整性,能够加载DLL
六,代码注入
与DLL注入不一样,代码注入仅向目标进程注入必要的代码而不是整个DLL
原理:用一个结构体来保存要注入代码使用的API地址(一般是user32.dll中的)以及所需要用到的数据(如MessageBoxA函数所需要的信息框名字和标题),并将这个结构体也注入进目标进程,再将线程过程代码都注入进目标进程。(一样利用OpenProcess -> VirtualAllocEx -> WriteProcessMemory -> CreateRemoteThread)
- #include<windows.h>
- #include<stdio.h>
- #include<string.h>
- DWORD WINAPI ThreadProc(LPVOID lParam);
- BOOL CodeInject(DWORD dwPID);
- typedef struct _THREAD_PARAM
- {
- FARPROC pFun[2]; //GetProcAddress() 和 LoadLibraryA()的地址
- char szBuf[4][128]; //二维数组,表示四个参数“user32.dll”,“MessageBoxA”,“内容”,“标题”
- }THREAD_PARAM, *PTHREAD_PARAM;
- typedef HMODULE (WINAPI *PFAR_LOADLIBRARYA)
- (
- LPCSTR lpLibFileName
- );
- typedef HMODULE(WINAPI *PFAR_GETPROCADDRESS)
- (
- HMODULE hModule,
- LPCSTR lpProcName
- );
- typedef int (WINAPI *PFMESSAGEBOXA)
- (
- HWND hWnd,
- LPCSTR lpText,
- LPCTSTR lpCaption,
- UINT type
- );
- int main(int argc, char *argv[])
- {
- DWORD dwPID = 0;
- if (argc != 2)
- {
- printf("请输入要注入程序的PID!\n");
- getchar();
- return 1;
- }
- dwPID = (DWORD)atol(argv[1]);
- CodeInject(dwPID);
- return 0;
- }
- DWORD WINAPI ThreadProc(LPVOID lParam)
- {
- PTHREAD_PARAM pParam = (PTHREAD_PARAM)lParam;
- HMODULE hMod = NULL;
- FARPROC pFunc = NULL;
- //pParam->pFun[0] 是 LoadLibraryA
- //pParam->szBuf[0] 是 "user32.dll"
- hMod = ((PFAR_LOADLIBRARYA)pParam->pFun[0])(pParam->szBuf[0]);
- pFunc = (FARPROC)((PFAR_GETPROCADDRESS)pParam->pFun[1])(hMod,pParam->szBuf[1]);
- ((PFMESSAGEBOXA)pFunc)(NULL, pParam->szBuf[2], pParam->szBuf[3], MB_OK);
- return 0;
- }
- BOOL CodeInject(DWORD dwPID)
- {
- HMODULE hMod = NULL;
- HANDLE hProcess = NULL;
- HANDLE hThread = NULL;
- DWORD dwSIZE = 0;
- THREAD_PARAM param = {0};
- LPVOID pRemoteBuf[2] = {0};
- hMod = GetModuleHandleA("kernel32.dll");
- //初始化结构体pParam
- param.pFun[0] = GetProcAddress(hMod, "LoadLibraryA");
- param.pFun[1] = GetProcAddress(hMod, "GetProcAddress");
- strcpy_s(param.szBuf[0],sizeof("user32.dll"),"user32.dll");
- strcpy_s(param.szBuf[1], sizeof("MessageBoxA"),"MessageBoxA");
- strcpy_s(param.szBuf[2], sizeof("Inject Success!"),"Inject Success!");
- strcpy_s(param.szBuf[3], sizeof("Success!"),"Success!");
- //获取进程句柄
- hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwPID);
- //分配内存空间
- dwSIZE = sizeof(THREAD_PARAM);
- pRemoteBuf[0] = VirtualAllocEx(hProcess,
- NULL, //为NULL不指定具体分配哪个地址
- dwSIZE, //分配空间的大小
- MEM_COMMIT,
- PAGE_READWRITE);
- WriteProcessMemory(hProcess,
- pRemoteBuf[0],
- (LPVOID)¶m,
- dwSIZE,
- NULL); //指定写入指定进程的字节数,为NULL则忽略
- dwSIZE = (DWORD)CodeInject - (DWORD)ThreadProc; //两个函数地址相减,一定要在Release下优化编译!!!!!!!
- pRemoteBuf[1] = VirtualAllocEx(hProcess,
- NULL,
- dwSIZE,
- MEM_COMMIT,
- PAGE_EXECUTE_READWRITE);
- WriteProcessMemory(hProcess,pRemoteBuf[1],(LPVOID)ThreadProc,dwSIZE,NULL);
- hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pRemoteBuf[1], pRemoteBuf[0], 0, NULL);
- WaitForSingleObject(hThread, INFINITE);
- CloseHandle(hThread);
- CloseHandle(hProcess);
- return TRUE;
- }
七,汇编代码注入
原理:将汇编代码的注入部分(CreateRemoteThread的传入的过程代码)用十六进制保存,再传入一个结构体(CreateRemoteThread的传入的参数),结构体有LoadLibrary和GetProcAddress两个API的地址,再在汇编代码中进行调用这个结构体这两个地址。
- #include<windows.h>
- #include<stdio.h>
- BOOL InjectCode(DWORD dwPID);
- BYTE g_InjectionCode[] = {
- 0x55,0x8B,0xEC,0x8B,0x75,0x08,0x68,0x6C,
- 0x6C,0x00,0x00,0x68,0x33,0x32,0x2E,0x64,
- 0x68,0x75,0x73,0x65,0x72,0x54,0xFF,0x16,
- 0x68,0x6F,0x78,0x41,0x00,0x68,0x61,0x67,
- 0x65,0x42,0x68,0x4D,0x65,0x73,0x73,0x54,
- 0x50,0xFF,0x56,0x04,0x6A,0x00,0xE8,0x0C,
- 0x00,0x00,0x00,0x52,0x65,0x76,0x65,0x72,
- 0x73,0x65,0x43,0x6F,0x72,0x65,0x00,0xE8,
- 0x14,0x00,0x00,0x00,0x77,0x77,0x77,0x2E,
- 0x72,0x65,0x76,0x65,0x72,0x73,0x65,0x63,
- 0x6F,0x72,0x65,0x2E,0x63,0x6F,0x6D,0x00,
- 0x6A,0x00,0xFF,0xD0,0x33,0xC0,0x8B,0xE5,
- 0x5D,0xC3
- };
- typedef struct _THREAD_PARAM
- {
- FARPROC pFunc[2];
- }THREAD_PARAM, *PTHREAD_PARAM;
- int main()
- {
- DWORD dwPID = 12056;
- InjectCode(dwPID);
- getchar();
- return 0;
- }
- BOOL InjectCode(DWORD dwPID)
- {
- HMODULE hMod = NULL;
- THREAD_PARAM param = { 0, };
- HANDLE hProcess = NULL;
- HANDLE hThread = NULL;
- LPVOID pRemoteBuf[2] = { 0, };
- hMod = GetModuleHandleA("kernel32.dll");
- // set THREAD_PARAM
- param.pFunc[0] = GetProcAddress(hMod, "LoadLibraryA");
- param.pFunc[1] = GetProcAddress(hMod, "GetProcAddress");
- // Open Process
- if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, // dwDesiredAccess
- FALSE, // bInheritHandle
- dwPID))) // dwProcessId
- {
- printf("OpenProcess() fail : err_code = %d\n", GetLastError());
- return FALSE;
- }
- // Allocation for THREAD_PARAM
- if (!(pRemoteBuf[0] = VirtualAllocEx(hProcess, // hProcess
- NULL, // lpAddress
- sizeof(THREAD_PARAM), // dwSize
- MEM_COMMIT, // flAllocationType
- PAGE_READWRITE))) // flProtect
- {
- printf("VirtualAllocEx() fail : err_code = %d\n", GetLastError());
- return FALSE;
- }
- if (!WriteProcessMemory(hProcess, // hProcess
- pRemoteBuf[0], // lpBaseAddress
- (LPVOID)¶m, // lpBuffer
- sizeof(THREAD_PARAM), // nSize
- NULL)) // [out] lpNumberOfBytesWritten
- {
- printf("WriteProcessMemory() fail : err_code = %d\n", GetLastError());
- return FALSE;
- }
- // Allocation for ThreadProc()
- if (!(pRemoteBuf[1] = VirtualAllocEx(hProcess, // hProcess
- NULL, // lpAddress
- sizeof(g_InjectionCode), // dwSize
- MEM_COMMIT, // flAllocationType
- PAGE_EXECUTE_READWRITE))) // flProtect
- {
- printf("VirtualAllocEx() fail : err_code = %d\n", GetLastError());
- return FALSE;
- }
- if (!WriteProcessMemory(hProcess, // hProcess
- pRemoteBuf[1], // lpBaseAddress
- (LPVOID)&g_InjectionCode, // lpBuffer
- sizeof(g_InjectionCode), // nSize
- NULL)) // [out] lpNumberOfBytesWritten
- {
- printf("WriteProcessMemory() fail : err_code = %d\n", GetLastError());
- return FALSE;
- }
- if (!(hThread = CreateRemoteThread(hProcess, // hProcess
- NULL, // lpThreadAttributes
- 0, // dwStackSize
- (LPTHREAD_START_ROUTINE)pRemoteBuf[1],
- pRemoteBuf[0], // lpParameter
- 0, // dwCreationFlags
- NULL))) // lpThreadId
- {
- printf("CreateRemoteThread() fail : err_code = %d\n", GetLastError());
- return FALSE;
- }
- WaitForSingleObject(hThread, INFINITE);
- CloseHandle(hThread);
- CloseHandle(hProcess);
- return TRUE;
- }
十六进制部分所代表的汇编代码:
- /*
- 004010ED 55 PUSH EBP
- 004010EE 8BEC MOV EBP,ESP
- 004010F0 8B75 08 MOV ESI,DWORD PTR SS:[EBP+8] ; ESI = 结构体的地址,地址表示的是API所代表的地址
- 004010F3 68 6C6C0000 PUSH 6C6C
- 004010F8 68 33322E64 PUSH 642E3233
- 004010FD 68 75736572 PUSH 72657375<span style="white-space:pre"> </span>; 三行表示的是"user32.dll"逆序push
- 00401102 54 PUSH ESP ; ESP表示的是 "user32.dll"字符串的首地址
- 00401103 FF16 CALL DWORD PTR DS:[ESI] ; 调用LoadLibraryA("user32.dll")
- 00401105 68 6F784100 PUSH 41786F
- 0040110A 68 61676542 PUSH 42656761
- 0040110F 68 4D657373 PUSH 7373654D
- 00401114 54 PUSH ESP ; - 字符串"MessageBoxA"的首地址
- 00401115 50 PUSH EAX ; - 前面LoadLibrary所返回的hMod
- 00401116 FF56 04 CALL DWORD PTR DS:[ESI+4] ; - GetProcAddress(hMod, "MessageBoxA")
- 00401119 6A 00 PUSH 0 ; - MB_OK (0)
- 0040111B E8 0C000000 CALL 0040112C<span style="white-space:pre"> </span>; CALL后面的是ASCLL,CALL的意思是PUSH EIP,相当于PUSH了后面字符串的首地址
- 00401120 <ASCII> ; - "ReverseCore", 0
- 0040112C E8 14000000 CALL 00401145
- 00401131 <ASCII> ; - "www.reversecore.com", 0
- 00401145 6A 00 PUSH 0 ; - hWnd (0)
- 00401147 FFD0 CALL EAX ; EAX是GetProcAddress所获得的地址存放在eax - MessageBoxA(0, "www.reversecore.com", "ReverseCore", 0)
- 00401149 33C0 XOR EAX,EAX <span style="white-space:pre"> </span>; API结果要返回0 到EAX中
- 0040114B 8BE5 MOV ESP,EBP
- 0040114D 5D POP EBP ; 清除堆栈
- 0040114E C3 RETN
- */
0则评论给“[转]注入小结”