Find index of particular function in COM Interface's Vtable - c++

I'm trying to hook the SetCooperativeLevel function in the DirectDraw object. My goal is very similar to the one in this question API Hook on a COM object function? however the only problem is that I don't know the exact offset in IDirectDraw's vtable for SetCooperativeLevel. Is there anyway to glean this from perhaps <ddraw.h> or programatically?
Here's the interface declaration for IDirectDraw, however I'm unsure how this corresponds to the vtable.
DECLARE_INTERFACE_( IDirectDraw, IUnknown )
{
STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE;
STDMETHOD_(ULONG,AddRef) (THIS) PURE;
STDMETHOD_(ULONG,Release) (THIS) PURE;
STDMETHOD(Compact)(THIS) PURE;
STDMETHOD(CreateClipper)(THIS_ DWORD, LPDIRECTDRAWCLIPPER FAR*, IUnknown FAR * ) PURE;
STDMETHOD(CreatePalette)(THIS_ DWORD, LPPALETTEENTRY, LPDIRECTDRAWPALETTE FAR*, IUnknown FAR * ) PURE;
STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC, LPDIRECTDRAWSURFACE FAR *, IUnknown FAR *) PURE;
STDMETHOD(DuplicateSurface)( THIS_ LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE FAR * ) PURE;
STDMETHOD(EnumDisplayModes)( THIS_ DWORD, LPDDSURFACEDESC, LPVOID, LPDDENUMMODESCALLBACK ) PURE;
STDMETHOD(EnumSurfaces)(THIS_ DWORD, LPDDSURFACEDESC, LPVOID,LPDDENUMSURFACESCALLBACK ) PURE;
STDMETHOD(FlipToGDISurface)(THIS) PURE;
STDMETHOD(GetCaps)( THIS_ LPDDCAPS, LPDDCAPS) PURE;
STDMETHOD(GetDisplayMode)( THIS_ LPDDSURFACEDESC) PURE;
STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD, LPDWORD ) PURE;
STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE FAR *) PURE;
STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD) PURE;
STDMETHOD(GetScanLine)(THIS_ LPDWORD) PURE;
STDMETHOD(GetVerticalBlankStatus)(THIS_ LPBOOL ) PURE;
STDMETHOD(Initialize)(THIS_ GUID FAR *) PURE;
STDMETHOD(RestoreDisplayMode)(THIS) PURE;
STDMETHOD(SetCooperativeLevel)(THIS_ HWND, DWORD) PURE; // I'm trying to hook this
STDMETHOD(SetDisplayMode)(THIS_ DWORD, DWORD,DWORD) PURE;
STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD, HANDLE ) PURE;
};

Answering my own question: The vtable is laid out in exactly the same order the interface functions are declared.

Related

The object created with CoCreateObject do not contain pointers to functions in vtable

Background:
I hooked CoCreateObject through the DLL to Excel.
Within it, an IFileOpenDialog object was created through the original CoCreateObject function.
The orig variable below is a pointer to IFileOpenDialog.
static HRESULT WINAPI HookedCoCreateInstance(
REFCLSID rclsid,
LPUNKNOWN pUnkOuter,
DWORD dwClsContext,
REFIID riid,
LPVOID *ppv
) {
HRESULT hres = old_CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv);
if (IsEqualGUID(rclsid, CLSID_FileOpenDialog) && !hres) {
IFileOpenDialog *orig = reinterpret_cast<IFileOpenDialog *>(ppv);
DebugPrintf("HookedCoCreateInstance AA: orig=%p, pUnkOuter=%p, dwClsContext=%u\n", orig, pUnkOuter, dwClsContext);
orig->QueryInterface(...)
But when I call orig->QueryInterface the exception is caused.
Looking at the vtable below, each entry contains a pointer.
However, the pointer contains another pointer that is not a function instruction set, as shown in the second picture.
Can a vtable contain nested?

CryptVerifyTimeStampSignature returning CRYPT_E_ASN1_BADTAG

I am trying to verify the timestamp of a signature with the CryptVerifyTimeStampSignature Windows Crypto API function. I am stuggling to understand what exactly should be passed into the pbTSContentInfo parameter.
BOOL CryptVerifyTimeStampSignature(
_In_ const BYTE pbTSContentInfo,
DWORD cbTSContentInfo,
_In_opt_ const DWORD pbData,
DWORD cbData,
_In_opt_ HCERTSTORE hAdditionalStore,
_Out_ PCRYPT_TIMESTAMP_CONTEXT ppTsContext,
_Out_opt_ PCCERT_CONTEXT *ppTsSigner,
_Out_opt_ HCERTSTORE *phStore
);
MSDN documentation states that pbTSContentInfo should contain:
A pointer to a buffer that contains time stamp content.
I am unsure what exactly this pointer should point to and where I can retrieve it from. The signature I am validating is an Authenticode signature on an executable. So far I have tried passing the encoded message returned by CryptMsgGetParam however this returns CRYPT_E_ASN1_BADTAG.
Thanks to anyone who can help!

pInvoke in c# (Managed code)

I am trying to pInvoke a C method in c#, but it is giving error;
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
C Method;
HRESULT FilterVolumeInstanceFindFirst(
_In_ LPCWSTR lpVolumeName,
_In_ INSTANCE_INFORMATION_CLASS dwInformationClass,
_Out_ LPVOID lpBuffer,
_In_ DWORD dwBufferSize,
_Out_ LPDWORD lpBytesReturned,
_Out_ LPHANDLE lpVolumeInstanceFind
);
typedef struct _INSTANCE_BASIC_INFORMATION {
ULONG NextEntryOffset;
USHORT InstanceNameLength;
USHORT InstanceNameBufferOffset;
} INSTANCE_BASIC_INFORMATION, *PINSTANCE_BASIC_INFORMATION;
This is my code
[DllImport("FltLib", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto)]
public static extern int FilterVolumeInstanceFindFirst([MarshalAs(UnmanagedType.LPWStr)]
string lpVolumeName,
_INSTANCE_BASIC_INFORMATION dwInformationClass,
// IntPtr dwInformationClass,
out StringBuilder lpBuffer,
int dwBufferSize,
out UInt32 lpBytesReturned,
ref IntPtr lpVolumeInstanceFind);
[StructLayout(LayoutKind.Sequential)]
public struct _INSTANCE_BASIC_INFORMATION
{
public uint NextEntryOffset;
public uint InstanceNameLength;
public uint InstanceNameBufferOffset;
}
and calling code is;
_INSTANCE_BASIC_INFORMATION ins = new _INSTANCE_BASIC_INFORMATION();
StringBuilder sb1 = new StringBuilder();
uint ret = 512;
IntPtr vol = new IntPtr(100);
int res = FilterVolumeInstanceFindFirst("H:", ins, out sb1, 516, out ret, ref vol);
Please help,
Thanks
Your p/invoke translations are wrong. You've got the wrong types in your struct. It should be:
[StructLayout(LayoutKind.Sequential)]
public struct INSTANCE_BASIC_INFORMATION
{
public uint NextEntryOffset;
public ushort InstanceNameLength;
public ushort InstanceNameBufferOffset;
}
And the function itself was somewhat off. It should be:
[DllImport("FltLib")]
public static extern uint FilterVolumeInstanceFindFirst(
[MarshalAs(UnmanagedType.LPWStr)]
string lpVolumeName,
uint dwInformationClass,
out INSTANCE_BASIC_INFORMATION lpBuffer,
uint dwBufferSize,
out uint lpBytesReturned,
out IntPtr lpVolumeInstanceFind
);
The information class is really an enum. Look up its value in the appropriate header file. A quick web search suggests that InstanceBasicInformation has a value of 0. Do check that for yourself though by consulting the header file. Pass the size of the struct as dwBufferSize.
The call should be along these lines:
INSTANCE_BASIC_INFORMATION basicInfo;
uint bytesReturned;
IntPtr volumeInstanceFind;
uint res = FilterVolumeInstanceFindFirst("H:", InstanceBasicInformation,
out basicInfo, (uint)Marshal.SizeOf(typeof(INSTANCE_BASIC_INFORMATION)),
out bytesReturned, volumeInstanceFind);
These translations are always easiest done by writing C++ code first. Then you know what a correct call sequence is without being confounded by erroneous p/invoke translation.

Why RtlCopyMemory failed

All, I was trying to use RtlCopyMemory to duplicate a structure instance, But seems it didn't successfully copy the instance before the callback returns. I didn't know if I missed something, Please help to review the below code. Thanks.
#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
#define RtlCopyMemory(Destination,Source,Length) memcpy((Destination),(Source),(Length))
typedef struct _FLT_RELATED_OBJECTS {
USHORT CONST Size;
USHORT CONST TransactionContext; //TxF mini-version
PFLT_FILTER CONST Filter;
PFLT_VOLUME CONST Volume;
PFLT_INSTANCE CONST Instance;
PFILE_OBJECT CONST FileObject;
PKTRANSACTION CONST Transaction;
} FLT_RELATED_OBJECTS, *PFLT_RELATED_OBJECTS;
FLT_POSTOP_CALLBACK_STATUS
CreateBackUpFile_WhenPostCreatedCallback (
_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_In_ PVOID CompletionContext,
_In_ FLT_POST_OPERATION_FLAGS Flags
)
{
PFLT_RELATED_OBJECTS copiedRelatedObj;
...
RtlZeroMemory(&copiedRelatedObj, FltObjects->Size);
KdBreakPoint();
RtlCopyMemory(&copiedRelatedObj,FltObjects,FltObjects->Size);
DbgPrint("The file name in the FltObjects is : %s\n",FltObjects->FileObject->FileName);
DbgPrint("The file name in the Duplicated FltObjects is : %s\n",copiedRelatedObj->FileObject->FileName);
...
}
RtlZeroMemory requires pointer to a memory block as its first argument. But you give it pointer to pointer ( as PFLT_RELATED_OBJECTS is already a pointer ). Use
FLT_RELATED_OBJECTS copiedRelatedObj;
PFLT_RELATED_OBJECTS copiedRelatedObj;
The copiedRelatedObj variable is a pointer. It is not initialized. Yell a bit invisible Microsoft C programmers for that dreadful habit of declaring pointer types. Then remove the P. Fix:
FLT_RELATED_OBJECTS copiedRelatedObj;

function pointers and dll load order

I am using function pointers and LoadLibrary. Following is the my code. When I added EvtExportLog after _EvtSubscribe call, it started corrupting _EvtSubscribe values, If i added it before as done in following code everything works fine, now When I add another function pointer I am facing the same problem, anybody know what could be the issue here.
HMODULE module = LoadLibrary(L"wevtapi.dll");
_EvtExportLog = (BOOL (WINAPI * )(EVT_HANDLE ,LPCWSTR ,LPCWSTR ,LPCWSTR ,DWORD ))GetProcAddress(module, "EvtExportLog");
_EvtClearLog = (BOOL (WINAPI * )(EVT_HANDLE ,LPCWSTR,LPCWSTR,DWORD))GetProcAddress(module, "EvtClearLog");
_EvtOpenLog = (EVT_HANDLE (WINAPI *)(EVT_HANDLE ,LPCWSTR ,DWORD ))GetProcAddress(module, "EvtOpenLog");
_EvtGetLogInfo = (BOOL (WINAPI * )( EVT_HANDLE, EVT_LOG_PROPERTY_ID, DWORD, PEVT_VARIANT ,PDWORD))GetProcAddress(module, "EvtGetLogInfo");
_EvtQuery = (EVT_HANDLE (WINAPI * )(EVT_HANDLE,LPCWSTR ,LPCWSTR ,DWORD))GetProcAddress(module, "EvtQuery");
_EvtNext = (BOOL (WINAPI * )(EVT_HANDLE ,DWORD,EVT_HANDLE*,DWORD,DWORD,PDWORD))GetProcAddress(module, "EvtNext");
_EvtClose = (BOOL (WINAPI *)(EVT_HANDLE))GetProcAddress(module, "EvtClose");
_EvtCreateRenderContext = (EVT_HANDLE (WINAPI *)(DWORD, LPCWSTR *, DWORD))GetProcAddress(module, "EvtCreateRenderContext");
_EvtFormatMessage = (BOOL (WINAPI *)(EVT_HANDLE, EVT_HANDLE, DWORD, DWORD, PEVT_VARIANT, DWORD, DWORD, LPWSTR, PDWORD))GetProcAddress(module, "EvtFormatMessage");
_EvtOpenPublisherMetadata = (EVT_HANDLE (WINAPI *)(EVT_HANDLE, LPCWSTR, LPCWSTR, LCID, DWORD))GetProcAddress(module, "EvtOpenPublisherMetadata");
_EvtRender = (BOOL (WINAPI *)(EVT_HANDLE, EVT_HANDLE, DWORD, DWORD, PVOID, PDWORD, PDWORD))GetProcAddress(module, "EvtRender");
_EvtSubscribe = (EVT_HANDLE (WINAPI *)(EVT_HANDLE, HANDLE, LPCWSTR, LPCWSTR, EVT_HANDLE, PVOID, EVT_SUBSCRIBE_CALLBACK, DWORD))GetProcAddress(module, "EvtSubscribe");
This has nothing to do with DLL Load order, you're trashing the stack somewhere else, and it just happens that _EvtSubscribe is the victim depending on how you order the objects on the stack. The easiest way to trash the stack is if you were calling a function with the wrong signature, possibly by transcribing them by hand instead of just using static linking and the header.