2013-07-01 4 views
0

enter image description here Windows x64에서 이름 (다른 프로세스에서)을 기준으로 모듈 기본 주소를 찾는 방법은 무엇입니까?외부 프로세스에서 Windows x64의 모듈 핸들 찾기

ProcessModuleCollection은 발견 만 : NTDLL.DLL wow64.dll wow64win.dll wow64cpu.dll (X32 및 x64 Windows 버전에서 작동) 이름으로 검색 모듈의 기본 빨간색 깜박임에 대한 기능의 예를 찾을 수 있습니다

? 당신은이 코드를 32 비트 프로세스를 대상으로려고하는 경우에

+0

"기본 주소"란 무엇입니까? –

+0

모듈 핸들 ... –

+1

질문을 더 명확하게해야합니다. 다른 프로세스를 조사하려고한다는 것은 언급하지 않았습니다. 'ProcessModuleCollection'는 x64에서 잘 작동하지만 예상되는 프로세스는 32 비트 WOW64 프로세스입니다. 아니면 다른 방향 일 수도 있습니다. 그럼 좀 더 자세히 설명해주세요. 질문을 편집하십시오. 외부 프로세스를 참조하는지 확인하십시오. 그리고 프로세스에 대해 알려주십시오. 그들은 둘 다 32 비트, 또는 둘 다 64 비트, 또는 혼합되어 있습니다. 그리고 혼합되면, 어떤 방법으로 라운드. 32 비트 에뮬레이터에서 64 비트 모듈을 쉽게 열거 할 수 없습니다. –

답변

3

Process.Modules를 호출하여 반환 된 ProcessModuleCollection 인스턴스는 당신이 필요로하는 정보를 가지고 : 내가 당신에게 유용 할 수 있습니다 GameDeception에 다음과 같은 네이티브 코드를 발견했습니다. 두 프로세스가 동일한 비트를 제공한다면 제공됩니다. 따라서 대상 프로세스가 32 비트 프로세스 인 경우 프로세스가 32 비트 프로세스인지 확인하십시오. 대상 프로세스가 64 비트 프로세스 인 경우 프로세스가 64 비트 프로세스인지 확인하십시오.

  1. 64 비트 OS : 당신이 질문에 포함 출력에서 ​​

    는 그 출력을 발생하는 시나리오임을 알 수있다.

  2. 코드가 64 비트 프로세스로 실행됩니다.
  3. 대상 프로세스는 32 비트 프로세스입니다.

만 실행 모듈과 같이, 모듈들 소수들이 WOW64 에뮬레이터에서 실행하는 32 비트 프로세스에 포함 된 64 개 비트 모듈 있음 (아마도)는 열거 이유.

Windows API를 사용하여 비트율이 다른 프로세스의 모듈을 열거 할 수 있다고 생각할 수도 있습니다. 그러나 당신은 할 수 없습니다. CreateToolhelp32Snapshot, Module32FirstModule32Next을 사용하면 Process.Modules을 사용하는 C# 코드와 동일한 결과가 나타납니다. 그리고 그것은 전혀 놀라운 것이 아닙니다. Win32에서 구현 된 .net이이 작업을 위해 설계된 기본 Win32 API를 호출한다는 것은 완벽합니다.

해결 방법은 Process.Modules에 대한 호출이 32 비트 프로세스에서 이루어 졌는지 확인하는 것입니다. 32 비트 및 64 비트 프로세스 모두를 대상으로 할 수 있어야하는 경우에는 서로 다른 비트 수의 일부 도우미 프로세스를 사용해야합니다.

업데이트

벤 보이트는 디버그 도움말 API에서 EnumerateLoadedModules64에 저를 가리 킵니다. 나는 이것을 깨닫지 못함을 고백한다. 그러나 도구 도움말 API와 동일한 비트 한계가있는 것 같습니다.

마지막으로, EnumProcessModulesEx은 64 비트 프로세스에서 32 비트 모듈을 열거 할 수 있습니다. LIST_MODULES_32BIT을 전달하면 실제로 64 비트 호출 프로세스에서 외부 32 비트 프로세스로로드 된 32 비트 모듈을 추출 할 수 있습니다.

+0

하지만이 방법은 나를 위해 작동하지 않습니다. WinAPI를 사용하는 방법? –

+0

[스크린 샷] (http://screenshot.su/img/9b/ba/d8/9bbad84c157588e904ba1f1984e2b37b.jpg) –

+0

그냥 똑같습니다. 'Process.Modules'가 구현되었다고 어떻게 상상합니까? 이것은 Windows API에 대한 호출입니다. 이제 저는 일을 할 수있는 문서화되지 않은 API가 있다고 생각합니다. –

2

, 다음이 당신을 위해 잘 작동합니다 :

/// <summary> 
    /// Gets the base address of a process' module with the specified name. 
    /// </summary> 
    /// <param name="moduleName">Name of the module.</param> 
    /// <returns>The module BaseAddress if successful; otherwise, IntPtr.Zero.</returns> 
    public IntPtr GetModuleBaseAddress(string moduleName) 
    { 
     var module = Memory.Process.Modules.Cast<ProcessModule>().FirstOrDefault(m => m.ModuleName == moduleName); 

     return module != null ? module.BaseAddress : IntPtr.Zero; 
    } 

을 Memory.Process 그냥 System.Diagnostics.Process 객체입니다. 실제 x64 프로세스에서 작동하는지는 확실치 않지만 32 비트 프로세스 (64 비트 플랫폼에서도)를 목표로 삼고있는 한이 코드는 프로세스 모듈의 기본 주소를 얻을 수 있습니다.

염두에 두어야 할 점은 ProcessModules을 열거 할 때마다 호출 수신자 아키텍처 (x86 또는 x64)에있는 모델 만 가져올 수 있다는 것입니다. x86 프로세스를 실행 중이고 다른 프로세스에서 Process.Modules을 호출하면 해당 프로세스의 x86 모듈 만 표시됩니다. x64에도 동일하게 적용됩니다. 이 문제를 해결하거나 x86 및 x64 용으로 프로젝트를 컴파일하고 각 응용 프로그램에 적합한 방법을 사용해야합니다.

편집 :

unsigned long ProcessDevice::getModuleAddress(DWORD proc, const char *modname) 
{ 
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, proc); 

    if(snapshot == INVALID_HANDLE_VALUE) 
    { 
     return 0; 
    } 

    MODULEENTRY32 mod; 
    mod.dwSize = sizeof(MODULEENTRY32); 

    if(Module32First(snapshot, &mod)) 
    { 
     if(strcmp(mod.szModule, modname) == 0) 
      return (unsigned long)mod.modBaseAddr; 

     while(Module32Next(snapshot, &mod)) 
     { 
      if(strcmp(mod.szModule, modname) == 0) 
       return (unsigned long)mod.modBaseAddr; 
     } 

     /* Failed to find the module */ 
     return 0; 
    } 
    else 
    { 
     /* Failed to read any module info */ 
     return 0; 
    } 
} 
+0

이것은 단지'ProcessModuleCollection'입니다. 그 질문에 명시된 것은 바로 필요한 정보를 제공하지 않는 것입니다. 32 비트에서 32 비트, 64 비트에서 64 비트까지 괜찮습니다. 그러나 혼합 bitness 아닙니다. 우리가 여기에있는 것이 분명합니다. –

+0

대상은 x32뿐만 아니라 x64 (때로는) 일 수 있습니다. 또한 다른 (외부) 과정에 필요합니다. –

+0

32 비트 프로세스에서는 x86으로, 64 비트 프로세스에서는 x64로 프로젝트를 빌드해야합니다. 그 주위에 문서화되지 않은 API의 그늘진 세계로 들어가는 방법이 있지만,'IntPtr'을 사용한다면 두 플랫폼 모두를위한 프로그램을 만드는 것이 더 쉽습니다. 너무 많은 문제를 겪어서는 안됩니다. – aevitas