CreateRemoteThread MessageBoxA导致远程进程崩溃

时间:2016-07-31 17:26:49

标签: c++ winapi virtual-memory dll-injection

我创建了一个简单的程序来计算MessaegBoxA中函数user32.dll的RVA,然后将该偏移量添加到远程进程内存中的dll的基本加载地址以获取函数MessageBoxA的地址。我创建了一个虚拟程序,它使用GetProcAddress在其内存中输出函数的地址,然后在我的程序中实现我自己的函数,以显示它为远程中相同函数计算的地址处理。它们始终匹配,所以我确定我在远程过程中查找MessageBoxA地址的功能不是问题所在。

我创建了一个struct,其中包含ThreadProc在使用MessageBoxA加载远程进程后WriteProcessMemory执行typedef struct { typedef int (WINAPI* _MessageBoxA)(HWND, LPCSTR, LPCSTR, UINT); _MessageBoxA MessageBoxA; //These are the four parameters passed to MessageBoxA HWND hwnd; LPCSTR msg; LPCSTR caption; UINT mb; }MB_DATA, *PMB_DATA; 所需的所有必要信息和参数。

msg

当我在我自己的虚拟程序上尝试此操作时,会显示消息框,但有奇怪的文字与我在captionMB_DATA成员中指定的字符串相反asic_string::erase。对于标题u)以及它所说的tlhelp32的消息,它说明了以下内容。当我尝试在除虚拟进程之外的任何其他进程中执行此操作时,它会使远程进程崩溃。我创建了一个函数,用user32.dll函数迭代已经在进程中加载​​的模块,以确保NULL存在,并且它是,并且我在该过程中查找函数地址的函数没有& #39;如果dll不存在,则返回main

此处所有相关功能和我的#include <windows.h> #include <tlhelp32.h> #include <stdio.h> #include <iostream> using namespace std; typedef struct { typedef int (WINAPI* _MessageBoxA)(HWND, LPCSTR, LPCSTR, UINT); _MessageBoxA MessageBoxA; HWND hwnd; LPCSTR msg; LPCSTR caption; UINT mb; }MB_DATA, *PMB_DATA; //Map the dll into memory void* GetFileImage(char path[]) { HANDLE hFile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); if(hFile == INVALID_HANDLE_VALUE){printf("Error getting file handle: %d", (int)GetLastError());return NULL;} HANDLE file_map = CreateFileMapping(hFile, NULL, PAGE_READONLY|SEC_IMAGE, 0, 0, "KernelMap"); if(file_map == INVALID_HANDLE_VALUE){printf("Error mapping file: %d", (int)GetLastError());return NULL;} LPVOID file_image = MapViewOfFile(file_map, FILE_MAP_READ, 0, 0, 0); if(file_image == 0){printf("Error getting mapped view: %d", (int)GetLastError());return NULL;} return file_image; } //Get to the function export directory and find the offset for the specified function from the //address in memory the dll was loaded at DWORD_PTR RVAddress(char* image, const char* proc_name) { PIMAGE_DOS_HEADER pDos_hdr = (PIMAGE_DOS_HEADER)image; PIMAGE_NT_HEADERS pNt_hdr = (PIMAGE_NT_HEADERS)(image+pDos_hdr->e_lfanew); IMAGE_OPTIONAL_HEADER opt_hdr = pNt_hdr->OptionalHeader; IMAGE_DATA_DIRECTORY exp_entry = opt_hdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; PIMAGE_EXPORT_DIRECTORY pExp_dir = (PIMAGE_EXPORT_DIRECTORY)(image+exp_entry.VirtualAddress); DWORD* func_table = (DWORD*)(image+pExp_dir->AddressOfFunctions); WORD* ord_table = (WORD*)(image+pExp_dir->AddressOfNameOrdinals); DWORD* name_table = (DWORD*)(image+pExp_dir->AddressOfNames); for(u_int i=0;i<pExp_dir->NumberOfNames;i++) { char* name = (char*)(image+name_table[i]); if(strcmp(proc_name, name) == 0) { return (DWORD_PTR)func_table[ord_table[i]]; } } return (DWORD_PTR)0; } //Add the RVA returned from RVAddress to the address of the dll to find the function in the //process memory LPVOID GetProcAddressEx(DWORD dwPid, char* mod_path, char* function_name, char* mod_name) { HANDLE hSnapshot = INVALID_HANDLE_VALUE; MODULEENTRY32 me32; me32.dwSize = sizeof(MODULEENTRY32); hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE|TH32CS_SNAPMODULE32, dwPid); if(hSnapshot == INVALID_HANDLE_VALUE){printf("Snapshot failed");return 0;} if(!(Module32First(hSnapshot, &me32))) { printf("Mod32First failed"); return 0; } BOOL found = FALSE; while(Module32Next(hSnapshot, &me32)) { if(stricmp(me32.szModule, mod_name) == 0) { CloseHandle(hSnapshot); found = TRUE; break; } } if(found == FALSE){return 0;} DWORD_PTR RVA = (DWORD_PTR)RVAddress((char*)GetFileImage(mod_path), function_name); LPVOID func_addr = me32.modBaseAddr+RVA; return func_addr; } 功能:

dependencies.hpp

#include "dependencies.hpp"
#define FUNC_SIZE 1024

typedef int (WINAPI* _MessageBoxA)(HWND, LPCSTR, LPCSTR, UINT);

int main()
{
    MB_DATA mb_data;
    mb_data.hwnd = NULL;
    mb_data.msg = "Hey";
    mb_data.caption = "Yo";
    mb_data.mb = MB_OK;

    SIZE_T nBytes = 0;

    char proc_path[MAX_PATH];
    char kernel_path[MAX_PATH];
    char user32_path[MAX_PATH];

    //get full path to the current process and store it in proc_path
    GetModuleFileName(GetModuleHandle(NULL), proc_path, MAX_PATH);
    //get full path to kernel32.dll and store it in kernel_path
    GetModuleFileName(GetModuleHandle("kernel32.dll"), kernel_path, MAX_PATH);
    //get full path to user3.dll and store it in user32_path
    GetModuleFileName(GetModuleHandle("user32.dll"), user32_path, MAX_PATH);

    //show all processes running and their PID's
    system("tasklist");

    DWORD dwPid = 0;
    printf("PID: ");
    scanf("%lu", &dwPid);
    //if dwPid is 0 assign it the pid of the current process
    if(dwPid == 0)
    {
        dwPid = GetCurrentProcessId();
    }

    //Get a handle to the process with all access rights
    HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
    //make sure the handle is valid
    if(hProc == NULL){printf("Error obtaining handle to process: %lu", GetLastError());return 1;}

    //Get the address of the function in the remote process
    LPVOID _MessageBoxA1 = GetProcAddressEx(dwPid, user32_path, (char*)"MessageBoxA", (char*)"user32.dll");
    //assign the pointer to the address to the member MessageBoxA of the MB_DATA structure
    mb_data.MessageBoxA = (_MessageBoxA)_MessageBoxA1;

    //allocate 2mb for our the ThreadProc callback function and the MB_DATA structure
    LPVOID lpBase = VirtualAllocEx(hProc, NULL, 2048, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    //did the allocation work
    if(lpBase == NULL){printf("Error allocating space: %lu", GetLastError());return 1;}

    //so I can check what was written with CheatEngine
    cout << "Base address of memory allocated in remote process: " << lpBase << endl;

    //Write the function into memory
    if(WriteProcessMemory(hProc, lpBase, (LPVOID)ThreadProc, FUNC_SIZE, &nBytes) == 0)
    {
        printf("Error writing function to process");
        return 1;
    }

    //the address the space left after having written ThreadProc into memory 
    LPVOID lpBuffer = lpBase+FUNC_SIZE;

    //Write the MB_DATA structure into the memory of the remote process
    if(WriteProcessMemory(hProc, lpBuffer, &mb_data, sizeof(MB_DATA), &nBytes) == 0)
    {
        printf("Error writing buffer to process");
    }

    //Run the ThreadProc function passing the MB_DATA structure to it as its lpParam parameter
    if(CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)lpBase, lpBuffer, 0, NULL) == NULL)
    {
        printf("Error creating remote thread: %lu", GetLastError());
        return 1;
    }

    //print a list of all the dll's being used by the process
    EnumerateModules(dwPid);

    system("pause");

    return 0;
}

的main.cpp

header

非常感谢任何帮助。非常感谢你! :)

1 个答案:

答案 0 :(得分:0)

mb_data.msg和mb_data.caption指向另一个进程中的内容?这已经足够用于崩溃错误。 ThreadProc中的内容不可见,但我不确定它没有relocs。实际上,ThreadProc必须是MB_DATA的成员函数,并且只能访问它的成员。很明显,你在注射时没有调试远程进程。显然,任务超出了你目前的水平