function pointers and dll load order - c++

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.

Related

CPP Windows string conversions confusion CStringA and LPCWSTR

I need to use WinAPI function to restart a windows service, I am not familiar with strings in C++.
My function receive as parameter: const CStringA& serviceName:
bool MyClassName::RestartServer(const CStringA& serviceName)
When I obtain SC Handle via OpenService(..) I need to provide type LPCWSTR :
SC_HANDLE SHandle = OpenService(hSCManager, LPCWSTR serviceNameAsWideString, SC_MANAGER_ALL_ACCESS);
How do I convert CStringA to LPCWSTR?
I tried to following:
CA2W(serviceName, CP_UTF8);
CString str("MyServiceName"); CStringW strw(str); LPCWSTR ptr = strw;
Both did not work properly, they compiled, but when I tried to execute the code.
It failed to OpenService().
What worked:
LPCWSTR newString = serviceName.AllocSysString();
What am I missing here? Why 1 and 2 did not work? Why 3 worked?
How do I properly deallocate newString?
Your code requires a conversion because you are calling the TCHAR-based OpenService() macro, which maps to either OpenServiceW() or OpenServiceA() depending on whether UNICODE is defined:
__checkReturn
WINADVAPI
SC_HANDLE
WINAPI
OpenServiceA(
__in SC_HANDLE hSCManager,
__in LPCSTR lpServiceName,
__in DWORD dwDesiredAccess
);
__checkReturn
WINADVAPI
SC_HANDLE
WINAPI
OpenServiceW(
__in SC_HANDLE hSCManager,
__in LPCWSTR lpServiceName,
__in DWORD dwDesiredAccess
);
#ifdef UNICODE
#define OpenService OpenServiceW
#else
#define OpenService OpenServiceA
#endif // !UNICODE
In your case, UNICODE is clearly being defined in your project, so your code is really calling OpenServiceW(), which is why it expects an LPCWSTR as input.
Your RestartServer() method takes a CStringA (char-based ANSI) string as input, so you should use OpenServiceA() explicitly to match the same character type, no conversion needed:
bool MyClassName::RestartServer(const CStringA& serviceName)
{
...
SC_HANDLE SHandle = OpenServiceA(hSCManager, serviceName, SC_MANAGER_ALL_ACCESS);
...
}
Otherwise, if you are going to continue using TCHAR-based functionality in your code 1, then you should change your RestartServer() method to take a CString instead of a CStringA so it adopts the same ANSI/Unicode mapping that OpenService() does (and other TCHAR-based functions do), again avoiding a conversion:
1: which you should not do, since there is rarely a need to ever write code for Win9x/ME nowadays. Windows has been a Unicode-based OS since NT4.
bool MyClassName::RestartServer(const CString& serviceName)
If that is not an option for you, then CA2W() will work just fine:
bool MyClassName::RestartServer(const CStringA& serviceName)
{
USES_CONVERSION;
...
SC_HANDLE SHandle = OpenService(hSCManager, ATL::CA2W(serviceName), SC_MANAGER_ALL_ACCESS);
...
}
Though, you might consider just using CString internally and let it handle a conversion if needed:
bool MyClassName::RestartServer(const CStringA& serviceName)
{
...
SC_HANDLE SHandle = OpenService(hSCManager, CString(serviceName), SC_MANAGER_ALL_ACCESS);
...
}
Or, make the code conditional:
bool MyClassName::RestartServer(const CStringA& serviceName)
{
...
SC_HANDLE SHandle = OpenService(hSCManager,
#ifdef UNICODE
CStringW(serviceName)
#else
serviceName
#endif
, SC_MANAGER_ALL_ACCESS);
...
}
CStringA and CStringW have constructors taking both const char* and const wchar_t* C strings.
Write following:
CStringW serviceNameW( serviceName );
About AllocSysString, it creates a copy in BSTR, they’re more complex than C strings, they’re null-terminated too but they also have length at negative offset. If you want to do manual memory management, call SysFreeString on the pointer. Or if you want BSTR but don’t want manual memory management, use CComBSTR class.

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.

How can I tell if a user wants hex or decimal display of numbers in an EEAddIn viewer function?

I have an old Visual Studio EEAddin-style debugger extension that is designed to take strings that have been mapped to integers at runtime and reverse the mapping in order to display the original string value in the watch window.
For example the display of the string mapped to the integer 0x39ad1dc4 is 0x39ad1dc4 (Hello, world!).
I would like to respect the setting of the debugger's "Hexadecimal Display" flag when I format the integer portion of the result, but I am not sure how (or even if) I can get access to that setting from my callback.
For reference, the EEAddin "custom viewer" callback I am using is:
typedef HRESULT (WINAPI * CUSTOMVIEWER)(DWORD address, DEBUGHELPER * helper, int base, BOOL useUnicodeStrings, char * result, size_t max, DWORD reserved);
One might think the base parameter would give me the information I need, but in my tests it's always been 10, no matter what the state of the hex-display option in the debugger is set to.
I have access to a DEBUGHELPER API that looks like this:
typedef struct tagDEBUGHELPER {
DWORD dwVersion;
HRESULT (WINAPI * ReadDebuggeeMemory)(struct tagDEBUGHELPER * self, DWORD address, DWORD bytesToRead, VOID * destination, DWORD * bytesActuallyRead );
// The API calls below are only supported when dwVersion is >= 0x20000.
DWORDLONG (WINAPI * GetRealAddress)(struct tagDEBUGHELPER * self);
HRESULT (WINAPI * ReadDebuggeeMemoryEx)(struct tagDEBUGHELPER * self, DWORDLONG address, DWORD bytesToRead, VOID * destination, DWORD * bytesActuallyRead);
int (WINAPI * GetProcessorType)(struct tagDEBUGHELPER * self);
} DEBUGHELPER;
I had to manually define this API based on sample code scattered around the internet; documentation of it and any potentially-related APIs is fairly hard to come by. The above structure and the callback type are the only portions of the API I'm aware of.
Is there a way I determine the state of the hexadecimal display checkbox with this, or some related API? I could re-write the viewer in a new extension platform if necessary, so long as that platform allows me to author extensions for native code.

Find index of particular function in COM Interface's Vtable

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.