2016-10-24 2 views
2

Я хочу получить точку входа в 64-битный процесс, который я написал из 32-битного процесса, так же, как вы бы использовали EnumProcessModule и взять память addr из основного модуль. Моя конечная цель - прочитать байт из памяти в моем 64-битном процессе от смещения к нему (запись + смещение).получить точку входа в 64-битную память процесса из 32-битного процесса

Но моя функция NtWow64ReadVirtualMemory64 продолжает сбой. Я думаю, что это как-то связано с моей записью addr.

#define PROC_BASIC_INFO 0 
    #define NT_WOW64_QUERY_INFORMATION_PROCESS_64_NAME "NtWow64QueryInformationProcess64" 
    #define NT_WOW64_READ_VIRTUAL_MEMORY_64_NAME "NtWow64ReadVirtualMemory64" 

    typedef UINT64 SYM; 
    typedef SIZE_T SIZE_T64; 

    HWND WINDOW_HANDLE; 
    HANDLE PROC_HANDLE; 
    DWORD PROC_ID; 
    UINT address; 
    UINT64 address64; 
    SIZE_T bytesRead; 
    SIZE_T64 bytesRead64; 

    using namespace std; 


    //initialize variables for importing of essential 64 bit reading functions 
    //from ntdll 
    typedef NTSTATUS(NTAPI *FUNC_NtReadVirtualMemory64) 
    ( 
     IN HANDLE ProcessHandle, 
     IN PVOID64 BaseAddress, 
     OUT PVOID Buffer, 
     IN ULONGLONG BufferLength, 
     OUT PULONGLONG ReturnLength OPTIONAL 
    ); 
    typedef NTSTATUS (NTAPI *FUNC_NtWow64QueryInformationProcess64) 
    (
     IN HANDLE ProcessHandle, 
     IN ULONG ProcessInformationClass, 
     OUT PVOID ProcessInformation64, 
     IN ULONG Length, 
     OUT PULONG ReturnLength OPTIONAL 
    ); 

    struct PROCESS_BASIC_INFORMATION64 { 

     SYM Reserved1; 
     SYM PebBaseAddress; 
     SYM Reserved2[2]; 
     SYM UniqueProcessId; 
     SYM Reserved3; 
     /* 
     NTSTATUS ExitStatus; 
     ULONG64 PebBaseAddress; 
     ULONG64 AffinityMask; 
     LONG BasePriority; 
     UINT64 Reserved1; 
     ULONG64 UniqueProcessId; 
     ULONG64 InheritedFromUniqueProcessId; 
     */ 
    }; 



    HINSTANCE ntdll = LoadLibrary("ntdll.dll"); 
    FUNC_NtWow64QueryInformationProcess64 NtWow64QueryInformationProcess64 = (FUNC_NtWow64QueryInformationProcess64)GetProcAddress(ntdll, NT_WOW64_QUERY_INFORMATION_PROCESS_64_NAME); 
    FUNC_NtReadVirtualMemory64 NtReadVirtualMemory64 = (FUNC_NtReadVirtualMemory64)GetProcAddress(ntdll, NT_WOW64_READ_VIRTUAL_MEMORY_64_NAME); 

    int Init32To64MemoryRead(const char* windowClass, const char* caption, SYM addressOffset) 
    { 

     DWORD cbNeeded; 
     DWORD dwdResult; 
     HMODULE mainModule; 
     BOOL enumResult; 
     ULONG read_length=0; 
     HINSTANCE ntdll; 
     PROCESS_BASIC_INFORMATION64 procInfo; 
     ZeroMemory(&procInfo, sizeof(procInfo)); 



     //Get the window handle 
     WINDOW_HANDLE = FindWindow(windowClass, NULL); 
     if (WINDOW_HANDLE == NULL) 
     { 
      //Window was not foud 
      return 10; 
     } 

     //Get the process ID 
     dwdResult = GetWindowThreadProcessId(WINDOW_HANDLE, &PROC_ID); 

     if (dwdResult == 0) 
     { 
      //Getting Process ID failed 
      return 20; 
     } 

     //Open the process 
     PROC_HANDLE = OpenProcess(PROCESS_ALL_ACCESS, false, PROC_ID); 

     if (PROC_HANDLE == NULL) 
     { 
      //Process failed to open 
      return 30; 
     } 
     DWORD result; 

     //Query Proc Information to get .exe entry point 
     result = NtWow64QueryInformationProcess64(PROC_HANDLE, 0, &procInfo, sizeof(procInfo), &read_length); 
     if (result != 0) 
     { 
      cerr << "Query Information Process has failed" << endl; 

      return 40; 
     } 

     address64 = (procInfo.PebBaseAddress + addressOffset); 
     cerr << address64 << endl; 

     string number; 
     stringstream stristream; 

     stristream << address64; 
     stristream >> number; 

     byte testByte = 0; 
     (byte)ReadMemory64<byte>(testByte); 

     system("PAUSE"); 
     return 1; 
    } 


template <typename _ret_t> _ret_t ReadMemory64(_ret_t& ret) 
{ 

    NTSTATUS result = NtReadVirtualMemory64(PROC_HANDLE, (void*)address64, &ret, 8, NULL); 
    ///* Debug # when too lazy for breakpoints 
    cerr <<"value: " << ret << endl; 
    cerr << "Error Code: " << GetLastError() << endl; 
    if (result != 0) 
    { 
     cerr << "ReadMemory Failed.\r\nAddress: " << address64 << "\r\nSize: " << sizeof(_ret_t) << "\r\nResult: " << result << endl; 
     cerr << "NtReadVirtualMemory64 has failed" << endl; 
     system("PAUSE"); 

    } //*/ 
    return ret; 
}; 

Я хотел бы знать, что я делаю неправильно.

Редактировать: При дальнейшем осмотре я заметил, что NtWow64ReadVirtualMemory не сохраняет значение в переменной «ret», используемой в качестве буфера.

+0

Похоже, этот парень работал над этой темой .. посмотрите на http://blog.rewolf.pl/blog/?p=319 – Aaron

+0

Спасибо! Я рассмотрю еще кое-что. , но похоже, что мы делаем то же самое, только он использует asm для доступа к функции ntdll, а также позволяет использовать функции x64 ntdll – Noobay

ответ

1

Я проверил простой тест и понял, что значение моего буфера - «ret» не было изменено при вставке в функцию «NtWow64ReadVirtualMemory64».
Код выполнялся и выполнялся без ошибок (компиляция и время выполнения), за исключением NtReadMemory64, возвращающего странное число (нет документации для функций NtWow64 ntdll, поэтому включение в нее не принесло ничего полезного).
Итак, я понял, что я либо предоставляю неисправный буфер, либо не читаю из допустимого адр. Памяти.

Поскольку я инициализировал буфер явно вне функции, я понял , что моя проблема - последняя (не предоставление допустимого адреса памяти).

Я использовал следующие при вызове NtReadVirtualMemory

NTSTATUS result = NtReadVirtualMemory64(PROC_HANDLE, (void*)address64, &ret, 8, NULL); 

, по-видимому, при вызове NtWow64ReadVirtualMemory64, я бросил ADDR в 32 битном пустой указатель (void*)address64, а с address64 является uint64 типа, литая усечен адрес, и я пытался прочитать сегмент памяти, который я не смог прочитать Я решил его, изменив приведение к (PVOID64)address64 , который отбрасывает его на собственный 64-битный указатель.

Проще, чем я думал, но нахождение этого было ад после нескольких дней поиска в Интернете и пересмотра кода.

Редактировать: это не отрезало его, так как мой адрес неверен. Мне нужно получить точку входа «.exe» через место основного модуля процесса в памяти.
глядя на то, как сейчас.
любая помощь приветствуется!

Смежные вопросы