2016-07-31 13 views
0

의 RVA를 계산하고 원격 프로세스의 메모리에있는 dll의 기본로드 주소에 해당 오프셋을 추가하는 간단한 프로그램을 만들었습니다. MessageBoxA. 더미 프로그램을 출력하여 GetProcAddress을 사용하여 메모리의 함수 주소를 출력 한 다음 내 프로그램에서 원격 프로세스의 동일한 함수에 대해 계산 한 주소를 표시하는 자체 함수를 구현합니다. 그들은 항상 일치하므로 원격 프로세스에서 MessageBoxA의 주소를 찾는 기능이 문제가되지 않습니다. CreateRemoteThread MessageBoxA로 인해 원격 프로세스가 중단됨

는 난이 WriteProcessMemory로드를 사용하면 원격 프로세스를 실행 MessageBoxA ThreadProc 필요한 모든 필요한 정보 및 매개 변수를 포함하는 struct했다.
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; 

난 내 자신의 더미 프로그램에 이것을 시도

는 메시지 상자가 표시되지만 문자열에 이상한 문자 반대와 나는 MB_DATAmsgcaption 회원에 지정된. 캡션이 asic_string::erase이고 메시지에 u)이라고 표시되어 있습니다. 그리고 내 더미 프로세스 인과 다른 프로세스에서이 작업을 시도하면 원격 프로세스가 충돌합니다. 나는 tlhelp32 함수와 함께 프로세스에로드 된 모듈을 반복하는 함수를 만들어 user32.dll이 존재하는지 확인하고 함수의 주소를 찾기위한 함수가 NULL과 같은 결과를 반환합니다. dll이 없습니다. 여기

모든 관련 기능과 내 main 기능 :

dependencies.hpp

#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; 
} 

MAIN.CPP

#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; 
} 

어떤 도움 대단히 감사하겠습니다. 고마워요! :)

+0

게시 된 코드가 완전하지 않습니다. -'ThreadProc'이 무엇인지 알지 못합니다. –

+0

@HarryJohnston 나는 크게 변화 시켰고 해결책을 찾았습니다. 그래서 더 이상 필요하지 않습니다. –

답변

0

mb_data.msg 및 mb_data.caption 다른 프로세스에서 무엇을 가리 킵니까 ?? 이것은 이미 충돌 오류에 충분합니다. ThreadProc에 무엇이 보이지 않으나 재배치가 없다는 것을 확신하지 못합니다. 실제로 ThreadProc은 MB_DATA의 멤버 함수 여야하며 멤버 만 액세스 할 수 있습니다. 당신이 분명히 당신이 주입 시간에 원격 프로세스를 디버깅하지 않는 게시물. 그 작업이 당신의 현재 레벨을 넘었다는 것입니다.

+0

나는 작은 모자를 쓰지 않을 수 있지만 왜'ThreadProc'는'MB_DATA'의 멤버인가? msg와 캡션의 문제를 지적 해 주셔서 감사합니다. 문자 배열이 자동으로 포인터로 사라지는 것을 잊어 버렸습니다. –

+0

"ThreadProc은 왜 MB_DATA의 멤버 여야합니까?"- 반드시 있어야하는 것은 아니지만 reloc을 포함해서는 안됩니다. 솔루션으로 - 멤버 함수이며 MB_DATA의 데이터 멤버에만 액세스합니다. 사실로 모든 경우 회원 또는 MB_DATA 다른 지점에서. void ThreadProc (MB_DATA *); - 현재의 사인이라고 생각해.GetFileImage - 리소스를 공개하지 않으려 고합니다. 일반적으로 LoadLibraryEx (DONT_RESOLVE_DLL_REFERENCES) 및 GetprocAddress를 사용하지 않는 것이 일반적입니다. – RbMm

+0

"relocs"는 무엇을 의미합니까? 재배치? –