2016-10-24 17 views
2

32bitプロセスから書き込んだ64bitプロセスへのエントリポイントを取得したいのですが、EnumProcessModuleと同じ方法でメインのメモリアドレスを取得しますモジュール。 私の最終目標は、64ビットプロセスのメモリからオフセットからそれまでのエントリ(オフセット+オフセット)を読み出すことです。32bitプロセスから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関数で使用できるドキュメントがないため、役に立たなかったようです)。
だから、私は欠陥のあるバッファを提供しているか、有効なメモリアドレスを読み込んでいないと考えました。

私は関数の外で明示的にバッファを初期化していたので、私は の問題が後者(有効なメモリアドレスを提供していない)であると考えました。

明らかNtWow64ReadVirtualMemory64を呼び出すときに、私は32ビットのvoidポインタ (void*)address64にADDRをキャスト、そしてaddress64はUINT64型であるため、キャストは切り捨て
NTSTATUS result = NtReadVirtualMemory64(PROC_HANDLE, (void*)address64, &ret, 8, NULL); 

NtReadVirtualMemory

を呼び出すときに、私は次のように使用していた

私が読むことができなかったメモリセグメントを読み取ろうとしていた キャストを(PVOID64)address64 に変更することで解決しました。これはネイティブの64ビットポインタにキャストします。

私は考えていたよりも簡単でしたが、グーグルグーグルとコードを見直したあと、それは大変でした。

編集: 私のアドレスが間違っているため、これはカットされませんでした。 メモリ内のプロセスのメインモジュールの位置を介して ".exe"エントリポイントを取得する必要があります。
今の方法を見てください。
ご迷惑をおかけして申し訳ございません。

関連する問題