// oxid.h: A set of types to help find and crack oxids. // This code is taken from a header file development by DevelopMentor instructors. // Copyright (c) 1999, DeveloMentor. // All rights reserved. No warranties extended. #pragma once #ifndef INC_OXID #define INC_OXID #include <assert.h> const unsigned long OBJREF_SIGNATURE = 0x574f454d; const unsigned long OBJREF_STANDARD = 0x1; const unsigned long OBJREF_HANDLER = 0x2; const unsigned long OBJREF_CUSTOM = 0x4; const unsigned long SORF_NOPING = 0x1000; typedef __int64 OXID; typedef __int64 OID; typedef GUID IPID; typedef struct tagDUALSTRINGARRAY { unsigned short wNumEntries; // Number of entries in array. unsigned short wSecurityOffset; // Offset of security info. unsigned short aStringArray[1]; } DUALSTRINGARRAY; typedef struct tagSTDOBJREF { unsigned long flags; unsigned long cPublicRefs; OXID oxid; OID oid; IPID ipid; } STDOBJREF; typedef struct tagOBJREF { unsigned long signature; unsigned long flags; GUID iid; union { struct { STDOBJREF std; DUALSTRINGARRAY saResAddr; } u_standard; struct { STDOBJREF std; CLSID clsid; DUALSTRINGARRAY saResAddr; } u_handler; struct { CLSID clsid; unsigned long cbExtension; unsigned long size; byte *pData; } u_custom; } u_objref; } OBJREF; inline HRESULT GetCurrentOXID(OXID* poxid) { CComPtr<IStream> spStm; HRESULT hr = CreateStreamOnHGlobal(0, FALSE, &spStm); if( FAILED(hr) ) return hr; Dummy dummy; // Implements IUnknown only hr = CoMarshalInterface(spStm, IID_IUnknown, &dummy, MSHCTX_INPROC, 0, MSHLFLAGS_NORMAL); if( FAILED(hr) ) return hr; HGLOBAL hglobal = 0; hr = GetHGlobalFromStream(spStm, &hglobal); if( SUCCEEDED(hr) ) { OBJREF* pobjref = (OBJREF*)GlobalLock(hglobal); assert(pobjref->signature == OBJREF_SIGNATURE); if (pobjref->flags & OBJREF_STANDARD) *poxid = pobjref->u_objref.u_standard.std.oxid; else if (pobjref->flags & OBJREF_HANDLER) *poxid = pobjref->u_objref.u_handler.std.oxid; else hr = E_UNEXPECTED; GlobalUnlock(hglobal); } LARGE_INTEGER li = { 0 }; spStm->Seek(li, STREAM_SEEK_SET, 0); CoReleaseMarshalData(spStm); return hr; } // Handy for cracking OXIDs typedef __int64 QWORD; inline DWORD LODWORD(const QWORD & qw) { return DWORD(qw); } inline DWORD HIDWORD(const QWORD & qw) { return ((DWORD)((qw >> 32) & 0xFFFFFFFF)); } enum { CCH_MAX_FOR_OXID = 22 }; // buffer size needed to format and null-terminate enum { CCH_MAX_FOR_GUID = 39 }; // buffer size needed to format GUID (with curlies), and null-terminate inline int StringFromOXID2(const OXID& roxid, WCHAR *pwsz, int cchMax) { if (cchMax < CCH_MAX_FOR_OXID) return 0; wsprintfW(pwsz, L"{%04X-%04X-%04X-%04X}", int(HIWORD(HIDWORD(roxid))), int(LOWORD(HIDWORD(roxid))), int(HIWORD(LODWORD(roxid))), int(LOWORD(LODWORD(roxid)))); return CCH_MAX_FOR_OXID; }
struct Dummy : IUnknown { STDMETHODIMP QueryInterface(REFIID riid, void **ppv) { if (riid == IID_IUnknown) return (*ppv = static_cast<IUnknown*>(this)), S_OK; else return (*ppv = 0), E_NOINTERFACE; } STDMETHODIMP_(ULONG) AddRef() { return 2; } STDMETHODIMP_(ULONG) Release() { return 1; } };#endif // INC_OXID
struct Dummy : IUnknown { STDMETHODIMP QueryInterface(REFIID riid, void **ppv) { if (riid == IID_IUnknown) return (*ppv = static_cast<IUnknown*>(this)), S_OK; else return (*ppv = 0), E_NOINTERFACE; } STDMETHODIMP_(ULONG) AddRef() { return 2; } STDMETHODIMP_(ULONG) Release() { return 1; } };