2016-10-24 70 views
2

我想從32位進程寫入一個64位進程的入口點,就像使用EnumProcessModule並採用主內存地址模塊。 我的最終目標是從我的64位進程的內存中讀取一個字節,從它的偏移量(輸入+偏移量)。從32位進程獲得64bit進程內存的入口點

但我的NtWow64ReadVirtualMemory64函數保持失敗。 我認爲這與我的入門內存地址有關。

#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

我運行了一個簡單的測試,發現當插入函數「NtWow64ReadVirtualMemory64」時,我的緩衝區「ret」的值沒有改變。
代碼編譯並運行沒有錯誤(編譯和運行時),除了NtReadMemory64返回一個奇怪的數字(沒有文檔可用於ntdll NtWow64函數,所以goolgling它沒有產生任何有用的東西)。
所以我想我要麼提供了一個錯誤的緩衝區,或者沒有從有效的內存地址讀取。

由於我確實在函數外初始化緩衝區,所以我想 我的問題是後者(不提供有效的內存地址)。

我用主叫NtReadVirtualMemory

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

顯然當以下,稱NtWow64ReadVirtualMemory64時,我投的地址到一個32位的空指針(void*)address64,並且由於address64是UINT64型,鑄造截斷地址,我試圖讀取一段內存段,我無法讀取 我解決了這個問題,通過將其轉換爲(PVOID64)address64 將其轉換爲本機64位指針。

比我想象的要簡單,但是經過幾天的谷歌搜索和審查代碼後發現它是地獄。

編輯: 這並沒有削減它,因爲我的地址是錯的。 我需要通過內存中進程主模塊的位置來獲取「.exe」的入口點。
看着如何現在。
任何幫助表示讚賞!

相關問題