2011-01-04 12 views
2

kernel32.dll, Advapi32.dll 등의 일부 함수를 연결하는 프로그램을 개발해야합니다. 예를 들어 RegOpenKey()와 같은 일부 기능의 기능을 변경해야합니다. 사실, 대상 프로그램에 어떤 코드도 삽입 할 수 없기 때문에 대상 프로그램이 시작될 때 먼저 해당 함수를 호출합니다. 또한 대상 프로세스에 코드를 삽입하지 않아도됩니다. 또한, 나는 현재 실행중인 모든 프로세스 및 응용 프로그램 (32 비트, 콘솔 응용 프로그램, Win 응용 프로그램)에 대해이 기능을 변경해야하며 장래에 이러한 응용 프로그램이 실행됩니다. DLL 삽입, DLL 후킹에 대한 많은 기사를 읽었지만이를 극복 할 방법이 없습니다. 도와주세요. 나에게 지식을 나눠주세요.시스템 Wide Api 후킹

+0

? 글로벌 후킹은 사람들이 정상적으로하는 일이 아닙니다. – YeenFei

답변

0

필요에 따라 추가 기능을 변경하거나 제공하려는 필요한 호출을 연결할 수있는 커널 드라이버를 작성해야합니다. 예를 들어 : write 전화를 걸면, 컴퓨터에서 실행되는 모든 프로그램 (예외가 거의없는 것 같지만 걱정할 필요는 없다)은 write 작업을 호출 할 때 적절한 정보로 호출 된 함수가 호출됩니다. 호출 프로세스 및 기타 정보 (일반적으로 콜백 데이터라고 함). 그럼 당신은 당신이 당신의 구부러진 기능에서 생각하고있는 것을 추가/추가 할 수 있습니다.

Windows XP SP3 이상을 사용하는 경우 레거시 Windows 드라이버와 비교하여 쉽게 배우고 구현할 수 있으므로 필터 드라이버를 사용할 수 있습니다. 필터 드라이버에는 한계가 있지만 요구 사항에 따라 완벽하게 맞습니다.

0

가장 좋은 방법은 핫 패칭 (Hot-Patching)입니다. MS가 업데이트 시스템을 통해 기능을 패치 할 때 시스템 전체의 우회 경로를 적용하는 방법입니다.

2

코드를 삽입하지 않고 가로채는 유일한 옵션은 커널 모드 드라이버입니다. 레지스트리 드라이버는 Vista +에서 쉽게 구현할 수 있지만 SSDT 레지스트리 연결을 만들어야합니다. SSDT는 XP 및 Vista/W7에서 동일한 코드로 작동하지 않으며 x64 환경에서는 전혀 작동하지 않습니다 (후킹 기술은 허용되지 않습니다). 그래서 XP 용 레지스트리 SSDT와 Vista 및 W7 용 CmRegisterCallback (more info)을 커널 모드 필터 드라이버에 연결해야합니다.

0

귀하의 설명에서 알 수 있듯이 특정 API의 동작을 변경하려고합니다. 그러나 API에 전달 된 데이터를 변경할지 아니면 단순히 요청을 무시 할지를 지정하지 않았습니다. 어쨌든, 그러한 요구 사항에 대해 가장 쉽고 간단한 해결책은 미니 필터 커널 드라이버를 작성하는 것입니다. 이 방법에서는 을 사용하고 CmRegisterCallback은 사용하지 않으므로이 레지스트리 키 필터는 콜백을 등록하여 레지스트리 이벤트를 필터링합니다. 그런 다음 변경할 각 레지스트리 이벤트를 처리하는 자체 콜백 함수를 작성할 수 있습니다. 다음은 미니 필터 커널 드라이버를 작성하는 방법에 대한 간단한 스 니펫입니다. 단순히 요청을 거부하거나 내용을 변경하여 API를 변경하기위한 논리를 작성해야한다는 것을 기억하십시오.

#include <fltKernel.h> 
#include <dontuse.h> 
#include <suppress.h> 

LARGE_INTEGER g_Cookie = { 0 }; 

NTSTATUS DriverRegistryCallback(
    _In_ PVOID CallbackContext, 
    _In_ PVOID Argument1, 
    _In_ PVOID Argument2 
    ) { 
    UNREFERENCED_PARAMETER(CallbackContext); 

    PREG_POST_OPERATION_INFORMATION PreInfo; 
    PREG_OPEN_KEY_INFORMATION_V1 OpenKey; 
    PREG_CREATE_KEY_INFORMATION_V1 CreateKey; 

    REG_NOTIFY_CLASS RegOp = (REG_NOTIFY_CLASS)(ULONG_PTR)Argument1; 
    switch (RegOp) { 
     case RegNtPreCreateKeyEx: 
      PreInfo = (PREG_POST_OPERATION_INFORMATION)Argument2; 
      CreateKey = (PREG_CREATE_KEY_INFORMATION_V1)PreInfo->PreInformation; 
      if (PreInfo->Status == STATUS_SUCCESS) { 
       // do something here 
      } 
      break; 

     case RegNtPreOpenKeyEx: 
      PreInfo = (PREG_POST_OPERATION_INFORMATION)Argument2; 
      OpenKey = (PREG_OPEN_KEY_INFORMATION_V1)PreInfo->PreInformation; 
      if (PreInfo->Status == STATUS_SUCCESS) { 
       // do something here 
      } 
      break; 

     default: 
      break; 
    } 

    return STATUS_SUCCESS; 
} 

VOID 
DriverUnload(
    _In_ PDRIVER_OBJECT pDriverObject 
    ) { 
    UNREFERENCED_PARAMETER(pDriverObject); 

    PAGED_CODE(); 

    NTSTATUS status = CmUnRegisterCallback(g_Cookie); 
    if (!NT_SUCCESS(status)) { 
     DbgPrint("[RegistryFilter] Failed to unregister callback\n"); 
    } 

    DbgPrint("[RegistryFilter] Driver unloaded successfully\n"); 
} 

NTSTATUS 
DriverEntry(
    _In_ PDRIVER_OBJECT pDriverObject, 
    _In_ PUNICODE_STRING pRegistryPath 
    ) { 
    UNREFERENCED_PARAMETER(pRegistryPath); 

    pDriverObject->DriverUnload = DriverUnload; 

    UNICODE_STRING AltitudeString = RTL_CONSTANT_STRING(L"360000"); 
    NTSTATUS status = CmRegisterCallbackEx(DriverRegistryCallback, &AltitudeString, pDriverObject, NULL, &g_Cookie, NULL); 
    if (!NT_SUCCESS(status)) { 
     DbgPrint("[RegistryFilter] Failed to register callback\n"); 

     return status; 
    } 

    DbgPrint("[RegistryFilter] Driver loaded successfully\n"); 

    return status; 
} 

이것은 최종 해결책이 아닙니다. 앞에서 언급 한 것처럼 자신의 정적 데이터로 반환 된 데이터를 비교하여 특정 호출에 대한 액세스를 거부 한 다음 STATUS_ACCESS_DENIED을 반환하거나 값을 보유한 데이터 구조를 변경 한 다음 다시 전달하기 위해 자신의 논리를 작성해야합니다. Open* 이벤트를 변경하려면 먼저 Create*을 처리해야 함을 알아야합니다. 어떤 Open* 이벤트도 앞에 와야하고 Create* 이벤트가 먼저 있어야하기 때문입니다.

참고로 SSDT는 Windows 버전에서 다른 버전으로 또는 서비스 팩에서 다른 버전으로 인덱스가 변경 될 때 권장되는 솔루션이 아닙니다. 신뢰할 수 없으며 일반적으로이 간단한 작업에는 권장되지 않습니다. 말할 것도없이 x64 아키텍처에서 작동하도록하는 데 문제가 있습니다.

편집 : Windows XP에서이 기능을 사용하려면 Vista +부터 시작해야한다는 점을 잊어 버렸습니다. 레지스트리 구조 이름뿐만 아니라 레지스트리 이벤트 이름도 변경되기 때문에 특정 변경이 필요합니다.

몇 가지 링크는 시작할 수도 있습니다
- CmRegisterCallbackEx (https://msdn.microsoft.com/en-us/library/windows/hardware/ff541921(v=vs.85).aspx)
- 윈도우 WDK CmRegisterCallbackEx 코드 샘플 생성하려는 어떤 소프트웨어 (https://github.com/Microsoft/Windows-driver-samples/tree/master/general/registry)