2012-12-13 3 views
2

IDropTarget :: Drop COM 메서드를 후크하려고하는데, 전에 IFileOperation :: RenameItems 메서드를 후킹하고 있기 때문에 제대로 작동하고 RenameItems 후킹을 위해 다음 코드를 사용했습니다. .IDropTarget :: Drop 메서드 후킹

#include "stdafx.h" 
#include <windows.h> 
#include "MinHook.h" 
#include <Winternl.h> 
#include <stdio.h> 
#include <shlwapi.h> 
#include <tchar.h> 
#include <string.h> 
#include <psapi.h> 
#include <strsafe.h> 
#include <Shobjidl.h> 
#include <Shellapi.h> 
#include <Shlguid.h> 

#if defined _M_X64 
#pragma comment(lib, "libMinHook.x64.lib") 
bool __is32bitMachine = false ; 
#elif defined _M_IX86 
#pragma comment(lib, "libMinHook.x86.lib") 
bool __is32bitMachine = true; 
#endif 

PVOID GetInterfaceMethod(PVOID intf, DWORD methodIndex) 
{ 
if (__is32bitMachine) 
    return *(PVOID*)(*(DWORD_PTR*)intf + methodIndex * 4); 
else 
    return *(PVOID*)(*(DWORD_PTR*)intf + methodIndex * 8); 
} 

typedef HRESULT (STDMETHODCALLTYPE *RenameItemsNext)(IFileOperation *pThis, IUnknown *pUnkItems, LPCWSTR pszNewName); 
RenameItemsNext Real_RenameItems = NULL; 
RenameItemsNext Actual_RenameItems ; 

HRESULT STDMETHODCALLTYPE RenameItemsCallback(IFileOperation *pThis, IUnknown *pUnkItems, LPCWSTR pszNewName) 
{ 
IID IID_ShellItemArray; 
IID IID_DataObject; 
CLSIDFromString(L"{b63ea76d-1f85-456f-a19c-48159efa858b}", &IID_ShellItemArray); 
CLSIDFromString(L"{0000010E-0000-0000-C000-000000000046}", &IID_DataObject); 

void *shellItemArray; 
void *dataObject; 
LPWSTR dstFN; 

if (pUnkItems->QueryInterface(IID_ShellItemArray, &shellItemArray) == S_OK) 
{ 
    DWORD numItems = 0; 
    IShellItem *shell; 
    IShellItemArray *pItems = (IShellItemArray *) pUnkItems; 
    pItems->GetCount(&numItems); 
    for (int i = 0; i < numItems; i++) 
    { 
     pItems->GetItemAt(i, &shell); 
     shell->GetDisplayName(SIGDN_FILESYSPATH, &dstFN); 
     MessageBoxW(NULL, dstFN, L"Renamed From", MB_OK); 
    } 
    MessageBoxW(NULL, pszNewName, L"Renamed To", MB_OK); 
} 

if (pUnkItems->QueryInterface(IID_DataObject, &dataObject) == S_OK) 
{ 
    Real_SHCreateShell = (SHCreateShellNext)GetProcAddress(LoadLibraryA("shell32.dll"), "SHCreateShellItemArrayFromDataObject"); 
    if (Real_SHCreateShell != NULL) 
    { 
     if (Real_SHCreateShell((IDataObject*)dataObject, IID_ShellItemArray, &shellItemArray) == S_OK) 
     { 
      DWORD numItems = 0; 
      IShellItem *shell; 
      IShellItemArray *pItems = (IShellItemArray *)shellItemArray; 
      pItems->GetCount(&numItems); 
      if (pItems->GetCount(&numItems) == S_OK) 
      { 
       for (int i = 0; i < numItems; i++) 
       { 
        if (pItems->GetItemAt(i, &shell) == S_OK) 
        { 
         shell->GetDisplayName(SIGDN_FILESYSPATH, &dstFN); 
         MessageBoxW(NULL, dstFN, L"Renamed From", MB_OK); 
        } 
       } 
      } 
     } 
    } 
    MessageBoxW(NULL, dstFN, L"Renamed To", MB_OK); 
} 
return Real_RenameItems(pThis, pUnkItems, pszNewName); 
} 

typedef HRESULT (WINAPI *COCREATEINSTANCE)(REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID*); 
COCREATEINSTANCE Real_CoCreateInstance = NULL; 

HRESULT WINAPI CoCreateInstanceCallback(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID *ppv) 
{ 
const char *IFileOperation_GUID = "{3AD05575-8857-4850-9277-11B85BDB8E09}"; 
char GUIDString[64]; 

HRESULT HR = Real_CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv); 

sprintf_s(GUIDString, 64, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\0", 
    rclsid.Data1, rclsid.Data2, rclsid.Data3, 
    rclsid.Data4[0], rclsid.Data4[1], 
    rclsid.Data4[2], rclsid.Data4[3], 
    rclsid.Data4[4], rclsid.Data4[5], 
    rclsid.Data4[6], rclsid.Data4[7]); 

if (strcmp(GUIDString, IFileOperation_GUID) == 0) 
{  
    if(Real_RenameItems == NULL) 
    { 
     Actual_RenameItems = (RenameItemsNext) GetInterfaceMethod(*ppv, 13); 

     if (MH_CreateHook(Actual_RenameItems, &RenameItemsCallback, reinterpret_cast<void**>(&Real_RenameItems)) != MH_OK) 
     { 
      MessageBoxW(NULL, L"Failed CreateHook Real_RenameItems", L"Info!", MB_ICONWARNING|MB_OK); 
     } 
     if (MH_EnableHook(Actual_RenameItems) != MH_OK) 
     { 
      MessageBoxW(NULL, L"Failed EnableHook Real_RenameItems", L"Info!", MB_ICONWARNING|MB_OK); 
     } 
    } 
} 
return HR; 
} 

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) 
{ 
switch (ul_reason_for_call) 
{ 
case DLL_PROCESS_ATTACH: 
    if (MH_Initialize() != MH_OK) 
    { 
     MessageBoxW(NULL, L"Failed Initialize", L"Info!", MB_ICONWARNING|MB_OK);  
    } 
    if (MH_CreateHook(&CoCreateInstance, &CoCreateInstanceCallback, reinterpret_cast<void**>(&Real_CoCreateInstance)) != MH_OK) 
    { 
     MessageBoxW(NULL, L"Failed MH_CreateHook CoCreateInstance", L"Info!", MB_ICONWARNING|MB_OK); 
    } 
    if (MH_EnableHook(&CoCreateInstance) != MH_OK) 
    { 
     MessageBoxW(NULL, L"Failed MH_EnableHook CoCreateInstance", L"Info!", MB_ICONWARNING|MB_OK); 
    } 
    break; 

case DLL_PROCESS_DETACH: 
    if (MH_Uninitialize() != MH_OK) 
    {    
    } 
    if (MH_DisableHook(Actual_RenameItems) != MH_OK) 
    { 
    } 
    if (MH_DisableHook(&CoCreateInstance) != MH_OK) 
    { 
    } 
    break; 
} 
return TRUE; 
} 

위의 코드는 IOFileOperation :: RenameItems을 위해 잘 작동하고 내가 IDropTarget :: 드롭 방법에 대해 동일한 코드를 구현하려고하지만 무슨 일이 일어나고 것은 드롭의 조작을 요구하지 않는 CoCreateInstance 함수 자체가, 그래서 어떤 도움이 나를 구현하는 방법이 IDropTarget :: Drop Hooking .......

+0

입니다 아니 모든 COM 인터페이스는 CoCreateInstance를 사용하여 만든 가져옵니다 coclass에()의 일부입니다 이

업데이트하는 데 도움이 될 수있다, RegisterDropTarget 기능 후크보십시오. IDropTarget은 물건을 떨어 뜨리는 것을 지원하는 창에 의해 구현됩니다. 그것은 결코 CoCreateInstance()를 호출하지 않을 것입니다. 이미 인스턴스가 있습니다. –

+0

ok ... 제발 우리가 어떻게 구현할 수 있는지 제안 해 주시겠습니까? – nagaradderKantesh

답변

1

일반적으로 IDropTarget은 내부 구현됩니다. 클라이언트 응용 프로그램에 등록하고 RegisterDropTarget 호출로 등록합니다. 실제로 함수 이름이 RegisterDragDrop

+0

RegisterDropTarget 함수를 찾지 못해서 정확히 어떤 함수를 시도해야하는지 알려주세요 .... – nagaradderKantesh

+0

죄송합니다. RegisterDragDrop라는 [링크] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms678405 (v = vs.85) .aspx) – Serik

+0

괜찮아요 ... 그리고 내가 RegisterDragDrop 함수를 시도했지만 끌어서 놓기 작업 중에는 호출하지 않기 때문에 도움이되지 않습니다. 그래서 다른 방법으로 도울 수 있습니다 .. – nagaradderKantesh