0

我正在尝试基于 ICredentialProvider 接口挂钩自定义凭据提供程序 UI。

使用本指南(Vtable Patching),我成功地钩住了 COM 接口。

但是挂钩GetCredentenialAt方法有问题,我将 vtable 索引设置为 10,然后尝试重新登录。LogonUI 屏幕闪烁:Ctrl+Alt+Del 屏幕:。

我的源代码:

#include "stdafx.h"
#include "VtableHooks.h"
#include "credentialprovider.h"

namespace Hook
{
    STDMETHODIMP GetCredentialAt(IUnknown* This, DWORD dwIndex, ICredentialProviderCredential** ppcpc);
    STDMETHODIMP QueryInterface(IUnknown* This, REFIID riid, void **ppvObject);
}

struct Context
{
    Context(): m_Name("Hooked object"){}
    PVOID m_OriginalQueryInterface;
    PVOID m_OriginalGetCredentialAt;
    ATL::CComBSTR m_Name;
};
std::auto_ptr<Context> g_Context;
HRESULT HookMethod(IUnknown* original, PVOID proxyMethod, PVOID* originalMethod, DWORD vtableOffset)
{   PVOID* originalVtable = *(PVOID**)original;
    if (originalVtable[vtableOffset] == proxyMethod)
        return S_OK;
    *originalMethod = originalVtable[vtableOffset];
    originalVtable[vtableOffset] = proxyMethod;
    return S_OK;
}

HRESULT InstallComInterfaceHooks(IUnknown* originalInterface, REFIID riid)
{
    HRESULT hr = S_OK;
    if (riid == IID_ICredentialProvider)
    {       
        // Only single instance of a target object is supported in the sample
        if (g_Context.get())return E_FAIL;

        ATL::CComPtr<ICredentialProvider> so;
        HRESULT hr = originalInterface->QueryInterface(IID_ICredentialProvider, (void**)&so);
            if (FAILED(hr)) return hr; // we need this interface to be present

        // remove protection from the vtable
        DWORD dwOld = 0;
        if (!::VirtualProtect(*(PVOID**)(originalInterface), sizeof(LONG_PTR), PAGE_EXECUTE_READWRITE, &dwOld))
            return E_FAIL;

        // hook interface methods
        g_Context.reset(new Context);
        HookMethod(so, (PVOID)Hook::QueryInterface, &g_Context->m_OriginalQueryInterface, 0);
        HookMethod(so, (PVOID)Hook::GetCredentialAt, &g_Context->m_OriginalGetCredentialAt, 10);    
    }
    return hr;
}

typedef HRESULT (WINAPI *QueryInterface_T)(IUnknown* This, REFIID riid, void **ppvObject);
STDMETHODIMP Hook::QueryInterface(IUnknown* This, REFIID riid, void **ppvObject)
{
    QueryInterface_T qi = (QueryInterface_T)g_Context->m_OriginalQueryInterface;
    HRESULT hr = qi(This, riid, ppvObject);
    return hr;
}

typedef HRESULT(WINAPI *GetCredentialAt_T)(IUnknown* This, DWORD dwIndex, ICredentialProviderCredential** ppcpc);
STDMETHODIMP Hook::GetCredentialAt(IUnknown* This, DWORD dwIndex, ICredentialProviderCredential** ppcpc)
{   
    GetCredentialAt_T qi = (GetCredentialAt_T)g_Context->m_OriginalGetCredentialAt;
    HRESULT hr = qi(This, dwIndex, ppcpc);
    return hr;
}
4

1 回答 1

0

使用 IDA,我正在显示加载第三个自定义 dll。这个 Dll 中断接口。

于 2015-03-19T16:24:59.173 回答