对CreateRemoteThread的使用
来源:互联网 发布:淘宝商城包包大全 编辑:程序博客网 时间:2024/05/16 13:48
本人小白水平,内容中有看不懂的地方请直接在留言中询问,如果代码中有错误或者用法不正确的地方还请立刻指出,本人QQ号 : 3216393922
对于 CreateRemoteThread,比较简单的用法是用LoadLibrary在目标进程中注入dll,也可以在远程线程中注入代码,并将它运行,不过,有一下几个注意点:
1、如何在远程线程中调用字符串?
所有的字符串必须在目标进程的地址空间中,所以我在目标进程内开辟了两个空间,一个用来存放代码,一个用来存放数据。将数据打包成结构体REMOTE_DATA,一次性运到目标进程中去,再将该结构体数据在目标进程中的地址作为线程函数的参数,这样就可以在线程函数中调用结构体中的字符串数据。
2、如何在远程线程中任意调用系统函数?
为了在远程线程中可以调用任何想调用的函数,必须拥有LoadLibraryW和GetProcAddress这两个函数,调用某一个函数时,先用LoadLibraryW得到函数所在的dll模块句柄,再用GetProcAddress得到函数地址。
例如:想要在远程线程函数内调用MessageBoxW函数,它在User32.dll中
先在数据结构体中定义函数名和dll名
CHAR szMessageBoxW[20] = “MessageBoxW”;
WCHAR szUser32[20] = TEXT(“user32.dll”);
再在远程线程函数中得到dll模块句柄
HMODULE hUser32 = LOADLIBRARYW(myData->szUser32);
然后申明MessageBoxW函数
typedef int(WINAPI* Func1)(HWND hwnd,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType);
Func1 MESSAGEBOXW = (Func1)GETPROCADDRESS(hUser32, myData->szMessageBoxW);
最后调用MessageBoxW函数
MESSAGEBOXW(NULL, myData->szText, myData->szCaption, MB_OK);
3、如何得到函数代码在内存中的大小?
#pragma check_stack(off)void test(){ //你的代码}void AfterFunc(){ return;}#pragma check_stack
调用SIZE_T cbSize = ((BYTE )(DWORD)AfterFunc - (BYTE )(DWORD)RemoteThreadFunc) + 10就可以得到函数test()的大小,该方法在Debug下无法使用,在Release中才可以使用。
目标是在进程PEView.exe中创建一个线程,线程中创建一个MessageBoxW
下面是代码:
#include <Windows.h>#include <TlHelp32.h>#include <stdlib.h>#include <string>#include <string.h>#include <stdio.h>#include <tchar.h>#include <Psapi.h>using namespace std;//1.定义进程名称const wstring& wsProcessName = TEXT("PEView.exe");//2.定义远程线程中使用的数据typedef struct{ WCHAR szCaption[50] = TEXT("123"); WCHAR szText[50] = TEXT("456"); //2.1需要使用的dll WCHAR szKernel32[20] = TEXT("kernel32.dll"); WCHAR szUser32[20] = TEXT("user32.dll"); WCHAR szGdi32[20] = TEXT("gdi32.dll"); //2.2需要使用的函数 CHAR szMessageBoxW[20] = "MessageBoxW"; CHAR szLoadCursorW[20] = "LoadCursorW"; CHAR szSetCursor[20] = "SetCursor"; CHAR szSleep[20] = "Sleep"; //2.3两个函数LoadLibraryW和GetProcAddressW的地址 DWORD dwLoadLibraryW = 0; DWORD dwGetProcAddress = 0;}REMOTE_DATA, *PREMOTE_DATA;REMOTE_DATA remoteData;//3.定义远程线程的函数#pragma check_stack(off)DWORD __stdcall RemoteThreadFunc(PREMOTE_DATA myData){ //LoadLibraryW-->LOADLIBRARYW typedef HMODULE(WINAPI* LoadLibraryWFunc)( LPCWSTR lpFileName ); LoadLibraryWFunc LOADLIBRARYW = (LoadLibraryWFunc)myData->dwLoadLibraryW; //GetProcAddress-->GETPROCADDRESS typedef FARPROC(WINAPI* GetProcAddressFunc)( HMODULE hModule, LPCSTR lpProcName ); GetProcAddressFunc GETPROCADDRESS = (GetProcAddressFunc)myData->dwGetProcAddress; //加载hUser32.dll并得到其句柄 HMODULE hKernel32 = LOADLIBRARYW(myData->szKernel32); HMODULE hUser32 = LOADLIBRARYW(myData->szUser32); HMODULE hGdi32 = LOADLIBRARYW(myData->szGdi32); //调用MessageBoxW typedef int(WINAPI* Func1)( HWND hwnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType ); Func1 MESSAGEBOXW = (Func1)GETPROCADDRESS(hUser32, myData->szMessageBoxW); MESSAGEBOXW(NULL, myData->szText, myData->szCaption, MB_OK); return 0;}void AfterFunc(){ return;}#pragma check_stackBOOL AdjustProcessTokenPrivilege(){ LUID luidTmp; HANDLE hToken; TOKEN_PRIVILEGES tkp; if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { return FALSE; } if (!::LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luidTmp)) { ::CloseHandle(hToken); return FALSE; } tkp.PrivilegeCount = 1; tkp.Privileges[0].Luid = luidTmp; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!::AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL)) { ::CloseHandle(hToken); return FALSE; } return TRUE;}BOOL Camp2str(wstring wsStrA, wstring wsStrB){ int nSize = wsStrA.length(); for (int i = 0; i < nSize; ++i) { if (wsStrA[i] >= 'A'&&wsStrA[i] <= 'Z') wsStrA[i] += 'a' - 'A'; } nSize = wsStrB.length(); for (int i = 0; i < nSize; ++i) { if (wsStrB[i] >= 'A'&&wsStrB[i] <= 'Z') wsStrB[i] += 'a' - 'A'; } return wsStrA == wsStrB;}DWORD GetProcessIdByName(const wstring& wsProcessName){ HANDLE hProcess = 0; DWORD dwProcess[2048], dwNeeded; TCHAR tcProcName[MAX_PATH] = { 0 }; wstring wsNowProcessName = L""; int nTempSize = 0; int nPos = 0; //将所有进程的ID保存在数组dwProcess中,共dwNeeded个进程 EnumProcesses(dwProcess, sizeof(dwProcess), &dwNeeded); //用ID打开每一个进程 for (int i = 0; i < (dwNeeded / sizeof(DWORD)); ++i) { if (dwProcess[i] != 0) { hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcess[i]); GetModuleFileNameEx(hProcess, NULL, tcProcName, MAX_PATH); nPos = wstring(tcProcName).find_last_of(L'\\'); if (nPos != wstring::npos) { wsNowProcessName = wstring(wstring(tcProcName).substr(nPos + 1)); if (Camp2str(wsProcessName, wsNowProcessName)) { DWORD aa = dwProcess[i]; return aa; } } } } return 0;}int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ //1.提权 if (!AdjustProcessTokenPrivilege()) { MessageBox(NULL, TEXT("无法提升权限"), TEXT("Fail"), MB_ICONERROR); return -1; } DWORD dwProID = 0; HANDLE hProcess = NULL; HANDLE hModuleSnap = INVALID_HANDLE_VALUE; HANDLE hThread = NULL; void* pRemoteData = NULL; void* pRemoteThread = NULL; __try { //2.获取进程ID dwProPID if ((dwProID = GetProcessIdByName(wsProcessName)) == 0) { MessageBox(NULL, TEXT("无法由进程名找到进程"), TEXT("Fail"), MB_ICONERROR); __leave; } //3.打开进程句柄hProcess if ((hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProID)) == NULL) { MessageBox(NULL, TEXT("无法打开进程"), TEXT("Fail"), MB_ICONERROR); __leave; } //4.在宿主进程中找到LoadLibraryW函数和GetProcAddressW函数的地址 //并分别赋给remoteData.dwLoadLibraryW和remoteData.dwGetProcAddress MODULEENTRY32W me32 = { sizeof(MODULEENTRY32W) }; hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProID); if (hModuleSnap == INVALID_HANDLE_VALUE) { MessageBox(NULL, TEXT("无法获取模块快照"), TEXT("Fail"), MB_ICONERROR); __leave; } if (!Module32FirstW(hModuleSnap, &me32)) { MessageBox(NULL, TEXT("无法获取模块快照"), TEXT("Fail"), MB_ICONERROR); __leave; } do { //找到目标进程中的Kernel32.dll if (lstrcmpiW(me32.szModule, TEXT("Kernel32.dll"))==0) { //获得本地hKernel32.dll或LoadLibraryW或GetProcAddress的地址 HANDLE hKernel32 = GetModuleHandleW(TEXT("Kernel32.dll")); DWORD loadlibraryw = (DWORD)GetProcAddress((HMODULE)hKernel32, (LPCSTR)"LoadLibraryW"); DWORD getprocaddress = (DWORD)GetProcAddress((HMODULE)hKernel32, (LPCSTR)"GetProcAddress"); if (hKernel32 == NULL || loadlibraryw == 0 || getprocaddress == 0) { MessageBox(NULL, TEXT("无法获得本地hKernel32.dll或LoadLibraryW或GetProcAddress的地址"), TEXT("Fail"), MB_ICONERROR); __leave; } //获得目标进程hKernel32.dll或LoadLibraryW或GetProcAddress的地址 remoteData.dwLoadLibraryW = loadlibraryw - (DWORD)hKernel32 + (DWORD)me32.hModule; remoteData.dwGetProcAddress = getprocaddress - (DWORD)hKernel32 + (DWORD)me32.hModule; break; } } while (Module32NextW(hModuleSnap, &me32)); CloseHandle(hModuleSnap); hModuleSnap = INVALID_HANDLE_VALUE; if (remoteData.dwLoadLibraryW == 0 || remoteData.dwGetProcAddress == 0) { MessageBox(NULL, TEXT("未能在目标进程中找到kernel32.dll"), TEXT("Fail"), MB_ICONERROR); __leave; } //5.1在宿主进程里分配内存,用于存参数remoteData pRemoteData = VirtualAllocEx(hProcess, NULL, sizeof(remoteData), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (pRemoteData == NULL) { MessageBox(NULL, TEXT("无法在宿主进程中分配内存"), TEXT("Fail"), MB_ICONERROR); __leave; } //5.2把remoteData写入到目标进程的内存pRemoteData中去 if (!WriteProcessMemory(hProcess, pRemoteData, &remoteData, sizeof(remoteData), NULL)) { MessageBox(NULL, TEXT("无法将数据remoteData写入宿主进程中"), TEXT("Fail"), MB_ICONERROR); __leave; } //6.1在宿主进程里分配内存,用于写线程函数RemoteThreadFunc SIZE_T cbSize = ((BYTE *)(DWORD)AfterFunc - (BYTE *)(DWORD)RemoteThreadFunc) + 10; if (cbSize <= 0) { cbSize = 2048; } pRemoteThread = VirtualAllocEx(hProcess, NULL, cbSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (pRemoteThread == NULL) { MessageBox(NULL, TEXT("无法在宿主进程中分配内存"), TEXT("Fail"), MB_ICONERROR); __leave; } //6.2.把RemoteThread指向的函数写入到目标进程的内存pRemoteThread中去 if (!WriteProcessMemory(hProcess, pRemoteThread, &RemoteThreadFunc, cbSize, NULL)) { MessageBox(NULL, TEXT("无法将线程函数RemoteThread写入宿主进程中"), TEXT("Fail"), MB_ICONERROR); __leave; } //7.启动注入宿主进程的线程 hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pRemoteThread, pRemoteData, 0, NULL); if (!hThread) { MessageBox(NULL, TEXT("无法在宿主进程中创建远程线程"), TEXT("Fail"), MB_ICONERROR); __leave; } //8.等待线程结束,然后清理内存 WaitForSingleObject(hThread, INFINITE); } __finally { if (hProcess != NULL) { CloseHandle(hProcess); } if (hModuleSnap != INVALID_HANDLE_VALUE) { CloseHandle(hModuleSnap); } if (hThread != NULL) { CloseHandle(hThread); } if (pRemoteThread != NULL) { VirtualFreeEx(hProcess, pRemoteThread, 0, MEM_RELEASE); } if (pRemoteData != NULL) { VirtualFreeEx(hProcess, pRemoteData, 0, MEM_RELEASE); } } return 0;}
- 对CreateRemoteThread的使用
- CreateRemoteThread的使用
- CreateRemoteThread的使用(转载)
- CreateRemoteThread的使用(转载)
- CreateRemoteThread的使用(转载)
- CreateRemoteThread 使用的两个例子
- CreateRemoteThread 使用
- 我的使用createremotethread控制excel右键的源程序
- 我的使用createremotethread控制excel右键的源程序
- 我的使用createremotethread控制excel右键的源程序
- 使用远程线程注入的三个函数CreateRemoteThread、NtCreateThreadEx、RtlCreateUserThread
- 简单的CreateRemoteThread例子
- CreateRemoteThread
- CreateRemoteThread
- CreateRemoteThread
- CreateRemoteThread
- CreateRemoteThread远程注入 使用例子
- CreateRemoteThread远程注入 使用例子
- cloudera安装--获取锁问题
- QQ缓存
- Ending、Java算法(2)-打印字符的ASCII码
- 基本数据结构之栈、队列、链表
- 使用maven构建多模块项目(三)
- 对CreateRemoteThread的使用
- 论文评述:Learning Deconvolution Network for Semantic Segmentation
- leetcode--Hamming Distance _我的解法
- leetcode27. Remove Element
- Scala 函数柯里化
- python cPickle之对象存取dump & load函数示例
- tensorflow 学习笔记(1)-introduction
- hihocoder 1483 区间价值(二分+双指针)
- 用php写水仙花,空心菱形,实心菱形,直角三角形