2016-09-22 6 views
0

고급 코드 주입 코드를 사용하여 원격 프로세스에서 .dll을 시작합니다. 당신은 여기에서 예를 들어이 작동하는 방법/코드 snipet를 찾을 수 있습니다코드 삽입을 사용하여 원격 프로세스에서 함수 실행

https://sourceforge.net/p/diagnostic/svn/HEAD/tree/src/RemoteInit.cpp

나는 몇 가지 응용 프로그램이 방법이 작동하지 않는 것으로 나타났습니다 -이 호스트 응용 프로그램을 충돌합니다. 가장 큰 문제는 자신의 후크 기능의 IT를 제공하여 kernel32.dll GetProcAddress을 차단 ConEmuHk64.dll 같은 특별한 종류의 3 번째 파티 소프트웨어 것 같다 -이 같은이 나는군요 함수 포인터 후 :

*((FARPROC*) &info.pfuncGetProcAddress) = GetProcAddress(hKernel32, "GetProcAddress"); 

하지만 그 대신 내가 포인터를 받고 있어요 함수는 ConEmuHk64.dll에 있습니다.

내 자신의 프로세스에서 해당 함수를 호출하는 것이 허용되지만 원격 프로세스에서 동일한 작업을 수행하려고 할 때 ConEmuHk64.dll을 사용할 수 없기 때문에 충돌합니다.

내가 메커니즘을 파악했습니다 방법을 수동으로 DOS/NE 다른 헤더에서 도보로 그 기능의 자동 프로브 정확한 주소 - 여기에 코드입니다 : 이것은 GetProcAddress을 위해 작동하는 것 같군

// 
// We use GetProcAddress as a base function, with exception to when GetProcAddress itself is hooked by 3-rd party 
// software and pointer to function returned to us is incorrect - then we try to locate function manually by 
// ourselfes. 
// 
FARPROC GetProcAddress2(HMODULE hDll, char* funcName) 
{ 
    FARPROC p = GetProcAddress(hDll, funcName); 

    if(!p) 
     return NULL; 

    IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER *) hDll; 

    if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) 
     return p; 

    IMAGE_NT_HEADERS* pNtHeaders = (IMAGE_NT_HEADERS *) (((char*) pDosHeader) + pDosHeader->e_lfanew); 

    if (pNtHeaders->Signature != IMAGE_NT_SIGNATURE) 
     return p; 

    IMAGE_OPTIONAL_HEADER* pOptionalHeader = &pNtHeaders->OptionalHeader; 

    if((char*) p >= (char*)hDll && (char*) p <= ((char*)hDll) + pOptionalHeader->SizeOfCode) 
     // Sounds like valid address. 
     return p; 

    // Does not sounds right, may be someone hooked given function ? (ConEmuHk64.dll or ConEmuHk.dll) 
    IMAGE_DATA_DIRECTORY* pDataDirectory = &pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; 
    IMAGE_EXPORT_DIRECTORY* pExp = (IMAGE_EXPORT_DIRECTORY *) ((size_t) pDosHeader + pDataDirectory->VirtualAddress); 

    ULONG* addrofnames = (ULONG *) ((BYTE*) hDll + pExp->AddressOfNames); 
    ULONG* funcaddr = (ULONG*) ((BYTE*) hDll + pExp->AddressOfFunctions); 

    for (DWORD i = 0; i < pExp->NumberOfNames; i++) 
    { 
     char* funcname = (char*) ((BYTE*) hDll + addrofnames[i]); 

     if (strcmp(funcname, funcName) == 0) 
     { 
      void* p2 = (void*) ((BYTE*) hDll + funcaddr[i]); 
      return (FARPROC) p2; 
     } 
    } //for 

    return p; 
} //GetProcAddress2 

- 나는 hooked 함수를 발견하고 그것의 행동을 오버라이드 할 수있다. 그러나이 방법은 일반적이지 않습니다. 다른 메서드에 대한 비슷한 함수 호출을 시도했습니다 (예 : FreeLibrary/AddDllDirectory/RemoveDllDirectory). 그리고 해당 함수 포인터는 dll 경계 밖으로 찾아냅니다. GetProcAddress은 DOS 헤더 앞에 주소를 반환합니다.

if((char*) p >= (char*)hDll && (char*) p <= ((char*)hDll) + pOptionalHeader->SizeOfCode) 

을하지만 수식을 개선 할 수있는 방법을 단서가없는 :

나는 DLL/코드 크기 범위에 의해 비교가 올바른 아니라고 생각한다.

이 수정 프로그램을 완전히 만드는 방법을 권해 주실 수 있습니다. 따라서 타사 소프트웨어가 어떤 기능을 가로채을 수 있으며 충돌없이 생존 할 수 있습니까?

답변

1

"내 보낸 함수 전달"이 사용 된 경우 (이 용어로 검색 될 수 있음) 함수 포인터 해석이 올바르지 않습니다.

올바른 함수 결정은 다음과 같이 작성할 수 있습니다. (위에서 볼 수있는 것은 일부 포럼에서 복사하여 붙여 넣은 함수입니다.)

// 
// We use GetProcAddress as a base function, with exception to when GetProcAddress itself is hooked by 3-rd party 
// software and pointer to function returned to us is incorrect - then we try to locate function manually by 
// ourselfes. 
// 
FARPROC GetProcAddress2(HMODULE hDll, char* funcName) 
{ 
    FARPROC p = GetProcAddress(hDll, funcName); 

    if(!p) 
     return NULL; 

    IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER *) hDll; 

    if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) 
     return p; 

    IMAGE_NT_HEADERS* pNtHeaders = (IMAGE_NT_HEADERS *) (((char*) pDosHeader) + pDosHeader->e_lfanew); 

    if (pNtHeaders->Signature != IMAGE_NT_SIGNATURE) 
     return p; 

    IMAGE_OPTIONAL_HEADER* pOptionalHeader = &pNtHeaders->OptionalHeader; 

    if((char*) p >= (char*)hDll && (char*) p <= ((char*)hDll) + pOptionalHeader->SizeOfCode) 
     // Sounds like valid address. 
     return p; 

    // Does not sounds right, may be someone hooked given function ? (ConEmuHk64.dll or ConEmuHk.dll) 
    IMAGE_DATA_DIRECTORY* pDataDirectory = &pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; 
    IMAGE_EXPORT_DIRECTORY* pExp = (IMAGE_EXPORT_DIRECTORY *) ((size_t) pDosHeader + pDataDirectory->VirtualAddress); 

    ULONG* addrofnames = (ULONG *) ((BYTE*) hDll + pExp->AddressOfNames); 
    ULONG* funcaddr = (ULONG*) ((BYTE*) hDll + pExp->AddressOfFunctions); 

    for (DWORD i = 0; i < pExp->NumberOfNames; i++) 
    { 
     char* funcname = (char*) ((BYTE*) hDll + addrofnames[i]); 

     if (strcmp(funcname, funcName) == 0) 
     { 
      ULONG addressOfFunction = funcaddr[i]; 
      void* p2 = (void*) ((BYTE*) hDll + addressOfFunction); 

      if(addressOfFunction >= pDataDirectory->VirtualAddress && addressOfFunction < pDataDirectory->VirtualAddress + pDataDirectory->Size) 
      { 
       // "Exported function forward" - address of function can be found in another module. 
       // Actually for example AddDllDirectory is truly located in KernelBase.dll (alias api-ms-win-core-libraryloader-l1-1-0.dll ?) 
       char* dll_func = (char*) p2; 
       char* pdot = strchr(dll_func, '.'); 
       if(!pdot) pdot = dll_func + strlen(dll_func); 
       CStringA dllName(dll_func, (int)(pdot - dll_func)); 
       dllName += ".dll"; 

       HMODULE hDll2 = GetModuleHandleA(dllName); 
       if(hDll2 == NULL) 
        return p; 

       return GetProcAddress2(hDll2, pdot + 1); 
      } 

      return (FARPROC) p2; 
     } 
    } //for 

    return p; 
} //GetProcAddress2 

이 외에도 여전히 .DLL 다른 주소를로드 할 수 사용하는 것도 가능하지만, 이것은 KERNEL32.DLL 또는 kernelbase.dll으로 발생하지 않습니다. 해결하는 한 가지 방법은 EasyHook 접근 방식을 사용하는 것입니다 - -

그러나 .DLL 리베이스가 문제로 오는 경우

여기에 있습니다 :

https://github.com/EasyHook/EasyHook/blob/b8b2e37cfe1c269eea7042420bde305eb127c973/EasyHookDll/RemoteHook/thread.c

참조 기능 GetRemoteFuncAddress.