远程线程注入实战采用手法让其他进程加载dll,获取窗口句柄或者通过窗口句柄获取进程id创建远程线程,其中的回调函数代码可以使用直接写的,也可以用Loadlibrary加载写入的dll路径,dll里面可以写你想要的代码
首先生成shellcode注入给其他进程
unsigned char data[321] = { 0x55, 0x8B, 0xEC, 0x83, 0xEC, 0x1C, 0x53, 0x8D, 0x45, 0xF0, 0xC7, 0x45, 0xFC, 0x63, 0x6D, 0x64, 0x00, 0x33, 0xDB, 0xC7, 0x45, 0xE4, 0x77, 0x73, 0x32, 0x5F, 0x50, 0xB9, 0x4C, 0x77, 0x26, 0x07, 0xC7, 0x45, 0xE8, 0x33, 0x32, 0x2E, 0x64, 0x66, 0xC7, 0x45, 0xEC, 0x6C, 0x6C, 0x88, 0x5D, 0xEE, 0xC7, 0x45, 0xF0, 0x75, 0x73, 0x65, 0x72, 0xC7, 0x45, 0xF4, 0x33, 0x32, 0x2E, 0x64, 0x66, 0xC7, 0x45, 0xF8, 0x6C, 0x6C, 0x88, 0x5D, 0xFA, 0xE8, 0x1D, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0x53, 0x8D, 0x45, 0xFC, 0xB9, 0x45, 0x83, 0x56, 0x07, 0x50, 0x8D, 0x45, 0xE4, 0x50, 0x53, 0xE8, 0x07, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0x5B, 0x8B, 0xE5, 0x5D, 0xC3, 0x83, 0xEC, 0x10, 0x64, 0xA1, 0x30, 0x00, 0x00, 0x00, 0x53, 0x55, 0x56, 0x8B, 0x40, 0x0C, 0x57, 0x89, 0x4C, 0x24, 0x18, 0x8B, 0x70, 0x0C, 0xE9, 0x8A, 0x00, 0x00, 0x00, 0x8B, 0x46, 0x30, 0x33, 0xC9, 0x8B, 0x5E, 0x2C, 0x8B, 0x36, 0x89, 0x44, 0x24, 0x14, 0x8B, 0x42, 0x3C, 0x8B, 0x6C, 0x10, 0x78, 0x89, 0x6C, 0x24, 0x10, 0x85, 0xED, 0x74, 0x6D, 0xC1, 0xEB, 0x10, 0x33, 0xFF, 0x85, 0xDB, 0x74, 0x1F, 0x8B, 0x6C, 0x24, 0x14, 0x8A, 0x04, 0x2F, 0xC1, 0xC9, 0x0D, 0x3C, 0x61, 0x0F, 0xBE, 0xC0, 0x7C, 0x03, 0x83, 0xC1, 0xE0, 0x03, 0xC8, 0x47, 0x3B, 0xFB, 0x72, 0xE9, 0x8B, 0x6C, 0x24, 0x10, 0x8B, 0x44, 0x2A, 0x20, 0x33, 0xDB, 0x8B, 0x7C, 0x2A, 0x18, 0x03, 0xC2, 0x89, 0x7C, 0x24, 0x14, 0x85, 0xFF, 0x74, 0x31, 0x8B, 0x28, 0x33, 0xFF, 0x03, 0xEA, 0x83, 0xC0, 0x04, 0x89, 0x44, 0x24, 0x1C, 0x0F, 0xBE, 0x45, 0x00, 0xC1, 0xCF, 0x0D, 0x03, 0xF8, 0x45, 0x80, 0x7D, 0xFF, 0x00, 0x75, 0xF0, 0x8D, 0x04, 0x0F, 0x3B, 0x44, 0x24, 0x18, 0x74, 0x20, 0x8B, 0x44, 0x24, 0x1C, 0x43, 0x3B, 0x5C, 0x24, 0x14, 0x72, 0xCF, 0x8B, 0x56, 0x18, 0x85, 0xD2, 0x0F, 0x85, 0x6B, 0xFF, 0xFF, 0xFF, 0x33, 0xC0, 0x5F, 0x5E, 0x5D, 0x5B, 0x83, 0xC4, 0x10, 0xC3, 0x8B, 0x74, 0x24, 0x10, 0x8B, 0x44, 0x16, 0x24, 0x8D, 0x04, 0x58, 0x0F, 0xB7, 0x0C, 0x10, 0x8B, 0x44, 0x16, 0x1C, 0x8D, 0x04, 0x88, 0x8B, 0x04, 0x10, 0x03, 0xC2, 0xEB, 0xDB }; int _tmain(int argc, _TCHAR* argv[]) { DWORD dwPid = 0; DWORD dwThread = 0; DWORD dwWrite; HWND hwnd = FindWindowA(NULL, "计算器"); GetWindowThreadProcessId(hwnd, &dwPid); HANDLE handle=OpenProcess(PROCESS_ALL_ACCESS, NULL, dwPid); LPVOID laddr=VirtualAllocEx(handle, NULL, 1, MEM_COMMIT, PAGE_EXECUTE_READWRITE); WriteProcessMemory(handle, laddr, data, 321, &dwWrite); HANDLE hRemote = CreateRemoteThread(handle, NULL, 0, (LPTHREAD_START_ROUTINE)laddr, NULL, 0, &dwThread); return 0; }
也可以使用winhex,看自己写的代码的机器码拷贝过去,不能有间接寻址执行的代码、
typedef int(__stdcall *PFN_MSGBOX)(HWND hWnd, // handle to owner window LPCSTR lpText, // text in message box LPCSTR lpCaption, // message box title UINT uType // message box style ); void test() { //MessageBoxA(NULL, "Hello World!", NULL, 0); PFN_MSGBOX pfn = (PFN_MSGBOX)0x75597E60; char szBuf[] = { 'H', 'e', 'l', 'l', 'o', '\0'}; pfn(NULL, szBuf, NULL, 0); }
远程线程让其他进程加载dll
1.获取窗口句柄
2.通过窗口句柄获取进程id
3.通过进程id获取进程句柄
4.然后在进程内开辟空间
5.直接执行代码:在里面写代码,注入dll:也可以写dll的路径
6.创建远程线程,其中的回调函数代码可以使用直接写的,也可以用Loadlibrary加载写入的dll路径,dll里面可以写你想要的代码。
Dll里面想要添加自己的功能,可以替换掉窗口的消息循环函数,这个时候就可以使用
SetWindowsLong
注入程序代码
int _tmain(int argc, _TCHAR* argv[]) { DWORD dwPid = 0; DWORD dwThread = 0; DWORD dwWrite; HWND hwnd = FindWindowA(NULL, "计算器"); GetWindowThreadProcessId(hwnd, &dwPid); HANDLE handle=OpenProcess(PROCESS_ALL_ACCESS, NULL, dwPid); char szbuf[] = "Remote.dll"; LPVOID laddr=VirtualAllocEx(handle, NULL, 1, MEM_COMMIT, PAGE_EXECUTE_READWRITE); WriteProcessMemory(handle, laddr, szbuf, sizeof(szbuf), &dwWrite); HANDLE hRemote = CreateRemoteThread(handle, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA, laddr, 0, &dwThread); WaitForSingleObject(hRemote, INFINITE); return 0; }
** dll代码**
LRESULT CALLBACK MyNewWindowProc(HWND ,UINT , WPARAM , LPARAM); LONG oldAddr; HMENU hMenu; DWORD WINAPI ThreadProc( LPVOID lpParameter // thread data ) { FreeLibraryAndExitThread(GetModuleHandleA("Remote.dll"),0); return 0; } BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { HMODULE hmodule=GetModuleHandle(NULL); HWND hWnd = FindWindowA(NULL, "计算器"); oldAddr=GetWindowLong(hWnd, GWL_WNDPROC); SetWindowLong(hWnd, GWL_WNDPROC, (LONG)MyNewWindowProc); hMenu=GetMenu(hWnd); AppendMenuA(hMenu, MF_STRING | MF_POPUP, 123, "弹框"); } break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } LRESULT CALLBACK MyNewWindowProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ) { switch (uMsg) { case WM_COMMAND: { if (LOWORD(wParam) == 132) { //卸载dll DeleteMenu(hMenu, 123, 0); DrawMenuBar(hwnd); SetWindowLong(hwnd, GWL_WNDPROC, (LONG)oldAddr); CreateThread(NULL, 0, ThreadProc, 0, 0, 0); } else if (LOWORD(wParam)==123) { TCHAR szbuf[256] = { 0 }; wsprintf(szbuf, L"hi:%d,lo%d", HIWORD(wParam), LOWORD(wParam)); MessageBox(NULL, szbuf, NULL, NULL); } } break; default: return CallWindowProc((WNDPROC)oldAddr, hwnd, uMsg, wParam, lParam); } }
** 卸载dll**
1.卸载dll首先要把原消息循环给设置回去
2.获取dll句柄
3.创建线程卸载
如果不创建线程卸载的话直接
他有返回值,然而dll的栈已经被释放了,所以会崩了程序。
所以我们
上面是dll中释放
主线程释放dll
转载请说明出处
草堂教程网 » Windows远程线程注入实战
草堂教程网 » Windows远程线程注入实战