2016-10-24 55 views
2

32 비트 프로세스에서 작성한 64 비트 프로세스의 진입 점을 얻으려는 것과 동일한 방법으로 EnumProcessModule을 사용하고 main 기준 치수. 나의 최종 목표는 내 64 비트 프로세스의 메모리에서 바이트를 오프셋 (오프셋 + 오프셋)으로 읽는 것입니다.32 비트 프로세스에서 64 비트 프로세스 메모리에 대한 진입 점 가져 오기

하지만 내 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

고마워요! 좀 더 살펴볼 것입니다. 하지만 우리는 똑같은 일을하고있는 것처럼 보입니다. 그는 ntdll 함수에 액세스하기 위해 asm을 사용하고 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 형이기 때문에, 캐스트는을 잘립니다 주소를 읽고 읽을 수없는 메모리 세그먼트를 읽으려고했습니다. 캐스트를 기본 64 비트 포인터로 캐스팅하는 (PVOID64)address64 으로 캐스트를 변경하여 해결했습니다.

내가 생각했던 것보다 간단하지만 코드를 검색하고 검토 한 후 지옥이었습니다.

편집 : 내 주소가 잘못 되었기 때문에이 내용이 잘리지 않았습니다. 프로세스의 주 모듈 위치를 통해 ".exe"진입 점을 메모리에 저장해야합니다.
지금 방법을 살펴보십시오.
도움을 주시면 감사하겠습니다.