diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..52396ce --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +*.sln +*.vcxproj +*.vcxproj.filters +.vs/ +build/ +Debug/ + +ParrotLoader/Release/ + +Release/ + +TeknoParrot\.sdf + +TeknoParrot\.v12\.suo + +TeknoParrot/TeknoParrot\.vcxproj\.user + +ParrotLoader/ParrotLoader\.vcxproj\.user + +*.user diff --git a/OpenParrot/deps/inc/dx8/d3d8.h b/OpenParrot/deps/inc/dx8/d3d8.h new file mode 100644 index 0000000..adf91eb --- /dev/null +++ b/OpenParrot/deps/inc/dx8/d3d8.h @@ -0,0 +1,1279 @@ +/*==========================================================================; + * + * Copyright (C) Microsoft Corporation. All Rights Reserved. + * + * File: d3d8.h + * Content: Direct3D include file + * + ****************************************************************************/ + +#ifndef _D3D8_H_ +#define _D3D8_H_ + +#ifndef DIRECT3D_VERSION +#define DIRECT3D_VERSION 0x0800 +#endif //DIRECT3D_VERSION + +// include this file content only if compiling for DX8 interfaces +#if(DIRECT3D_VERSION >= 0x0800) + + +/* This identifier is passed to Direct3DCreate8 in order to ensure that an + * application was built against the correct header files. This number is + * incremented whenever a header (or other) change would require applications + * to be rebuilt. If the version doesn't match, Direct3DCreate8 will fail. + * (The number itself has no meaning.)*/ + +#define D3D_SDK_VERSION 220 + + +#include + +#define COM_NO_WINDOWS_H +#include + +#include + +#if !defined(HMONITOR_DECLARED) && (WINVER < 0x0500) + #define HMONITOR_DECLARED + DECLARE_HANDLE(HMONITOR); +#endif + +#define D3DAPI WINAPI + +/* + * Interface IID's + */ +#if defined( _WIN32 ) && !defined( _NO_COM) + +/* IID_IDirect3D8 */ +/* {1DD9E8DA-1C77-4d40-B0CF-98FEFDFF9512} */ +DEFINE_GUID(IID_IDirect3D8, 0x1dd9e8da, 0x1c77, 0x4d40, 0xb0, 0xcf, 0x98, 0xfe, 0xfd, 0xff, 0x95, 0x12); + +/* IID_IDirect3DDevice8 */ +/* {7385E5DF-8FE8-41D5-86B6-D7B48547B6CF} */ +DEFINE_GUID(IID_IDirect3DDevice8, 0x7385e5df, 0x8fe8, 0x41d5, 0x86, 0xb6, 0xd7, 0xb4, 0x85, 0x47, 0xb6, 0xcf); + +/* IID_IDirect3DResource8 */ +/* {1B36BB7B-09B7-410a-B445-7D1430D7B33F} */ +DEFINE_GUID(IID_IDirect3DResource8, 0x1b36bb7b, 0x9b7, 0x410a, 0xb4, 0x45, 0x7d, 0x14, 0x30, 0xd7, 0xb3, 0x3f); + +/* IID_IDirect3DBaseTexture8 */ +/* {B4211CFA-51B9-4a9f-AB78-DB99B2BB678E} */ +DEFINE_GUID(IID_IDirect3DBaseTexture8, 0xb4211cfa, 0x51b9, 0x4a9f, 0xab, 0x78, 0xdb, 0x99, 0xb2, 0xbb, 0x67, 0x8e); + +/* IID_IDirect3DTexture8 */ +/* {E4CDD575-2866-4f01-B12E-7EECE1EC9358} */ +DEFINE_GUID(IID_IDirect3DTexture8, 0xe4cdd575, 0x2866, 0x4f01, 0xb1, 0x2e, 0x7e, 0xec, 0xe1, 0xec, 0x93, 0x58); + +/* IID_IDirect3DCubeTexture8 */ +/* {3EE5B968-2ACA-4c34-8BB5-7E0C3D19B750} */ +DEFINE_GUID(IID_IDirect3DCubeTexture8, 0x3ee5b968, 0x2aca, 0x4c34, 0x8b, 0xb5, 0x7e, 0x0c, 0x3d, 0x19, 0xb7, 0x50); + +/* IID_IDirect3DVolumeTexture8 */ +/* {4B8AAAFA-140F-42ba-9131-597EAFAA2EAD} */ +DEFINE_GUID(IID_IDirect3DVolumeTexture8, 0x4b8aaafa, 0x140f, 0x42ba, 0x91, 0x31, 0x59, 0x7e, 0xaf, 0xaa, 0x2e, 0xad); + +/* IID_IDirect3DVertexBuffer8 */ +/* {8AEEEAC7-05F9-44d4-B591-000B0DF1CB95} */ +DEFINE_GUID(IID_IDirect3DVertexBuffer8, 0x8aeeeac7, 0x05f9, 0x44d4, 0xb5, 0x91, 0x00, 0x0b, 0x0d, 0xf1, 0xcb, 0x95); + +/* IID_IDirect3DIndexBuffer8 */ +/* {0E689C9A-053D-44a0-9D92-DB0E3D750F86} */ +DEFINE_GUID(IID_IDirect3DIndexBuffer8, 0x0e689c9a, 0x053d, 0x44a0, 0x9d, 0x92, 0xdb, 0x0e, 0x3d, 0x75, 0x0f, 0x86); + +/* IID_IDirect3DSurface8 */ +/* {B96EEBCA-B326-4ea5-882F-2FF5BAE021DD} */ +DEFINE_GUID(IID_IDirect3DSurface8, 0xb96eebca, 0xb326, 0x4ea5, 0x88, 0x2f, 0x2f, 0xf5, 0xba, 0xe0, 0x21, 0xdd); + +/* IID_IDirect3DVolume8 */ +/* {BD7349F5-14F1-42e4-9C79-972380DB40C0} */ +DEFINE_GUID(IID_IDirect3DVolume8, 0xbd7349f5, 0x14f1, 0x42e4, 0x9c, 0x79, 0x97, 0x23, 0x80, 0xdb, 0x40, 0xc0); + +/* IID_IDirect3DSwapChain8 */ +/* {928C088B-76B9-4C6B-A536-A590853876CD} */ +DEFINE_GUID(IID_IDirect3DSwapChain8, 0x928c088b, 0x76b9, 0x4c6b, 0xa5, 0x36, 0xa5, 0x90, 0x85, 0x38, 0x76, 0xcd); + +#endif + +#ifdef __cplusplus + +interface IDirect3D8; +interface IDirect3DDevice8; + +interface IDirect3DResource8; +interface IDirect3DBaseTexture8; +interface IDirect3DTexture8; +interface IDirect3DVolumeTexture8; +interface IDirect3DCubeTexture8; + +interface IDirect3DVertexBuffer8; +interface IDirect3DIndexBuffer8; + +interface IDirect3DSurface8; +interface IDirect3DVolume8; + +interface IDirect3DSwapChain8; + +#endif + + +typedef interface IDirect3D8 IDirect3D8; +typedef interface IDirect3DDevice8 IDirect3DDevice8; +typedef interface IDirect3DResource8 IDirect3DResource8; +typedef interface IDirect3DBaseTexture8 IDirect3DBaseTexture8; +typedef interface IDirect3DTexture8 IDirect3DTexture8; +typedef interface IDirect3DVolumeTexture8 IDirect3DVolumeTexture8; +typedef interface IDirect3DCubeTexture8 IDirect3DCubeTexture8; +typedef interface IDirect3DVertexBuffer8 IDirect3DVertexBuffer8; +typedef interface IDirect3DIndexBuffer8 IDirect3DIndexBuffer8; +typedef interface IDirect3DSurface8 IDirect3DSurface8; +typedef interface IDirect3DVolume8 IDirect3DVolume8; +typedef interface IDirect3DSwapChain8 IDirect3DSwapChain8; + +#include "d3d8types.h" +#include "d3d8caps.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * DLL Function for creating a Direct3D8 object. This object supports + * enumeration and allows the creation of Direct3DDevice8 objects. + * Pass the value of the constant D3D_SDK_VERSION to this function, so + * that the run-time can validate that your application was compiled + * against the right headers. + */ + +IDirect3D8 * WINAPI Direct3DCreate8(UINT SDKVersion); + + +/* + * Direct3D interfaces + */ + + + + + + +#undef INTERFACE +#define INTERFACE IDirect3D8 + +DECLARE_INTERFACE_(IDirect3D8, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3D8 methods ***/ + STDMETHOD(RegisterSoftwareDevice)(THIS_ void* pInitializeFunction) PURE; + STDMETHOD_(UINT, GetAdapterCount)(THIS) PURE; + STDMETHOD(GetAdapterIdentifier)(THIS_ UINT Adapter,DWORD Flags,D3DADAPTER_IDENTIFIER8* pIdentifier) PURE; + STDMETHOD_(UINT, GetAdapterModeCount)(THIS_ UINT Adapter) PURE; + STDMETHOD(EnumAdapterModes)(THIS_ UINT Adapter,UINT Mode,D3DDISPLAYMODE* pMode) PURE; + STDMETHOD(GetAdapterDisplayMode)(THIS_ UINT Adapter,D3DDISPLAYMODE* pMode) PURE; + STDMETHOD(CheckDeviceType)(THIS_ UINT Adapter,D3DDEVTYPE CheckType,D3DFORMAT DisplayFormat,D3DFORMAT BackBufferFormat,BOOL Windowed) PURE; + STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE RType,D3DFORMAT CheckFormat) PURE; + STDMETHOD(CheckDeviceMultiSampleType)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL Windowed,D3DMULTISAMPLE_TYPE MultiSampleType) PURE; + STDMETHOD(CheckDepthStencilMatch)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT RenderTargetFormat,D3DFORMAT DepthStencilFormat) PURE; + STDMETHOD(GetDeviceCaps)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS8* pCaps) PURE; + STDMETHOD_(HMONITOR, GetAdapterMonitor)(THIS_ UINT Adapter) PURE; + STDMETHOD(CreateDevice)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice8** ppReturnedDeviceInterface) PURE; +}; + +typedef struct IDirect3D8 *LPDIRECT3D8, *PDIRECT3D8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3D8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3D8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3D8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3D8_RegisterSoftwareDevice(p,a) (p)->lpVtbl->RegisterSoftwareDevice(p,a) +#define IDirect3D8_GetAdapterCount(p) (p)->lpVtbl->GetAdapterCount(p) +#define IDirect3D8_GetAdapterIdentifier(p,a,b,c) (p)->lpVtbl->GetAdapterIdentifier(p,a,b,c) +#define IDirect3D8_GetAdapterModeCount(p,a) (p)->lpVtbl->GetAdapterModeCount(p,a) +#define IDirect3D8_EnumAdapterModes(p,a,b,c) (p)->lpVtbl->EnumAdapterModes(p,a,b,c) +#define IDirect3D8_GetAdapterDisplayMode(p,a,b) (p)->lpVtbl->GetAdapterDisplayMode(p,a,b) +#define IDirect3D8_CheckDeviceType(p,a,b,c,d,e) (p)->lpVtbl->CheckDeviceType(p,a,b,c,d,e) +#define IDirect3D8_CheckDeviceFormat(p,a,b,c,d,e,f) (p)->lpVtbl->CheckDeviceFormat(p,a,b,c,d,e,f) +#define IDirect3D8_CheckDeviceMultiSampleType(p,a,b,c,d,e) (p)->lpVtbl->CheckDeviceMultiSampleType(p,a,b,c,d,e) +#define IDirect3D8_CheckDepthStencilMatch(p,a,b,c,d,e) (p)->lpVtbl->CheckDepthStencilMatch(p,a,b,c,d,e) +#define IDirect3D8_GetDeviceCaps(p,a,b,c) (p)->lpVtbl->GetDeviceCaps(p,a,b,c) +#define IDirect3D8_GetAdapterMonitor(p,a) (p)->lpVtbl->GetAdapterMonitor(p,a) +#define IDirect3D8_CreateDevice(p,a,b,c,d,e,f) (p)->lpVtbl->CreateDevice(p,a,b,c,d,e,f) +#else +#define IDirect3D8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3D8_AddRef(p) (p)->AddRef() +#define IDirect3D8_Release(p) (p)->Release() +#define IDirect3D8_RegisterSoftwareDevice(p,a) (p)->RegisterSoftwareDevice(a) +#define IDirect3D8_GetAdapterCount(p) (p)->GetAdapterCount() +#define IDirect3D8_GetAdapterIdentifier(p,a,b,c) (p)->GetAdapterIdentifier(a,b,c) +#define IDirect3D8_GetAdapterModeCount(p,a) (p)->GetAdapterModeCount(a) +#define IDirect3D8_EnumAdapterModes(p,a,b,c) (p)->EnumAdapterModes(a,b,c) +#define IDirect3D8_GetAdapterDisplayMode(p,a,b) (p)->GetAdapterDisplayMode(a,b) +#define IDirect3D8_CheckDeviceType(p,a,b,c,d,e) (p)->CheckDeviceType(a,b,c,d,e) +#define IDirect3D8_CheckDeviceFormat(p,a,b,c,d,e,f) (p)->CheckDeviceFormat(a,b,c,d,e,f) +#define IDirect3D8_CheckDeviceMultiSampleType(p,a,b,c,d,e) (p)->CheckDeviceMultiSampleType(a,b,c,d,e) +#define IDirect3D8_CheckDepthStencilMatch(p,a,b,c,d,e) (p)->CheckDepthStencilMatch(a,b,c,d,e) +#define IDirect3D8_GetDeviceCaps(p,a,b,c) (p)->GetDeviceCaps(a,b,c) +#define IDirect3D8_GetAdapterMonitor(p,a) (p)->GetAdapterMonitor(a) +#define IDirect3D8_CreateDevice(p,a,b,c,d,e,f) (p)->CreateDevice(a,b,c,d,e,f) +#endif + + + + + + + + + + + + + + + + + + + +#undef INTERFACE +#define INTERFACE IDirect3DDevice8 + +DECLARE_INTERFACE_(IDirect3DDevice8, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DDevice8 methods ***/ + STDMETHOD(TestCooperativeLevel)(THIS) PURE; + STDMETHOD_(UINT, GetAvailableTextureMem)(THIS) PURE; + STDMETHOD(ResourceManagerDiscardBytes)(THIS_ DWORD Bytes) PURE; + STDMETHOD(GetDirect3D)(THIS_ IDirect3D8** ppD3D8) PURE; + STDMETHOD(GetDeviceCaps)(THIS_ D3DCAPS8* pCaps) PURE; + STDMETHOD(GetDisplayMode)(THIS_ D3DDISPLAYMODE* pMode) PURE; + STDMETHOD(GetCreationParameters)(THIS_ D3DDEVICE_CREATION_PARAMETERS *pParameters) PURE; + STDMETHOD(SetCursorProperties)(THIS_ UINT XHotSpot,UINT YHotSpot,IDirect3DSurface8* pCursorBitmap) PURE; + STDMETHOD_(void, SetCursorPosition)(THIS_ int X,int Y,DWORD Flags) PURE; + STDMETHOD_(BOOL, ShowCursor)(THIS_ BOOL bShow) PURE; + STDMETHOD(CreateAdditionalSwapChain)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DSwapChain8** pSwapChain) PURE; + STDMETHOD(Reset)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters) PURE; + STDMETHOD(Present)(THIS_ CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) PURE; + STDMETHOD(GetBackBuffer)(THIS_ UINT BackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface8** ppBackBuffer) PURE; + STDMETHOD(GetRasterStatus)(THIS_ D3DRASTER_STATUS* pRasterStatus) PURE; + STDMETHOD_(void, SetGammaRamp)(THIS_ DWORD Flags,CONST D3DGAMMARAMP* pRamp) PURE; + STDMETHOD_(void, GetGammaRamp)(THIS_ D3DGAMMARAMP* pRamp) PURE; + STDMETHOD(CreateTexture)(THIS_ UINT Width,UINT Height,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture8** ppTexture) PURE; + STDMETHOD(CreateVolumeTexture)(THIS_ UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture8** ppVolumeTexture) PURE; + STDMETHOD(CreateCubeTexture)(THIS_ UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture8** ppCubeTexture) PURE; + STDMETHOD(CreateVertexBuffer)(THIS_ UINT Length,DWORD Usage,DWORD FVF,D3DPOOL Pool,IDirect3DVertexBuffer8** ppVertexBuffer) PURE; + STDMETHOD(CreateIndexBuffer)(THIS_ UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer8** ppIndexBuffer) PURE; + STDMETHOD(CreateRenderTarget)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,BOOL Lockable,IDirect3DSurface8** ppSurface) PURE; + STDMETHOD(CreateDepthStencilSurface)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,IDirect3DSurface8** ppSurface) PURE; + STDMETHOD(CreateImageSurface)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,IDirect3DSurface8** ppSurface) PURE; + STDMETHOD(CopyRects)(THIS_ IDirect3DSurface8* pSourceSurface,CONST RECT* pSourceRectsArray,UINT cRects,IDirect3DSurface8* pDestinationSurface,CONST POINT* pDestPointsArray) PURE; + STDMETHOD(UpdateTexture)(THIS_ IDirect3DBaseTexture8* pSourceTexture,IDirect3DBaseTexture8* pDestinationTexture) PURE; + STDMETHOD(GetFrontBuffer)(THIS_ IDirect3DSurface8* pDestSurface) PURE; + STDMETHOD(SetRenderTarget)(THIS_ IDirect3DSurface8* pRenderTarget,IDirect3DSurface8* pNewZStencil) PURE; + STDMETHOD(GetRenderTarget)(THIS_ IDirect3DSurface8** ppRenderTarget) PURE; + STDMETHOD(GetDepthStencilSurface)(THIS_ IDirect3DSurface8** ppZStencilSurface) PURE; + STDMETHOD(BeginScene)(THIS) PURE; + STDMETHOD(EndScene)(THIS) PURE; + STDMETHOD(Clear)(THIS_ DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil) PURE; + STDMETHOD(SetTransform)(THIS_ D3DTRANSFORMSTATETYPE State,CONST D3DMATRIX* pMatrix) PURE; + STDMETHOD(GetTransform)(THIS_ D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) PURE; + STDMETHOD(MultiplyTransform)(THIS_ D3DTRANSFORMSTATETYPE,CONST D3DMATRIX*) PURE; + STDMETHOD(SetViewport)(THIS_ CONST D3DVIEWPORT8* pViewport) PURE; + STDMETHOD(GetViewport)(THIS_ D3DVIEWPORT8* pViewport) PURE; + STDMETHOD(SetMaterial)(THIS_ CONST D3DMATERIAL8* pMaterial) PURE; + STDMETHOD(GetMaterial)(THIS_ D3DMATERIAL8* pMaterial) PURE; + STDMETHOD(SetLight)(THIS_ DWORD Index,CONST D3DLIGHT8*) PURE; + STDMETHOD(GetLight)(THIS_ DWORD Index,D3DLIGHT8*) PURE; + STDMETHOD(LightEnable)(THIS_ DWORD Index,BOOL Enable) PURE; + STDMETHOD(GetLightEnable)(THIS_ DWORD Index,BOOL* pEnable) PURE; + STDMETHOD(SetClipPlane)(THIS_ DWORD Index,CONST float* pPlane) PURE; + STDMETHOD(GetClipPlane)(THIS_ DWORD Index,float* pPlane) PURE; + STDMETHOD(SetRenderState)(THIS_ D3DRENDERSTATETYPE State,DWORD Value) PURE; + STDMETHOD(GetRenderState)(THIS_ D3DRENDERSTATETYPE State,DWORD* pValue) PURE; + STDMETHOD(BeginStateBlock)(THIS) PURE; + STDMETHOD(EndStateBlock)(THIS_ DWORD* pToken) PURE; + STDMETHOD(ApplyStateBlock)(THIS_ DWORD Token) PURE; + STDMETHOD(CaptureStateBlock)(THIS_ DWORD Token) PURE; + STDMETHOD(DeleteStateBlock)(THIS_ DWORD Token) PURE; + STDMETHOD(CreateStateBlock)(THIS_ D3DSTATEBLOCKTYPE Type,DWORD* pToken) PURE; + STDMETHOD(SetClipStatus)(THIS_ CONST D3DCLIPSTATUS8* pClipStatus) PURE; + STDMETHOD(GetClipStatus)(THIS_ D3DCLIPSTATUS8* pClipStatus) PURE; + STDMETHOD(GetTexture)(THIS_ DWORD Stage,IDirect3DBaseTexture8** ppTexture) PURE; + STDMETHOD(SetTexture)(THIS_ DWORD Stage,IDirect3DBaseTexture8* pTexture) PURE; + STDMETHOD(GetTextureStageState)(THIS_ DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) PURE; + STDMETHOD(SetTextureStageState)(THIS_ DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) PURE; + STDMETHOD(ValidateDevice)(THIS_ DWORD* pNumPasses) PURE; + STDMETHOD(GetInfo)(THIS_ DWORD DevInfoID,void* pDevInfoStruct,DWORD DevInfoStructSize) PURE; + STDMETHOD(SetPaletteEntries)(THIS_ UINT PaletteNumber,CONST PALETTEENTRY* pEntries) PURE; + STDMETHOD(GetPaletteEntries)(THIS_ UINT PaletteNumber,PALETTEENTRY* pEntries) PURE; + STDMETHOD(SetCurrentTexturePalette)(THIS_ UINT PaletteNumber) PURE; + STDMETHOD(GetCurrentTexturePalette)(THIS_ UINT *PaletteNumber) PURE; + STDMETHOD(DrawPrimitive)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) PURE; + STDMETHOD(DrawIndexedPrimitive)(THIS_ D3DPRIMITIVETYPE,UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) PURE; + STDMETHOD(DrawPrimitiveUP)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) PURE; + STDMETHOD(DrawIndexedPrimitiveUP)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,UINT NumVertexIndices,UINT PrimitiveCount,CONST void* pIndexData,D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) PURE; + STDMETHOD(ProcessVertices)(THIS_ UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) PURE; + STDMETHOD(CreateVertexShader)(THIS_ CONST DWORD* pDeclaration,CONST DWORD* pFunction,DWORD* pHandle,DWORD Usage) PURE; + STDMETHOD(SetVertexShader)(THIS_ DWORD Handle) PURE; + STDMETHOD(GetVertexShader)(THIS_ DWORD* pHandle) PURE; + STDMETHOD(DeleteVertexShader)(THIS_ DWORD Handle) PURE; + STDMETHOD(SetVertexShaderConstant)(THIS_ DWORD Register,CONST void* pConstantData,DWORD ConstantCount) PURE; + STDMETHOD(GetVertexShaderConstant)(THIS_ DWORD Register,void* pConstantData,DWORD ConstantCount) PURE; + STDMETHOD(GetVertexShaderDeclaration)(THIS_ DWORD Handle,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(GetVertexShaderFunction)(THIS_ DWORD Handle,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(SetStreamSource)(THIS_ UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) PURE; + STDMETHOD(GetStreamSource)(THIS_ UINT StreamNumber,IDirect3DVertexBuffer8** ppStreamData,UINT* pStride) PURE; + STDMETHOD(SetIndices)(THIS_ IDirect3DIndexBuffer8* pIndexData,UINT BaseVertexIndex) PURE; + STDMETHOD(GetIndices)(THIS_ IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) PURE; + STDMETHOD(CreatePixelShader)(THIS_ CONST DWORD* pFunction,DWORD* pHandle) PURE; + STDMETHOD(SetPixelShader)(THIS_ DWORD Handle) PURE; + STDMETHOD(GetPixelShader)(THIS_ DWORD* pHandle) PURE; + STDMETHOD(DeletePixelShader)(THIS_ DWORD Handle) PURE; + STDMETHOD(SetPixelShaderConstant)(THIS_ DWORD Register,CONST void* pConstantData,DWORD ConstantCount) PURE; + STDMETHOD(GetPixelShaderConstant)(THIS_ DWORD Register,void* pConstantData,DWORD ConstantCount) PURE; + STDMETHOD(GetPixelShaderFunction)(THIS_ DWORD Handle,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(DrawRectPatch)(THIS_ UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) PURE; + STDMETHOD(DrawTriPatch)(THIS_ UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) PURE; + STDMETHOD(DeletePatch)(THIS_ UINT Handle) PURE; +}; + +typedef struct IDirect3DDevice8 *LPDIRECT3DDEVICE8, *PDIRECT3DDEVICE8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DDevice8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DDevice8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DDevice8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DDevice8_TestCooperativeLevel(p) (p)->lpVtbl->TestCooperativeLevel(p) +#define IDirect3DDevice8_GetAvailableTextureMem(p) (p)->lpVtbl->GetAvailableTextureMem(p) +#define IDirect3DDevice8_ResourceManagerDiscardBytes(p,a) (p)->lpVtbl->ResourceManagerDiscardBytes(p,a) +#define IDirect3DDevice8_GetDirect3D(p,a) (p)->lpVtbl->GetDirect3D(p,a) +#define IDirect3DDevice8_GetDeviceCaps(p,a) (p)->lpVtbl->GetDeviceCaps(p,a) +#define IDirect3DDevice8_GetDisplayMode(p,a) (p)->lpVtbl->GetDisplayMode(p,a) +#define IDirect3DDevice8_GetCreationParameters(p,a) (p)->lpVtbl->GetCreationParameters(p,a) +#define IDirect3DDevice8_SetCursorProperties(p,a,b,c) (p)->lpVtbl->SetCursorProperties(p,a,b,c) +#define IDirect3DDevice8_SetCursorPosition(p,a,b,c) (p)->lpVtbl->SetCursorPosition(p,a,b,c) +#define IDirect3DDevice8_ShowCursor(p,a) (p)->lpVtbl->ShowCursor(p,a) +#define IDirect3DDevice8_CreateAdditionalSwapChain(p,a,b) (p)->lpVtbl->CreateAdditionalSwapChain(p,a,b) +#define IDirect3DDevice8_Reset(p,a) (p)->lpVtbl->Reset(p,a) +#define IDirect3DDevice8_Present(p,a,b,c,d) (p)->lpVtbl->Present(p,a,b,c,d) +#define IDirect3DDevice8_GetBackBuffer(p,a,b,c) (p)->lpVtbl->GetBackBuffer(p,a,b,c) +#define IDirect3DDevice8_GetRasterStatus(p,a) (p)->lpVtbl->GetRasterStatus(p,a) +#define IDirect3DDevice8_SetGammaRamp(p,a,b) (p)->lpVtbl->SetGammaRamp(p,a,b) +#define IDirect3DDevice8_GetGammaRamp(p,a) (p)->lpVtbl->GetGammaRamp(p,a) +#define IDirect3DDevice8_CreateTexture(p,a,b,c,d,e,f,g) (p)->lpVtbl->CreateTexture(p,a,b,c,d,e,f,g) +#define IDirect3DDevice8_CreateVolumeTexture(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->CreateVolumeTexture(p,a,b,c,d,e,f,g,h) +#define IDirect3DDevice8_CreateCubeTexture(p,a,b,c,d,e,f) (p)->lpVtbl->CreateCubeTexture(p,a,b,c,d,e,f) +#define IDirect3DDevice8_CreateVertexBuffer(p,a,b,c,d,e) (p)->lpVtbl->CreateVertexBuffer(p,a,b,c,d,e) +#define IDirect3DDevice8_CreateIndexBuffer(p,a,b,c,d,e) (p)->lpVtbl->CreateIndexBuffer(p,a,b,c,d,e) +#define IDirect3DDevice8_CreateRenderTarget(p,a,b,c,d,e,f) (p)->lpVtbl->CreateRenderTarget(p,a,b,c,d,e,f) +#define IDirect3DDevice8_CreateDepthStencilSurface(p,a,b,c,d,e) (p)->lpVtbl->CreateDepthStencilSurface(p,a,b,c,d,e) +#define IDirect3DDevice8_CreateImageSurface(p,a,b,c,d) (p)->lpVtbl->CreateImageSurface(p,a,b,c,d) +#define IDirect3DDevice8_CopyRects(p,a,b,c,d,e) (p)->lpVtbl->CopyRects(p,a,b,c,d,e) +#define IDirect3DDevice8_UpdateTexture(p,a,b) (p)->lpVtbl->UpdateTexture(p,a,b) +#define IDirect3DDevice8_GetFrontBuffer(p,a) (p)->lpVtbl->GetFrontBuffer(p,a) +#define IDirect3DDevice8_SetRenderTarget(p,a,b) (p)->lpVtbl->SetRenderTarget(p,a,b) +#define IDirect3DDevice8_GetRenderTarget(p,a) (p)->lpVtbl->GetRenderTarget(p,a) +#define IDirect3DDevice8_GetDepthStencilSurface(p,a) (p)->lpVtbl->GetDepthStencilSurface(p,a) +#define IDirect3DDevice8_BeginScene(p) (p)->lpVtbl->BeginScene(p) +#define IDirect3DDevice8_EndScene(p) (p)->lpVtbl->EndScene(p) +#define IDirect3DDevice8_Clear(p,a,b,c,d,e,f) (p)->lpVtbl->Clear(p,a,b,c,d,e,f) +#define IDirect3DDevice8_SetTransform(p,a,b) (p)->lpVtbl->SetTransform(p,a,b) +#define IDirect3DDevice8_GetTransform(p,a,b) (p)->lpVtbl->GetTransform(p,a,b) +#define IDirect3DDevice8_MultiplyTransform(p,a,b) (p)->lpVtbl->MultiplyTransform(p,a,b) +#define IDirect3DDevice8_SetViewport(p,a) (p)->lpVtbl->SetViewport(p,a) +#define IDirect3DDevice8_GetViewport(p,a) (p)->lpVtbl->GetViewport(p,a) +#define IDirect3DDevice8_SetMaterial(p,a) (p)->lpVtbl->SetMaterial(p,a) +#define IDirect3DDevice8_GetMaterial(p,a) (p)->lpVtbl->GetMaterial(p,a) +#define IDirect3DDevice8_SetLight(p,a,b) (p)->lpVtbl->SetLight(p,a,b) +#define IDirect3DDevice8_GetLight(p,a,b) (p)->lpVtbl->GetLight(p,a,b) +#define IDirect3DDevice8_LightEnable(p,a,b) (p)->lpVtbl->LightEnable(p,a,b) +#define IDirect3DDevice8_GetLightEnable(p,a,b) (p)->lpVtbl->GetLightEnable(p,a,b) +#define IDirect3DDevice8_SetClipPlane(p,a,b) (p)->lpVtbl->SetClipPlane(p,a,b) +#define IDirect3DDevice8_GetClipPlane(p,a,b) (p)->lpVtbl->GetClipPlane(p,a,b) +#define IDirect3DDevice8_SetRenderState(p,a,b) (p)->lpVtbl->SetRenderState(p,a,b) +#define IDirect3DDevice8_GetRenderState(p,a,b) (p)->lpVtbl->GetRenderState(p,a,b) +#define IDirect3DDevice8_BeginStateBlock(p) (p)->lpVtbl->BeginStateBlock(p) +#define IDirect3DDevice8_EndStateBlock(p,a) (p)->lpVtbl->EndStateBlock(p,a) +#define IDirect3DDevice8_ApplyStateBlock(p,a) (p)->lpVtbl->ApplyStateBlock(p,a) +#define IDirect3DDevice8_CaptureStateBlock(p,a) (p)->lpVtbl->CaptureStateBlock(p,a) +#define IDirect3DDevice8_DeleteStateBlock(p,a) (p)->lpVtbl->DeleteStateBlock(p,a) +#define IDirect3DDevice8_CreateStateBlock(p,a,b) (p)->lpVtbl->CreateStateBlock(p,a,b) +#define IDirect3DDevice8_SetClipStatus(p,a) (p)->lpVtbl->SetClipStatus(p,a) +#define IDirect3DDevice8_GetClipStatus(p,a) (p)->lpVtbl->GetClipStatus(p,a) +#define IDirect3DDevice8_GetTexture(p,a,b) (p)->lpVtbl->GetTexture(p,a,b) +#define IDirect3DDevice8_SetTexture(p,a,b) (p)->lpVtbl->SetTexture(p,a,b) +#define IDirect3DDevice8_GetTextureStageState(p,a,b,c) (p)->lpVtbl->GetTextureStageState(p,a,b,c) +#define IDirect3DDevice8_SetTextureStageState(p,a,b,c) (p)->lpVtbl->SetTextureStageState(p,a,b,c) +#define IDirect3DDevice8_ValidateDevice(p,a) (p)->lpVtbl->ValidateDevice(p,a) +#define IDirect3DDevice8_GetInfo(p,a,b,c) (p)->lpVtbl->GetInfo(p,a,b,c) +#define IDirect3DDevice8_SetPaletteEntries(p,a,b) (p)->lpVtbl->SetPaletteEntries(p,a,b) +#define IDirect3DDevice8_GetPaletteEntries(p,a,b) (p)->lpVtbl->GetPaletteEntries(p,a,b) +#define IDirect3DDevice8_SetCurrentTexturePalette(p,a) (p)->lpVtbl->SetCurrentTexturePalette(p,a) +#define IDirect3DDevice8_GetCurrentTexturePalette(p,a) (p)->lpVtbl->GetCurrentTexturePalette(p,a) +#define IDirect3DDevice8_DrawPrimitive(p,a,b,c) (p)->lpVtbl->DrawPrimitive(p,a,b,c) +#define IDirect3DDevice8_DrawIndexedPrimitive(p,a,b,c,d,e) (p)->lpVtbl->DrawIndexedPrimitive(p,a,b,c,d,e) +#define IDirect3DDevice8_DrawPrimitiveUP(p,a,b,c,d) (p)->lpVtbl->DrawPrimitiveUP(p,a,b,c,d) +#define IDirect3DDevice8_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) +#define IDirect3DDevice8_ProcessVertices(p,a,b,c,d,e) (p)->lpVtbl->ProcessVertices(p,a,b,c,d,e) +#define IDirect3DDevice8_CreateVertexShader(p,a,b,c,d) (p)->lpVtbl->CreateVertexShader(p,a,b,c,d) +#define IDirect3DDevice8_SetVertexShader(p,a) (p)->lpVtbl->SetVertexShader(p,a) +#define IDirect3DDevice8_GetVertexShader(p,a) (p)->lpVtbl->GetVertexShader(p,a) +#define IDirect3DDevice8_DeleteVertexShader(p,a) (p)->lpVtbl->DeleteVertexShader(p,a) +#define IDirect3DDevice8_SetVertexShaderConstant(p,a,b,c) (p)->lpVtbl->SetVertexShaderConstant(p,a,b,c) +#define IDirect3DDevice8_GetVertexShaderConstant(p,a,b,c) (p)->lpVtbl->GetVertexShaderConstant(p,a,b,c) +#define IDirect3DDevice8_GetVertexShaderDeclaration(p,a,b,c) (p)->lpVtbl->GetVertexShaderDeclaration(p,a,b,c) +#define IDirect3DDevice8_GetVertexShaderFunction(p,a,b,c) (p)->lpVtbl->GetVertexShaderFunction(p,a,b,c) +#define IDirect3DDevice8_SetStreamSource(p,a,b,c) (p)->lpVtbl->SetStreamSource(p,a,b,c) +#define IDirect3DDevice8_GetStreamSource(p,a,b,c) (p)->lpVtbl->GetStreamSource(p,a,b,c) +#define IDirect3DDevice8_SetIndices(p,a,b) (p)->lpVtbl->SetIndices(p,a,b) +#define IDirect3DDevice8_GetIndices(p,a,b) (p)->lpVtbl->GetIndices(p,a,b) +#define IDirect3DDevice8_CreatePixelShader(p,a,b) (p)->lpVtbl->CreatePixelShader(p,a,b) +#define IDirect3DDevice8_SetPixelShader(p,a) (p)->lpVtbl->SetPixelShader(p,a) +#define IDirect3DDevice8_GetPixelShader(p,a) (p)->lpVtbl->GetPixelShader(p,a) +#define IDirect3DDevice8_DeletePixelShader(p,a) (p)->lpVtbl->DeletePixelShader(p,a) +#define IDirect3DDevice8_SetPixelShaderConstant(p,a,b,c) (p)->lpVtbl->SetPixelShaderConstant(p,a,b,c) +#define IDirect3DDevice8_GetPixelShaderConstant(p,a,b,c) (p)->lpVtbl->GetPixelShaderConstant(p,a,b,c) +#define IDirect3DDevice8_GetPixelShaderFunction(p,a,b,c) (p)->lpVtbl->GetPixelShaderFunction(p,a,b,c) +#define IDirect3DDevice8_DrawRectPatch(p,a,b,c) (p)->lpVtbl->DrawRectPatch(p,a,b,c) +#define IDirect3DDevice8_DrawTriPatch(p,a,b,c) (p)->lpVtbl->DrawTriPatch(p,a,b,c) +#define IDirect3DDevice8_DeletePatch(p,a) (p)->lpVtbl->DeletePatch(p,a) +#else +#define IDirect3DDevice8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DDevice8_AddRef(p) (p)->AddRef() +#define IDirect3DDevice8_Release(p) (p)->Release() +#define IDirect3DDevice8_TestCooperativeLevel(p) (p)->TestCooperativeLevel() +#define IDirect3DDevice8_GetAvailableTextureMem(p) (p)->GetAvailableTextureMem() +#define IDirect3DDevice8_ResourceManagerDiscardBytes(p,a) (p)->ResourceManagerDiscardBytes(a) +#define IDirect3DDevice8_GetDirect3D(p,a) (p)->GetDirect3D(a) +#define IDirect3DDevice8_GetDeviceCaps(p,a) (p)->GetDeviceCaps(a) +#define IDirect3DDevice8_GetDisplayMode(p,a) (p)->GetDisplayMode(a) +#define IDirect3DDevice8_GetCreationParameters(p,a) (p)->GetCreationParameters(a) +#define IDirect3DDevice8_SetCursorProperties(p,a,b,c) (p)->SetCursorProperties(a,b,c) +#define IDirect3DDevice8_SetCursorPosition(p,a,b,c) (p)->SetCursorPosition(a,b,c) +#define IDirect3DDevice8_ShowCursor(p,a) (p)->ShowCursor(a) +#define IDirect3DDevice8_CreateAdditionalSwapChain(p,a,b) (p)->CreateAdditionalSwapChain(a,b) +#define IDirect3DDevice8_Reset(p,a) (p)->Reset(a) +#define IDirect3DDevice8_Present(p,a,b,c,d) (p)->Present(a,b,c,d) +#define IDirect3DDevice8_GetBackBuffer(p,a,b,c) (p)->GetBackBuffer(a,b,c) +#define IDirect3DDevice8_GetRasterStatus(p,a) (p)->GetRasterStatus(a) +#define IDirect3DDevice8_SetGammaRamp(p,a,b) (p)->SetGammaRamp(a,b) +#define IDirect3DDevice8_GetGammaRamp(p,a) (p)->GetGammaRamp(a) +#define IDirect3DDevice8_CreateTexture(p,a,b,c,d,e,f,g) (p)->CreateTexture(a,b,c,d,e,f,g) +#define IDirect3DDevice8_CreateVolumeTexture(p,a,b,c,d,e,f,g,h) (p)->CreateVolumeTexture(a,b,c,d,e,f,g,h) +#define IDirect3DDevice8_CreateCubeTexture(p,a,b,c,d,e,f) (p)->CreateCubeTexture(a,b,c,d,e,f) +#define IDirect3DDevice8_CreateVertexBuffer(p,a,b,c,d,e) (p)->CreateVertexBuffer(a,b,c,d,e) +#define IDirect3DDevice8_CreateIndexBuffer(p,a,b,c,d,e) (p)->CreateIndexBuffer(a,b,c,d,e) +#define IDirect3DDevice8_CreateRenderTarget(p,a,b,c,d,e,f) (p)->CreateRenderTarget(a,b,c,d,e,f) +#define IDirect3DDevice8_CreateDepthStencilSurface(p,a,b,c,d,e) (p)->CreateDepthStencilSurface(a,b,c,d,e) +#define IDirect3DDevice8_CreateImageSurface(p,a,b,c,d) (p)->CreateImageSurface(a,b,c,d) +#define IDirect3DDevice8_CopyRects(p,a,b,c,d,e) (p)->CopyRects(a,b,c,d,e) +#define IDirect3DDevice8_UpdateTexture(p,a,b) (p)->UpdateTexture(a,b) +#define IDirect3DDevice8_GetFrontBuffer(p,a) (p)->GetFrontBuffer(a) +#define IDirect3DDevice8_SetRenderTarget(p,a,b) (p)->SetRenderTarget(a,b) +#define IDirect3DDevice8_GetRenderTarget(p,a) (p)->GetRenderTarget(a) +#define IDirect3DDevice8_GetDepthStencilSurface(p,a) (p)->GetDepthStencilSurface(a) +#define IDirect3DDevice8_BeginScene(p) (p)->BeginScene() +#define IDirect3DDevice8_EndScene(p) (p)->EndScene() +#define IDirect3DDevice8_Clear(p,a,b,c,d,e,f) (p)->Clear(a,b,c,d,e,f) +#define IDirect3DDevice8_SetTransform(p,a,b) (p)->SetTransform(a,b) +#define IDirect3DDevice8_GetTransform(p,a,b) (p)->GetTransform(a,b) +#define IDirect3DDevice8_MultiplyTransform(p,a,b) (p)->MultiplyTransform(a,b) +#define IDirect3DDevice8_SetViewport(p,a) (p)->SetViewport(a) +#define IDirect3DDevice8_GetViewport(p,a) (p)->GetViewport(a) +#define IDirect3DDevice8_SetMaterial(p,a) (p)->SetMaterial(a) +#define IDirect3DDevice8_GetMaterial(p,a) (p)->GetMaterial(a) +#define IDirect3DDevice8_SetLight(p,a,b) (p)->SetLight(a,b) +#define IDirect3DDevice8_GetLight(p,a,b) (p)->GetLight(a,b) +#define IDirect3DDevice8_LightEnable(p,a,b) (p)->LightEnable(a,b) +#define IDirect3DDevice8_GetLightEnable(p,a,b) (p)->GetLightEnable(a,b) +#define IDirect3DDevice8_SetClipPlane(p,a,b) (p)->SetClipPlane(a,b) +#define IDirect3DDevice8_GetClipPlane(p,a,b) (p)->GetClipPlane(a,b) +#define IDirect3DDevice8_SetRenderState(p,a,b) (p)->SetRenderState(a,b) +#define IDirect3DDevice8_GetRenderState(p,a,b) (p)->GetRenderState(a,b) +#define IDirect3DDevice8_BeginStateBlock(p) (p)->BeginStateBlock() +#define IDirect3DDevice8_EndStateBlock(p,a) (p)->EndStateBlock(a) +#define IDirect3DDevice8_ApplyStateBlock(p,a) (p)->ApplyStateBlock(a) +#define IDirect3DDevice8_CaptureStateBlock(p,a) (p)->CaptureStateBlock(a) +#define IDirect3DDevice8_DeleteStateBlock(p,a) (p)->DeleteStateBlock(a) +#define IDirect3DDevice8_CreateStateBlock(p,a,b) (p)->CreateStateBlock(a,b) +#define IDirect3DDevice8_SetClipStatus(p,a) (p)->SetClipStatus(a) +#define IDirect3DDevice8_GetClipStatus(p,a) (p)->GetClipStatus(a) +#define IDirect3DDevice8_GetTexture(p,a,b) (p)->GetTexture(a,b) +#define IDirect3DDevice8_SetTexture(p,a,b) (p)->SetTexture(a,b) +#define IDirect3DDevice8_GetTextureStageState(p,a,b,c) (p)->GetTextureStageState(a,b,c) +#define IDirect3DDevice8_SetTextureStageState(p,a,b,c) (p)->SetTextureStageState(a,b,c) +#define IDirect3DDevice8_ValidateDevice(p,a) (p)->ValidateDevice(a) +#define IDirect3DDevice8_GetInfo(p,a,b,c) (p)->GetInfo(a,b,c) +#define IDirect3DDevice8_SetPaletteEntries(p,a,b) (p)->SetPaletteEntries(a,b) +#define IDirect3DDevice8_GetPaletteEntries(p,a,b) (p)->GetPaletteEntries(a,b) +#define IDirect3DDevice8_SetCurrentTexturePalette(p,a) (p)->SetCurrentTexturePalette(a) +#define IDirect3DDevice8_GetCurrentTexturePalette(p,a) (p)->GetCurrentTexturePalette(a) +#define IDirect3DDevice8_DrawPrimitive(p,a,b,c) (p)->DrawPrimitive(a,b,c) +#define IDirect3DDevice8_DrawIndexedPrimitive(p,a,b,c,d,e) (p)->DrawIndexedPrimitive(a,b,c,d,e) +#define IDirect3DDevice8_DrawPrimitiveUP(p,a,b,c,d) (p)->DrawPrimitiveUP(a,b,c,d) +#define IDirect3DDevice8_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) (p)->DrawIndexedPrimitiveUP(a,b,c,d,e,f,g,h) +#define IDirect3DDevice8_ProcessVertices(p,a,b,c,d,e) (p)->ProcessVertices(a,b,c,d,e) +#define IDirect3DDevice8_CreateVertexShader(p,a,b,c,d) (p)->CreateVertexShader(a,b,c,d) +#define IDirect3DDevice8_SetVertexShader(p,a) (p)->SetVertexShader(a) +#define IDirect3DDevice8_GetVertexShader(p,a) (p)->GetVertexShader(a) +#define IDirect3DDevice8_DeleteVertexShader(p,a) (p)->DeleteVertexShader(a) +#define IDirect3DDevice8_SetVertexShaderConstant(p,a,b,c) (p)->SetVertexShaderConstant(a,b,c) +#define IDirect3DDevice8_GetVertexShaderConstant(p,a,b,c) (p)->GetVertexShaderConstant(a,b,c) +#define IDirect3DDevice8_GetVertexShaderDeclaration(p,a,b,c) (p)->GetVertexShaderDeclaration(a,b,c) +#define IDirect3DDevice8_GetVertexShaderFunction(p,a,b,c) (p)->GetVertexShaderFunction(a,b,c) +#define IDirect3DDevice8_SetStreamSource(p,a,b,c) (p)->SetStreamSource(a,b,c) +#define IDirect3DDevice8_GetStreamSource(p,a,b,c) (p)->GetStreamSource(a,b,c) +#define IDirect3DDevice8_SetIndices(p,a,b) (p)->SetIndices(a,b) +#define IDirect3DDevice8_GetIndices(p,a,b) (p)->GetIndices(a,b) +#define IDirect3DDevice8_CreatePixelShader(p,a,b) (p)->CreatePixelShader(a,b) +#define IDirect3DDevice8_SetPixelShader(p,a) (p)->SetPixelShader(a) +#define IDirect3DDevice8_GetPixelShader(p,a) (p)->GetPixelShader(a) +#define IDirect3DDevice8_DeletePixelShader(p,a) (p)->DeletePixelShader(a) +#define IDirect3DDevice8_SetPixelShaderConstant(p,a,b,c) (p)->SetPixelShaderConstant(a,b,c) +#define IDirect3DDevice8_GetPixelShaderConstant(p,a,b,c) (p)->GetPixelShaderConstant(a,b,c) +#define IDirect3DDevice8_GetPixelShaderFunction(p,a,b,c) (p)->GetPixelShaderFunction(a,b,c) +#define IDirect3DDevice8_DrawRectPatch(p,a,b,c) (p)->DrawRectPatch(a,b,c) +#define IDirect3DDevice8_DrawTriPatch(p,a,b,c) (p)->DrawTriPatch(a,b,c) +#define IDirect3DDevice8_DeletePatch(p,a) (p)->DeletePatch(a) +#endif + + + +#undef INTERFACE +#define INTERFACE IDirect3DSwapChain8 + +DECLARE_INTERFACE_(IDirect3DSwapChain8, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DSwapChain8 methods ***/ + STDMETHOD(Present)(THIS_ CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) PURE; + STDMETHOD(GetBackBuffer)(THIS_ UINT BackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface8** ppBackBuffer) PURE; +}; + +typedef struct IDirect3DSwapChain8 *LPDIRECT3DSWAPCHAIN8, *PDIRECT3DSWAPCHAIN8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DSwapChain8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DSwapChain8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DSwapChain8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DSwapChain8_Present(p,a,b,c,d) (p)->lpVtbl->Present(p,a,b,c,d) +#define IDirect3DSwapChain8_GetBackBuffer(p,a,b,c) (p)->lpVtbl->GetBackBuffer(p,a,b,c) +#else +#define IDirect3DSwapChain8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DSwapChain8_AddRef(p) (p)->AddRef() +#define IDirect3DSwapChain8_Release(p) (p)->Release() +#define IDirect3DSwapChain8_Present(p,a,b,c,d) (p)->Present(a,b,c,d) +#define IDirect3DSwapChain8_GetBackBuffer(p,a,b,c) (p)->GetBackBuffer(a,b,c) +#endif + + + +#undef INTERFACE +#define INTERFACE IDirect3DResource8 + +DECLARE_INTERFACE_(IDirect3DResource8, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DResource8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; +}; + +typedef struct IDirect3DResource8 *LPDIRECT3DRESOURCE8, *PDIRECT3DRESOURCE8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DResource8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DResource8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DResource8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DResource8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DResource8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DResource8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DResource8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DResource8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DResource8_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DResource8_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DResource8_GetType(p) (p)->lpVtbl->GetType(p) +#else +#define IDirect3DResource8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DResource8_AddRef(p) (p)->AddRef() +#define IDirect3DResource8_Release(p) (p)->Release() +#define IDirect3DResource8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DResource8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DResource8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DResource8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DResource8_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DResource8_GetPriority(p) (p)->GetPriority() +#define IDirect3DResource8_PreLoad(p) (p)->PreLoad() +#define IDirect3DResource8_GetType(p) (p)->GetType() +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DBaseTexture8 + +DECLARE_INTERFACE_(IDirect3DBaseTexture8, IDirect3DResource8) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DResource8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE; + STDMETHOD_(DWORD, GetLOD)(THIS) PURE; + STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE; +}; + +typedef struct IDirect3DBaseTexture8 *LPDIRECT3DBASETEXTURE8, *PDIRECT3DBASETEXTURE8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DBaseTexture8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DBaseTexture8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DBaseTexture8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DBaseTexture8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DBaseTexture8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DBaseTexture8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DBaseTexture8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DBaseTexture8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DBaseTexture8_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DBaseTexture8_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DBaseTexture8_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DBaseTexture8_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a) +#define IDirect3DBaseTexture8_GetLOD(p) (p)->lpVtbl->GetLOD(p) +#define IDirect3DBaseTexture8_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p) +#else +#define IDirect3DBaseTexture8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DBaseTexture8_AddRef(p) (p)->AddRef() +#define IDirect3DBaseTexture8_Release(p) (p)->Release() +#define IDirect3DBaseTexture8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DBaseTexture8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DBaseTexture8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DBaseTexture8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DBaseTexture8_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DBaseTexture8_GetPriority(p) (p)->GetPriority() +#define IDirect3DBaseTexture8_PreLoad(p) (p)->PreLoad() +#define IDirect3DBaseTexture8_GetType(p) (p)->GetType() +#define IDirect3DBaseTexture8_SetLOD(p,a) (p)->SetLOD(a) +#define IDirect3DBaseTexture8_GetLOD(p) (p)->GetLOD() +#define IDirect3DBaseTexture8_GetLevelCount(p) (p)->GetLevelCount() +#endif + + + + + +#undef INTERFACE +#define INTERFACE IDirect3DTexture8 + +DECLARE_INTERFACE_(IDirect3DTexture8, IDirect3DBaseTexture8) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DBaseTexture8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE; + STDMETHOD_(DWORD, GetLOD)(THIS) PURE; + STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE; + STDMETHOD(GetLevelDesc)(THIS_ UINT Level,D3DSURFACE_DESC *pDesc) PURE; + STDMETHOD(GetSurfaceLevel)(THIS_ UINT Level,IDirect3DSurface8** ppSurfaceLevel) PURE; + STDMETHOD(LockRect)(THIS_ UINT Level,D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags) PURE; + STDMETHOD(UnlockRect)(THIS_ UINT Level) PURE; + STDMETHOD(AddDirtyRect)(THIS_ CONST RECT* pDirtyRect) PURE; +}; + +typedef struct IDirect3DTexture8 *LPDIRECT3DTEXTURE8, *PDIRECT3DTEXTURE8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DTexture8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DTexture8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DTexture8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DTexture8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DTexture8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DTexture8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DTexture8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DTexture8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DTexture8_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DTexture8_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DTexture8_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DTexture8_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a) +#define IDirect3DTexture8_GetLOD(p) (p)->lpVtbl->GetLOD(p) +#define IDirect3DTexture8_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p) +#define IDirect3DTexture8_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b) +#define IDirect3DTexture8_GetSurfaceLevel(p,a,b) (p)->lpVtbl->GetSurfaceLevel(p,a,b) +#define IDirect3DTexture8_LockRect(p,a,b,c,d) (p)->lpVtbl->LockRect(p,a,b,c,d) +#define IDirect3DTexture8_UnlockRect(p,a) (p)->lpVtbl->UnlockRect(p,a) +#define IDirect3DTexture8_AddDirtyRect(p,a) (p)->lpVtbl->AddDirtyRect(p,a) +#else +#define IDirect3DTexture8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DTexture8_AddRef(p) (p)->AddRef() +#define IDirect3DTexture8_Release(p) (p)->Release() +#define IDirect3DTexture8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DTexture8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DTexture8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DTexture8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DTexture8_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DTexture8_GetPriority(p) (p)->GetPriority() +#define IDirect3DTexture8_PreLoad(p) (p)->PreLoad() +#define IDirect3DTexture8_GetType(p) (p)->GetType() +#define IDirect3DTexture8_SetLOD(p,a) (p)->SetLOD(a) +#define IDirect3DTexture8_GetLOD(p) (p)->GetLOD() +#define IDirect3DTexture8_GetLevelCount(p) (p)->GetLevelCount() +#define IDirect3DTexture8_GetLevelDesc(p,a,b) (p)->GetLevelDesc(a,b) +#define IDirect3DTexture8_GetSurfaceLevel(p,a,b) (p)->GetSurfaceLevel(a,b) +#define IDirect3DTexture8_LockRect(p,a,b,c,d) (p)->LockRect(a,b,c,d) +#define IDirect3DTexture8_UnlockRect(p,a) (p)->UnlockRect(a) +#define IDirect3DTexture8_AddDirtyRect(p,a) (p)->AddDirtyRect(a) +#endif + + + + + +#undef INTERFACE +#define INTERFACE IDirect3DVolumeTexture8 + +DECLARE_INTERFACE_(IDirect3DVolumeTexture8, IDirect3DBaseTexture8) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DBaseTexture8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE; + STDMETHOD_(DWORD, GetLOD)(THIS) PURE; + STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE; + STDMETHOD(GetLevelDesc)(THIS_ UINT Level,D3DVOLUME_DESC *pDesc) PURE; + STDMETHOD(GetVolumeLevel)(THIS_ UINT Level,IDirect3DVolume8** ppVolumeLevel) PURE; + STDMETHOD(LockBox)(THIS_ UINT Level,D3DLOCKED_BOX* pLockedVolume,CONST D3DBOX* pBox,DWORD Flags) PURE; + STDMETHOD(UnlockBox)(THIS_ UINT Level) PURE; + STDMETHOD(AddDirtyBox)(THIS_ CONST D3DBOX* pDirtyBox) PURE; +}; + +typedef struct IDirect3DVolumeTexture8 *LPDIRECT3DVOLUMETEXTURE8, *PDIRECT3DVOLUMETEXTURE8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DVolumeTexture8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DVolumeTexture8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DVolumeTexture8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DVolumeTexture8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DVolumeTexture8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DVolumeTexture8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DVolumeTexture8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DVolumeTexture8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DVolumeTexture8_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DVolumeTexture8_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DVolumeTexture8_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DVolumeTexture8_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a) +#define IDirect3DVolumeTexture8_GetLOD(p) (p)->lpVtbl->GetLOD(p) +#define IDirect3DVolumeTexture8_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p) +#define IDirect3DVolumeTexture8_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b) +#define IDirect3DVolumeTexture8_GetVolumeLevel(p,a,b) (p)->lpVtbl->GetVolumeLevel(p,a,b) +#define IDirect3DVolumeTexture8_LockBox(p,a,b,c,d) (p)->lpVtbl->LockBox(p,a,b,c,d) +#define IDirect3DVolumeTexture8_UnlockBox(p,a) (p)->lpVtbl->UnlockBox(p,a) +#define IDirect3DVolumeTexture8_AddDirtyBox(p,a) (p)->lpVtbl->AddDirtyBox(p,a) +#else +#define IDirect3DVolumeTexture8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DVolumeTexture8_AddRef(p) (p)->AddRef() +#define IDirect3DVolumeTexture8_Release(p) (p)->Release() +#define IDirect3DVolumeTexture8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DVolumeTexture8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DVolumeTexture8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DVolumeTexture8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DVolumeTexture8_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DVolumeTexture8_GetPriority(p) (p)->GetPriority() +#define IDirect3DVolumeTexture8_PreLoad(p) (p)->PreLoad() +#define IDirect3DVolumeTexture8_GetType(p) (p)->GetType() +#define IDirect3DVolumeTexture8_SetLOD(p,a) (p)->SetLOD(a) +#define IDirect3DVolumeTexture8_GetLOD(p) (p)->GetLOD() +#define IDirect3DVolumeTexture8_GetLevelCount(p) (p)->GetLevelCount() +#define IDirect3DVolumeTexture8_GetLevelDesc(p,a,b) (p)->GetLevelDesc(a,b) +#define IDirect3DVolumeTexture8_GetVolumeLevel(p,a,b) (p)->GetVolumeLevel(a,b) +#define IDirect3DVolumeTexture8_LockBox(p,a,b,c,d) (p)->LockBox(a,b,c,d) +#define IDirect3DVolumeTexture8_UnlockBox(p,a) (p)->UnlockBox(a) +#define IDirect3DVolumeTexture8_AddDirtyBox(p,a) (p)->AddDirtyBox(a) +#endif + + + + + +#undef INTERFACE +#define INTERFACE IDirect3DCubeTexture8 + +DECLARE_INTERFACE_(IDirect3DCubeTexture8, IDirect3DBaseTexture8) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DBaseTexture8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE; + STDMETHOD_(DWORD, GetLOD)(THIS) PURE; + STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE; + STDMETHOD(GetLevelDesc)(THIS_ UINT Level,D3DSURFACE_DESC *pDesc) PURE; + STDMETHOD(GetCubeMapSurface)(THIS_ D3DCUBEMAP_FACES FaceType,UINT Level,IDirect3DSurface8** ppCubeMapSurface) PURE; + STDMETHOD(LockRect)(THIS_ D3DCUBEMAP_FACES FaceType,UINT Level,D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags) PURE; + STDMETHOD(UnlockRect)(THIS_ D3DCUBEMAP_FACES FaceType,UINT Level) PURE; + STDMETHOD(AddDirtyRect)(THIS_ D3DCUBEMAP_FACES FaceType,CONST RECT* pDirtyRect) PURE; +}; + +typedef struct IDirect3DCubeTexture8 *LPDIRECT3DCUBETEXTURE8, *PDIRECT3DCUBETEXTURE8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DCubeTexture8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DCubeTexture8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DCubeTexture8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DCubeTexture8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DCubeTexture8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DCubeTexture8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DCubeTexture8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DCubeTexture8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DCubeTexture8_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DCubeTexture8_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DCubeTexture8_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DCubeTexture8_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a) +#define IDirect3DCubeTexture8_GetLOD(p) (p)->lpVtbl->GetLOD(p) +#define IDirect3DCubeTexture8_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p) +#define IDirect3DCubeTexture8_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b) +#define IDirect3DCubeTexture8_GetCubeMapSurface(p,a,b,c) (p)->lpVtbl->GetCubeMapSurface(p,a,b,c) +#define IDirect3DCubeTexture8_LockRect(p,a,b,c,d,e) (p)->lpVtbl->LockRect(p,a,b,c,d,e) +#define IDirect3DCubeTexture8_UnlockRect(p,a,b) (p)->lpVtbl->UnlockRect(p,a,b) +#define IDirect3DCubeTexture8_AddDirtyRect(p,a,b) (p)->lpVtbl->AddDirtyRect(p,a,b) +#else +#define IDirect3DCubeTexture8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DCubeTexture8_AddRef(p) (p)->AddRef() +#define IDirect3DCubeTexture8_Release(p) (p)->Release() +#define IDirect3DCubeTexture8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DCubeTexture8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DCubeTexture8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DCubeTexture8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DCubeTexture8_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DCubeTexture8_GetPriority(p) (p)->GetPriority() +#define IDirect3DCubeTexture8_PreLoad(p) (p)->PreLoad() +#define IDirect3DCubeTexture8_GetType(p) (p)->GetType() +#define IDirect3DCubeTexture8_SetLOD(p,a) (p)->SetLOD(a) +#define IDirect3DCubeTexture8_GetLOD(p) (p)->GetLOD() +#define IDirect3DCubeTexture8_GetLevelCount(p) (p)->GetLevelCount() +#define IDirect3DCubeTexture8_GetLevelDesc(p,a,b) (p)->GetLevelDesc(a,b) +#define IDirect3DCubeTexture8_GetCubeMapSurface(p,a,b,c) (p)->GetCubeMapSurface(a,b,c) +#define IDirect3DCubeTexture8_LockRect(p,a,b,c,d,e) (p)->LockRect(a,b,c,d,e) +#define IDirect3DCubeTexture8_UnlockRect(p,a,b) (p)->UnlockRect(a,b) +#define IDirect3DCubeTexture8_AddDirtyRect(p,a,b) (p)->AddDirtyRect(a,b) +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DVertexBuffer8 + +DECLARE_INTERFACE_(IDirect3DVertexBuffer8, IDirect3DResource8) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DResource8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD(Lock)(THIS_ UINT OffsetToLock,UINT SizeToLock,BYTE** ppbData,DWORD Flags) PURE; + STDMETHOD(Unlock)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3DVERTEXBUFFER_DESC *pDesc) PURE; +}; + +typedef struct IDirect3DVertexBuffer8 *LPDIRECT3DVERTEXBUFFER8, *PDIRECT3DVERTEXBUFFER8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DVertexBuffer8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DVertexBuffer8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DVertexBuffer8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DVertexBuffer8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DVertexBuffer8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DVertexBuffer8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DVertexBuffer8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DVertexBuffer8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DVertexBuffer8_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DVertexBuffer8_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DVertexBuffer8_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DVertexBuffer8_Lock(p,a,b,c,d) (p)->lpVtbl->Lock(p,a,b,c,d) +#define IDirect3DVertexBuffer8_Unlock(p) (p)->lpVtbl->Unlock(p) +#define IDirect3DVertexBuffer8_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a) +#else +#define IDirect3DVertexBuffer8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DVertexBuffer8_AddRef(p) (p)->AddRef() +#define IDirect3DVertexBuffer8_Release(p) (p)->Release() +#define IDirect3DVertexBuffer8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DVertexBuffer8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DVertexBuffer8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DVertexBuffer8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DVertexBuffer8_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DVertexBuffer8_GetPriority(p) (p)->GetPriority() +#define IDirect3DVertexBuffer8_PreLoad(p) (p)->PreLoad() +#define IDirect3DVertexBuffer8_GetType(p) (p)->GetType() +#define IDirect3DVertexBuffer8_Lock(p,a,b,c,d) (p)->Lock(a,b,c,d) +#define IDirect3DVertexBuffer8_Unlock(p) (p)->Unlock() +#define IDirect3DVertexBuffer8_GetDesc(p,a) (p)->GetDesc(a) +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DIndexBuffer8 + +DECLARE_INTERFACE_(IDirect3DIndexBuffer8, IDirect3DResource8) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DResource8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD(Lock)(THIS_ UINT OffsetToLock,UINT SizeToLock,BYTE** ppbData,DWORD Flags) PURE; + STDMETHOD(Unlock)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3DINDEXBUFFER_DESC *pDesc) PURE; +}; + +typedef struct IDirect3DIndexBuffer8 *LPDIRECT3DINDEXBUFFER8, *PDIRECT3DINDEXBUFFER8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DIndexBuffer8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DIndexBuffer8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DIndexBuffer8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DIndexBuffer8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DIndexBuffer8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DIndexBuffer8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DIndexBuffer8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DIndexBuffer8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DIndexBuffer8_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DIndexBuffer8_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DIndexBuffer8_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DIndexBuffer8_Lock(p,a,b,c,d) (p)->lpVtbl->Lock(p,a,b,c,d) +#define IDirect3DIndexBuffer8_Unlock(p) (p)->lpVtbl->Unlock(p) +#define IDirect3DIndexBuffer8_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a) +#else +#define IDirect3DIndexBuffer8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DIndexBuffer8_AddRef(p) (p)->AddRef() +#define IDirect3DIndexBuffer8_Release(p) (p)->Release() +#define IDirect3DIndexBuffer8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DIndexBuffer8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DIndexBuffer8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DIndexBuffer8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DIndexBuffer8_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DIndexBuffer8_GetPriority(p) (p)->GetPriority() +#define IDirect3DIndexBuffer8_PreLoad(p) (p)->PreLoad() +#define IDirect3DIndexBuffer8_GetType(p) (p)->GetType() +#define IDirect3DIndexBuffer8_Lock(p,a,b,c,d) (p)->Lock(a,b,c,d) +#define IDirect3DIndexBuffer8_Unlock(p) (p)->Unlock() +#define IDirect3DIndexBuffer8_GetDesc(p,a) (p)->GetDesc(a) +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DSurface8 + +DECLARE_INTERFACE_(IDirect3DSurface8, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DSurface8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD(GetContainer)(THIS_ REFIID riid,void** ppContainer) PURE; + STDMETHOD(GetDesc)(THIS_ D3DSURFACE_DESC *pDesc) PURE; + STDMETHOD(LockRect)(THIS_ D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags) PURE; + STDMETHOD(UnlockRect)(THIS) PURE; +}; + +typedef struct IDirect3DSurface8 *LPDIRECT3DSURFACE8, *PDIRECT3DSURFACE8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DSurface8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DSurface8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DSurface8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DSurface8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DSurface8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DSurface8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DSurface8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DSurface8_GetContainer(p,a,b) (p)->lpVtbl->GetContainer(p,a,b) +#define IDirect3DSurface8_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a) +#define IDirect3DSurface8_LockRect(p,a,b,c) (p)->lpVtbl->LockRect(p,a,b,c) +#define IDirect3DSurface8_UnlockRect(p) (p)->lpVtbl->UnlockRect(p) +#else +#define IDirect3DSurface8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DSurface8_AddRef(p) (p)->AddRef() +#define IDirect3DSurface8_Release(p) (p)->Release() +#define IDirect3DSurface8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DSurface8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DSurface8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DSurface8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DSurface8_GetContainer(p,a,b) (p)->GetContainer(a,b) +#define IDirect3DSurface8_GetDesc(p,a) (p)->GetDesc(a) +#define IDirect3DSurface8_LockRect(p,a,b,c) (p)->LockRect(a,b,c) +#define IDirect3DSurface8_UnlockRect(p) (p)->UnlockRect() +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DVolume8 + +DECLARE_INTERFACE_(IDirect3DVolume8, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DVolume8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD(GetContainer)(THIS_ REFIID riid,void** ppContainer) PURE; + STDMETHOD(GetDesc)(THIS_ D3DVOLUME_DESC *pDesc) PURE; + STDMETHOD(LockBox)(THIS_ D3DLOCKED_BOX * pLockedVolume,CONST D3DBOX* pBox,DWORD Flags) PURE; + STDMETHOD(UnlockBox)(THIS) PURE; +}; + +typedef struct IDirect3DVolume8 *LPDIRECT3DVOLUME8, *PDIRECT3DVOLUME8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DVolume8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DVolume8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DVolume8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DVolume8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DVolume8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DVolume8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DVolume8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DVolume8_GetContainer(p,a,b) (p)->lpVtbl->GetContainer(p,a,b) +#define IDirect3DVolume8_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a) +#define IDirect3DVolume8_LockBox(p,a,b,c) (p)->lpVtbl->LockBox(p,a,b,c) +#define IDirect3DVolume8_UnlockBox(p) (p)->lpVtbl->UnlockBox(p) +#else +#define IDirect3DVolume8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DVolume8_AddRef(p) (p)->AddRef() +#define IDirect3DVolume8_Release(p) (p)->Release() +#define IDirect3DVolume8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DVolume8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DVolume8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DVolume8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DVolume8_GetContainer(p,a,b) (p)->GetContainer(a,b) +#define IDirect3DVolume8_GetDesc(p,a) (p)->GetDesc(a) +#define IDirect3DVolume8_LockBox(p,a,b,c) (p)->LockBox(a,b,c) +#define IDirect3DVolume8_UnlockBox(p) (p)->UnlockBox() +#endif + +/**************************************************************************** + * Flags for SetPrivateData method on all D3D8 interfaces + * + * The passed pointer is an IUnknown ptr. The SizeOfData argument to SetPrivateData + * must be set to sizeof(IUnknown*). Direct3D will call AddRef through this + * pointer and Release when the private data is destroyed. The data will be + * destroyed when another SetPrivateData with the same GUID is set, when + * FreePrivateData is called, or when the D3D8 object is freed. + ****************************************************************************/ +#define D3DSPD_IUNKNOWN 0x00000001L + +/**************************************************************************** + * + * Parameter for IDirect3D8 Enum and GetCaps8 functions to get the info for + * the current mode only. + * + ****************************************************************************/ + +#define D3DCURRENT_DISPLAY_MODE 0x00EFFFFFL + +/**************************************************************************** + * + * Flags for IDirect3D8::CreateDevice's BehaviorFlags + * + ****************************************************************************/ + +#define D3DCREATE_FPU_PRESERVE 0x00000002L +#define D3DCREATE_MULTITHREADED 0x00000004L + +#define D3DCREATE_PUREDEVICE 0x00000010L +#define D3DCREATE_SOFTWARE_VERTEXPROCESSING 0x00000020L +#define D3DCREATE_HARDWARE_VERTEXPROCESSING 0x00000040L +#define D3DCREATE_MIXED_VERTEXPROCESSING 0x00000080L + +#define D3DCREATE_DISABLE_DRIVER_MANAGEMENT 0x00000100L + + +/**************************************************************************** + * + * Parameter for IDirect3D8::CreateDevice's iAdapter + * + ****************************************************************************/ + +#define D3DADAPTER_DEFAULT 0 + +/**************************************************************************** + * + * Flags for IDirect3D8::EnumAdapters + * + ****************************************************************************/ + +#define D3DENUM_NO_WHQL_LEVEL 0x00000002L + +/**************************************************************************** + * + * Maximum number of back-buffers supported in DX8 + * + ****************************************************************************/ + +#define D3DPRESENT_BACK_BUFFERS_MAX 3L + +/**************************************************************************** + * + * Flags for IDirect3DDevice8::SetGammaRamp + * + ****************************************************************************/ + +#define D3DSGR_NO_CALIBRATION 0x00000000L +#define D3DSGR_CALIBRATE 0x00000001L + +/**************************************************************************** + * + * Flags for IDirect3DDevice8::SetCursorPosition + * + ****************************************************************************/ + +#define D3DCURSOR_IMMEDIATE_UPDATE 0x00000001L + +/**************************************************************************** + * + * Flags for DrawPrimitive/DrawIndexedPrimitive + * Also valid for Begin/BeginIndexed + * Also valid for VertexBuffer::CreateVertexBuffer + ****************************************************************************/ + + +/* + * DirectDraw error codes + */ +#define _FACD3D 0x876 +#define MAKE_D3DHRESULT( code ) MAKE_HRESULT( 1, _FACD3D, code ) + +/* + * Direct3D Errors + */ +#define D3D_OK S_OK + +#define D3DERR_WRONGTEXTUREFORMAT MAKE_D3DHRESULT(2072) +#define D3DERR_UNSUPPORTEDCOLOROPERATION MAKE_D3DHRESULT(2073) +#define D3DERR_UNSUPPORTEDCOLORARG MAKE_D3DHRESULT(2074) +#define D3DERR_UNSUPPORTEDALPHAOPERATION MAKE_D3DHRESULT(2075) +#define D3DERR_UNSUPPORTEDALPHAARG MAKE_D3DHRESULT(2076) +#define D3DERR_TOOMANYOPERATIONS MAKE_D3DHRESULT(2077) +#define D3DERR_CONFLICTINGTEXTUREFILTER MAKE_D3DHRESULT(2078) +#define D3DERR_UNSUPPORTEDFACTORVALUE MAKE_D3DHRESULT(2079) +#define D3DERR_CONFLICTINGRENDERSTATE MAKE_D3DHRESULT(2081) +#define D3DERR_UNSUPPORTEDTEXTUREFILTER MAKE_D3DHRESULT(2082) +#define D3DERR_CONFLICTINGTEXTUREPALETTE MAKE_D3DHRESULT(2086) +#define D3DERR_DRIVERINTERNALERROR MAKE_D3DHRESULT(2087) + +#define D3DERR_NOTFOUND MAKE_D3DHRESULT(2150) +#define D3DERR_MOREDATA MAKE_D3DHRESULT(2151) +#define D3DERR_DEVICELOST MAKE_D3DHRESULT(2152) +#define D3DERR_DEVICENOTRESET MAKE_D3DHRESULT(2153) +#define D3DERR_NOTAVAILABLE MAKE_D3DHRESULT(2154) +#define D3DERR_OUTOFVIDEOMEMORY MAKE_D3DHRESULT(380) +#define D3DERR_INVALIDDEVICE MAKE_D3DHRESULT(2155) +#define D3DERR_INVALIDCALL MAKE_D3DHRESULT(2156) +#define D3DERR_DRIVERINVALIDCALL MAKE_D3DHRESULT(2157) + +#ifdef __cplusplus +}; +#endif + +#endif /* (DIRECT3D_VERSION >= 0x0800) */ +#endif /* _D3D_H_ */ + diff --git a/OpenParrot/deps/inc/dx8/d3d8caps.h b/OpenParrot/deps/inc/dx8/d3d8caps.h new file mode 100644 index 0000000..6af8e6c --- /dev/null +++ b/OpenParrot/deps/inc/dx8/d3d8caps.h @@ -0,0 +1,364 @@ +/*==========================================================================; + * + * Copyright (C) Microsoft Corporation. All Rights Reserved. + * + * File: d3d8caps.h + * Content: Direct3D capabilities include file + * + ***************************************************************************/ + +#ifndef _D3D8CAPS_H +#define _D3D8CAPS_H + +#ifndef DIRECT3D_VERSION +#define DIRECT3D_VERSION 0x0800 +#endif //DIRECT3D_VERSION + +// include this file content only if compiling for DX8 interfaces +#if(DIRECT3D_VERSION >= 0x0800) + +#if defined(_X86_) || defined(_IA64_) +#pragma pack(4) +#endif + +typedef struct _D3DCAPS8 +{ + /* Device Info */ + D3DDEVTYPE DeviceType; + UINT AdapterOrdinal; + + /* Caps from DX7 Draw */ + DWORD Caps; + DWORD Caps2; + DWORD Caps3; + DWORD PresentationIntervals; + + /* Cursor Caps */ + DWORD CursorCaps; + + /* 3D Device Caps */ + DWORD DevCaps; + + DWORD PrimitiveMiscCaps; + DWORD RasterCaps; + DWORD ZCmpCaps; + DWORD SrcBlendCaps; + DWORD DestBlendCaps; + DWORD AlphaCmpCaps; + DWORD ShadeCaps; + DWORD TextureCaps; + DWORD TextureFilterCaps; // D3DPTFILTERCAPS for IDirect3DTexture8's + DWORD CubeTextureFilterCaps; // D3DPTFILTERCAPS for IDirect3DCubeTexture8's + DWORD VolumeTextureFilterCaps; // D3DPTFILTERCAPS for IDirect3DVolumeTexture8's + DWORD TextureAddressCaps; // D3DPTADDRESSCAPS for IDirect3DTexture8's + DWORD VolumeTextureAddressCaps; // D3DPTADDRESSCAPS for IDirect3DVolumeTexture8's + + DWORD LineCaps; // D3DLINECAPS + + DWORD MaxTextureWidth, MaxTextureHeight; + DWORD MaxVolumeExtent; + + DWORD MaxTextureRepeat; + DWORD MaxTextureAspectRatio; + DWORD MaxAnisotropy; + float MaxVertexW; + + float GuardBandLeft; + float GuardBandTop; + float GuardBandRight; + float GuardBandBottom; + + float ExtentsAdjust; + DWORD StencilCaps; + + DWORD FVFCaps; + DWORD TextureOpCaps; + DWORD MaxTextureBlendStages; + DWORD MaxSimultaneousTextures; + + DWORD VertexProcessingCaps; + DWORD MaxActiveLights; + DWORD MaxUserClipPlanes; + DWORD MaxVertexBlendMatrices; + DWORD MaxVertexBlendMatrixIndex; + + float MaxPointSize; + + DWORD MaxPrimitiveCount; // max number of primitives per DrawPrimitive call + DWORD MaxVertexIndex; + DWORD MaxStreams; + DWORD MaxStreamStride; // max stride for SetStreamSource + + DWORD VertexShaderVersion; + DWORD MaxVertexShaderConst; // number of vertex shader constant registers + + DWORD PixelShaderVersion; + float MaxPixelShaderValue; // max value of pixel shader arithmetic component + +} D3DCAPS8; + +// +// BIT DEFINES FOR D3DCAPS8 DWORD MEMBERS +// + +// +// Caps +// +#define D3DCAPS_READ_SCANLINE 0x00020000L + +// +// Caps2 +// +#define D3DCAPS2_NO2DDURING3DSCENE 0x00000002L +#define D3DCAPS2_FULLSCREENGAMMA 0x00020000L +#define D3DCAPS2_CANRENDERWINDOWED 0x00080000L +#define D3DCAPS2_CANCALIBRATEGAMMA 0x00100000L +#define D3DCAPS2_RESERVED 0x02000000L +#define D3DCAPS2_CANMANAGERESOURCE 0x10000000L +#define D3DCAPS2_DYNAMICTEXTURES 0x20000000L + +// +// Caps3 +// +#define D3DCAPS3_RESERVED 0x8000001fL + +// Indicates that the device can respect the ALPHABLENDENABLE render state +// when fullscreen while using the FLIP or DISCARD swap effect. +// COPY and COPYVSYNC swap effects work whether or not this flag is set. +#define D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD 0x00000020L + +// +// PresentationIntervals +// +#define D3DPRESENT_INTERVAL_DEFAULT 0x00000000L +#define D3DPRESENT_INTERVAL_ONE 0x00000001L +#define D3DPRESENT_INTERVAL_TWO 0x00000002L +#define D3DPRESENT_INTERVAL_THREE 0x00000004L +#define D3DPRESENT_INTERVAL_FOUR 0x00000008L +#define D3DPRESENT_INTERVAL_IMMEDIATE 0x80000000L + +// +// CursorCaps +// +// Driver supports HW color cursor in at least hi-res modes(height >=400) +#define D3DCURSORCAPS_COLOR 0x00000001L +// Driver supports HW cursor also in low-res modes(height < 400) +#define D3DCURSORCAPS_LOWRES 0x00000002L + +// +// DevCaps +// +#define D3DDEVCAPS_EXECUTESYSTEMMEMORY 0x00000010L /* Device can use execute buffers from system memory */ +#define D3DDEVCAPS_EXECUTEVIDEOMEMORY 0x00000020L /* Device can use execute buffers from video memory */ +#define D3DDEVCAPS_TLVERTEXSYSTEMMEMORY 0x00000040L /* Device can use TL buffers from system memory */ +#define D3DDEVCAPS_TLVERTEXVIDEOMEMORY 0x00000080L /* Device can use TL buffers from video memory */ +#define D3DDEVCAPS_TEXTURESYSTEMMEMORY 0x00000100L /* Device can texture from system memory */ +#define D3DDEVCAPS_TEXTUREVIDEOMEMORY 0x00000200L /* Device can texture from device memory */ +#define D3DDEVCAPS_DRAWPRIMTLVERTEX 0x00000400L /* Device can draw TLVERTEX primitives */ +#define D3DDEVCAPS_CANRENDERAFTERFLIP 0x00000800L /* Device can render without waiting for flip to complete */ +#define D3DDEVCAPS_TEXTURENONLOCALVIDMEM 0x00001000L /* Device can texture from nonlocal video memory */ +#define D3DDEVCAPS_DRAWPRIMITIVES2 0x00002000L /* Device can support DrawPrimitives2 */ +#define D3DDEVCAPS_SEPARATETEXTUREMEMORIES 0x00004000L /* Device is texturing from separate memory pools */ +#define D3DDEVCAPS_DRAWPRIMITIVES2EX 0x00008000L /* Device can support Extended DrawPrimitives2 i.e. DX7 compliant driver*/ +#define D3DDEVCAPS_HWTRANSFORMANDLIGHT 0x00010000L /* Device can support transformation and lighting in hardware and DRAWPRIMITIVES2EX must be also */ +#define D3DDEVCAPS_CANBLTSYSTONONLOCAL 0x00020000L /* Device supports a Tex Blt from system memory to non-local vidmem */ +#define D3DDEVCAPS_HWRASTERIZATION 0x00080000L /* Device has HW acceleration for rasterization */ +#define D3DDEVCAPS_PUREDEVICE 0x00100000L /* Device supports D3DCREATE_PUREDEVICE */ +#define D3DDEVCAPS_QUINTICRTPATCHES 0x00200000L /* Device supports quintic Beziers and BSplines */ +#define D3DDEVCAPS_RTPATCHES 0x00400000L /* Device supports Rect and Tri patches */ +#define D3DDEVCAPS_RTPATCHHANDLEZERO 0x00800000L /* Indicates that RT Patches may be drawn efficiently using handle 0 */ +#define D3DDEVCAPS_NPATCHES 0x01000000L /* Device supports N-Patches */ + +// +// PrimitiveMiscCaps +// +#define D3DPMISCCAPS_MASKZ 0x00000002L +#define D3DPMISCCAPS_LINEPATTERNREP 0x00000004L +#define D3DPMISCCAPS_CULLNONE 0x00000010L +#define D3DPMISCCAPS_CULLCW 0x00000020L +#define D3DPMISCCAPS_CULLCCW 0x00000040L +#define D3DPMISCCAPS_COLORWRITEENABLE 0x00000080L +#define D3DPMISCCAPS_CLIPPLANESCALEDPOINTS 0x00000100L /* Device correctly clips scaled points to clip planes */ +#define D3DPMISCCAPS_CLIPTLVERTS 0x00000200L /* device will clip post-transformed vertex primitives */ +#define D3DPMISCCAPS_TSSARGTEMP 0x00000400L /* device supports D3DTA_TEMP for temporary register */ +#define D3DPMISCCAPS_BLENDOP 0x00000800L /* device supports D3DRS_BLENDOP */ +#define D3DPMISCCAPS_NULLREFERENCE 0x00001000L /* Reference Device that doesnt render */ + +// +// LineCaps +// +#define D3DLINECAPS_TEXTURE 0x00000001L +#define D3DLINECAPS_ZTEST 0x00000002L +#define D3DLINECAPS_BLEND 0x00000004L +#define D3DLINECAPS_ALPHACMP 0x00000008L +#define D3DLINECAPS_FOG 0x00000010L + +// +// RasterCaps +// +#define D3DPRASTERCAPS_DITHER 0x00000001L +#define D3DPRASTERCAPS_PAT 0x00000008L +#define D3DPRASTERCAPS_ZTEST 0x00000010L +#define D3DPRASTERCAPS_FOGVERTEX 0x00000080L +#define D3DPRASTERCAPS_FOGTABLE 0x00000100L +#define D3DPRASTERCAPS_ANTIALIASEDGES 0x00001000L +#define D3DPRASTERCAPS_MIPMAPLODBIAS 0x00002000L +#define D3DPRASTERCAPS_ZBIAS 0x00004000L +#define D3DPRASTERCAPS_ZBUFFERLESSHSR 0x00008000L +#define D3DPRASTERCAPS_FOGRANGE 0x00010000L +#define D3DPRASTERCAPS_ANISOTROPY 0x00020000L +#define D3DPRASTERCAPS_WBUFFER 0x00040000L +#define D3DPRASTERCAPS_WFOG 0x00100000L +#define D3DPRASTERCAPS_ZFOG 0x00200000L +#define D3DPRASTERCAPS_COLORPERSPECTIVE 0x00400000L /* Device iterates colors perspective correct */ +#define D3DPRASTERCAPS_STRETCHBLTMULTISAMPLE 0x00800000L + +// +// ZCmpCaps, AlphaCmpCaps +// +#define D3DPCMPCAPS_NEVER 0x00000001L +#define D3DPCMPCAPS_LESS 0x00000002L +#define D3DPCMPCAPS_EQUAL 0x00000004L +#define D3DPCMPCAPS_LESSEQUAL 0x00000008L +#define D3DPCMPCAPS_GREATER 0x00000010L +#define D3DPCMPCAPS_NOTEQUAL 0x00000020L +#define D3DPCMPCAPS_GREATEREQUAL 0x00000040L +#define D3DPCMPCAPS_ALWAYS 0x00000080L + +// +// SourceBlendCaps, DestBlendCaps +// +#define D3DPBLENDCAPS_ZERO 0x00000001L +#define D3DPBLENDCAPS_ONE 0x00000002L +#define D3DPBLENDCAPS_SRCCOLOR 0x00000004L +#define D3DPBLENDCAPS_INVSRCCOLOR 0x00000008L +#define D3DPBLENDCAPS_SRCALPHA 0x00000010L +#define D3DPBLENDCAPS_INVSRCALPHA 0x00000020L +#define D3DPBLENDCAPS_DESTALPHA 0x00000040L +#define D3DPBLENDCAPS_INVDESTALPHA 0x00000080L +#define D3DPBLENDCAPS_DESTCOLOR 0x00000100L +#define D3DPBLENDCAPS_INVDESTCOLOR 0x00000200L +#define D3DPBLENDCAPS_SRCALPHASAT 0x00000400L +#define D3DPBLENDCAPS_BOTHSRCALPHA 0x00000800L +#define D3DPBLENDCAPS_BOTHINVSRCALPHA 0x00001000L + +// +// ShadeCaps +// +#define D3DPSHADECAPS_COLORGOURAUDRGB 0x00000008L +#define D3DPSHADECAPS_SPECULARGOURAUDRGB 0x00000200L +#define D3DPSHADECAPS_ALPHAGOURAUDBLEND 0x00004000L +#define D3DPSHADECAPS_FOGGOURAUD 0x00080000L + +// +// TextureCaps +// +#define D3DPTEXTURECAPS_PERSPECTIVE 0x00000001L /* Perspective-correct texturing is supported */ +#define D3DPTEXTURECAPS_POW2 0x00000002L /* Power-of-2 texture dimensions are required - applies to non-Cube/Volume textures only. */ +#define D3DPTEXTURECAPS_ALPHA 0x00000004L /* Alpha in texture pixels is supported */ +#define D3DPTEXTURECAPS_SQUAREONLY 0x00000020L /* Only square textures are supported */ +#define D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE 0x00000040L /* Texture indices are not scaled by the texture size prior to interpolation */ +#define D3DPTEXTURECAPS_ALPHAPALETTE 0x00000080L /* Device can draw alpha from texture palettes */ +// Device can use non-POW2 textures if: +// 1) D3DTEXTURE_ADDRESS is set to CLAMP for this texture's stage +// 2) D3DRS_WRAP(N) is zero for this texture's coordinates +// 3) mip mapping is not enabled (use magnification filter only) +#define D3DPTEXTURECAPS_NONPOW2CONDITIONAL 0x00000100L +#define D3DPTEXTURECAPS_PROJECTED 0x00000400L /* Device can do D3DTTFF_PROJECTED */ +#define D3DPTEXTURECAPS_CUBEMAP 0x00000800L /* Device can do cubemap textures */ +#define D3DPTEXTURECAPS_VOLUMEMAP 0x00002000L /* Device can do volume textures */ +#define D3DPTEXTURECAPS_MIPMAP 0x00004000L /* Device can do mipmapped textures */ +#define D3DPTEXTURECAPS_MIPVOLUMEMAP 0x00008000L /* Device can do mipmapped volume textures */ +#define D3DPTEXTURECAPS_MIPCUBEMAP 0x00010000L /* Device can do mipmapped cube maps */ +#define D3DPTEXTURECAPS_CUBEMAP_POW2 0x00020000L /* Device requires that cubemaps be power-of-2 dimension */ +#define D3DPTEXTURECAPS_VOLUMEMAP_POW2 0x00040000L /* Device requires that volume maps be power-of-2 dimension */ + +// +// TextureFilterCaps +// +#define D3DPTFILTERCAPS_MINFPOINT 0x00000100L /* Min Filter */ +#define D3DPTFILTERCAPS_MINFLINEAR 0x00000200L +#define D3DPTFILTERCAPS_MINFANISOTROPIC 0x00000400L +#define D3DPTFILTERCAPS_MIPFPOINT 0x00010000L /* Mip Filter */ +#define D3DPTFILTERCAPS_MIPFLINEAR 0x00020000L +#define D3DPTFILTERCAPS_MAGFPOINT 0x01000000L /* Mag Filter */ +#define D3DPTFILTERCAPS_MAGFLINEAR 0x02000000L +#define D3DPTFILTERCAPS_MAGFANISOTROPIC 0x04000000L +#define D3DPTFILTERCAPS_MAGFAFLATCUBIC 0x08000000L +#define D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC 0x10000000L + +// +// TextureAddressCaps +// +#define D3DPTADDRESSCAPS_WRAP 0x00000001L +#define D3DPTADDRESSCAPS_MIRROR 0x00000002L +#define D3DPTADDRESSCAPS_CLAMP 0x00000004L +#define D3DPTADDRESSCAPS_BORDER 0x00000008L +#define D3DPTADDRESSCAPS_INDEPENDENTUV 0x00000010L +#define D3DPTADDRESSCAPS_MIRRORONCE 0x00000020L + +// +// StencilCaps +// +#define D3DSTENCILCAPS_KEEP 0x00000001L +#define D3DSTENCILCAPS_ZERO 0x00000002L +#define D3DSTENCILCAPS_REPLACE 0x00000004L +#define D3DSTENCILCAPS_INCRSAT 0x00000008L +#define D3DSTENCILCAPS_DECRSAT 0x00000010L +#define D3DSTENCILCAPS_INVERT 0x00000020L +#define D3DSTENCILCAPS_INCR 0x00000040L +#define D3DSTENCILCAPS_DECR 0x00000080L + +// +// TextureOpCaps +// +#define D3DTEXOPCAPS_DISABLE 0x00000001L +#define D3DTEXOPCAPS_SELECTARG1 0x00000002L +#define D3DTEXOPCAPS_SELECTARG2 0x00000004L +#define D3DTEXOPCAPS_MODULATE 0x00000008L +#define D3DTEXOPCAPS_MODULATE2X 0x00000010L +#define D3DTEXOPCAPS_MODULATE4X 0x00000020L +#define D3DTEXOPCAPS_ADD 0x00000040L +#define D3DTEXOPCAPS_ADDSIGNED 0x00000080L +#define D3DTEXOPCAPS_ADDSIGNED2X 0x00000100L +#define D3DTEXOPCAPS_SUBTRACT 0x00000200L +#define D3DTEXOPCAPS_ADDSMOOTH 0x00000400L +#define D3DTEXOPCAPS_BLENDDIFFUSEALPHA 0x00000800L +#define D3DTEXOPCAPS_BLENDTEXTUREALPHA 0x00001000L +#define D3DTEXOPCAPS_BLENDFACTORALPHA 0x00002000L +#define D3DTEXOPCAPS_BLENDTEXTUREALPHAPM 0x00004000L +#define D3DTEXOPCAPS_BLENDCURRENTALPHA 0x00008000L +#define D3DTEXOPCAPS_PREMODULATE 0x00010000L +#define D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR 0x00020000L +#define D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA 0x00040000L +#define D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR 0x00080000L +#define D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA 0x00100000L +#define D3DTEXOPCAPS_BUMPENVMAP 0x00200000L +#define D3DTEXOPCAPS_BUMPENVMAPLUMINANCE 0x00400000L +#define D3DTEXOPCAPS_DOTPRODUCT3 0x00800000L +#define D3DTEXOPCAPS_MULTIPLYADD 0x01000000L +#define D3DTEXOPCAPS_LERP 0x02000000L + +// +// FVFCaps +// +#define D3DFVFCAPS_TEXCOORDCOUNTMASK 0x0000ffffL /* mask for texture coordinate count field */ +#define D3DFVFCAPS_DONOTSTRIPELEMENTS 0x00080000L /* Device prefers that vertex elements not be stripped */ +#define D3DFVFCAPS_PSIZE 0x00100000L /* Device can receive point size */ + +// +// VertexProcessingCaps +// +#define D3DVTXPCAPS_TEXGEN 0x00000001L /* device can do texgen */ +#define D3DVTXPCAPS_MATERIALSOURCE7 0x00000002L /* device can do DX7-level colormaterialsource ops */ +#define D3DVTXPCAPS_DIRECTIONALLIGHTS 0x00000008L /* device can do directional lights */ +#define D3DVTXPCAPS_POSITIONALLIGHTS 0x00000010L /* device can do positional lights (includes point and spot) */ +#define D3DVTXPCAPS_LOCALVIEWER 0x00000020L /* device can do local viewer */ +#define D3DVTXPCAPS_TWEENING 0x00000040L /* device can do vertex tweening */ +#define D3DVTXPCAPS_NO_VSDT_UBYTE4 0x00000080L /* device does not support D3DVSDT_UBYTE4 */ + +#pragma pack() + +#endif /* (DIRECT3D_VERSION >= 0x0800) */ +#endif /* _D3D8CAPS_H_ */ + diff --git a/OpenParrot/deps/inc/dx8/d3d8types.h b/OpenParrot/deps/inc/dx8/d3d8types.h new file mode 100644 index 0000000..5d622af --- /dev/null +++ b/OpenParrot/deps/inc/dx8/d3d8types.h @@ -0,0 +1,1684 @@ +/*==========================================================================; + * + * Copyright (C) Microsoft Corporation. All Rights Reserved. + * + * File: d3d8types.h + * Content: Direct3D capabilities include file + * + ***************************************************************************/ + +#ifndef _D3D8TYPES_H_ +#define _D3D8TYPES_H_ + +#ifndef DIRECT3D_VERSION +#define DIRECT3D_VERSION 0x0800 +#endif //DIRECT3D_VERSION + +// include this file content only if compiling for DX8 interfaces +#if(DIRECT3D_VERSION >= 0x0800) + +#include + +#if _MSC_VER >= 1200 +#pragma warning(push) +#endif +#pragma warning(disable:4201) // anonymous unions warning +#if defined(_X86_) || defined(_IA64_) +#pragma pack(4) +#endif + +// D3DCOLOR is equivalent to D3DFMT_A8R8G8B8 +#ifndef D3DCOLOR_DEFINED +typedef DWORD D3DCOLOR; +#define D3DCOLOR_DEFINED +#endif + +// maps unsigned 8 bits/channel to D3DCOLOR +#define D3DCOLOR_ARGB(a,r,g,b) \ + ((D3DCOLOR)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff))) +#define D3DCOLOR_RGBA(r,g,b,a) D3DCOLOR_ARGB(a,r,g,b) +#define D3DCOLOR_XRGB(r,g,b) D3DCOLOR_ARGB(0xff,r,g,b) + +// maps floating point channels (0.f to 1.f range) to D3DCOLOR +#define D3DCOLOR_COLORVALUE(r,g,b,a) \ + D3DCOLOR_RGBA((DWORD)((r)*255.f),(DWORD)((g)*255.f),(DWORD)((b)*255.f),(DWORD)((a)*255.f)) + + +#ifndef D3DVECTOR_DEFINED +typedef struct _D3DVECTOR { + float x; + float y; + float z; +} D3DVECTOR; +#define D3DVECTOR_DEFINED +#endif + +#ifndef D3DCOLORVALUE_DEFINED +typedef struct _D3DCOLORVALUE { + float r; + float g; + float b; + float a; +} D3DCOLORVALUE; +#define D3DCOLORVALUE_DEFINED +#endif + +#ifndef D3DRECT_DEFINED +typedef struct _D3DRECT { + LONG x1; + LONG y1; + LONG x2; + LONG y2; +} D3DRECT; +#define D3DRECT_DEFINED +#endif + +#ifndef D3DMATRIX_DEFINED +typedef struct _D3DMATRIX { + union { + struct { + float _11, _12, _13, _14; + float _21, _22, _23, _24; + float _31, _32, _33, _34; + float _41, _42, _43, _44; + + }; + float m[4][4]; + }; +} D3DMATRIX; +#define D3DMATRIX_DEFINED +#endif + +typedef struct _D3DVIEWPORT8 { + DWORD X; + DWORD Y; /* Viewport Top left */ + DWORD Width; + DWORD Height; /* Viewport Dimensions */ + float MinZ; /* Min/max of clip Volume */ + float MaxZ; +} D3DVIEWPORT8; + +/* + * Values for clip fields. + */ + +// Max number of user clipping planes, supported in D3D. +#define D3DMAXUSERCLIPPLANES 32 + +// These bits could be ORed together to use with D3DRS_CLIPPLANEENABLE +// +#define D3DCLIPPLANE0 (1 << 0) +#define D3DCLIPPLANE1 (1 << 1) +#define D3DCLIPPLANE2 (1 << 2) +#define D3DCLIPPLANE3 (1 << 3) +#define D3DCLIPPLANE4 (1 << 4) +#define D3DCLIPPLANE5 (1 << 5) + +// The following bits are used in the ClipUnion and ClipIntersection +// members of the D3DCLIPSTATUS8 +// + +#define D3DCS_LEFT 0x00000001L +#define D3DCS_RIGHT 0x00000002L +#define D3DCS_TOP 0x00000004L +#define D3DCS_BOTTOM 0x00000008L +#define D3DCS_FRONT 0x00000010L +#define D3DCS_BACK 0x00000020L +#define D3DCS_PLANE0 0x00000040L +#define D3DCS_PLANE1 0x00000080L +#define D3DCS_PLANE2 0x00000100L +#define D3DCS_PLANE3 0x00000200L +#define D3DCS_PLANE4 0x00000400L +#define D3DCS_PLANE5 0x00000800L + +#define D3DCS_ALL (D3DCS_LEFT | \ + D3DCS_RIGHT | \ + D3DCS_TOP | \ + D3DCS_BOTTOM | \ + D3DCS_FRONT | \ + D3DCS_BACK | \ + D3DCS_PLANE0 | \ + D3DCS_PLANE1 | \ + D3DCS_PLANE2 | \ + D3DCS_PLANE3 | \ + D3DCS_PLANE4 | \ + D3DCS_PLANE5) + +typedef struct _D3DCLIPSTATUS8 { + DWORD ClipUnion; + DWORD ClipIntersection; +} D3DCLIPSTATUS8; + +typedef struct _D3DMATERIAL8 { + D3DCOLORVALUE Diffuse; /* Diffuse color RGBA */ + D3DCOLORVALUE Ambient; /* Ambient color RGB */ + D3DCOLORVALUE Specular; /* Specular 'shininess' */ + D3DCOLORVALUE Emissive; /* Emissive color RGB */ + float Power; /* Sharpness if specular highlight */ +} D3DMATERIAL8; + +typedef enum _D3DLIGHTTYPE { + D3DLIGHT_POINT = 1, + D3DLIGHT_SPOT = 2, + D3DLIGHT_DIRECTIONAL = 3, + D3DLIGHT_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DLIGHTTYPE; + +typedef struct _D3DLIGHT8 { + D3DLIGHTTYPE Type; /* Type of light source */ + D3DCOLORVALUE Diffuse; /* Diffuse color of light */ + D3DCOLORVALUE Specular; /* Specular color of light */ + D3DCOLORVALUE Ambient; /* Ambient color of light */ + D3DVECTOR Position; /* Position in world space */ + D3DVECTOR Direction; /* Direction in world space */ + float Range; /* Cutoff range */ + float Falloff; /* Falloff */ + float Attenuation0; /* Constant attenuation */ + float Attenuation1; /* Linear attenuation */ + float Attenuation2; /* Quadratic attenuation */ + float Theta; /* Inner angle of spotlight cone */ + float Phi; /* Outer angle of spotlight cone */ +} D3DLIGHT8; + +/* + * Options for clearing + */ +#define D3DCLEAR_TARGET 0x00000001l /* Clear target surface */ +#define D3DCLEAR_ZBUFFER 0x00000002l /* Clear target z buffer */ +#define D3DCLEAR_STENCIL 0x00000004l /* Clear stencil planes */ + +/* + * The following defines the rendering states + */ + +typedef enum _D3DSHADEMODE { + D3DSHADE_FLAT = 1, + D3DSHADE_GOURAUD = 2, + D3DSHADE_PHONG = 3, + D3DSHADE_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DSHADEMODE; + +typedef enum _D3DFILLMODE { + D3DFILL_POINT = 1, + D3DFILL_WIREFRAME = 2, + D3DFILL_SOLID = 3, + D3DFILL_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DFILLMODE; + +typedef struct _D3DLINEPATTERN { + WORD wRepeatFactor; + WORD wLinePattern; +} D3DLINEPATTERN; + +typedef enum _D3DBLEND { + D3DBLEND_ZERO = 1, + D3DBLEND_ONE = 2, + D3DBLEND_SRCCOLOR = 3, + D3DBLEND_INVSRCCOLOR = 4, + D3DBLEND_SRCALPHA = 5, + D3DBLEND_INVSRCALPHA = 6, + D3DBLEND_DESTALPHA = 7, + D3DBLEND_INVDESTALPHA = 8, + D3DBLEND_DESTCOLOR = 9, + D3DBLEND_INVDESTCOLOR = 10, + D3DBLEND_SRCALPHASAT = 11, + D3DBLEND_BOTHSRCALPHA = 12, + D3DBLEND_BOTHINVSRCALPHA = 13, + D3DBLEND_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DBLEND; + +typedef enum _D3DBLENDOP { + D3DBLENDOP_ADD = 1, + D3DBLENDOP_SUBTRACT = 2, + D3DBLENDOP_REVSUBTRACT = 3, + D3DBLENDOP_MIN = 4, + D3DBLENDOP_MAX = 5, + D3DBLENDOP_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DBLENDOP; + +typedef enum _D3DTEXTUREADDRESS { + D3DTADDRESS_WRAP = 1, + D3DTADDRESS_MIRROR = 2, + D3DTADDRESS_CLAMP = 3, + D3DTADDRESS_BORDER = 4, + D3DTADDRESS_MIRRORONCE = 5, + D3DTADDRESS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DTEXTUREADDRESS; + +typedef enum _D3DCULL { + D3DCULL_NONE = 1, + D3DCULL_CW = 2, + D3DCULL_CCW = 3, + D3DCULL_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DCULL; + +typedef enum _D3DCMPFUNC { + D3DCMP_NEVER = 1, + D3DCMP_LESS = 2, + D3DCMP_EQUAL = 3, + D3DCMP_LESSEQUAL = 4, + D3DCMP_GREATER = 5, + D3DCMP_NOTEQUAL = 6, + D3DCMP_GREATEREQUAL = 7, + D3DCMP_ALWAYS = 8, + D3DCMP_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DCMPFUNC; + +typedef enum _D3DSTENCILOP { + D3DSTENCILOP_KEEP = 1, + D3DSTENCILOP_ZERO = 2, + D3DSTENCILOP_REPLACE = 3, + D3DSTENCILOP_INCRSAT = 4, + D3DSTENCILOP_DECRSAT = 5, + D3DSTENCILOP_INVERT = 6, + D3DSTENCILOP_INCR = 7, + D3DSTENCILOP_DECR = 8, + D3DSTENCILOP_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DSTENCILOP; + +typedef enum _D3DFOGMODE { + D3DFOG_NONE = 0, + D3DFOG_EXP = 1, + D3DFOG_EXP2 = 2, + D3DFOG_LINEAR = 3, + D3DFOG_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DFOGMODE; + +typedef enum _D3DZBUFFERTYPE { + D3DZB_FALSE = 0, + D3DZB_TRUE = 1, // Z buffering + D3DZB_USEW = 2, // W buffering + D3DZB_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DZBUFFERTYPE; + +// Primitives supported by draw-primitive API +typedef enum _D3DPRIMITIVETYPE { + D3DPT_POINTLIST = 1, + D3DPT_LINELIST = 2, + D3DPT_LINESTRIP = 3, + D3DPT_TRIANGLELIST = 4, + D3DPT_TRIANGLESTRIP = 5, + D3DPT_TRIANGLEFAN = 6, + D3DPT_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DPRIMITIVETYPE; + +typedef enum _D3DTRANSFORMSTATETYPE { + D3DTS_VIEW = 2, + D3DTS_PROJECTION = 3, + D3DTS_TEXTURE0 = 16, + D3DTS_TEXTURE1 = 17, + D3DTS_TEXTURE2 = 18, + D3DTS_TEXTURE3 = 19, + D3DTS_TEXTURE4 = 20, + D3DTS_TEXTURE5 = 21, + D3DTS_TEXTURE6 = 22, + D3DTS_TEXTURE7 = 23, + D3DTS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DTRANSFORMSTATETYPE; + +#define D3DTS_WORLDMATRIX(index) (D3DTRANSFORMSTATETYPE)(index + 256) +#define D3DTS_WORLD D3DTS_WORLDMATRIX(0) +#define D3DTS_WORLD1 D3DTS_WORLDMATRIX(1) +#define D3DTS_WORLD2 D3DTS_WORLDMATRIX(2) +#define D3DTS_WORLD3 D3DTS_WORLDMATRIX(3) + +typedef enum _D3DRENDERSTATETYPE { + D3DRS_ZENABLE = 7, /* D3DZBUFFERTYPE (or TRUE/FALSE for legacy) */ + D3DRS_FILLMODE = 8, /* D3DFILLMODE */ + D3DRS_SHADEMODE = 9, /* D3DSHADEMODE */ + D3DRS_LINEPATTERN = 10, /* D3DLINEPATTERN */ + D3DRS_ZWRITEENABLE = 14, /* TRUE to enable z writes */ + D3DRS_ALPHATESTENABLE = 15, /* TRUE to enable alpha tests */ + D3DRS_LASTPIXEL = 16, /* TRUE for last-pixel on lines */ + D3DRS_SRCBLEND = 19, /* D3DBLEND */ + D3DRS_DESTBLEND = 20, /* D3DBLEND */ + D3DRS_CULLMODE = 22, /* D3DCULL */ + D3DRS_ZFUNC = 23, /* D3DCMPFUNC */ + D3DRS_ALPHAREF = 24, /* D3DFIXED */ + D3DRS_ALPHAFUNC = 25, /* D3DCMPFUNC */ + D3DRS_DITHERENABLE = 26, /* TRUE to enable dithering */ + D3DRS_ALPHABLENDENABLE = 27, /* TRUE to enable alpha blending */ + D3DRS_FOGENABLE = 28, /* TRUE to enable fog blending */ + D3DRS_SPECULARENABLE = 29, /* TRUE to enable specular */ + D3DRS_ZVISIBLE = 30, /* TRUE to enable z checking */ + D3DRS_FOGCOLOR = 34, /* D3DCOLOR */ + D3DRS_FOGTABLEMODE = 35, /* D3DFOGMODE */ + D3DRS_FOGSTART = 36, /* Fog start (for both vertex and pixel fog) */ + D3DRS_FOGEND = 37, /* Fog end */ + D3DRS_FOGDENSITY = 38, /* Fog density */ + D3DRS_EDGEANTIALIAS = 40, /* TRUE to enable edge antialiasing */ + D3DRS_ZBIAS = 47, /* LONG Z bias */ + D3DRS_RANGEFOGENABLE = 48, /* Enables range-based fog */ + D3DRS_STENCILENABLE = 52, /* BOOL enable/disable stenciling */ + D3DRS_STENCILFAIL = 53, /* D3DSTENCILOP to do if stencil test fails */ + D3DRS_STENCILZFAIL = 54, /* D3DSTENCILOP to do if stencil test passes and Z test fails */ + D3DRS_STENCILPASS = 55, /* D3DSTENCILOP to do if both stencil and Z tests pass */ + D3DRS_STENCILFUNC = 56, /* D3DCMPFUNC fn. Stencil Test passes if ((ref & mask) stencilfn (stencil & mask)) is true */ + D3DRS_STENCILREF = 57, /* Reference value used in stencil test */ + D3DRS_STENCILMASK = 58, /* Mask value used in stencil test */ + D3DRS_STENCILWRITEMASK = 59, /* Write mask applied to values written to stencil buffer */ + D3DRS_TEXTUREFACTOR = 60, /* D3DCOLOR used for multi-texture blend */ + D3DRS_WRAP0 = 128, /* wrap for 1st texture coord. set */ + D3DRS_WRAP1 = 129, /* wrap for 2nd texture coord. set */ + D3DRS_WRAP2 = 130, /* wrap for 3rd texture coord. set */ + D3DRS_WRAP3 = 131, /* wrap for 4th texture coord. set */ + D3DRS_WRAP4 = 132, /* wrap for 5th texture coord. set */ + D3DRS_WRAP5 = 133, /* wrap for 6th texture coord. set */ + D3DRS_WRAP6 = 134, /* wrap for 7th texture coord. set */ + D3DRS_WRAP7 = 135, /* wrap for 8th texture coord. set */ + D3DRS_CLIPPING = 136, + D3DRS_LIGHTING = 137, + D3DRS_AMBIENT = 139, + D3DRS_FOGVERTEXMODE = 140, + D3DRS_COLORVERTEX = 141, + D3DRS_LOCALVIEWER = 142, + D3DRS_NORMALIZENORMALS = 143, + D3DRS_DIFFUSEMATERIALSOURCE = 145, + D3DRS_SPECULARMATERIALSOURCE = 146, + D3DRS_AMBIENTMATERIALSOURCE = 147, + D3DRS_EMISSIVEMATERIALSOURCE = 148, + D3DRS_VERTEXBLEND = 151, + D3DRS_CLIPPLANEENABLE = 152, + D3DRS_SOFTWAREVERTEXPROCESSING = 153, + D3DRS_POINTSIZE = 154, /* float point size */ + D3DRS_POINTSIZE_MIN = 155, /* float point size min threshold */ + D3DRS_POINTSPRITEENABLE = 156, /* BOOL point texture coord control */ + D3DRS_POINTSCALEENABLE = 157, /* BOOL point size scale enable */ + D3DRS_POINTSCALE_A = 158, /* float point attenuation A value */ + D3DRS_POINTSCALE_B = 159, /* float point attenuation B value */ + D3DRS_POINTSCALE_C = 160, /* float point attenuation C value */ + D3DRS_MULTISAMPLEANTIALIAS = 161, // BOOL - set to do FSAA with multisample buffer + D3DRS_MULTISAMPLEMASK = 162, // DWORD - per-sample enable/disable + D3DRS_PATCHEDGESTYLE = 163, // Sets whether patch edges will use float style tessellation + D3DRS_PATCHSEGMENTS = 164, // Number of segments per edge when drawing patches + D3DRS_DEBUGMONITORTOKEN = 165, // DEBUG ONLY - token to debug monitor + D3DRS_POINTSIZE_MAX = 166, /* float point size max threshold */ + D3DRS_INDEXEDVERTEXBLENDENABLE = 167, + D3DRS_COLORWRITEENABLE = 168, // per-channel write enable + D3DRS_TWEENFACTOR = 170, // float tween factor + D3DRS_BLENDOP = 171, // D3DBLENDOP setting + D3DRS_POSITIONORDER = 172, // NPatch position interpolation order. D3DORDER_LINEAR or D3DORDER_CUBIC (default) + D3DRS_NORMALORDER = 173, // NPatch normal interpolation order. D3DORDER_LINEAR (default) or D3DORDER_QUADRATIC + + D3DRS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DRENDERSTATETYPE; + +// Values for material source +typedef enum _D3DMATERIALCOLORSOURCE +{ + D3DMCS_MATERIAL = 0, // Color from material is used + D3DMCS_COLOR1 = 1, // Diffuse vertex color is used + D3DMCS_COLOR2 = 2, // Specular vertex color is used + D3DMCS_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum +} D3DMATERIALCOLORSOURCE; + +// Bias to apply to the texture coordinate set to apply a wrap to. +#define D3DRENDERSTATE_WRAPBIAS 128UL + +/* Flags to construct the WRAP render states */ +#define D3DWRAP_U 0x00000001L +#define D3DWRAP_V 0x00000002L +#define D3DWRAP_W 0x00000004L + +/* Flags to construct the WRAP render states for 1D thru 4D texture coordinates */ +#define D3DWRAPCOORD_0 0x00000001L // same as D3DWRAP_U +#define D3DWRAPCOORD_1 0x00000002L // same as D3DWRAP_V +#define D3DWRAPCOORD_2 0x00000004L // same as D3DWRAP_W +#define D3DWRAPCOORD_3 0x00000008L + +/* Flags to construct D3DRS_COLORWRITEENABLE */ +#define D3DCOLORWRITEENABLE_RED (1L<<0) +#define D3DCOLORWRITEENABLE_GREEN (1L<<1) +#define D3DCOLORWRITEENABLE_BLUE (1L<<2) +#define D3DCOLORWRITEENABLE_ALPHA (1L<<3) + +/* + * State enumerants for per-stage texture processing. + */ +typedef enum _D3DTEXTURESTAGESTATETYPE +{ + D3DTSS_COLOROP = 1, /* D3DTEXTUREOP - per-stage blending controls for color channels */ + D3DTSS_COLORARG1 = 2, /* D3DTA_* (texture arg) */ + D3DTSS_COLORARG2 = 3, /* D3DTA_* (texture arg) */ + D3DTSS_ALPHAOP = 4, /* D3DTEXTUREOP - per-stage blending controls for alpha channel */ + D3DTSS_ALPHAARG1 = 5, /* D3DTA_* (texture arg) */ + D3DTSS_ALPHAARG2 = 6, /* D3DTA_* (texture arg) */ + D3DTSS_BUMPENVMAT00 = 7, /* float (bump mapping matrix) */ + D3DTSS_BUMPENVMAT01 = 8, /* float (bump mapping matrix) */ + D3DTSS_BUMPENVMAT10 = 9, /* float (bump mapping matrix) */ + D3DTSS_BUMPENVMAT11 = 10, /* float (bump mapping matrix) */ + D3DTSS_TEXCOORDINDEX = 11, /* identifies which set of texture coordinates index this texture */ + D3DTSS_ADDRESSU = 13, /* D3DTEXTUREADDRESS for U coordinate */ + D3DTSS_ADDRESSV = 14, /* D3DTEXTUREADDRESS for V coordinate */ + D3DTSS_BORDERCOLOR = 15, /* D3DCOLOR */ + D3DTSS_MAGFILTER = 16, /* D3DTEXTUREFILTER filter to use for magnification */ + D3DTSS_MINFILTER = 17, /* D3DTEXTUREFILTER filter to use for minification */ + D3DTSS_MIPFILTER = 18, /* D3DTEXTUREFILTER filter to use between mipmaps during minification */ + D3DTSS_MIPMAPLODBIAS = 19, /* float Mipmap LOD bias */ + D3DTSS_MAXMIPLEVEL = 20, /* DWORD 0..(n-1) LOD index of largest map to use (0 == largest) */ + D3DTSS_MAXANISOTROPY = 21, /* DWORD maximum anisotropy */ + D3DTSS_BUMPENVLSCALE = 22, /* float scale for bump map luminance */ + D3DTSS_BUMPENVLOFFSET = 23, /* float offset for bump map luminance */ + D3DTSS_TEXTURETRANSFORMFLAGS = 24, /* D3DTEXTURETRANSFORMFLAGS controls texture transform */ + D3DTSS_ADDRESSW = 25, /* D3DTEXTUREADDRESS for W coordinate */ + D3DTSS_COLORARG0 = 26, /* D3DTA_* third arg for triadic ops */ + D3DTSS_ALPHAARG0 = 27, /* D3DTA_* third arg for triadic ops */ + D3DTSS_RESULTARG = 28, /* D3DTA_* arg for result (CURRENT or TEMP) */ + D3DTSS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DTEXTURESTAGESTATETYPE; + +// Values, used with D3DTSS_TEXCOORDINDEX, to specify that the vertex data(position +// and normal in the camera space) should be taken as texture coordinates +// Low 16 bits are used to specify texture coordinate index, to take the WRAP mode from +// +#define D3DTSS_TCI_PASSTHRU 0x00000000 +#define D3DTSS_TCI_CAMERASPACENORMAL 0x00010000 +#define D3DTSS_TCI_CAMERASPACEPOSITION 0x00020000 +#define D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR 0x00030000 + +/* + * Enumerations for COLOROP and ALPHAOP texture blending operations set in + * texture processing stage controls in D3DTSS. + */ +typedef enum _D3DTEXTUREOP +{ + // Control + D3DTOP_DISABLE = 1, // disables stage + D3DTOP_SELECTARG1 = 2, // the default + D3DTOP_SELECTARG2 = 3, + + // Modulate + D3DTOP_MODULATE = 4, // multiply args together + D3DTOP_MODULATE2X = 5, // multiply and 1 bit + D3DTOP_MODULATE4X = 6, // multiply and 2 bits + + // Add + D3DTOP_ADD = 7, // add arguments together + D3DTOP_ADDSIGNED = 8, // add with -0.5 bias + D3DTOP_ADDSIGNED2X = 9, // as above but left 1 bit + D3DTOP_SUBTRACT = 10, // Arg1 - Arg2, with no saturation + D3DTOP_ADDSMOOTH = 11, // add 2 args, subtract product + // Arg1 + Arg2 - Arg1*Arg2 + // = Arg1 + (1-Arg1)*Arg2 + + // Linear alpha blend: Arg1*(Alpha) + Arg2*(1-Alpha) + D3DTOP_BLENDDIFFUSEALPHA = 12, // iterated alpha + D3DTOP_BLENDTEXTUREALPHA = 13, // texture alpha + D3DTOP_BLENDFACTORALPHA = 14, // alpha from D3DRS_TEXTUREFACTOR + + // Linear alpha blend with pre-multiplied arg1 input: Arg1 + Arg2*(1-Alpha) + D3DTOP_BLENDTEXTUREALPHAPM = 15, // texture alpha + D3DTOP_BLENDCURRENTALPHA = 16, // by alpha of current color + + // Specular mapping + D3DTOP_PREMODULATE = 17, // modulate with next texture before use + D3DTOP_MODULATEALPHA_ADDCOLOR = 18, // Arg1.RGB + Arg1.A*Arg2.RGB + // COLOROP only + D3DTOP_MODULATECOLOR_ADDALPHA = 19, // Arg1.RGB*Arg2.RGB + Arg1.A + // COLOROP only + D3DTOP_MODULATEINVALPHA_ADDCOLOR = 20, // (1-Arg1.A)*Arg2.RGB + Arg1.RGB + // COLOROP only + D3DTOP_MODULATEINVCOLOR_ADDALPHA = 21, // (1-Arg1.RGB)*Arg2.RGB + Arg1.A + // COLOROP only + + // Bump mapping + D3DTOP_BUMPENVMAP = 22, // per pixel env map perturbation + D3DTOP_BUMPENVMAPLUMINANCE = 23, // with luminance channel + + // This can do either diffuse or specular bump mapping with correct input. + // Performs the function (Arg1.R*Arg2.R + Arg1.G*Arg2.G + Arg1.B*Arg2.B) + // where each component has been scaled and offset to make it signed. + // The result is replicated into all four (including alpha) channels. + // This is a valid COLOROP only. + D3DTOP_DOTPRODUCT3 = 24, + + // Triadic ops + D3DTOP_MULTIPLYADD = 25, // Arg0 + Arg1*Arg2 + D3DTOP_LERP = 26, // (Arg0)*Arg1 + (1-Arg0)*Arg2 + + D3DTOP_FORCE_DWORD = 0x7fffffff, +} D3DTEXTUREOP; + +/* + * Values for COLORARG0,1,2, ALPHAARG0,1,2, and RESULTARG texture blending + * operations set in texture processing stage controls in D3DRENDERSTATE. + */ +#define D3DTA_SELECTMASK 0x0000000f // mask for arg selector +#define D3DTA_DIFFUSE 0x00000000 // select diffuse color (read only) +#define D3DTA_CURRENT 0x00000001 // select stage destination register (read/write) +#define D3DTA_TEXTURE 0x00000002 // select texture color (read only) +#define D3DTA_TFACTOR 0x00000003 // select D3DRS_TEXTUREFACTOR (read only) +#define D3DTA_SPECULAR 0x00000004 // select specular color (read only) +#define D3DTA_TEMP 0x00000005 // select temporary register color (read/write) +#define D3DTA_COMPLEMENT 0x00000010 // take 1.0 - x (read modifier) +#define D3DTA_ALPHAREPLICATE 0x00000020 // replicate alpha to color components (read modifier) + +// +// Values for D3DTSS_***FILTER texture stage states +// +typedef enum _D3DTEXTUREFILTERTYPE +{ + D3DTEXF_NONE = 0, // filtering disabled (valid for mip filter only) + D3DTEXF_POINT = 1, // nearest + D3DTEXF_LINEAR = 2, // linear interpolation + D3DTEXF_ANISOTROPIC = 3, // anisotropic + D3DTEXF_FLATCUBIC = 4, // cubic + D3DTEXF_GAUSSIANCUBIC = 5, // different cubic kernel + D3DTEXF_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum +} D3DTEXTUREFILTERTYPE; + +/* Bits for Flags in ProcessVertices call */ + +#define D3DPV_DONOTCOPYDATA (1 << 0) + +//------------------------------------------------------------------- + +// Flexible vertex format bits +// +#define D3DFVF_RESERVED0 0x001 +#define D3DFVF_POSITION_MASK 0x00E +#define D3DFVF_XYZ 0x002 +#define D3DFVF_XYZRHW 0x004 +#define D3DFVF_XYZB1 0x006 +#define D3DFVF_XYZB2 0x008 +#define D3DFVF_XYZB3 0x00a +#define D3DFVF_XYZB4 0x00c +#define D3DFVF_XYZB5 0x00e + +#define D3DFVF_NORMAL 0x010 +#define D3DFVF_PSIZE 0x020 +#define D3DFVF_DIFFUSE 0x040 +#define D3DFVF_SPECULAR 0x080 + +#define D3DFVF_TEXCOUNT_MASK 0xf00 +#define D3DFVF_TEXCOUNT_SHIFT 8 +#define D3DFVF_TEX0 0x000 +#define D3DFVF_TEX1 0x100 +#define D3DFVF_TEX2 0x200 +#define D3DFVF_TEX3 0x300 +#define D3DFVF_TEX4 0x400 +#define D3DFVF_TEX5 0x500 +#define D3DFVF_TEX6 0x600 +#define D3DFVF_TEX7 0x700 +#define D3DFVF_TEX8 0x800 + +#define D3DFVF_LASTBETA_UBYTE4 0x1000 + +#define D3DFVF_RESERVED2 0xE000 // 4 reserved bits + +//--------------------------------------------------------------------- +// Vertex Shaders +// + +/* + +Vertex Shader Declaration + +The declaration portion of a vertex shader defines the static external +interface of the shader. The information in the declaration includes: + +- Assignments of vertex shader input registers to data streams. These +assignments bind a specific vertex register to a single component within a +vertex stream. A vertex stream element is identified by a byte offset +within the stream and a type. The type specifies the arithmetic data type +plus the dimensionality (1, 2, 3, or 4 values). Stream data which is +less than 4 values are always expanded out to 4 values with zero or more +0.F values and one 1.F value. + +- Assignment of vertex shader input registers to implicit data from the +primitive tessellator. This controls the loading of vertex data which is +not loaded from a stream, but rather is generated during primitive +tessellation prior to the vertex shader. + +- Loading data into the constant memory at the time a shader is set as the +current shader. Each token specifies values for one or more contiguous 4 +DWORD constant registers. This allows the shader to update an arbitrary +subset of the constant memory, overwriting the device state (which +contains the current values of the constant memory). Note that these +values can be subsequently overwritten (between DrawPrimitive calls) +during the time a shader is bound to a device via the +SetVertexShaderConstant method. + + +Declaration arrays are single-dimensional arrays of DWORDs composed of +multiple tokens each of which is one or more DWORDs. The single-DWORD +token value 0xFFFFFFFF is a special token used to indicate the end of the +declaration array. The single DWORD token value 0x00000000 is a NOP token +with is ignored during the declaration parsing. Note that 0x00000000 is a +valid value for DWORDs following the first DWORD for multiple word tokens. + +[31:29] TokenType + 0x0 - NOP (requires all DWORD bits to be zero) + 0x1 - stream selector + 0x2 - stream data definition (map to vertex input memory) + 0x3 - vertex input memory from tessellator + 0x4 - constant memory from shader + 0x5 - extension + 0x6 - reserved + 0x7 - end-of-array (requires all DWORD bits to be 1) + +NOP Token (single DWORD token) + [31:29] 0x0 + [28:00] 0x0 + +Stream Selector (single DWORD token) + [31:29] 0x1 + [28] indicates whether this is a tessellator stream + [27:04] 0x0 + [03:00] stream selector (0..15) + +Stream Data Definition (single DWORD token) + Vertex Input Register Load + [31:29] 0x2 + [28] 0x0 + [27:20] 0x0 + [19:16] type (dimensionality and data type) + [15:04] 0x0 + [03:00] vertex register address (0..15) + Data Skip (no register load) + [31:29] 0x2 + [28] 0x1 + [27:20] 0x0 + [19:16] count of DWORDS to skip over (0..15) + [15:00] 0x0 + Vertex Input Memory from Tessellator Data (single DWORD token) + [31:29] 0x3 + [28] indicates whether data is normals or u/v + [27:24] 0x0 + [23:20] vertex register address (0..15) + [19:16] type (dimensionality) + [15:04] 0x0 + [03:00] vertex register address (0..15) + +Constant Memory from Shader (multiple DWORD token) + [31:29] 0x4 + [28:25] count of 4*DWORD constants to load (0..15) + [24:07] 0x0 + [06:00] constant memory address (0..95) + +Extension Token (single or multiple DWORD token) + [31:29] 0x5 + [28:24] count of additional DWORDs in token (0..31) + [23:00] extension-specific information + +End-of-array token (single DWORD token) + [31:29] 0x7 + [28:00] 0x1fffffff + +The stream selector token must be immediately followed by a contiguous set of stream data definition tokens. This token sequence fully defines that stream, including the set of elements within the stream, the order in which the elements appear, the type of each element, and the vertex register into which to load an element. +Streams are allowed to include data which is not loaded into a vertex register, thus allowing data which is not used for this shader to exist in the vertex stream. This skipped data is defined only by a count of DWORDs to skip over, since the type information is irrelevant. +The token sequence: +Stream Select: stream=0 +Stream Data Definition (Load): type=FLOAT3; register=3 +Stream Data Definition (Load): type=FLOAT3; register=4 +Stream Data Definition (Skip): count=2 +Stream Data Definition (Load): type=FLOAT2; register=7 + +defines stream zero to consist of 4 elements, 3 of which are loaded into registers and the fourth skipped over. Register 3 is loaded with the first three DWORDs in each vertex interpreted as FLOAT data. Register 4 is loaded with the 4th, 5th, and 6th DWORDs interpreted as FLOAT data. The next two DWORDs (7th and 8th) are skipped over and not loaded into any vertex input register. Register 7 is loaded with the 9th and 10th DWORDS interpreted as FLOAT data. +Placing of tokens other than NOPs between the Stream Selector and Stream Data Definition tokens is disallowed. + +*/ + +typedef enum _D3DVSD_TOKENTYPE +{ + D3DVSD_TOKEN_NOP = 0, // NOP or extension + D3DVSD_TOKEN_STREAM, // stream selector + D3DVSD_TOKEN_STREAMDATA, // stream data definition (map to vertex input memory) + D3DVSD_TOKEN_TESSELLATOR, // vertex input memory from tessellator + D3DVSD_TOKEN_CONSTMEM, // constant memory from shader + D3DVSD_TOKEN_EXT, // extension + D3DVSD_TOKEN_END = 7, // end-of-array (requires all DWORD bits to be 1) + D3DVSD_FORCE_DWORD = 0x7fffffff,// force 32-bit size enum +} D3DVSD_TOKENTYPE; + +#define D3DVSD_TOKENTYPESHIFT 29 +#define D3DVSD_TOKENTYPEMASK (7 << D3DVSD_TOKENTYPESHIFT) + +#define D3DVSD_STREAMNUMBERSHIFT 0 +#define D3DVSD_STREAMNUMBERMASK (0xF << D3DVSD_STREAMNUMBERSHIFT) + +#define D3DVSD_DATALOADTYPESHIFT 28 +#define D3DVSD_DATALOADTYPEMASK (0x1 << D3DVSD_DATALOADTYPESHIFT) + +#define D3DVSD_DATATYPESHIFT 16 +#define D3DVSD_DATATYPEMASK (0xF << D3DVSD_DATATYPESHIFT) + +#define D3DVSD_SKIPCOUNTSHIFT 16 +#define D3DVSD_SKIPCOUNTMASK (0xF << D3DVSD_SKIPCOUNTSHIFT) + +#define D3DVSD_VERTEXREGSHIFT 0 +#define D3DVSD_VERTEXREGMASK (0x1F << D3DVSD_VERTEXREGSHIFT) + +#define D3DVSD_VERTEXREGINSHIFT 20 +#define D3DVSD_VERTEXREGINMASK (0xF << D3DVSD_VERTEXREGINSHIFT) + +#define D3DVSD_CONSTCOUNTSHIFT 25 +#define D3DVSD_CONSTCOUNTMASK (0xF << D3DVSD_CONSTCOUNTSHIFT) + +#define D3DVSD_CONSTADDRESSSHIFT 0 +#define D3DVSD_CONSTADDRESSMASK (0x7F << D3DVSD_CONSTADDRESSSHIFT) + +#define D3DVSD_CONSTRSSHIFT 16 +#define D3DVSD_CONSTRSMASK (0x1FFF << D3DVSD_CONSTRSSHIFT) + +#define D3DVSD_EXTCOUNTSHIFT 24 +#define D3DVSD_EXTCOUNTMASK (0x1F << D3DVSD_EXTCOUNTSHIFT) + +#define D3DVSD_EXTINFOSHIFT 0 +#define D3DVSD_EXTINFOMASK (0xFFFFFF << D3DVSD_EXTINFOSHIFT) + +#define D3DVSD_MAKETOKENTYPE(tokenType) ((tokenType << D3DVSD_TOKENTYPESHIFT) & D3DVSD_TOKENTYPEMASK) + +// macros for generation of CreateVertexShader Declaration token array + +// Set current stream +// _StreamNumber [0..(MaxStreams-1)] stream to get data from +// +#define D3DVSD_STREAM( _StreamNumber ) \ + (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_STREAM) | (_StreamNumber)) + +// Set tessellator stream +// +#define D3DVSD_STREAMTESSSHIFT 28 +#define D3DVSD_STREAMTESSMASK (1 << D3DVSD_STREAMTESSSHIFT) +#define D3DVSD_STREAM_TESS( ) \ + (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_STREAM) | (D3DVSD_STREAMTESSMASK)) + +// bind single vertex register to vertex element from vertex stream +// +// _VertexRegister [0..15] address of the vertex register +// _Type [D3DVSDT_*] dimensionality and arithmetic data type + +#define D3DVSD_REG( _VertexRegister, _Type ) \ + (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_STREAMDATA) | \ + ((_Type) << D3DVSD_DATATYPESHIFT) | (_VertexRegister)) + +// Skip _DWORDCount DWORDs in vertex +// +#define D3DVSD_SKIP( _DWORDCount ) \ + (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_STREAMDATA) | 0x10000000 | \ + ((_DWORDCount) << D3DVSD_SKIPCOUNTSHIFT)) + +// load data into vertex shader constant memory +// +// _ConstantAddress [0..95] - address of constant array to begin filling data +// _Count [0..15] - number of constant vectors to load (4 DWORDs each) +// followed by 4*_Count DWORDS of data +// +#define D3DVSD_CONST( _ConstantAddress, _Count ) \ + (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_CONSTMEM) | \ + ((_Count) << D3DVSD_CONSTCOUNTSHIFT) | (_ConstantAddress)) + +// enable tessellator generated normals +// +// _VertexRegisterIn [0..15] address of vertex register whose input stream +// will be used in normal computation +// _VertexRegisterOut [0..15] address of vertex register to output the normal to +// +#define D3DVSD_TESSNORMAL( _VertexRegisterIn, _VertexRegisterOut ) \ + (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_TESSELLATOR) | \ + ((_VertexRegisterIn) << D3DVSD_VERTEXREGINSHIFT) | \ + ((0x02) << D3DVSD_DATATYPESHIFT) | (_VertexRegisterOut)) + +// enable tessellator generated surface parameters +// +// _VertexRegister [0..15] address of vertex register to output parameters +// +#define D3DVSD_TESSUV( _VertexRegister ) \ + (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_TESSELLATOR) | 0x10000000 | \ + ((0x01) << D3DVSD_DATATYPESHIFT) | (_VertexRegister)) + +// Generates END token +// +#define D3DVSD_END() 0xFFFFFFFF + +// Generates NOP token +#define D3DVSD_NOP() 0x00000000 + +// bit declarations for _Type fields +#define D3DVSDT_FLOAT1 0x00 // 1D float expanded to (value, 0., 0., 1.) +#define D3DVSDT_FLOAT2 0x01 // 2D float expanded to (value, value, 0., 1.) +#define D3DVSDT_FLOAT3 0x02 // 3D float expanded to (value, value, value, 1.) +#define D3DVSDT_FLOAT4 0x03 // 4D float +#define D3DVSDT_D3DCOLOR 0x04 // 4D packed unsigned bytes mapped to 0. to 1. range + // Input is in D3DCOLOR format (ARGB) expanded to (R, G, B, A) +#define D3DVSDT_UBYTE4 0x05 // 4D unsigned byte +#define D3DVSDT_SHORT2 0x06 // 2D signed short expanded to (value, value, 0., 1.) +#define D3DVSDT_SHORT4 0x07 // 4D signed short + +// assignments of vertex input registers for fixed function vertex shader +// +#define D3DVSDE_POSITION 0 +#define D3DVSDE_BLENDWEIGHT 1 +#define D3DVSDE_BLENDINDICES 2 +#define D3DVSDE_NORMAL 3 +#define D3DVSDE_PSIZE 4 +#define D3DVSDE_DIFFUSE 5 +#define D3DVSDE_SPECULAR 6 +#define D3DVSDE_TEXCOORD0 7 +#define D3DVSDE_TEXCOORD1 8 +#define D3DVSDE_TEXCOORD2 9 +#define D3DVSDE_TEXCOORD3 10 +#define D3DVSDE_TEXCOORD4 11 +#define D3DVSDE_TEXCOORD5 12 +#define D3DVSDE_TEXCOORD6 13 +#define D3DVSDE_TEXCOORD7 14 +#define D3DVSDE_POSITION2 15 +#define D3DVSDE_NORMAL2 16 + +// Maximum supported number of texture coordinate sets +#define D3DDP_MAXTEXCOORD 8 + + +// +// Instruction Token Bit Definitions +// +#define D3DSI_OPCODE_MASK 0x0000FFFF + +typedef enum _D3DSHADER_INSTRUCTION_OPCODE_TYPE +{ + D3DSIO_NOP = 0, // PS/VS + D3DSIO_MOV , // PS/VS + D3DSIO_ADD , // PS/VS + D3DSIO_SUB , // PS + D3DSIO_MAD , // PS/VS + D3DSIO_MUL , // PS/VS + D3DSIO_RCP , // VS + D3DSIO_RSQ , // VS + D3DSIO_DP3 , // PS/VS + D3DSIO_DP4 , // PS/VS + D3DSIO_MIN , // VS + D3DSIO_MAX , // VS + D3DSIO_SLT , // VS + D3DSIO_SGE , // VS + D3DSIO_EXP , // VS + D3DSIO_LOG , // VS + D3DSIO_LIT , // VS + D3DSIO_DST , // VS + D3DSIO_LRP , // PS + D3DSIO_FRC , // VS + D3DSIO_M4x4 , // VS + D3DSIO_M4x3 , // VS + D3DSIO_M3x4 , // VS + D3DSIO_M3x3 , // VS + D3DSIO_M3x2 , // VS + + D3DSIO_TEXCOORD = 64, // PS + D3DSIO_TEXKILL , // PS + D3DSIO_TEX , // PS + D3DSIO_TEXBEM , // PS + D3DSIO_TEXBEML , // PS + D3DSIO_TEXREG2AR , // PS + D3DSIO_TEXREG2GB , // PS + D3DSIO_TEXM3x2PAD , // PS + D3DSIO_TEXM3x2TEX , // PS + D3DSIO_TEXM3x3PAD , // PS + D3DSIO_TEXM3x3TEX , // PS + D3DSIO_TEXM3x3DIFF , // PS + D3DSIO_TEXM3x3SPEC , // PS + D3DSIO_TEXM3x3VSPEC , // PS + D3DSIO_EXPP , // VS + D3DSIO_LOGP , // VS + D3DSIO_CND , // PS + D3DSIO_DEF , // PS + D3DSIO_TEXREG2RGB , // PS + D3DSIO_TEXDP3TEX , // PS + D3DSIO_TEXM3x2DEPTH , // PS + D3DSIO_TEXDP3 , // PS + D3DSIO_TEXM3x3 , // PS + D3DSIO_TEXDEPTH , // PS + D3DSIO_CMP , // PS + D3DSIO_BEM , // PS + + D3DSIO_PHASE = 0xFFFD, + D3DSIO_COMMENT = 0xFFFE, + D3DSIO_END = 0xFFFF, + + D3DSIO_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum +} D3DSHADER_INSTRUCTION_OPCODE_TYPE; + +// +// Co-Issue Instruction Modifier - if set then this instruction is to be +// issued in parallel with the previous instruction(s) for which this bit +// is not set. +// +#define D3DSI_COISSUE 0x40000000 + +// +// Parameter Token Bit Definitions +// +#define D3DSP_REGNUM_MASK 0x00001FFF + +// destination parameter write mask +#define D3DSP_WRITEMASK_0 0x00010000 // Component 0 (X;Red) +#define D3DSP_WRITEMASK_1 0x00020000 // Component 1 (Y;Green) +#define D3DSP_WRITEMASK_2 0x00040000 // Component 2 (Z;Blue) +#define D3DSP_WRITEMASK_3 0x00080000 // Component 3 (W;Alpha) +#define D3DSP_WRITEMASK_ALL 0x000F0000 // All Components + +// destination parameter modifiers +#define D3DSP_DSTMOD_SHIFT 20 +#define D3DSP_DSTMOD_MASK 0x00F00000 + +typedef enum _D3DSHADER_PARAM_DSTMOD_TYPE +{ + D3DSPDM_NONE = 0<>8)&0xFF) +#define D3DSHADER_VERSION_MINOR(_Version) (((_Version)>>0)&0xFF) + +// destination/source parameter register type +#define D3DSI_COMMENTSIZE_SHIFT 16 +#define D3DSI_COMMENTSIZE_MASK 0x7FFF0000 +#define D3DSHADER_COMMENT(_DWordSize) \ + ((((_DWordSize)<= 1200 +#pragma warning(pop) +#else +#pragma warning(default:4201) +#endif + +#endif /* (DIRECT3D_VERSION >= 0x0800) */ +#endif /* _D3D8TYPES(P)_H_ */ + diff --git a/OpenParrot/deps/inc/ini_parser.hpp b/OpenParrot/deps/inc/ini_parser.hpp new file mode 100644 index 0000000..99acf1e --- /dev/null +++ b/OpenParrot/deps/inc/ini_parser.hpp @@ -0,0 +1,314 @@ +/* + * Copyright (c) 2013-2015 Denilson das Mercês Amorim + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + */ +#ifndef LINB_INI_PARSER_HPP +#define LINB_INI_PARSER_HPP + +/* + * STL-like INI Container + */ + +#include // for std::string +#include // for std::map +#include // for std::FILE +#include // for std::find_if +#include // for std::function + +namespace linb +{ + template< + class CharT = char, /* Not compatible with other type here, since we're using C streams */ + class StringType = std::basic_string, + class KeyContainer = std::map, + class SectionContainer = std::map + > class basic_ini + { + public: + typedef CharT char_type; + typedef StringType string_type; + typedef KeyContainer key_container; + typedef SectionContainer section_container; + + // Typedef container values types + typedef typename section_container::value_type value_type; + typedef typename section_container::key_type key_type; + typedef typename section_container::mapped_type mapped_type; + + // Typedef common types + typedef typename section_container::size_type size_type; + typedef typename section_container::difference_type difference_type; + + // Typedef iterators + typedef typename section_container::iterator iterator; + typedef typename section_container::const_iterator const_iterator; + typedef typename section_container::reverse_iterator reverse_iterator; + typedef typename section_container::const_reverse_iterator const_reverse_iterator; + + // typedef References and pointers + typedef typename section_container::reference reference; + typedef typename section_container::const_reference const_reference; + typedef typename section_container::pointer pointer; + typedef typename section_container::const_pointer const_pointer; + + private: + section_container data; + + public: + + basic_ini() + { } + + basic_ini(const char_type* filename) + { this->read_file(filename); } + + /* Iterator methods */ + iterator begin() + { return data.begin(); } + const_iterator begin() const + { return data.begin(); } + iterator end() + { return data.end(); } + const_iterator end() const + { return data.end(); } + const_iterator cbegin() const + { return data.cbegin(); } + const_iterator cend() const + { return data.cend(); } + + /* Reverse iterator methods */ + reverse_iterator rbegin() + { return data.rbegin(); } + const_reverse_iterator rbegin() const + { return data.rbegin(); } + reverse_iterator rend() + { return data.rend(); } + const_reverse_iterator rend() const + { return data.rend(); } + const_reverse_iterator crbegin() const + { return data.crbegin(); } + const_reverse_iterator crend() const + { return data.crend(); } + + /* Acessing index methods */ + mapped_type& operator[](const string_type& sect) + { return data[sect]; } + mapped_type& operator[](string_type&& sect) + { return data[std::forward(sect)]; } + mapped_type& at( const string_type& sect) + { return data.at(sect); } + const mapped_type& at(const string_type& sect) const + { return data.at(sect); } + + /* Capacity information */ + bool empty() const + { return data.empty(); } + size_type size() const + { return data.size(); } + size_type max_size() const + { return data.max_size(); } + + /* Modifiers */ + void clear() + { return data.clear(); } + + /* Lookup */ + size_type count(const string_type& sect) + { return data.count(sect); } + iterator find(const string_type& sect) + { return data.find(sect); } + + /* Gets a value from the specified section & key, default_value is returned if the sect & key doesn't exist */ + string_type get(const string_type& sect, const key_type& key, const string_type& default_value) + { + auto it = this->find(sect); + if(it != this->end()) + { + auto itv = it->second.find(key); + if(itv != it->second.end()) + return itv->second; + } + return default_value; + } + + /* Sets the value of a value in the ini */ + void set(const string_type& sect, const key_type& key, const string_type& value) + { + (*this)[sect][key] = value; // no emplace since overwrite! + } + + /* Too lazy to continue this container... If you need more methods, just add it */ + + +#if 1 + bool read_file(const char_type* filename) + { + /* Using C stream in a STL-like container, funny? + */ + if(FILE* f = fopen(filename, "r")) + { + key_container* keys = nullptr; + char_type buf[2048]; + string_type line; + string_type key; + string_type value; + string_type null_string; + size_type pos; + + // Trims an string + auto trim = [](string_type& s, bool trimLeft, bool trimRight) -> string_type& + { + if(s.size()) + { + // Ignore UTF-8 BOM + while(s.size() >= 3 && s[0] == (char)(0xEF) && s[1] == (char)(0xBB) && s[2] == (char)(0xBF)) + s.erase(s.begin(), s.begin() + 3); + + if(trimLeft) + s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::function(::isspace)))); + if(trimRight) + s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::function(::isspace))).base(), s.end()); + } + return s; + }; + + // Start parsing + while(fgets(buf, sizeof(buf), f)) + { + // What a thing, reading into a char buffer and then putting in the string... + line = buf; + + // Find comment and remove anything after it from the line + if((pos = line.find_first_of(';')) != line.npos) + line.erase(pos); + + // Trim the string, and if it gets empty, skip this line + if(trim(line, true, true).empty()) + continue; + + // Find section name + if(line.front() == '[' && line.back() == ']') + { + pos = line.length() - 1; //line.find_first_of(']'); + if(pos != line.npos) + { + trim(key.assign(line, 1, pos-1), true, true); + keys = &data[std::move(key)]; // Create section + } + else + keys = nullptr; + } + else + { + // Find key and value positions + pos = line.find_first_of('='); + if(pos == line.npos) + { + // There's only the key + key = line; // No need for trim, line is already trimmed + value.clear(); + } + else + { + // There's the key and the value + trim(key.assign(line, 0, pos), false, true); // trim the right + trim(value.assign(line, pos + 1, line.npos), true, false); // trim the left + } + + // Put the key/value into the current keys object, or into the section "" if no section has been found + #if __cplusplus >= 201103L || _MSC_VER >= 1800 + (keys ? *keys : data[null_string]).emplace(std::move(key), std::move(value)); + #else + (keys ? *keys : data[null_string])[key] = value; + key.clear(); value.clear(); + #endif + } + } + + fclose(f); + return true; + } + return false; + } + + /* + * Dumps the content of this container into an ini file + */ + bool write_file(const char_type* filename) + { + if(FILE* f = fopen(filename, "w")) + { + bool first = true; + for(auto& sec : this->data) + { + fprintf(f, first? "[%s]\n" : "\n[%s]\n", sec.first.c_str()); + first = false; + for(auto& kv : sec.second) + { + if(kv.second.empty()) + fprintf(f, "%s\n", kv.first.c_str()); + else + fprintf(f, "%s = %s\n", kv.first.c_str(), kv.second.c_str()); + } + } + fclose(f); + return true; + } + return false; + } + + + /* + */ + bool load_file(const char_type* filename) + { + return read_file(filename); + } + + bool load_file(const StringType& filename) + { + return load_file(filename.c_str()); + } + + bool write_file(const StringType& filename) + { + return write_file(filename.c_str()); + } +#endif + + + + }; + + + /* Use default basic_ini + * + * Limitations: + * * Not unicode aware + * * Case sensitive + * * Sections must have unique keys + */ + typedef basic_ini<> ini; +} + +#endif + diff --git a/OpenParrot/deps/inc/injector/assembly.hpp b/OpenParrot/deps/inc/injector/assembly.hpp new file mode 100644 index 0000000..622f57e --- /dev/null +++ b/OpenParrot/deps/inc/injector/assembly.hpp @@ -0,0 +1,178 @@ +/* + * Injectors - Useful Assembly Stuff + * + * Copyright (C) 2012-2014 LINK/2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + */ +#pragma once + +// This header is very restrict about compiler and architecture +#ifndef _MSC_VER // MSVC is much more flexible when we're talking about inline assembly +#error Cannot use this header in another compiler other than MSVC +#endif +#ifndef _M_IX86 +#error Supported only in x86 +#endif + +// +#include "injector.hpp" + +namespace injector +{ + struct reg_pack + { + // The ordering is very important, don't change + // The first field is the last to be pushed and first to be poped + + // PUSHFD / POPFD + uint32_t ef; + + // PUSHAD/POPAD -- must be the lastest fields (because of esp) + union + { + uint32_t arr[8]; + struct { uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; }; + }; + + enum reg_name { + reg_edi, reg_esi, reg_ebp, reg_esp, reg_ebx, reg_edx, reg_ecx, reg_eax + }; + + enum ef_flag { + carry_flag = 0, parity_flag = 2, adjust_flag = 4, zero_flag = 6, sign_flag = 7, + direction_flag = 10, overflow_flag = 11 + }; + + uint32_t& operator[](size_t i) + { return this->arr[i]; } + const uint32_t& operator[](size_t i) const + { return this->arr[i]; } + + template // bit starts from 0, use ef_flag enum + bool flag() + { + return (this->ef & (1 << bit)) != 0; + } + + bool jnb() + { + return flag() == false; + } + }; + + // Lowest level stuff (actual assembly) goes on the following namespace + // PRIVATE! Skip this, not interesting for you. + namespace injector_asm + { + // Wrapper functor, so the assembly can use some templating + template + struct wrapper + { + static void call(reg_pack* regs) + { + T fun; fun(*regs); + } + }; + + // Constructs a reg_pack and calls the wrapper functor + template // where W is of type wrapper + inline void __declspec(naked) make_reg_pack_and_call() + { + _asm + { + // Construct the reg_pack structure on the stack + pushad // Pushes general purposes registers to reg_pack + add [esp+12], 4 // Add 4 to reg_pack::esp 'cuz of our return pointer, let it be as before this func is called + pushfd // Pushes EFLAGS to reg_pack + + // Call wrapper sending reg_pack as parameter + push esp + call W::call + add esp, 4 + + // Destructs the reg_pack from the stack + sub [esp+12+4], 4 // Fix reg_pack::esp before popping it (doesn't make a difference though) (+4 because eflags) + popfd // Warning: Do not use any instruction that changes EFLAGS after this (-> sub affects EF!! <-) + popad + + // Back to normal flow + ret + } + } + }; + + + /* + * MakeInline + * Makes inline assembly (but not assembly, an actual functor of type FuncT) at address + */ + template + void MakeInline(memory_pointer_tr at) + { + typedef injector_asm::wrapper functor; + if(false) functor::call(nullptr); // To instantiate the template, if not done _asm will fail + MakeCALL(at, injector_asm::make_reg_pack_and_call); + } + + /* + * MakeInline + * Same as above, but it NOPs everything between at and end (exclusive), then performs MakeInline + */ + template + void MakeInline(memory_pointer_tr at, memory_pointer_tr end) + { + MakeRangedNOP(at, end); + MakeInline(at); + } + + /* + * MakeInline + * Same as above, but (at,end) are template parameters. + * On this case the functor can be passed as argument since there will be one func instance for each at,end not just for each FuncT + */ + template + void MakeInline(FuncT func) + { + static FuncT static_func = func; // Stores the func object + static_func = func; // + + // Encapsulates the call to static_func + struct Caps + { + void operator()(reg_pack& regs) + { static_func(regs); } + }; + + // Does the actual MakeInline + return MakeInline(lazy_pointer::get(), lazy_pointer::get()); + } + + /* + * MakeInline + * Same as above, but (end) is calculated by the length of a call instruction + */ + template + void MakeInline(FuncT func) + { + return MakeInline(func); + } +}; diff --git a/OpenParrot/deps/inc/injector/calling.hpp b/OpenParrot/deps/inc/injector/calling.hpp new file mode 100644 index 0000000..0a1dd62 --- /dev/null +++ b/OpenParrot/deps/inc/injector/calling.hpp @@ -0,0 +1,127 @@ +/* + * Injectors - Function Calls Using Variadic Templates + * + * Copyright (C) 2014 LINK/2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + */ +#pragma once +#include "injector.hpp" +#include +#include + +#if __cplusplus >= 201103L || _MSC_VER >= 1800 // MSVC 2013 +#else +#error "This feature is not supported on this compiler" +#endif + +namespace injector +{ + template + struct cstd; + + template + struct cstd + { + // Call function at @p returning @Ret with args @Args + static Ret call(memory_pointer_tr p, Args... a) + { + auto fn = (Ret(*)(Args...)) p.get(); + return fn(std::forward(a)...); + } + + template // Uses lazy pointer + static Ret call(Args... a) + { + return call(lazy_pointer::get(), std::forward(a)...); + } + }; + + template + struct stdcall; + + template + struct stdcall + { + // Call function at @p returning @Ret with args @Args + static Ret call(memory_pointer_tr p, Args... a) + { + auto fn = (Ret(__stdcall *)(Args...)) p.get(); + return fn(std::forward(a)...); + } + + template // Uses lazy pointer + static Ret call(Args... a) + { + return call(lazy_pointer::get(), std::forward(a)...); + } + }; + + template + struct fastcall; + + template + struct fastcall + { + // Call function at @p returning @Ret with args @Args + static Ret call(memory_pointer_tr p, Args... a) + { + auto fn = (Ret(__fastcall *)(Args...)) p.get();; + return fn(std::forward(a)...); + } + + template // Uses lazy pointer + static Ret call(Args... a) + { + return call(lazy_pointer::get(), std::forward(a)...); + } + }; + + template + struct thiscall; + + template + struct thiscall + { + // Call function at @p returning @Ret with args @Args + static Ret call(memory_pointer_tr p, Args... a) + { + auto fn = (Ret(__thiscall *)(Args...)) p.get(); + return fn(std::forward(a)...); + } + + // Call function at the index @i from the vtable of the object @a[0] + template + static Ret vtbl(Args... a) + { + auto obj = raw_ptr(std::get<0>(std::forward_as_tuple(a...))); + auto p = raw_ptr( (*obj.template get()) [i] ); + return call(p, std::forward(a)...); + } + + template // Uses lazy pointer + static Ret call(Args... a) + { + return call(lazy_pointer::get(), std::forward(a)...); + } + }; +} + diff --git a/OpenParrot/deps/inc/injector/gvm/gvm.hpp b/OpenParrot/deps/inc/injector/gvm/gvm.hpp new file mode 100644 index 0000000..27a0562 --- /dev/null +++ b/OpenParrot/deps/inc/injector/gvm/gvm.hpp @@ -0,0 +1,229 @@ +/* + * Injectors - Base Header + * + * Copyright (C) 2012-2014 LINK/2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + */ +#pragma once +#include +#include +#include + +namespace injector +{ + +#if 1 // GVM and Address Translator, Not very interesting for the users, so skip reading those... + +/* + * game_version_manager + * Detects the game, the game version and the game region + * This assumes the executable is decrypted, so, Silent's ASI Loader is recommended. + */ +#ifndef INJECTOR_OWN_GVM +#ifndef INJECTOR_GVM_DUMMY +class game_version_manager +{ + public: + // Set this if you would like that MessagesBox contain PluginName as caption + const char* PluginName; + + private: + char game, region, major, minor, majorRevision, minorRevision, cracker, steam; + + public: + game_version_manager() + { + #ifdef INJECTOR_GVM_PLUGIN_NAME + PluginName = INJECTOR_GVM_PLUGIN_NAME; + #else + PluginName = "Unknown Plugin Name"; + #endif + + this->Clear(); + } + + + // Clear any information about game version + void Clear() + { + game = region = major = minor = majorRevision = minorRevision = cracker = steam = 0; + } + + // Checks if I don't know the game we are attached to + bool IsUnknown() { return game == 0; } + // Checks if this is the steam version + bool IsSteam() { return steam != 0; } + // Gets the game we are attached to (0, '3', 'V', 'S', 'I', 'E') + char GetGame() { return game; } + // Gets the region from the game we are attached to (0, 'U', 'E'); + char GetRegion() { return region; } + // Get major and minor version of the game (e.g. [major = 1, minor = 0] = 1.0) + int GetMajorVersion() { return major; } + int GetMinorVersion() { return minor; } + int GetMajorRevisionVersion() { return majorRevision; } + int GetMinorRevisionVersion() { return minorRevision; } + + bool IsHoodlum() { return cracker == 'H'; } + + // Region conditions + bool IsUS() { return region == 'U'; } + bool IsEU() { return region == 'E'; } + + // Game Conditions + bool IsIII() { return game == '3'; } + bool IsVC () { return game == 'V'; } + bool IsSA () { return game == 'S'; } + bool IsIV () { return game == 'I'; } + bool IsEFLC(){ return game == 'E'; } + + // Detects game, region and version; returns false if could not detect it + bool Detect(); + + // Gets the game version as text, the buffer must contain at least 32 bytes of space. + char* GetVersionText(char* buffer) + { + if(this->IsUnknown()) + { + strcpy(buffer, "UNKNOWN GAME"); + return buffer; + } + + const char* g = this->IsIII() ? "III" : this->IsVC() ? "VC" : this->IsSA() ? "SA" : this->IsIV() ? "IV" : this->IsEFLC() ? "EFLC" : "UNK"; + const char* r = this->IsUS()? "US" : this->IsEU()? "EURO" : "UNK_REGION"; + const char* s = this->IsSteam()? "Steam" : ""; + sprintf(buffer, "GTA %s %d.%d.%d.%d %s%s", g, major, minor, majorRevision, minorRevision, r, s); + return buffer; + } + + + public: + // Raises a error saying that you could not detect the game version + void RaiseCouldNotDetect() + { + MessageBoxA(0, + "Could not detect the game version\nContact the mod creator!", + PluginName, MB_ICONERROR + ); + } + + // Raises a error saying that the exe version is incompatible (and output the exe name) + void RaiseIncompatibleVersion() + { + char buf[128], v[32]; + sprintf(buf, + "An incompatible exe version has been detected! (%s)\nContact the mod creator!", + GetVersionText(v) + ); + MessageBoxA(0, buf, PluginName, MB_ICONERROR); + } +}; +#else // INJECTOR_GVM_DUMMY +class game_version_manager +{ + public: + bool Detect() { return true; } +}; +#endif // INJECTOR_GVM_DUMMY +#endif // INJECTOR_OWN_GVM + + +/* + * address_manager + * Address translator from 1.0 executables to other executables offsets + * Inherits from game_version_manager ;) + */ +class address_manager : public game_version_manager +{ + private: + address_manager() + { + this->Detect(); + } + + // You could implement your translator for the address your plugin uses + // If not implemented, the translator won't translate anything, just return the samething as before + #ifdef INJECTOR_GVM_HAS_TRANSLATOR + void* translator(void* p); + #else + void* translator(void* p) { return p; } + #endif + + public: + // Translates address p to the running executable pointer + void* translate(void* p) + { + return translator(p); + } + + + public: + // Address manager singleton + static address_manager& singleton() + { + static address_manager m; + return m; + } + + // Static version of translate() + static void* translate_address(void* p) + { + return singleton().translate(p); + } + + // + static void set_name(const char* modname) + { + singleton().PluginName = modname; + } + + public: + // Functors for memory translation: + + // Translates aslr translator + struct fn_mem_translator_aslr + { + void* operator()(void* p) const + { + static uintptr_t module = (uintptr_t)GetModuleHandle(NULL); + return (void*)((uintptr_t)(p)-(0x400000 - module)); + } + }; + + // Translates nothing translator + struct fn_mem_translator_nop + { + void* operator()(void* p) const + { return p; } + }; + + // Real translator + struct fn_mem_translator + { + void* operator()(void* p) const + { return translate_address(p); } + }; +}; + +#endif // #if 1 + + +} \ No newline at end of file diff --git a/OpenParrot/deps/inc/injector/gvm/translator.hpp b/OpenParrot/deps/inc/injector/gvm/translator.hpp new file mode 100644 index 0000000..c6ac430 --- /dev/null +++ b/OpenParrot/deps/inc/injector/gvm/translator.hpp @@ -0,0 +1,203 @@ +/* + * Injectors - Address Translation Management + * + * Copyright (C) 2014 LINK/2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + */ +#pragma once + +#if !defined(INJECTOR_GVM_HAS_TRANSLATOR) +#error Missing INJECTOR_GVM_HAS_TRANSLATOR on compiler definitions +#endif + +/* + * This is a quick solution for address translations if you're too lazy to implement a proper address_manager::translator by yourself + * So, just call address_translator_manager::singleton().translate(p) from your address_manager::translator and that's it. + * It'll translate addresses based on 'address_translator' objects, when one gets constructed it turns into a possible translator. + * At the constructor of your derived 'address_translator' make the map object to have [addr_to_translate] = translated_addr; + * There's also the virtual method 'fallback' that will get called when the translation wasn't possible, you can do some fallback stuff here + * (such as return the pointer as is or output a error message) + */ + +#include "../injector.hpp" +#include +#include +#include + +namespace injector +{ + /* + * address_translator + * Base for an address translator + */ + class address_translator + { + private: + bool enabled; + void add(); + void remove(); + + protected: + friend class address_translator_manager; + std::map map; + + public: + address_translator() : enabled(true) + { + // Must have bounds filled with min ptr and max ptr to have search working properly + map.insert(std::make_pair(raw_ptr(0x00000000u), raw_ptr(0x00000000u))); + map.insert(std::make_pair(raw_ptr(0xffffffffu), raw_ptr(0xffffffffu))); + add(); + } + + ~address_translator() + { + remove(); + } + + virtual void* fallback(void*) const + { + return nullptr; + } + + + // Enables or disables this translator + void enable(bool enable_it) + { + if(enable_it) this->enable(); + else this->disable(); + } + + // Enables this translator + void enable() + { + this->enabled = true; + } + + // Disables this translator + void disable() + { + this->enabled = false; + } + + // Checks if this translator is enabled + bool is_enabled() const + { + return enabled; + } + }; + + /* + * address_translator_manager + * Manages the address_translator objects + */ + class address_translator_manager + { + protected: + friend class address_manager; + friend class address_translator; + + std::list translators; + + void add(const address_translator& t) + { + translators.push_front(&t); + } + + void remove(const address_translator& t) + { + translators.remove(&t); + } + + public: + // Translates the address p + void* translator(void* p); + + // Singleton object + static address_translator_manager& singleton() + { + static address_translator_manager mgr; + return mgr; + } + }; + + + + inline void* address_translator_manager::translator(void* p_) + { + static const size_t max_ptr_dist = 7; + + // Tries to find an address in a translator map + auto try_map = [](const std::map& map, memory_pointer_raw p) -> memory_pointer_raw + { + memory_pointer_raw result = nullptr; + + // Find first element in the map that is greater than or equal to p + auto it = map.lower_bound(p); + if(it != map.end()) + { + // If it's not exactly the address, get back one position on the table + if(it->first != p) --it; + + auto diff = (p - it->first).as_int(); // What's the difference between p and that address? + if(diff <= max_ptr_dist) // Could we live with this difference in hands? + result = it->second + raw_ptr(diff); // Yes, we can! + } + + return result; + }; + + + // + memory_pointer_raw result = nullptr; + + // Try to find translation for this pointer + auto& mgr = address_translator_manager::singleton().translators; + for(auto it = mgr.begin(); result == nullptr && it != mgr.end(); ++it) + { + auto& t = **it; + if(t.is_enabled()) result = try_map(t.map, p_); + } + + // If we couldn't translate the address, notify and try to fallback + if(result.is_null()) + { + for(auto it = mgr.begin(); result == nullptr && it != mgr.end(); ++it) + { + auto& t = **it; + if(t.is_enabled()) result = t.fallback(p_); + } + } + + return result.get(); + } + + inline void address_translator::add() + { + address_translator_manager::singleton().add(*this); + } + + inline void address_translator::remove() + { + address_translator_manager::singleton().remove(*this); + } +} diff --git a/OpenParrot/deps/inc/injector/hooking.hpp b/OpenParrot/deps/inc/injector/hooking.hpp new file mode 100644 index 0000000..ec7d797 --- /dev/null +++ b/OpenParrot/deps/inc/injector/hooking.hpp @@ -0,0 +1,687 @@ +/* + * Injectors - Classes for making your hooking life easy + * + * Copyright (C) 2013-2014 LINK/2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + */ +#pragma once +#include "injector.hpp" +#include +#include +#include // for std::shared_ptr +#include + +namespace injector +{ + /* + * scoped_base + * Base for any scoped hooking type + * !!!! NOTICE !!!! --> Any derived which implements/reimplements restore() should implement a destructor calling it + */ + class scoped_base + { + public: + virtual ~scoped_base() {} + virtual void restore() = 0; + }; + + /* + * scoped_basic + * Base for scoped types which will need a buffer to save/restore stuff + */ + template // TODO specialize bufsize=0 to be dynamic + class scoped_basic : public scoped_base + { + private: + uint8_t buf[bufsize];// Saved content + memory_pointer_raw addr; // Data saved from this address + size_t size; // Size saved + bool saved; // Something saved? + bool vp; // Virtual protect? + + public: + + static const bool is_dynamic = false; + + // Restore the previosly saved data + // Problems may arise if someone else hooked the same place using the same method + virtual void restore() + { + #ifndef INJECTOR_SCOPED_NOSAVE_NORESTORE + if(this->saved) + { + WriteMemoryRaw(this->addr, this->buf, this->size, this->vp); + this->saved = false; + } + #endif + } + + // Save buffer at @addr with @size and virtual protect @vp + virtual void save(memory_pointer_tr addr, size_t size, bool vp) + { + #ifndef INJECTOR_SCOPED_NOSAVE_NORESTORE + assert(size <= bufsize); // Debug Safeness + this->restore(); // Restore anything we have saved + this->saved = true; // Mark that we have data save + this->addr = addr.get(); // Save address + this->size = size; // Save size + this->vp = vp; // Save virtual protect + ReadMemoryRaw(addr, buf, size, vp); // Save buffer + #endif + } + + public: + // Constructor, initialises + scoped_basic() : saved(false) + {} + + ~scoped_basic() + { + this->restore(); + } + + // No copy construction, we can't do this! Sure we can move construct :) + scoped_basic(const scoped_basic&) = delete; + scoped_basic(scoped_basic&& rhs) + { + *this = std::move(rhs); + } + + scoped_basic& operator=(const scoped_basic& rhs) = delete; + scoped_basic& operator=(scoped_basic&& rhs) + { + if(this->saved = rhs.saved) + { + assert(bufsize >= rhs.size); + + this->addr = rhs.addr; + this->size = rhs.size; + this->vp = rhs.vp; + memcpy(buf, rhs.buf, rhs.size); + + rhs.saved = false; + } + return *this; + } + }; + + /* + * RAII wrapper for memory writes + * Can save only basic and POD types + */ + template + class scoped_write : public scoped_basic + { + public: + // Save buffer at @addr with @size and virtual protect @vp and then overwrite it with @value + void write(memory_pointer_tr addr, void* value, size_t size, bool vp) + { + this->save(addr, size, vp); + return WriteMemoryRaw(addr, value, size, vp); + } + + // Save buffer at @addr with size sizeof(@value) and virtual protect @vp and then overwrite it with @value + template + void write(memory_pointer_tr addr, T value, bool vp = false) + { + this->save(addr, sizeof(T), vp); + return WriteMemory(addr, value, vp); + } + + // Constructors, move constructors, assigment operators........ + scoped_write() = default; + scoped_write(const scoped_write&) = delete; + scoped_write(scoped_write&& rhs) : scoped_basic(std::move(rhs)) {} + scoped_write& operator=(const scoped_write& rhs) = delete; + scoped_write& operator=(scoped_write&& rhs) + { scoped_basic::operator=(std::move(rhs)); return *this; } + }; + + /* + * RAII wrapper for filling + */ + template + class scoped_fill : public scoped_basic + { + public: + // Fills memory at @addr with value @value and size @size and virtual protect @vp + void fill(memory_pointer_tr addr, uint8_t value, size_t size, bool vp) + { + this->save(addr, size, vp); + return MemoryFill(addr, value, size, vp); + } + + // Constructors, move constructors, assigment operators........ + scoped_fill() = default; + scoped_fill(const scoped_fill&) = delete; + scoped_fill(scoped_fill&& rhs) : scoped_basic(std::move(rhs)) {} + scoped_fill& operator=(const scoped_fill& rhs) = delete; + scoped_fill& operator=(scoped_fill&& rhs) + { scoped_basic::operator=(std::move(rhs)); return *this; } + + scoped_fill(memory_pointer_tr addr, uint8_t value, size_t size, bool vp) + { fill(addr, value, vp); } + }; + + /* + * RAII wrapper for nopping + */ + template + class scoped_nop : public scoped_basic + { + public: + // Makes NOP at @addr with value @value and size @size and virtual protect @vp + void make_nop(memory_pointer_tr addr, size_t size = 1, bool vp = true) + { + this->save(addr, size, vp); + return MakeNOP(addr, size, vp); + } + + // Constructors, move constructors, assigment operators........ + scoped_nop() = default; + scoped_nop(const scoped_nop&) = delete; + scoped_nop(scoped_nop&& rhs) : scoped_basic(std::move(rhs)) {} + scoped_nop& operator=(const scoped_nop& rhs) = delete; + scoped_nop& operator=(scoped_nop&& rhs) + { scoped_basic::operator=(std::move(rhs)); return *this; } + + scoped_nop(memory_pointer_tr addr, size_t size = 1, bool vp = true) + { make_nop(addr, size, vp); } + }; + + /* + * RAII wrapper for MakeJMP + */ + class scoped_jmp : public scoped_basic<5> + { + public: + // Makes NOP at @addr with value @value and size @size and virtual protect @vp + memory_pointer_raw make_jmp(memory_pointer_tr at, memory_pointer_raw dest, bool vp = true) + { + this->save(at, 5, vp); + return MakeJMP(at, dest, vp); + } + + // Constructors, move constructors, assigment operators........ + scoped_jmp() = default; + scoped_jmp(const scoped_jmp&) = delete; + scoped_jmp(scoped_jmp&& rhs) : scoped_basic<5>(std::move(rhs)) {} + scoped_jmp& operator=(const scoped_jmp& rhs) = delete; + scoped_jmp& operator=(scoped_jmp&& rhs) + { scoped_basic<5>::operator=(std::move(rhs)); return *this; } + + scoped_jmp(memory_pointer_tr at, memory_pointer_raw dest, bool vp = true) + { make_jmp(at, dest, vp); } + }; + + /* + * RAII wrapper for MakeCALL + */ + class scoped_call : public scoped_basic<5> + { + public: + // Makes NOP at @addr with value @value and size @size and virtual protect @vp + memory_pointer_raw make_call(memory_pointer_tr at, memory_pointer_raw dest, bool vp = true) + { + this->save(at, 5, vp); + return MakeCALL(at, dest, vp); + } + + // Constructors, move constructors, assigment operators........ + scoped_call() = default; + scoped_call(const scoped_call&) = delete; + scoped_call(scoped_call&& rhs) : scoped_basic<5>(std::move(rhs)) {} + scoped_call& operator=(const scoped_call& rhs) = delete; + scoped_call& operator=(scoped_call&& rhs) + { scoped_basic<5>::operator=(std::move(rhs)); return *this; } + + scoped_call(memory_pointer_tr at, memory_pointer_raw dest, bool vp = true) + { make_call(at, dest, vp); } + }; + + +#if __cplusplus >= 201103L || _MSC_VER >= 1800 // C++11 or MSVC 2013 required for variadic templates + + /* + * function_hooker_manager + * Manages many function_hookers that points to the same address + * The need for this function arises because otherwise we would only be able to allow one hook per address using function_hookers + * This manager takes care of the amount of hooks placed in a particular address, calls the hooks and unhooks when necessary. + */ + template + class function_hooker_manager : protected scoped_call + { + private: + using func_type_raw = typename ToManage::func_type_raw; + using func_type = typename ToManage::func_type; + using functor_type = typename ToManage::functor_type; + using assoc_type = std::list>; + + // Only construction is allowed... by myself ofcourse... + function_hooker_manager() = default; + function_hooker_manager(const function_hooker_manager&) = delete; + function_hooker_manager(function_hooker_manager&&) = delete; + + // + func_type_raw original; // Pointer to the original function we've replaced + assoc_type assoc; // Association between owners of a hook and the hook (map) + bool has_hooked = false; // Is the hook already in place? + + // Find assoc iterator for the content owned by 'owned' + typename assoc_type::iterator find_assoc(const ToManage& owner) + { + for(auto it = assoc.begin(); it != assoc.end(); ++it) + if(it->first == &owner) return it; + return assoc.end(); + } + + // Adds a new item to the association map (or override if already in the map) + void add(const ToManage& hooker, functor_type functor) + { + auto it = find_assoc(hooker); + if(it != assoc.end()) + it->second = std::move(functor); + else + assoc.emplace_back(&hooker, std::move(functor)); + } + + public: + // Forwards the call to all the installed hooks + static Ret call_hooks(Args&... args) + { + auto& manager = *instance(); + + if(manager.assoc.size() == 0) // This may be uncommon but may happen (?), no hook installed + return manager.original(args...); + + // Functor for the original call + func_type original = [&manager](Args... args) -> Ret { + return manager.original(args...); + }; + + if(manager.assoc.size() == 1) + { + // We have only one hook, just use it directly no need to go further in complexity + auto& functor = manager.assoc.begin()->second; + return functor(std::move(original), args...); + } + else + { + // Build a serie of functors which captures the previous functor sending it to the next functor, + // that's what would happen if the hooks took place independent of the template staticness (AAAAAAA) + func_type next = std::move(original); + for(auto it = manager.assoc.begin(); it != manager.assoc.end(); ++it) + { + auto& functor = it->second; + next = [functor, next](Args... args) -> Ret + { + return functor(next, args...); + }; + } + return next(args...); + } + } + + public: + + // Installs a hook associated with the function_hooker 'hooker' which would call the specified 'functor' + // We need an auxiliar function pointer 'ptr' (to abstract calling conventions) which should forward itself to ^call_hooks + void make_call(const ToManage& hooker, functor_type functor, memory_pointer_raw ptr) + { + this->add(hooker, std::move(functor)); + + // Make sure we only hook this address for the manager once + if(!this->has_hooked) + { + // (the following cast is needed for __thiscall functions) + this->original = (func_type_raw) (void*) scoped_call::make_call(hooker.addr, ptr).get(); + this->has_hooked = true; + } + } + + // Restores the state of the call we've replaced in the game code + // All installed hooks gets uninstalled after this + void restore() + { + if(this->has_hooked) + { + this->has_hooked = false; + this->assoc.clear(); + return scoped_call::restore(); + } + } + + // Replaces the hook associated with 'from' to be associated with 'to' + // After this call the 'from' object has no association in this manager + void replace(const ToManage& from, const ToManage& to) + { + auto it = find_assoc(from); + if(it != assoc.end()) + { + auto functor = std::move(it->second); + assoc.erase(it); + this->add(to, std::move(functor)); + } + } + + // Removes the hook associated with the specified 'hooker' + // If the number of hooks reaches zero after the remotion, a restore will take place + void remove(const ToManage& hooker) + { + auto it = find_assoc(hooker); + if(it != assoc.end()) + { + assoc.erase(it); + if(assoc.size() == 0) this->restore(); + } + } + + // The instance of this specific manager + // This work as a shared pointer to avoid the static destruction of the manager even when a static function_hooker + // still wants to use it. + static std::shared_ptr instance() + { + static auto fm_ptr = std::shared_ptr(new function_hooker_manager()); + return fm_ptr; + } + + }; + + + /* + * function_hooker_base + * Base for any function_hooker, this class manages the relationship with the function hooker manager + */ + template + class function_hooker_base : public scoped_base + { + public: + static const uintptr_t addr = addr1; + + using func_type_raw = FuncType; + using func_type = std::function; + using functor_type = std::function; + using manager_type = function_hooker_manager; + + public: + // Constructors, move constructors, assigment operators........ + function_hooker_base(const function_hooker_base&) = delete; + function_hooker_base& operator=(const function_hooker_base& rhs) = delete; + + function_hooker_base() : manager(manager_type::instance()) + {} + + // + virtual ~function_hooker_base() + { + this->restore(); + } + + // The move constructor should do a replace in the manager + function_hooker_base(function_hooker_base&& rhs) + : scoped_base(std::move(rhs)), has_call(rhs.has_call), + manager(rhs.manager) // (don't move the manager!, every function_hooker should own one) + { + manager->replace(rhs, *this); + } + + // The move assignment operator should also do a replace in the manager + function_hooker_base& operator=(function_hooker_base&& rhs) + { + scoped_base::operator=(std::move(rhs)); + manager->replace(rhs, *this); + this->has_call = rhs.has_call; + this->manager = rhs.manager; // (don't move the manager! every function_hooker should own one) + return *this; + } + + // Deriveds should implement a proper make_call (yeah it's virtual so derived-deriveds can do some fest) + virtual void make_call(functor_type functor) = 0; + + // Restores the state of the call we've replaced in the game code + virtual void restore() + { + this->has_call = false; + manager->remove(*this); + } + + // Checkers whether a hook is installed + bool has_hooked() + { + return this->has_call; + } + + private: + bool has_call = false; // Has a hook installed? + std::shared_ptr manager; // **EVERY** function_hooker should have a ownership over it's manager_type + // this prevents the static destruction of the manager_type while it may be still needed. + + protected: // Forwarders to the function hooker manager + + void make_call(functor_type functor, memory_pointer_raw ptr) + { + this->has_call = true; + manager->make_call(*this, std::move(functor), ptr); + } + + static Ret call_hooks(Args&... a) + { + return manager_type::call_hooks(a...); + } + }; + + + + + /* + * function_hooker + * For standard conventions (usually __cdecl) + */ + template + struct function_hooker; + + template + class function_hooker + : public function_hooker_base + { + private: + using base = function_hooker_base; + + // The hook caller + static Ret call(Args... a) + { + return base::call_hooks(a...); + } + + public: + // Constructors, move constructors, assigment operators........ + function_hooker() = default; + function_hooker(const function_hooker&) = delete; + function_hooker(function_hooker&& rhs) : base(std::move(rhs)) {} + function_hooker& operator=(const function_hooker& rhs) = delete; + function_hooker& operator=(function_hooker&& rhs) + { base::operator=(std::move(rhs)); return *this; } + + // Makes the hook + void make_call(typename base::functor_type functor) + { + return base::make_call(std::move(functor), raw_ptr(call)); + } + }; + + + /* + * function_hooker_stdcall + * For stdcall conventions (__stdcall) + */ + template + struct function_hooker_stdcall; + + template + struct function_hooker_stdcall + : public function_hooker_base + { + private: + using base = function_hooker_base; + + // The hook caller + static Ret __stdcall call(Args... a) + { + return base::call_hooks(a...); + } + + public: + // Constructors, move constructors, assigment operators........ + function_hooker_stdcall() = default; + function_hooker_stdcall(const function_hooker_stdcall&) = delete; + function_hooker_stdcall(function_hooker_stdcall&& rhs) : base(std::move(rhs)) {} + function_hooker_stdcall& operator=(const function_hooker_stdcall& rhs) = delete; + function_hooker_stdcall& operator=(function_hooker_stdcall&& rhs) + { base::operator=(std::move(rhs)); return *this; } + + // Makes the hook + void make_call(typename base::functor_type functor) + { + return base::make_call(std::move(functor), raw_ptr(call)); + } + }; + + + /* + * function_hooker_fastcall + * For fastcall conventions (__fastcall) + */ + template + struct function_hooker_fastcall; + + template + struct function_hooker_fastcall + : public function_hooker_base + { + private: + using base = function_hooker_base; + + // The hook caller + static Ret __fastcall call(Args... a) + { + return base::call_hooks(a...); + } + + public: + // Constructors, move constructors, assigment operators........ + function_hooker_fastcall() = default; + function_hooker_fastcall(const function_hooker_fastcall&) = delete; + function_hooker_fastcall(function_hooker_fastcall&& rhs) : base(std::move(rhs)) {} + function_hooker_fastcall& operator=(const function_hooker_fastcall& rhs) = delete; + function_hooker_fastcall& operator=(function_hooker_fastcall&& rhs) + { base::operator=(std::move(rhs)); return *this; } + + // Makes the hook + void make_call(typename base::functor_type functor) + { + return base::make_call(std::move(functor), raw_ptr(call)); + } + }; + + + /* + * function_hooker_thiscall + * For thiscall conventions (__thiscall, class methods) + */ + template + struct function_hooker_thiscall; + + template + struct function_hooker_thiscall + : public function_hooker_base + { + private: + using base = function_hooker_base; + + // The hook caller + static Ret __thiscall call(Args... a) + { + return base::call_hooks(a...); + } + + public: + // Constructors, move constructors, assigment operators........ + function_hooker_thiscall() = default; + function_hooker_thiscall(const function_hooker_thiscall&) = delete; + function_hooker_thiscall(function_hooker_thiscall&& rhs) : base(std::move(rhs)) {} + function_hooker_thiscall& operator=(const function_hooker_thiscall& rhs) = delete; + function_hooker_thiscall& operator=(function_hooker_thiscall&& rhs) + { base::operator=(std::move(rhs)); return *this; } + + // Makes the hook + void make_call(typename base::functor_type functor) + { + return base::make_call(std::move(functor), raw_ptr(call)); + } + }; + + + + /******************* HELPERS ******************/ + + /* + * Adds a hook to be alive for the entire program lifetime + * That means the hook received will be alive until the program dies. + * Note: Parameter must be a rvalue + */ + template inline + T& add_static_hook(T&& hooker) + { + static std::list a; + return *a.emplace(a.end(), std::move(hooker)); + } + + /* + * Makes a hook which is alive until it gets out of scope + * 'T' must be any function_hooker object + */ + template inline + T make_function_hook(F functor) + { + T a; + a.make_call(std::move(functor)); + return a; + } + + /* + * Makes a hook which is alive for the entire lifetime of this program + * 'T' must be any function_hooker object + */ + template inline + T& make_static_hook(F functor) + { + return add_static_hook(make_function_hook(std::move(functor))); + } + + + // TODO when we have access to C++14 add a make_function_hook, make_stdcall_function_hook, and so on + // the problem behind implement it with C++11 is that lambdas cannot be generic and the first param of a hook is a functor pointing + // to the previous call pointer + +#endif + +} diff --git a/OpenParrot/deps/inc/injector/injector.hpp b/OpenParrot/deps/inc/injector/injector.hpp new file mode 100644 index 0000000..11a79fa --- /dev/null +++ b/OpenParrot/deps/inc/injector/injector.hpp @@ -0,0 +1,752 @@ +/* + * Injectors - Base Header + * + * Copyright (C) 2012-2014 LINK/2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + */ +#pragma once +#define INJECTOR_HAS_INJECTOR_HPP +#include +#include +#include +#include "gvm/gvm.hpp" +/* + The following macros (#define) are relevant on this header: + + INJECTOR_GVM_HAS_TRANSLATOR + If defined, the user should provide their own address_manager::translator function. + That function is responssible for translating a void pointer (that mayn't be an actual pointer) into an actual address. + The meaning of that void pointer will be made by YOU when you send it to the functions that receive pointers on this library. + The default translator does nothing but returns that void pointer as the address. + + INJECTOR_GVM_OWN_DETECT + If defined, the user should provide it's own game detection function thought game_version_manager::Detect + By default it provide an good detection for the Grand Theft Auto series. + + INJECTOR_GVM_PLUGIN_NAME + If this is defined, it will be used as the plugin name used at error messages. + By default it will use ""Unknown Plugin Name" + + INJECTOR_GVM_DUMMY + If defined, the game_version_manager will be a dummy object + By default it provides a nice gvm for Grand Theft Auto series + + INJECTOR_OWN_GVM + If defined, the game_version_manager should be implemented by the user before including this library. + By default it provides a nice gvm for Grand Theft Auto series +*/ +#include "gvm/gvm.hpp" + + + +namespace injector +{ + + +/* + * auto_pointer + * Casts itself to another pointer type in the lhs + */ +union auto_pointer +{ + protected: + friend union memory_pointer_tr; + template friend union basic_memory_pointer; + + void* p; + uintptr_t a; + + public: + auto_pointer() : p(0) {} + auto_pointer(const auto_pointer& x) : p(x.p) {} + explicit auto_pointer(void* x) : p(x) {} + explicit auto_pointer(uint32_t x) : a(x) {} + + bool is_null() const { return this->p != nullptr; } + + #if __cplusplus >= 201103L || _MSC_VER >= 1800 + explicit operator bool() const { return is_null(); } + #endif + + auto_pointer get() const { return *this; } + template T* get() const { return (T*) this->p; } + template T* get_raw() const { return (T*) this->p; } + + template + operator T*() const { return reinterpret_cast(p); } +}; + +/* + * basic_memory_pointer + * A memory pointer class that is capable of many operations, including address translation + * MemTranslator is the translator functor + */ +template +union basic_memory_pointer +{ + protected: + void* p; + uintptr_t a; + + // Translates address p to the running executable pointer + static auto_pointer memory_translate(void* p) + { + return auto_pointer(MemTranslator()(p)); + } + + public: + basic_memory_pointer() : p(nullptr) {} + basic_memory_pointer(std::nullptr_t) : p(nullptr) {} + basic_memory_pointer(uintptr_t x) : a(x) {} + basic_memory_pointer(const auto_pointer& x) : p(x.p) {} + basic_memory_pointer(const basic_memory_pointer& rhs) : p(rhs.p) {} + + template + basic_memory_pointer(T* x) : p((void*)x) {} + + + + + // Gets the translated pointer (plus automatic casting to lhs) + auto_pointer get() const { return memory_translate(p); } + + // Gets the translated pointer (casted to T*) + template T* get() const { return get(); } + + // Gets the raw pointer, without translation (casted to T*) + template T* get_raw() const { return auto_pointer(p); } + + // This type can get assigned from void* and uintptr_t + basic_memory_pointer& operator=(void* x) { return p = x, *this; } + basic_memory_pointer& operator=(uintptr_t x) { return a = x, *this; } + + /* Arithmetic */ + basic_memory_pointer operator+(const basic_memory_pointer& rhs) const + { return basic_memory_pointer(this->a + rhs.a); } + + basic_memory_pointer operator-(const basic_memory_pointer& rhs) const + { return basic_memory_pointer(this->a - rhs.a); } + + basic_memory_pointer operator*(const basic_memory_pointer& rhs) const + { return basic_memory_pointer(this->a * rhs.a); } + + basic_memory_pointer operator/(const basic_memory_pointer& rhs) const + { return basic_memory_pointer(this->a / rhs.a); } + + + /* Comparision */ + bool operator==(const basic_memory_pointer& rhs) const + { return this->a == rhs.a; } + + bool operator!=(const basic_memory_pointer& rhs) const + { return this->a != rhs.a; } + + bool operator<(const basic_memory_pointer& rhs) const + { return this->a < rhs.a; } + + bool operator<=(const basic_memory_pointer& rhs) const + { return this->a <= rhs.a; } + + bool operator>(const basic_memory_pointer& rhs) const + { return this->a > rhs.a; } + + bool operator>=(const basic_memory_pointer& rhs) const + { return this->a >=rhs.a; } + + bool is_null() const { return this->p == nullptr; } + uintptr_t as_int() const { return this->a; } // does not perform translation + + + +#if __cplusplus >= 201103L || _MSC_VER >= 1800 // MSVC 2013 + /* Conversion to other types */ + explicit operator uintptr_t() const + { return this->a; } // does not perform translation + explicit operator bool() const + { return this->p != nullptr; } +#else + //operator bool() -------------- Causes casting problems because of implicitness, use !is_null() + //{ return this->p != nullptr; } +#endif + +}; + + // Typedefs including memory translator for the above type +typedef basic_memory_pointer memory_pointer; +typedef basic_memory_pointer memory_pointer_raw; +typedef basic_memory_pointer memory_pointer_aslr; + + + +/* + * memory_pointer_tr + * Stores a basic_memory_pointer as a raw pointer from translated pointer + */ +union memory_pointer_tr +{ + protected: + void* p; + uintptr_t a; + + public: + template + memory_pointer_tr(const basic_memory_pointer& ptr) + : p(ptr.get()) + {} // Constructs from a basic_memory_pointer + + memory_pointer_tr(const auto_pointer& ptr) + : p(ptr.p) + {} // Constructs from a auto_pointer, probably comming from basic_memory_pointer::get + + memory_pointer_tr(const memory_pointer_tr& rhs) + : p(rhs.p) + {} // Constructs from my own type, copy constructor + + memory_pointer_tr(uintptr_t x) + : p(memory_pointer(x).get()) + {} // Constructs from a integer, translating the address + + memory_pointer_tr(void* x) + : p(memory_pointer(x).get()) + {} // Constructs from a void pointer, translating the address + + // Just to be method-compatible with basic_memory_pointer ... + auto_pointer get() { return auto_pointer(p); } + template T* get() { return get(); } + template T* get_raw() { return get(); } + + memory_pointer_tr operator+(const uintptr_t& rhs) const + { return memory_pointer_raw(this->a + rhs); } + + memory_pointer_tr operator-(const uintptr_t& rhs) const + { return memory_pointer_raw(this->a - rhs); } + + memory_pointer_tr operator*(const uintptr_t& rhs) const + { return memory_pointer_raw(this->a * rhs); } + + memory_pointer_tr operator/(const uintptr_t& rhs) const + { return memory_pointer_raw(this->a / rhs); } + + bool is_null() const { return this->p == nullptr; } + uintptr_t as_int() const { return this->a; } + +#if __cplusplus >= 201103L + explicit operator uintptr_t() const + { return this->a; } +#else +#endif + +}; + + + + + + + +/* + * ProtectMemory + * Makes the address @addr have a protection of @protection + */ +inline bool ProtectMemory(memory_pointer_tr addr, size_t size, DWORD protection) +{ + return VirtualProtect(addr.get(), size, protection, &protection) != 0; +} + +/* + * UnprotectMemory + * Unprotect the memory at @addr with size @size so it have all accesses (execute, read and write) + * Returns the old protection to out_oldprotect + */ +inline bool UnprotectMemory(memory_pointer_tr addr, size_t size, DWORD& out_oldprotect) +{ + return VirtualProtect(addr.get(), size, PAGE_EXECUTE_READWRITE, &out_oldprotect) != 0; +} + +/* + * scoped_unprotect + * RAII wrapper for UnprotectMemory + * On construction unprotects the memory, on destruction reprotects the memory + */ +struct scoped_unprotect +{ + memory_pointer_raw addr; + size_t size; + DWORD dwOldProtect; + bool bUnprotected; + + scoped_unprotect(memory_pointer_tr addr, size_t size) + { + if(size == 0) bUnprotected = false; + else bUnprotected = UnprotectMemory(this->addr = addr.get(), this->size = size, dwOldProtect); + } + + ~scoped_unprotect() + { + if(bUnprotected) ProtectMemory(this->addr.get(), this->size, this->dwOldProtect); + } +}; + + + + + + + + +/* + * WriteMemoryRaw + * Writes into memory @addr the content of @value with a sizeof @size + * Does memory unprotection if @vp is true + */ +inline void WriteMemoryRaw(memory_pointer_tr addr, void* value, size_t size, bool vp) +{ + scoped_unprotect xprotect(addr, vp? size : 0); + memcpy(addr.get(), value, size); +} + +/* + * ReadMemoryRaw + * Reads the memory at @addr with a sizeof @size into address @ret + * Does memory unprotection if @vp is true + */ +inline void ReadMemoryRaw(memory_pointer_tr addr, void* ret, size_t size, bool vp) +{ + scoped_unprotect xprotect(addr, vp? size : 0); + memcpy(ret, addr.get(), size); +} + +/* + * MemoryFill + * Fills the memory at @addr with the byte @value doing it @size times + * Does memory unprotection if @vp is true + */ +inline void MemoryFill(memory_pointer_tr addr, uint8_t value, size_t size, bool vp) +{ + scoped_unprotect xprotect(addr, vp? size : 0); + memset(addr.get(), value, size); +} + +/* + * WriteObject + * Assigns the object @value into the same object type at @addr + * Does memory unprotection if @vp is true + */ +template +inline T& WriteObject(memory_pointer_tr addr, const T& value, bool vp = false) +{ + scoped_unprotect xprotect(addr, vp? sizeof(value) : 0); + return (*addr.get() = value); +} + +/* + * ReadObject + * Assigns the object @value with the value of the same object type at @addr + * Does memory unprotection if @vp is true + */ +template +inline T& ReadObject(memory_pointer_tr addr, T& value, bool vp = false) +{ + scoped_unprotect xprotect(addr, vp? sizeof(value) : 0); + return (value = *addr.get()); +} + + +/* + * WriteMemory + * Writes the object of type T into the address @addr + * Does memory unprotection if @vp is true + */ +template +inline void WriteMemory(memory_pointer_tr addr, T value, bool vp = false) +{ + WriteObject(addr, value, vp); +} + +/* + * ReadMemory + * Reads the object type T at address @addr + * Does memory unprotection if @vp is true + */ +template +inline T ReadMemory(memory_pointer_tr addr, bool vp = false) +{ + T value; + return ReadObject(addr, value, vp); +} + +/* + * AdjustPointer + * Searches in the range [@addr, @addr + @max_search] for a pointer in the range [@default_base, @default_end] and replaces + * it with the proper offset in the pointer @replacement_base. + * Does memory unprotection if @vp is true. + */ + inline memory_pointer_raw AdjustPointer(memory_pointer_tr addr, + memory_pointer_raw replacement_base, memory_pointer_tr default_base, memory_pointer_tr default_end, + size_t max_search = 8, bool vp = true) + { + scoped_unprotect xprotect(addr, vp? max_search + sizeof(void*) : 0); + for(size_t i = 0; i < max_search; ++i) + { + memory_pointer_raw ptr = ReadMemory(addr + i); + if(ptr >= default_base.get() && ptr <= default_end.get()) + { + auto result = replacement_base + (ptr - default_base.get()); + WriteMemory(addr + i, result.get()); + return result; + } + } + return nullptr; + } + + + + + + +/* + * GetAbsoluteOffset + * Gets absolute address based on relative offset @rel_value from instruction that ends at @end_of_instruction + */ +inline memory_pointer_raw GetAbsoluteOffset(int rel_value, memory_pointer_tr end_of_instruction) +{ + return end_of_instruction.get() + rel_value; +} + +/* + * GetRelativeOffset + * Gets relative offset based on absolute address @abs_value for instruction that ends at @end_of_instruction + */ +inline int GetRelativeOffset(memory_pointer_tr abs_value, memory_pointer_tr end_of_instruction) +{ + return uintptr_t(abs_value.get() - end_of_instruction.get()); +} + +/* + * ReadRelativeOffset + * Reads relative offset from address @at + */ +inline memory_pointer_raw ReadRelativeOffset(memory_pointer_tr at, size_t sizeof_addr = 4, bool vp = true) +{ + switch(sizeof_addr) + { + case 1: return (GetAbsoluteOffset(ReadMemory (at, vp), at+sizeof_addr)); + case 2: return (GetAbsoluteOffset(ReadMemory(at, vp), at+sizeof_addr)); + case 4: return (GetAbsoluteOffset(ReadMemory(at, vp), at+sizeof_addr)); + } + return nullptr; +} + +/* + * MakeRelativeOffset + * Writes relative offset into @at based on absolute destination @dest + */ +inline void MakeRelativeOffset(memory_pointer_tr at, memory_pointer_tr dest, size_t sizeof_addr = 4, bool vp = true) +{ + switch(sizeof_addr) + { + case 1: WriteMemory (at, static_cast (GetRelativeOffset(dest, at+sizeof_addr)), vp); + case 2: WriteMemory(at, static_cast(GetRelativeOffset(dest, at+sizeof_addr)), vp); + case 4: WriteMemory(at, static_cast(GetRelativeOffset(dest, at+sizeof_addr)), vp); + } +} + +/* + * GetBranchDestination + * Gets the destination of a branch instruction at address @at + * *** Works only with JMP and CALL for now *** + */ +inline memory_pointer_raw GetBranchDestination(memory_pointer_tr at, bool vp = true) +{ + switch(ReadMemory(at, vp)) + { + // We need to handle other instructions (and prefixes) later... + case 0xE8: // call rel + case 0xE9: // jmp rel + return ReadRelativeOffset(at + 1, 4, vp); + + case 0xFF: + switch(ReadMemory(at + 1, vp)) + { + case 0x15: // call dword ptr [addr] + case 0x25: // jmp dword ptr [addr] + return *(ReadMemory(at + 2, vp)); + } + break; + } + return nullptr; +} + +/* + * MakeJMP + * Creates a JMP instruction at address @at that jumps into address @dest + * If there was already a branch instruction there, returns the previosly destination of the branch + */ +inline memory_pointer_raw MakeJMP(memory_pointer_tr at, memory_pointer_raw dest, bool vp = true) +{ + auto p = GetBranchDestination(at, vp); + WriteMemory(at, 0xE9, vp); + MakeRelativeOffset(at+1, dest, 4, vp); + return p; +} + +/* + * MakeCALL + * Creates a CALL instruction at address @at that jumps into address @dest + * If there was already a branch instruction there, returns the previosly destination of the branch + */ +inline memory_pointer_raw MakeCALL(memory_pointer_tr at, memory_pointer_raw dest, bool vp = true) +{ + auto p = GetBranchDestination(at, vp); + WriteMemory(at, 0xE8, vp); + MakeRelativeOffset(at+1, dest, 4, vp); + return p; +} + +/* + * MakeJA + * Creates a JA instruction at address @at that jumps if above into address @dest + * If there was already a branch instruction there, returns the previosly destination of the branch + */ +inline void MakeJA(memory_pointer_tr at, memory_pointer_raw dest, bool vp = true) +{ + WriteMemory(at, 0x87F0, vp); + MakeRelativeOffset(at+2, dest, 4, vp); +} + +/* + * MakeNOP + * Creates a bunch of NOP instructions at address @at + */ +inline void MakeNOP(memory_pointer_tr at, size_t count = 1, bool vp = true) +{ + MemoryFill(at, 0x90, count, vp); +} + +/* + * MakeRangedNOP + * Creates a bunch of NOP instructions at address @at until address @until + */ +inline void MakeRangedNOP(memory_pointer_tr at, memory_pointer_tr until, bool vp = true) +{ + return MakeNOP(at, size_t(until.get_raw() - at.get_raw()), vp); +} + + +/* + * MakeRET + * Creates a RET instruction at address @at popping @pop values from the stack + * If @pop is equal to 0 it will use the 1 byte form of the instruction + */ +inline void MakeRET(memory_pointer_tr at, uint16_t pop = 0, bool vp = true) +{ + WriteMemory(at, pop? 0xC2 : 0xC3, vp); + if(pop) WriteMemory(at+1, pop, vp); +} + + + + + +/* + * lazy_pointer + * Lazy pointer, where it's final value will get evaluated only once when finally needed. + */ + template + struct lazy_pointer + { + public: + // Returns the final raw pointer + static auto_pointer get() + { + return xget().get(); + } + + template + static T* get() + { + return get().get(); + } + + private: + // Returns the final pointer + static memory_pointer_raw xget() + { + static void* ptr = nullptr; + if(!ptr) ptr = memory_pointer(addr).get(); + return memory_pointer_raw(ptr); + } +}; + + /* + * lazy_object + * Lazy object, where it's final object will get evaluated only once when finally needed. + */ + template + struct lazy_object + { + static T& get() + { + static T data; + static bool has_data = false; + if(!has_data) + { + ReadObject(addr, data, true); + has_data = true; + } + return data; + } + }; + + + /* + Helpers + */ + + template +inline memory_pointer mem_ptr(T p) +{ + return memory_pointer(p); +} + +template +inline memory_pointer_raw raw_ptr(T p) +{ + return memory_pointer_raw(p); +} + +template +inline memory_pointer_raw raw_ptr(basic_memory_pointer p) +{ + return raw_ptr(p.get()); +} + +template +inline memory_pointer_raw lazy_ptr() +{ + return lazy_pointer::get(); +} + +template +inline memory_pointer_aslr aslr_ptr(T p) +{ + return memory_pointer_aslr(p); +} + + + + + + +#ifndef INJECTOR_GVM_OWN_DETECT // Should we implement our detection method? + +// Detects game, region and version; returns false if could not detect it +inline bool game_version_manager::Detect() +{ + // Cleanup data + this->Clear(); + + // Find NT header + uintptr_t base = (uintptr_t) GetModuleHandleA(NULL); + IMAGE_DOS_HEADER* dos = (IMAGE_DOS_HEADER*)(base); + IMAGE_NT_HEADERS* nt = (IMAGE_NT_HEADERS*)(base + dos->e_lfanew); + + // Look for game and version thought the entry-point + // Thanks to Silent for many of the entry point offsets + switch (base + nt->OptionalHeader.AddressOfEntryPoint + (0x400000 - base)) + { + case 0x5C1E70: // GTA III 1.0 + game = '3', major = 1, minor = 0, region = 0, steam = false; + return true; + + case 0x5C2130: // GTA III 1.1 + game = '3', major = 1, minor = 1, region = 0, steam = false; + return true; + + case 0x5C6FD0: // GTA III 1.1 (Cracked Steam Version) + case 0x9912ED: // GTA III 1.1 (Encrypted Steam Version) + game = '3', major = 1, minor = 1, region = 0, steam = true; + return true; + + case 0x667BF0: // GTA VC 1.0 + game = 'V', major = 1, minor = 0, region = 0, steam = false; + return true; + + case 0x667C40: // GTA VC 1.1 + game = 'V', major = 1, minor = 1, region = 0, steam = false; + return true; + + case 0x666BA0: // GTA VC 1.1 (Cracked Steam Version) + case 0xA402ED: // GTA VC 1.1 (Encrypted Steam Version) + game = 'V', major = 1, minor = 1, region = 0, steam = true; + return true; + + case 0x82457C: // GTA SA 1.0 US Cracked + case 0x824570: // GTA SA 1.0 US Compact + game = 'S', major = 1, minor = 0, region = 'U', steam = false; + cracker = injector::ReadMemory(raw_ptr(0x406A20), true) == 0xE9? 'H' : 0; + return true; + + case 0x8245BC: // GTA SA 1.0 EU Cracked (??????) + case 0x8245B0: // GTA SA 1.0 EU Cracked + game = 'S', major = 1, minor = 0, region = 'E', steam = false; + cracker = injector::ReadMemory(raw_ptr(0x406A20), true) == 0xE9? 'H' : 0; // just to say 'securom' + return true; + + case 0x8252FC: // GTA SA 1.1 US Cracked + game = 'S', major = 1, minor = 1, region = 'U', steam = false; + return true; + + case 0x82533C: // GTA SA 1.1 EU Cracked + game = 'S', major = 1, minor = 1, region = 'E', steam = false; + return true; + + case 0x85EC4A: // GTA SA 3.0 (Cracked Steam Version) + case 0xD3C3DB: // GTA SA 3.0 (Encrypted Steam Version) + game = 'S', major = 3, minor = 0, region = 0, steam = true; + return true; + + case 0xC965AD: // GTA IV 1.0.0.4 US + game = 'I', major = 1, minor = 0, majorRevision = 0, minorRevision = 4, region = 'U', steam = false; + return true; + + case 0xD0D011: // GTA IV 1.0.0.7 US + game = 'I', major = 1, minor = 0, majorRevision = 0, minorRevision = 7, region = 'U', steam = false; + return true; + + case 0xD0AF06: // GTA EFLC 1.1.2.0 US + game = 'E', major = 1, minor = 1, majorRevision = 2, minorRevision = 0, region = 'U', steam = false; + return true; + + case 0x1415FF790: // GTA 5 v1.0.350.2 Non-Steam US + game = '5', major = 1, minor = 0, majorRevision = 350, minorRevision = 2, region = 'U', steam = false; + return true; + default: + return false; + } +} + +#endif + + +} // namespace + diff --git a/OpenParrot/deps/inc/injector/utility.hpp b/OpenParrot/deps/inc/injector/utility.hpp new file mode 100644 index 0000000..0a5eafc --- /dev/null +++ b/OpenParrot/deps/inc/injector/utility.hpp @@ -0,0 +1,56 @@ +/* + * Injectors - Utility / Helpers + * + * Copyright (C) 2014 LINK/2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + */ +#pragma once + +namespace injector +{ + template + T return_value() + { + return value; + } + + template + void* force_ptr(const T& fun) + { + auto ptr = fun; + return *(void**)&ptr; + } + + + // Helper structure to help calling back what was there before a hook + // e.g. hb.fun = MakeCALL(0x0, raw_ptr(my_hook)); + template + struct hook_back + { + typedef FuncType func_type; + + func_type fun; + + hook_back() : fun(nullptr) + {} + }; +}; diff --git a/OpenParrot/premake5.lua b/OpenParrot/premake5.lua new file mode 100644 index 0000000..3961451 --- /dev/null +++ b/OpenParrot/premake5.lua @@ -0,0 +1,25 @@ +project "OpenParrot" + targetname "OpenParrot" + language "C++" + kind "SharedLib" + + files + { + "src/**.cpp", "src/**.h", + "deps/cpp/**.cpp", "deps/inc/**.h" + } + + includedirs { "src", "deps/inc/" } + libdirs { "deps/lib/" } + + --pchheader 'StdInc.h' + --pchsource 'src/StdInc.cpp' + + links { "MinHook", "udis86" } + + postbuildcommands { } + + filter "platforms:x64" + files { "src/win64init.asm" } + + targetsuffix "64" \ No newline at end of file diff --git a/OpenParrot/src/Functions/Games/ES3X/MachStorm.cpp b/OpenParrot/src/Functions/Games/ES3X/MachStorm.cpp new file mode 100644 index 0000000..2c28b42 --- /dev/null +++ b/OpenParrot/src/Functions/Games/ES3X/MachStorm.cpp @@ -0,0 +1,23 @@ +#if _M_IX86 +#include +#include "Utility/InitFunction.h" +#include "Functions/Global.h" + +extern LPCSTR hookPort; +static InitFunction MachStormFunc([]() +{ + DWORD imageBase = (DWORD)GetModuleHandleA(0); + + // Patch to ignore all errors + injector::WriteMemory(imageBase + 0x7071E, 0x90909090, true); + + // Patch to skip extra device strange init (also delays game start on real cabinet several minutes!!!) + injector::WriteMemory(imageBase + 0x76430, 0xC340C033, true); + injector::WriteMemory(imageBase + 0x76870, 0xC340C033, true); + + // Patch test menu etc + injector::WriteMemoryRaw(imageBase + 0x544BB0, (char*)".\\%c%s.dat", 12, true); + + hookPort = "COM3"; +}, GameID::MachStorm); +#endif \ No newline at end of file diff --git a/OpenParrot/src/Functions/Games/Europa-R/FordRacing.cpp b/OpenParrot/src/Functions/Games/Europa-R/FordRacing.cpp new file mode 100644 index 0000000..f065b56 --- /dev/null +++ b/OpenParrot/src/Functions/Games/Europa-R/FordRacing.cpp @@ -0,0 +1,53 @@ +#include +#include "Utility/InitFunction.h" +#include "Functions/Global.h" +#if _M_IX86 +signed int FordRacingControlInit() +{ + // start input thread + ((void(*)(int, int, int))0x4E0803)(0x4DE030, 0, 0); + + // set input initialized + *(DWORD*)0x6B02A0 = 1; + + // device count + *(DWORD*)0x6B0290 = 1; + + // set joystick + *(char**)0x6A9AF4 = "JOYSTICK"; + + // create mutex + *(DWORD*)0x6A9A74 = (DWORD)CreateMutex(NULL, FALSE, NULL); + + return 1; +} +extern int* ffbOffset; + +int __stdcall FordRacingFfbFunc(DWORD device, DWORD data) +{ + if(device == 0x378) + { + *ffbOffset = data; + } + return 0; +} + +static InitFunction fordRacingFunc([]() +{ + + DWORD oldprot = 0; + DWORD oldprot2 = 0; + VirtualProtect((LPVOID)0x401000, 0xEE000, 0x40, &oldprot); + + // readfile call + static DWORD source = (DWORD)(LPVOID)&ReadFileHooked; + *(DWORD *)0x4DE005 = (DWORD)(LPVOID)&source; + VirtualProtect((LPVOID)0x401000, 0xEE000, oldprot, &oldprot2); + + // replace input init + injector::MakeJMP(0x4DE1F0, FordRacingControlInit); + // Hook FFB calls + injector::MakeJMP(0x00467C9A, FordRacingFfbFunc); + +}, GameID::FordRacing); +#endif \ No newline at end of file diff --git a/OpenParrot/src/Functions/Games/Europa-R/SR3.cpp b/OpenParrot/src/Functions/Games/Europa-R/SR3.cpp new file mode 100644 index 0000000..cd1c920 --- /dev/null +++ b/OpenParrot/src/Functions/Games/Europa-R/SR3.cpp @@ -0,0 +1,42 @@ +#include +#include "Utility/InitFunction.h" +#include "Functions/Global.h" +#if _M_IX86 +extern int* ffbOffset; + +int __stdcall Sr3FfbFunc(DWORD device, DWORD data) +{ + *ffbOffset = data; + return 0; +} + +static InitFunction sr3Func([]() +{ + DWORD oldprot = 0; + DWORD oldprot2 = 0; + VirtualProtect((LPVOID)0x401000, 0x273000, 0x40, &oldprot); + // force controller init + //injector::MakeJMP(0x57B2F0, ReturnTrue); + memcpy((LPVOID)0x57B2F0, "\x33\xC0\x40\xC3", 4); + + // disable checks for controller pointer + memset((LPVOID)0x57B670, 0x90, 15); + + // dereference + memset((LPVOID)0x57B684, 0x90, 3); + + // Hook FFB + // Remove loading of inpout32.dll + injector::MakeNOP(0x006582A8, 0x17); + // Give our own pointer to the FFB func + injector::WriteMemory(0x006582A8, 0xB8, true); + injector::WriteMemory(0x006582A9, (DWORD)Sr3FfbFunc, true); + // + + // ReadFile call + static DWORD source = (DWORD)(LPVOID)&ReadFileHooked; + *(DWORD *)0x57B696 = (DWORD)(LPVOID)&source; + VirtualProtect((LPVOID)0x401000, 0x273000, oldprot, &oldprot2); + +}, GameID::SR3); +#endif \ No newline at end of file diff --git a/OpenParrot/src/Functions/Games/Nesica/NesicaGeneric.cpp b/OpenParrot/src/Functions/Games/Nesica/NesicaGeneric.cpp new file mode 100644 index 0000000..6e826ce --- /dev/null +++ b/OpenParrot/src/Functions/Games/Nesica/NesicaGeneric.cpp @@ -0,0 +1,41 @@ +#include +#include "Utility/GameDetect.h" +#include "Utility/InitFunction.h" +#include "Functions/Nesica_Libs/CryptoPipe.h" +#include "Functions/Nesica_Libs/FastIoEmu.h" +#include "Functions/Nesica_Libs/RfidEmu.h" +#include "Functions/Nesica_Libs/NesysEmu.h" + +static InitFunction initFunction([]() +{ + init_FastIoEmu(); + init_RfidEmu(X2Type::RFID); + init_NesysEmu(); +#if _M_IX86 + if(GameDetect::NesicaKey != NesicaKey::None) + init_CryptoPipe(GameDetect::NesicaKey); +#endif +}, GameID::Nesica); + +static int ReturnTrue() +{ + return 1; +} + +static InitFunction initFunction_SOR([]() +{ + uintptr_t imageBase = (uintptr_t)GetModuleHandleA(0); + init_FastIoEmu(); + init_RfidEmu(X2Type::RFID); + safeJMP(imageBase + 0xFA350, ReturnTrue); + safeJMP(imageBase + 0xF8FC0, ReturnTrue); + // Patch data dir to game dir pls D:/ -> .\\ + // + injector::WriteMemory(imageBase + 0x21B9AC0, 0x2F002E002E, true); + init_NesysEmu(); + if (ToBool(config["General"]["Windowed"])) + { + injector::WriteMemory(imageBase + 0xFF703C, 0xF633C1FFC1FFC933, true); + injector::WriteMemory(imageBase + 0xFF703C+0x08, 0xC6FFC6FF, true); + } +}, GameID::SchoolOfRagnarok); \ No newline at end of file diff --git a/OpenParrot/src/Functions/Games/TypeX2/DirectInputWrapper.cpp b/OpenParrot/src/Functions/Games/TypeX2/DirectInputWrapper.cpp new file mode 100644 index 0000000..6aa1a92 --- /dev/null +++ b/OpenParrot/src/Functions/Games/TypeX2/DirectInputWrapper.cpp @@ -0,0 +1,385 @@ +#pragma optimize("", off) +// ============================================================================ +// ttx_monitor: Opensource TaitoTypeX loader +// by Romhack +// ============================================================================ +// Fake API do DirectInput, assim impedimos que os jogos tenham acesso aos controles. +#include +#include "StdInc.h" +#include "Utility/InitFunction.h" + +#define DIRECTINPUT_VERSION 0x800 +#include + +#pragma comment(lib, "dxguid.lib") + +#define COM_NO_WINDOWS_H +#include +#include "Utility/GameDetect.h" + +typedef HRESULT(__stdcall *LPDirectInput8Create)(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID * ppvOut, LPUNKNOWN punkOuter); + +LPDirectInput8Create __DirectInput8Create; +static DIDEVICEINSTANCEA devi; + +#pragma pack(4) +struct FAR HookIUnknown +{ + virtual HRESULT QueryInterface(LPVOID _this, REFIID riid, LPVOID *ppvObj); + virtual ULONG AddRef(LPVOID _this); + virtual ULONG Release(LPVOID _this); +}; + +static HookIUnknown UnknownInfo, *pUnknownInfo = &UnknownInfo; + +HRESULT HookIUnknown::QueryInterface(LPVOID _this, REFIID riid, LPVOID *ppvObj) +{ + *ppvObj = NULL; + return DIERR_UNSUPPORTED; +} + +ULONG HookIUnknown::AddRef(LPVOID _this) +{ + return 0; +} + +ULONG HookIUnknown::Release(LPVOID _this) +{ + return 0; +} + +#pragma pack(4) +struct FAR HookIDirectInputDevice +{ + virtual HRESULT QueryInterface(LPVOID _this, REFIID riid, LPVOID *ppvObj); + virtual ULONG AddRef(LPVOID _this); + virtual ULONG Release(LPVOID _this); + + virtual HRESULT GetCapabilities(LPVOID _this, LPDIDEVCAPS lpDIDevCaps); + virtual HRESULT EnumObjects(LPVOID _this, LPDIENUMDEVICEOBJECTSCALLBACK lpCallback, LPVOID pvRef, DWORD dwFlags); + virtual HRESULT GetProperty(LPVOID _this, REFGUID rguidProp, LPDIPROPHEADER pdiph); + virtual HRESULT SetProperty(LPVOID _this, REFGUID rguidProp, LPCDIPROPHEADER pdiph); + virtual HRESULT Acquire(LPVOID _this); + virtual HRESULT Unacquire(LPVOID _this); + virtual HRESULT GetDeviceState(LPVOID _this, DWORD cbData, LPVOID lpvData); + virtual HRESULT GetDeviceData(LPVOID _this, DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags); + virtual HRESULT SetDataFormat(LPVOID _this, LPCDIDATAFORMAT lpdf); + virtual HRESULT SetEventNotification(LPVOID _this, HANDLE hEvent); + virtual HRESULT SetCooperativeLevel(LPVOID _this, HWND hwnd, DWORD dwFlags); + virtual HRESULT GetObjectInfo(LPVOID _this, LPDIDEVICEOBJECTINSTANCE pdidoi, DWORD dwObj, DWORD dwHow); + virtual HRESULT GetDeviceInfo(LPVOID _this, LPDIDEVICEINSTANCE pdidi); + virtual HRESULT RunControlPanel(LPVOID _this, HWND hwndOwner, DWORD dwFlags); + virtual HRESULT Initialize(LPVOID _this, HINSTANCE hinst, DWORD dwVersion, REFGUID rguid); + virtual HRESULT CreateEffect(LPVOID _this, REFGUID rguid, LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT * ppdeff, LPUNKNOWN punkOuter); + virtual HRESULT EnumEffects(LPVOID _this, LPDIENUMEFFECTSCALLBACK lpCallback, LPVOID pvRef, DWORD dwEffType); + virtual HRESULT GetEffectInfo(LPVOID _this, LPDIEFFECTINFOA pdei, REFGUID rguid); + virtual HRESULT GetForceFeedbackState(LPVOID _this, LPDWORD pdwOut); + virtual HRESULT SendForceFeedbackCommand(LPVOID _this, DWORD dwFlags); + virtual HRESULT EnumCreatedEffectObjects(LPVOID _this, LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID pvRef, DWORD fl); + virtual HRESULT Escape(LPVOID _this, LPDIEFFESCAPE pesc); + virtual HRESULT Poll(LPVOID _this); + virtual HRESULT SendDeviceData(LPVOID _this, DWORD cbObjectData, LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD fl); + virtual HRESULT EnumEffectsInFile(LPVOID _this, LPCSTR lpszFileName, LPDIENUMEFFECTSINFILECALLBACK pec, LPVOID pvRef, DWORD dwFlags); + virtual HRESULT WriteEffectToFile(LPVOID _this, LPCSTR lpszFileName, DWORD dwEntries, LPCDIFILEEFFECT rgDiFileEft, DWORD dwFlags); + virtual HRESULT BuildActionMap(LPVOID _this, LPDIACTIONFORMAT lpdiaf, LPCTSTR lpszUserName, DWORD dwFlags); + virtual HRESULT SetActionMap(LPVOID _this, LPCDIACTIONFORMAT lpdiActionFormat, LPCTSTR lptszUserName, DWORD dwFlags); + virtual HRESULT GetImageInfo(LPVOID _this, LPDIDEVICEIMAGEINFOHEADER lpdiDevImageInfoHeader); +}; + +static HookIDirectInputDevice FakeDevice, *pFakeDevice = &FakeDevice; + +HRESULT HookIDirectInputDevice::QueryInterface(LPVOID _this, REFIID riid, LPVOID *ppvObj) +{ + *ppvObj = NULL; + + return 0; +} + +ULONG HookIDirectInputDevice::AddRef(LPVOID _this) +{ + return 2; +} + +ULONG HookIDirectInputDevice::Release(LPVOID _this) +{ + return 0; +} + + +HRESULT HookIDirectInputDevice::GetCapabilities(LPVOID _this, LPDIDEVCAPS lpDIDevCaps) +{ + return DI_OK; +} + +HRESULT HookIDirectInputDevice::EnumObjects(LPVOID _this, LPDIENUMDEVICEOBJECTSCALLBACK lpCallback, LPVOID pvRef, DWORD dwFlags) +{ + return DI_OK; +} + +HRESULT HookIDirectInputDevice::GetProperty(LPVOID _this, REFGUID rguidProp, LPDIPROPHEADER pdiph) +{ + return DI_OK; +} + +HRESULT HookIDirectInputDevice::SetProperty(LPVOID _this, REFGUID rguidProp, LPCDIPROPHEADER pdiph) +{ + return DI_OK; +} + +HRESULT HookIDirectInputDevice::Acquire(LPVOID _this) +{ + return DI_OK; +} + +HRESULT HookIDirectInputDevice::Unacquire(LPVOID _this) +{ + return DI_OK; +} + +HRESULT HookIDirectInputDevice::GetDeviceState(LPVOID _this, DWORD cbData, LPVOID lpvData) +{ + if (lpvData) + { + ZeroMemory(lpvData, cbData); + } + + return DI_OK; +} + +HRESULT HookIDirectInputDevice::GetDeviceData(LPVOID _this, DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) +{ + if (rgdod) + { + ZeroMemory(rgdod, cbObjectData * (*pdwInOut)); + } + + return DI_OK; +} + +HRESULT HookIDirectInputDevice::SetDataFormat(LPVOID _this, LPCDIDATAFORMAT lpdf) +{ + return DI_OK; +} + +HRESULT HookIDirectInputDevice::SetEventNotification(LPVOID _this, HANDLE hEvent) +{ + return DI_OK; +} + +HRESULT HookIDirectInputDevice::SetCooperativeLevel(LPVOID _this, HWND hwnd, DWORD dwFlags) +{ + return DI_OK; +} + +HRESULT HookIDirectInputDevice::GetObjectInfo(LPVOID _this, LPDIDEVICEOBJECTINSTANCE pdidoi, DWORD dwObj, DWORD dwHow) +{ + return DI_OK; +} + +HRESULT HookIDirectInputDevice::GetDeviceInfo(LPVOID _this, LPDIDEVICEINSTANCE pdidi) +{ + return DI_OK; +} + +HRESULT HookIDirectInputDevice::RunControlPanel(LPVOID _this, HWND hwndOwner, DWORD dwFlags) +{ + return DI_OK; +} + +HRESULT HookIDirectInputDevice::Initialize(LPVOID _this, HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) +{ + return DI_OK; +} + +HRESULT HookIDirectInputDevice::CreateEffect(LPVOID _this, REFGUID rguid, LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT * ppdeff,LPUNKNOWN punkOuter) +{ + return DIERR_UNSUPPORTED; +} + +HRESULT HookIDirectInputDevice::EnumEffects(LPVOID _this, LPDIENUMEFFECTSCALLBACK lpCallback, LPVOID pvRef, DWORD dwEffType) +{ + return DIERR_UNSUPPORTED; +} + +HRESULT HookIDirectInputDevice::GetEffectInfo(LPVOID _this, LPDIEFFECTINFOA pdei, REFGUID rguid) +{ + return DIERR_UNSUPPORTED; +} + + +HRESULT HookIDirectInputDevice::GetForceFeedbackState(LPVOID _this, LPDWORD pdwOut) +{ + return DIERR_UNSUPPORTED; +} + +HRESULT HookIDirectInputDevice::SendForceFeedbackCommand(LPVOID _this, DWORD dwFlags) +{ + return DIERR_UNSUPPORTED; +} + +HRESULT HookIDirectInputDevice::EnumCreatedEffectObjects(LPVOID _this, LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID pvRef, DWORD fl) +{ + return DIERR_UNSUPPORTED; +} + +HRESULT HookIDirectInputDevice::Escape(LPVOID _this, LPDIEFFESCAPE pesc) +{ + return DIERR_UNSUPPORTED; +} + +HRESULT HookIDirectInputDevice::Poll(LPVOID _this) +{ + return DI_NOEFFECT; +} + +HRESULT HookIDirectInputDevice::SendDeviceData(LPVOID _this, DWORD cbObjectData, LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD fl) +{ + return DIERR_UNSUPPORTED; +} + +HRESULT HookIDirectInputDevice::EnumEffectsInFile(LPVOID _this, LPCSTR lpszFileName, LPDIENUMEFFECTSINFILECALLBACK pec, LPVOID pvRef, DWORD dwFlags) +{ + return DIERR_UNSUPPORTED; +} + +HRESULT HookIDirectInputDevice::WriteEffectToFile(LPVOID _this, LPCSTR lpszFileName, DWORD dwEntries, LPCDIFILEEFFECT rgDiFileEft, DWORD dwFlags) +{ + return DIERR_UNSUPPORTED; +} + +HRESULT HookIDirectInputDevice::BuildActionMap(LPVOID _this, LPDIACTIONFORMAT lpdiaf, LPCTSTR lpszUserName, DWORD dwFlags) +{ + return DIERR_UNSUPPORTED; +} + +HRESULT HookIDirectInputDevice::SetActionMap(LPVOID _this, LPCDIACTIONFORMAT lpdiActionFormat, LPCTSTR lptszUserName, DWORD dwFlags) +{ + return DIERR_UNSUPPORTED; +} + +HRESULT HookIDirectInputDevice::GetImageInfo(LPVOID _this, LPDIDEVICEIMAGEINFOHEADER lpdiDevImageInfoHeader) +{ + return DIERR_UNSUPPORTED; +} + +#pragma pack(4) +struct FAR HookIDirectInput8 +{ + virtual HRESULT QueryInterface(LPVOID _this, REFIID riid, LPVOID *ppvObj); + virtual ULONG AddRef(LPVOID _this); + virtual ULONG Release(LPVOID _this); + + virtual HRESULT CreateDevice(LPVOID _this, REFGUID rguid, LPDIRECTINPUTDEVICE8A * lplpDirectInputDevice, LPUNKNOWN pUnkOuter); + + virtual HRESULT EnumDevices(LPVOID _this, DWORD dwDevType, LPDIENUMDEVICESCALLBACK lpCallback, LPVOID pvRef, DWORD dwFlags); + + virtual HRESULT GetDeviceStatus(LPVOID _this, REFGUID rguidInstance); + + virtual HRESULT RunControlPanel(LPVOID _this, HWND hwndOwner, DWORD dwFlags); + + virtual HRESULT Initialize(LPVOID _this, HINSTANCE hinst, DWORD dwVersion); + + virtual HRESULT FindDevice(LPVOID _this, REFGUID rguidClass, LPCTSTR ptszName, LPGUID pguidInstance); + + virtual HRESULT EnumDevicesBySemantics(LPVOID _this, LPCTSTR ptszUserName, LPDIACTIONFORMAT lpdiActionFormat, LPDIENUMDEVICESBYSEMANTICSCB lpCallback, LPVOID pvRef, DWORD dwFlags); + + virtual HRESULT ConfigureDevices(LPVOID _this, LPDICONFIGUREDEVICESCALLBACK lpdiCallback, LPDICONFIGUREDEVICESPARAMS lpdiCDParams, DWORD dwFlags, LPVOID pvRefData); +}; + +static HookIDirectInput8 FakeInterface, *pFakeInterface = &FakeInterface; + +HRESULT HookIDirectInput8::QueryInterface(LPVOID _this, REFIID riid, LPVOID *ppvObj) +{ + *ppvObj = NULL; + + return DIERR_UNSUPPORTED; +} + +ULONG HookIDirectInput8::AddRef(LPVOID _this) +{ + return 0; +} + +ULONG HookIDirectInput8::Release(LPVOID _this) +{ + return 0; +} + +HRESULT HookIDirectInput8::CreateDevice(LPVOID _this, REFGUID rguid, LPDIRECTINPUTDEVICE8A * lplpDirectInputDevice, LPUNKNOWN pUnkOuter) +{ + if (rguid == GUID_SysKeyboard) + { +// info(true, V("DirectInput8::CreateDevice: Device is keyboard")); + } + else if (rguid == GUID_SysMouse) + { +// info(true, V("DirectInput8::CreateDevice: Device is mouse")); + } + else if (rguid == GUID_Joystick) + { +// info(true, V("DirectInput8::CreateDevice: Device is joypad")); + } + + *lplpDirectInputDevice = (LPDIRECTINPUTDEVICE8A)pFakeDevice; + + if (pUnkOuter) + { + pUnkOuter = (LPUNKNOWN)NULL; + } + + return DI_OK; +} + +HRESULT HookIDirectInput8::EnumDevices(LPVOID _this, DWORD dwDevType, LPDIENUMDEVICESCALLBACK lpCallback, LPVOID pvRef, DWORD dwFlags) +{ + return DI_OK; +} + + +HRESULT HookIDirectInput8::GetDeviceStatus(LPVOID _this, REFGUID rguidInstance) +{ + return DI_OK; +} + + +HRESULT HookIDirectInput8::RunControlPanel(LPVOID _this, HWND hwndOwner, DWORD dwFlags) +{ + return DIERR_UNSUPPORTED; +} + +HRESULT HookIDirectInput8::Initialize(LPVOID _this, HINSTANCE hinst, DWORD dwVersion) +{ + return DI_OK; +} + +HRESULT HookIDirectInput8::FindDevice(LPVOID _this, REFGUID rguidClass, LPCTSTR ptszName, LPGUID pguidInstance) +{ + return DI_OK; +} + +HRESULT HookIDirectInput8::EnumDevicesBySemantics(LPVOID _this, LPCTSTR ptszUserName, LPDIACTIONFORMAT lpdiActionFormat, LPDIENUMDEVICESBYSEMANTICSCB lpCallback, LPVOID pvRef, DWORD dwFlags) +{ + return DI_OK; +} + +HRESULT HookIDirectInput8::ConfigureDevices(LPVOID _this, LPDICONFIGUREDEVICESCALLBACK lpdiCallback, LPDICONFIGUREDEVICESPARAMS lpdiCDParams, DWORD dwFlags, LPVOID pvRefData) +{ + return DI_OK; +} + +HRESULT __stdcall Hook_DirectInput8Create(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID * ppvOut, LPUNKNOWN punkOuter) +{ + *ppvOut = (LPVOID)pFakeInterface; + + return DI_OK; +} + +static InitFunction initFunc([]() +{ + MH_Initialize(); + + MH_CreateHookApi(L"DINPUT8.dll", "DirectInput8Create", &Hook_DirectInput8Create, (void**)&__DirectInput8Create); + + MH_EnableHook(MH_ALL_HOOKS); +}); +#pragma optimize("", on) \ No newline at end of file diff --git a/OpenParrot/src/Functions/Games/TypeX2/TypeX2Generic.cpp b/OpenParrot/src/Functions/Games/TypeX2/TypeX2Generic.cpp new file mode 100644 index 0000000..4326c3e --- /dev/null +++ b/OpenParrot/src/Functions/Games/TypeX2/TypeX2Generic.cpp @@ -0,0 +1,238 @@ +#pragma optimize("", off) +#include +#include "Utility/GameDetect.h" +#include "Utility/InitFunction.h" +#include "Functions/Global.h" +#if _M_IX86 +using namespace std::string_literals; + +void AddCommOverride(HANDLE hFile); + +static HANDLE __stdcall CreateFileAWrap(LPCSTR lpFileName, + DWORD dwDesiredAccess, + DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile) +{ + if (GameDetect::X2Type == X2Type::BG4 && lpFileName[1] == ':' && lpFileName[2] == '\\') + { + lpFileName += 3; + } + + if (strnicmp(lpFileName, "D:\\", 3) == 0) + { + if (GetFileAttributesA(lpFileName) == INVALID_FILE_ATTRIBUTES) + { + wchar_t pathRoot[MAX_PATH]; + GetModuleFileNameW(GetModuleHandle(nullptr), pathRoot, _countof(pathRoot)); + + wcsrchr(pathRoot, L'\\')[0] = L'\0'; + + // assume just ASCII + std::string fn = lpFileName; + std::wstring wfn(fn.begin(), fn.end()); + + CreateDirectoryW((pathRoot + L"\\TeknoParrot\\"s).c_str(), nullptr); + + return CreateFileW((pathRoot + L"\\TeknoParrot\\"s + wfn.substr(3)).c_str(), + dwDesiredAccess, + dwShareMode, + lpSecurityAttributes, + dwCreationDisposition, + dwFlagsAndAttributes, + hTemplateFile); + } + } + + if (GameDetect::X2Type == X2Type::BG4 || GameDetect::X2Type == X2Type::VRL) + { + if (strncmp(lpFileName, "COM1", 4) == 0) + { + HANDLE hFile = (HANDLE)0x8001; + + AddCommOverride(hFile); + + return hFile; + } + } + return CreateFileA(lpFileName, + dwDesiredAccess, + dwShareMode, + lpSecurityAttributes, + dwCreationDisposition, + dwFlagsAndAttributes, + hTemplateFile); +} + +#include + +static std::map> g_replyBuffers; + +static BOOL __stdcall ReadFileWrap(HANDLE hFile, + LPVOID lpBuffer, + DWORD nNumberOfBytesToRead, + LPDWORD lpNumberOfBytesRead, + LPOVERLAPPED lpOverlapped) +{ + if (hFile == (HANDLE)0x8001) + { + auto& outQueue = g_replyBuffers[hFile]; + + int toRead = min(outQueue.size(), nNumberOfBytesToRead); + + std::copy(outQueue.begin(), outQueue.begin() + toRead, reinterpret_cast(lpBuffer)); + outQueue.erase(outQueue.begin(), outQueue.begin() + toRead); + + *lpNumberOfBytesRead = toRead; + + return TRUE; + } + return ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped); +} + +static DWORD __stdcall GetFileAttributesAWrap(LPCSTR lpFileName) +{ + if (GameDetect::X2Type == X2Type::BG4 && lpFileName[1] == ':' && lpFileName[2] == '\\') + { + lpFileName += 3; + } + return GetFileAttributesA(lpFileName); +} + +extern int* wheelSection; + +BOOL __stdcall WriteFileWrap(HANDLE hFile, + LPVOID lpBuffer, + DWORD nNumberOfBytesToWrite, + LPDWORD lpNumberOfBytesWritten, + LPOVERLAPPED lpOverlapped) +{ + if (hFile == (HANDLE)0x8001) + { + DWORD pos = 0; + + char bytes[2] = { 0 }; + uint8_t* taskBuffer = (uint8_t*)lpBuffer; + + while (pos < nNumberOfBytesToWrite) + { + switch (taskBuffer[pos]) + { + case 0x20: + g_replyBuffers[hFile].push_back(1); + + pos += 2; + break; + + case 0x1F: + case 0x00: + case 0x04: + { + int wheelValue = *wheelSection; + + if (GameDetect::X2Type == X2Type::VRL) + { + wheelValue = 255 - wheelValue; + } + + wheelValue = (int)((wheelValue / 256.0f) * 1024.0f); + wheelValue += 1024; + + g_replyBuffers[hFile].push_back(HIBYTE(wheelValue)); + g_replyBuffers[hFile].push_back(LOBYTE(wheelValue)); + + pos += 2; + break; + } + default: + pos += 2; + break; + } + } + + *lpNumberOfBytesWritten = nNumberOfBytesToWrite; + + return TRUE; + } + return WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped); +} + +static InitFunction initFunction([]() +{ + DWORD imageBase = (DWORD)GetModuleHandleA(0); + if (GameDetect::X2Type == X2Type::None) + { + return; + } + + iatHook("kernel32.dll", CreateFileAWrap, "CreateFileA"); + + switch (GameDetect::X2Type) + { + case X2Type::VRL: + { + //injector::MakeNOP(0x0040E22E, 2, true); + injector::WriteMemory(0x0041C800, 0x08C2C033, true); + injector::WriteMemory(0x0041C804, 0x00, true); + + iatHook("kernel32.dll", ReadFileWrap, "ReadFile"); + iatHook("kernel32.dll", WriteFileWrap, "WriteFile"); + break; + } + case X2Type::Raiden4: + { + //injector::WriteMemory(0x49DDB0, 0xC3C301B0, true); + injector::WriteMemory(0x00496EA0, 0xEB, true); + break; + } + case X2Type::BG4: + { + injector::MakeNOP(0x4CBCB8, 10); + injector::WriteMemory(0x4CBCB8, 0xB8, true); + injector::WriteMemory(0x4CBCB9, 1, true); + + if (!ToBool(config["General"]["Windowed"])) + { + injector::MakeRET(0x5F21B0, 4); + } + + iatHook("kernel32.dll", ReadFileWrap, "ReadFile"); + iatHook("kernel32.dll", WriteFileWrap, "WriteFile"); + iatHook("kernel32.dll", GetFileAttributesAWrap, "GetFileAttributesA"); + + break; + } + case X2Type::Lupin3: + { + injector::MakeNOP(0x48C66C, 12); + + break; + } + } + + if(GameDetect::currentGame == GameID::KOFMIRA) + { + injector::WriteMemory(0x0040447C, 0x000800B8, true); + injector::WriteMemory(0x0040447C+4, 0x9000, true); + } + + if(GameDetect::currentGame == GameID::TetrisGM3) + { + injector::WriteMemory(0x0046A0AC, 0x00005C2E, true); + } + + if(GameDetect::currentGame == GameID::SamuraiSpiritsSen) + { + injector::WriteMemory(0x0040117A, 0x90909090, true); + injector::WriteMemory(0x0040117A+4, 0x90, true); + injector::WriteMemory(0x00401188, 0x9090, true); + injector::WriteMemory(0x004B73DE, 0x9090, true); + injector::WriteMemory(0x004B73ED, 0xEB, true); + injector::WriteMemory(0x004C640C, 0xEB, true); + injector::WriteMemory(0x004CE1C0, 0xC340C033, true); + } +}); +#endif +#pragma optimize("", on) \ No newline at end of file diff --git a/OpenParrot/src/Functions/Global.cpp b/OpenParrot/src/Functions/Global.cpp new file mode 100644 index 0000000..196a753 --- /dev/null +++ b/OpenParrot/src/Functions/Global.cpp @@ -0,0 +1,197 @@ +#include +#include +#include "Global.h" + +DWORD dongleRegion = 1; +BYTE pcbModelType = 2; +DWORD sysCRC; +char dongleGameId[4]; +#pragma optimize("", off) +void *__cdecl memcpy_0(void *a1, const void *a2, size_t a3) +{ + __try + { + memcpy(a1, a2, a3); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + + } + return 0; +} + +// used in SR3 and Ford Racing +BOOL WINAPI ReadFileHooked(_In_ HANDLE hFile, _Out_writes_bytes_to_opt_(nNumberOfBytesToRead, *lpNumberOfBytesRead) __out_data_source(FILE) LPVOID lpBuffer, _In_ DWORD nNumberOfBytesToRead, _Out_opt_ LPDWORD lpNumberOfBytesRead, _Inout_opt_ LPOVERLAPPED lpOverlapped) +{ + static HANDLE file = CreateFileA("\\\\.\\pipe\\TeknoParrotPipe", GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, NULL); + + ReadFile(file, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped); + + return TRUE; +} + +std::wstring utf8_decode(const std::string &str) +{ + if (str.empty()) return std::wstring(); + int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0); + std::wstring wstrTo(size_needed, 0); + MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed); + return wstrTo; +} + +DWORD WINAPI QuitGameThread(__in LPVOID lpParameter) +{ + while (true) + { + if (GetAsyncKeyState(VK_ESCAPE)) + { +#ifndef _DEBUG + TerminateProcess(GetCurrentProcess(), 0); +#endif + //ExitProcess(0); + } + + Sleep(300); + } +} + +/* WINDOW HOOKS */ + +DWORD g_windowStyle; + +int g_x = 0; +int g_y = 0; + +int g_width = 0; +int g_height = 0; + +HWND hwndWindowA; +HWND hwndWindowW; + +HWND WINAPI CreateWindowExAHk(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam) +{ +#ifdef _DEBUG + info(true, "CreateWindowExAHk called"); +#endif + if (lpWindowName) + { + dwStyle = g_windowStyle; + } + + HWND thisWindow = CreateWindowExA(dwExStyle, lpClassName, lpWindowName, dwStyle, g_x, g_y, g_width, g_height, hWndParent, hMenu, hInstance, lpParam); + + if (lpWindowName) + { + hwndWindowA = thisWindow; + } + + return thisWindow; +} + +HWND WINAPI CreateWindowExWHk(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam) +{ +#ifdef _DEBUG + info(true, "CreateWindowExWHk called"); +#endif + if (lpWindowName) + { + dwStyle = g_windowStyle; + } + + HWND thisWindow = CreateWindowExW(dwExStyle, lpClassName, lpWindowName, dwStyle, g_x, g_y, g_width, g_height, hWndParent, hMenu, hInstance, lpParam); + + if (lpWindowName) + { + hwndWindowW = thisWindow; + } + + return thisWindow; +} + +BOOL WINAPI AdjustWindowRectHk(LPRECT lpRect, DWORD dwStyle, BOOL bMenu) +{ +#ifdef _DEBUG + info(true, "AdjustWindowRectHk called"); +#endif + dwStyle = g_windowStyle; + + return AdjustWindowRect(lpRect, dwStyle, bMenu); +} + +BOOL WINAPI SetWindowPosHk(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags) +{ +#ifdef _DEBUG + info(true, "SetWindowPosHk called"); +#endif + if (hwndWindowA == hWnd || hwndWindowW == hWnd) + { + X = g_x; + Y = g_y; + } + + return SetWindowPos(hWnd, hWndInsertAfter, X, Y, cx, cy, uFlags); +} + +LONG __stdcall ChangeDisplaySettingsHk(DEVMODEA *lpDevMode, DWORD dwFlags) +{ +#ifdef _DEBUG + info(true, "ChangeDisplaySettingsHk called"); +#endif + lpDevMode = NULL; // retain original changes instead of applying modified values + + return ChangeDisplaySettingsA(lpDevMode, dwFlags); +} + +BOOL WINAPI UpdateWindowHk(HWND hWnd) +{ + return true; +} + +void init_windowHooks(windowHooks* data) +{ + g_windowStyle = WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX; + + int rx, ry; + GetDesktopResolution(rx, ry); + + g_x = (rx / 2) - (g_width / 2); + g_y = (ry / 2) - (g_height / 2); + + if (data->createWindowExA != NULL) + { + *(HWND*)data->createWindowExA = (HWND)CreateWindowExAHk; + } + + if (data->createWindowExW != NULL) + { + *(HWND*)data->createWindowExW = (HWND)CreateWindowExWHk; + } + + if (data->adjustWindowRect != NULL) + { + *(BOOL*)data->adjustWindowRect = (BOOL)AdjustWindowRectHk; + } + + if (data->setWindowPos != NULL) + { + *(BOOL*)data->setWindowPos = (BOOL)SetWindowPosHk; + } + + if (data->changeDisplaySettings != NULL) + { + *(LONG*)data->changeDisplaySettings = (LONG)ChangeDisplaySettingsHk; + } + + if (data->updateWindow != NULL) + { + *(BOOL*)data->updateWindow = (BOOL)UpdateWindowHk; + } +} +/* END WINDOW HOOKS */ + + +static InitFunction globalFunc([]() +{ + CreateThread(NULL, 0, QuitGameThread, NULL, 0, NULL); +}, GameID::Global); +#pragma optimize("", on) \ No newline at end of file diff --git a/OpenParrot/src/Functions/Global.h b/OpenParrot/src/Functions/Global.h new file mode 100644 index 0000000..b8167e6 --- /dev/null +++ b/OpenParrot/src/Functions/Global.h @@ -0,0 +1,103 @@ +#pragma once + +BOOL WINAPI ReadFileHooked(_In_ HANDLE hFile, _Out_writes_bytes_to_opt_(nNumberOfBytesToRead, *lpNumberOfBytesRead) __out_data_source(FILE) LPVOID lpBuffer, _In_ DWORD nNumberOfBytesToRead, _Out_opt_ LPDWORD lpNumberOfBytesRead, _Inout_opt_ LPOVERLAPPED lpOverlapped); +void *__cdecl memcpy_0(void *a1, const void *a2, size_t a3); + +struct windowHooks +{ + int createWindowExA; + int createWindowExW; + int adjustWindowRect; + int setWindowPos; + int changeDisplaySettings; + int updateWindow; +}; + +void init_windowHooks(windowHooks* data); +std::wstring utf8_decode(const std::string &str); + +namespace +{ + template + inline T* getRVA(uintptr_t rva) + { + return (T*)((char*)GetModuleHandle(nullptr) + rva); + } + + template + inline bool iat_matches_ordinal(uintptr_t* nameTableEntry, TOrdinal ordinal) + { + + } + + template<> + inline bool iat_matches_ordinal(uintptr_t* nameTableEntry, int ordinal) + { + if (IMAGE_SNAP_BY_ORDINAL(*nameTableEntry)) + { + return IMAGE_ORDINAL(*nameTableEntry) == ordinal; + } + + return false; + } + + template<> + inline bool iat_matches_ordinal(uintptr_t* nameTableEntry, const char* ordinal) + { + if (!IMAGE_SNAP_BY_ORDINAL(*nameTableEntry)) + { + auto import = getRVA(*nameTableEntry); + + return !_stricmp(import->Name, ordinal); + } + + return false; + } +} + +template +T iatHook(const char* moduleName, T function, TOrdinal ordinal) +{ + IMAGE_DOS_HEADER* imageHeader = (IMAGE_DOS_HEADER*)(GetModuleHandle(nullptr)); + IMAGE_NT_HEADERS* ntHeader = getRVA(imageHeader->e_lfanew); + + IMAGE_IMPORT_DESCRIPTOR* descriptor = getRVA(ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); + + while (descriptor->Name) + { + const char* name = getRVA(descriptor->Name); + + if (_stricmp(name, moduleName)) + { + descriptor++; + + continue; + } + + if (descriptor->OriginalFirstThunk == 0) + { + return nullptr; + } + + auto nameTableEntry = getRVA(descriptor->OriginalFirstThunk); + auto addressTableEntry = getRVA(descriptor->FirstThunk); + + while (*nameTableEntry) + { + if (iat_matches_ordinal(nameTableEntry, ordinal)) + { + T origEntry = (T)*addressTableEntry; + injector::WriteMemory(addressTableEntry, (uintptr_t)function, true); + + return origEntry; + } + + nameTableEntry++; + addressTableEntry++; + } + + return nullptr; + } + + return nullptr; +} \ No newline at end of file diff --git a/OpenParrot/src/Functions/Nesica_Libs/CryptoPipe.cpp b/OpenParrot/src/Functions/Nesica_Libs/CryptoPipe.cpp new file mode 100644 index 0000000..35431d6 --- /dev/null +++ b/OpenParrot/src/Functions/Nesica_Libs/CryptoPipe.cpp @@ -0,0 +1,311 @@ +#include +#if _M_IX86 +#include "CryptoPipe.h" +#include +#pragma comment(lib, "Advapi32.lib") + +// TODO: NEED TO BE PLACED IN FILES! +const char *key_magicalbeat = "0702000000A40000525341320002000001000100411FE010238446E4C51A60E182DD275B6C1D35DE1B3B1392C7F9A70DFB01C8BF2309CC85E74D88ECE52041F985D785BB7CBD3F3A8BFC89E8D2A5A8440796CDD2BD2B2D5FB954F36193AA685E568DC940284E45BBDDFF89E721EBBF670362F8F6D5D73B0CAA16AD31C8F819A0936FAB11BB11A855C213D9C583A8621A97AE82DA7108DC76DAB389CD14A5E577C5E9A1908A0D0EF56A3FE1AA0F6103450F4650C8218FC47412A3ADBDD146E68E5FC49D4D64AD28641941FC6FD057DE15233BAD288FA032390566E9B4FFED0B9F5A31A2A587B3F68405BF1A3A79AE05BA256C8C2C81ADBD14DFAA8EF774684AD6D606574BB426DF079270A0A333E65B281D6FECD260D618F32475ACE360DE3A8CB6540192A94FA00E01109F77BBA9709428C2E3A3"; +const char *key_bbcf = "0702000000a400005253413200020000010001008f35cf7db98ccacf0e4586b2bc2816911e6629328edd4678424312e1c698e4a8341232da9a37ef7fe4257185522b618b49d3939b8e83b1a591e0c06d5d0223c50da989e3ab190e4b989ebaee4d04428a00bfb6e7840f17a5e7f6c2e8d5e776eb0b3af84ad026ef84cb69e8e7933a5a99342018764317a73780507cdb5b6154d629b8da775bb09b132e3dfac255b771863809acfa64fea8f07a94801096d9046955d8729eb98779f8561fdf8f6531ad051546aacd74702f486e456e3c0361346ed6033004ee562885912cafdd91d9a4844d267437eee304b4f06c46b75bbe972b31a414972fdb5e0a69999734685e54598f0565f9afc0cd162434fb9d37e983154fefb3080f8ff41ff9be8596fa4042b96a441f6b1f8eb416c127a57f256ff055"; +const char *key_persona4arena = "0702000000A40000525341320002000001000100359073C4EF2B8E9556FFDED09E5E1C4374169BA2A2077E9993C34E7FB3B499D9624F620018AFAEEED697D7E72432B488E8E4A2A1B648EE24C9E878D9145A36D87F39DFCFD4AA3751C70039DFB4CE022A85A81D7440287538A41EB3B3D9A0F0FD4B481E274B71AF8BDD36AC6F7A930CC67E41BE6E65628A50F3779082555FF7D97FB45E4D6973BEB316D220BC45E2F20FBD1FD9271CEA65AC14B09136D99A31A179CE1933F5343FE930D858769FD7B861C7BF3ECC187792A9C200856822C1AB2138628CB7183DBCE115589A4A0F213FD77B91758D13D762714666B97A428723895512E57C29AB3C68113120D7CB3269A605AC483601BD6B1BDAC238759D564EA6DA64A445FC502251FBEAA2621BD157040C60637371096A6B261D0FCB767F9F7C"; +const char *key_bbcp = "0702000000a400005253413200020000010001008f35cf7db98ccacf0e4586b2bc2816911e6629328edd4678424312e1c698e4a8341232da9a37ef7fe4257185522b618b49d3939b8e83b1a591e0c06d5d0223c50da989e3ab190e4b989ebaee4d04428a00bfb6e7840f17a5e7f6c2e8d5e776eb0b3af84ad026ef84cb69e8e7933a5a99342018764317a73780507cdb5b6154d629b8da775bb09b132e3dfac255b771863809acfa64fea8f07a94801096d9046955d8729eb98779f8561fdf8f6531ad051546aacd74702f486e456e3c0361346ed6033004ee562885912cafdd91d9a4844d267437eee304b4f06c46b75bbe972b31a414972fdb5e0a69999734685e54598f0565f9afc0cd162434fb9d37e983154fefb3080f8ff41ff9be8596fa4042b96a441f6b1f8eb416c127a57f256ff055"; +const char *key_kofxiiiclimax = "0702000000A400005253413200020000010001000D20722B0858DCFAE9783F33E67BED82A0C1A3FE17FBB733B056A2337ADA9DAAE028079B07EE25CBCC9C2B72AA6154CEEF898C8CA9F168684D9A3806D6F622D4FF5CFFDDA03325FD7322D1CBF9CD8E45773E116B353871EEF7E5DCAAE3DCE1F8F326C1922DE4B76F1DD075DB788D67B6719126FBB2497FA0CB855F56651334DA152F3AED5D8A53C92A83F08177535B44420FEB2617E932791DC9DB0A26250755FDC37B74BCFF5DDDFDB2E52AE59D7E52042A022D37A9D73339ECA29F0DF60C1F792BCB25A3BCC5ED53D6A0DA2D403246C12EA958C4F5DAE9FFA0D10B7C31ECC3E5DC9A2418104B3A7825FBC527177EE00056176A3176323DE62CC834D36095D26CC9841D331A72814FE0D04BCE0B3A666C6896E0571E77323D5B6797B20168B9"; +const char *key_persona4ultimix = "0702000000a40000525341320002000001000100359073c4ef2b8e9556ffded09e5e1c4374169ba2a2077e9993c34e7fb3b499d9624f620018afaeeed697d7e72432b488e8e4a2a1b648ee24c9e878d9145a36d87f39dfcfd4aa3751c70039dfb4ce022a85a81d7440287538a41eb3b3d9a0f0fd4b481e274b71af8bdd36ac6f7a930cc67e41be6e65628a50f3779082555ff7d97fb45e4d6973beb316d220bc45e2f20fbd1fd9271cea65ac14b09136d99a31a179ce1933f5343fe930d858769fd7b861c7bf3ecc187792a9c200856822c1ab2138628cb7183dbce115589a4a0f213fd77b91758d13d762714666b97a428723895512e57c29ab3c68113120d7cb3269a605ac483601bd6b1bdac238759d564ea6da64a445fc502251fbeaa2621bd157040c60637371096a6b261d0fcb767f9f7c"; +const char *key_usf4 = "0702000000a40000525341320002000001000100b77cb7dfef27ca5ed4895576c6a68518bab782e60dae9dffad94434fb9366125e46630352261afe960e8401a3c5ee1cfc15ec2b1849e02a3dcc30e47ea3100a5c7175f9207aab497a9c9c0bf19d30a9fbb294a761147607927163685624dced391d3ae2211c6c11350077070386a195a8641f0e7920ddbcb200f990f55c76dc73de119d62751e5cb6cfa3653481d3e711b666c9a6cc9c2a4e50f4e55ce2831a821d75448cda3a2d6f3b359012bff571842c34a844989a4af0a4a5081cb8dc0780173865658cd8b999f9baaa3febc9c95b1477cd6af5060af603e597b3547fd0021a422c3a2cd0028523b5bd12b23bd4a6d2924ca920870cba2f38477631589cc4251590fba955d114f2ce0d6228c4932c1f2d9b753cda2d646591c48e164820e"; + +DWORD dword_44DEC4; +DWORD dword_44DEC0; + +void LogStuff(const char* text, int a) +{ + //printf("%s", text); +} + +DWORD LinkRC5Data(const char* file, void* buf, int gameId) +{ + DWORD num = 0; + char key[308]; + if (!buf) + return 308; + switch (gameId) + { + case 0: + for (int i = 0; i < 308; i++) + { + sscanf(&key_magicalbeat[i * 2], "%02x", &num); + key[i] = num; + } + break; + case 1: + for (int i = 0; i < 308; i++) + { + sscanf(&key_bbcf[i * 2], "%02x", &num); + key[i] = num; + } + break; + case 2: + for (int i = 0; i < 308; i++) + { + sscanf(&key_persona4arena[i * 2], "%02x", &num); + key[i] = num; + } + break; + case 3: + for (int i = 0; i < 308; i++) + { + sscanf(&key_bbcp[i * 2], "%02x", &num); + key[i] = num; + } + break; + case 4: + for (int i = 0; i < 308; i++) + { + sscanf(&key_kofxiiiclimax[i * 2], "%02x", &num); + key[i] = num; + } + break; + case 5: + for (int i = 0; i < 308; i++) + { + sscanf(&key_persona4ultimix[i * 2], "%02x", &num); + key[i] = num; + } + break; + case 6: + for (int i = 0; i < 308; i++) + { + sscanf(&key_usf4[i * 2], "%02x", &num); + key[i] = num; + } + break; + default: + break; + } + memcpy(buf, key, 308); + return 308; +} + +HCRYPTPROV GenerateKey() +{ + HCRYPTPROV result; // eax@2 + HCRYPTPROV phProv; // [sp+4h] [bp-4h]@1 + + phProv = 0; + if (CryptAcquireContextA(&phProv, "TypeXAppCrypt", "Microsoft Base Cryptographic Provider v1.0", 1u, 0) + || (result = CryptAcquireContextA(&phProv, "TypeXAppCrypt", "Microsoft Base Cryptographic Provider v1.0", 1u, CRYPT_NEWKEYSET)) != 0) + { + result = phProv; + } + return result; +} + +bool __cdecl ReadFromPipe_410390(HANDLE hPipe, BYTE** a2, DWORD* a3, bool* pMode) +{ + signed int dwSizeBytePos; // esi@1 + int dwAllocSizeState; // ebp@1 + char i; // bl@2 + DWORD dwLastError; // eax@4 + //unsigned __int16 v8; // dx@16 + int dwAllocSize; // ebp@18 + HANDLE hHeap1; // eax@18 + BYTE *pResultBuffer; // esi@18 + bool bResult; // al@19 + HANDLE hHeap2; // eax@21 + int v14 = 0; // [sp+0h] [bp-18h]@0 + unsigned char Buffer; // [sp+13h] [bp-5h]@3 + DWORD NumberOfBytesRead; // [sp+14h] [bp-4h]@3 + + dwSizeBytePos = 0; + dwAllocSizeState = 0; + while (true) + { + for (i = 0;; i = 1) + { + do + { + readByteLabel: + if (ReadFile(hPipe, &Buffer, 1u, &NumberOfBytesRead, 0)) + break; + dwLastError = GetLastError(); + if (dwLastError == ERROR_BROKEN_PIPE) + return false; + } while (dwLastError != ERROR_IO_PENDING); + if (Buffer != 0xFF) + break; + if (i) + { + i = 0; + goto LABEL_9; + } + } + if ((Buffer == 0xFE || Buffer == 0xFD) && i) + { + *pMode = Buffer != 0xFE; + dwSizeBytePos = 1; + continue; + } + break; + } +LABEL_9: + switch (dwSizeBytePos) + { + case 1: + dwAllocSizeState |= Buffer; + ++dwSizeBytePos; + goto readByteLabel; + case 2: + dwAllocSizeState |= Buffer << 8; + ++dwSizeBytePos; + goto readByteLabel; + case 3: + dwAllocSizeState |= Buffer << 16; + ++dwSizeBytePos; + goto readByteLabel; + case 4: + dwAllocSize = (Buffer << 24) | dwAllocSizeState; + hHeap1 = GetProcessHeap(); + pResultBuffer = (BYTE*)HeapAlloc(hHeap1, 0, dwAllocSize); + if (!pResultBuffer) + { + //LogStuff("Heap Allo\n", v14); + return false; + } + if (!ReadFile(hPipe, pResultBuffer, dwAllocSize, &NumberOfBytesRead, 0)) + { + hHeap2 = GetProcessHeap(); + HeapFree(hHeap2, 0, pResultBuffer); + return false; + } + *a3 = dwAllocSize; + *a2 = pResultBuffer; + bResult = true; + break; + default: + goto readByteLabel; + } + return bResult; +} + +HANDLE PipeStuff_410550(int gameId) +{ + HANDLE result; // eax@1 + HANDLE hPipe; // edi@1 + DWORD dwRC5DataLen; // esi@4 + unsigned __int8 *pRC5DataBuf; // ebx@4 + BYTE *pbDataTemp; // esi@12 + HANDLE hHeap1; // eax@12 + BYTE *v6; // esi@13 + HANDLE hHeap2; // eax@13 + DWORD v8; // ST14_4@17 + HANDLE hHeap3; // eax@17 + BYTE *v10; // esi@17 + HANDLE hHeap4; // eax@17 + int v12 = 0; // [sp-Ch] [bp-38h]@1 + char v13; // [sp+6h] [bp-26h]@6 + bool bMode; + DWORD dwRead; + //char a4[5]; // [sp+7h] [bp-25h]@7 + DWORD pdwDataLen; // [sp+Ch] [bp-20h]@15 + HCRYPTKEY v16; // [sp+10h] [bp-1Ch]@9 + HCRYPTPROV hProv; // [sp+14h] [bp-18h]@3 + HCRYPTKEY hKey; // [sp+18h] [bp-14h]@11 + DWORD dwDataLen; // [sp+1Ch] [bp-10h]@7 + BYTE *pbData; // [sp+20h] [bp-Ch]@7 + int Buffer; // [sp+24h] [bp-8h]@8 + HCRYPTKEY phKey; // [sp+28h] [bp-4h]@4 + + hProv = GenerateKey(); + result = CreateNamedPipeA("\\\\.\\pipe\\TtxAppCtyptPipe", PIPE_ACCESS_DUPLEX, PIPE_WAIT, 1u, 0x400u, 0x400u, 1000u, 0); + hPipe = result; + if (result != INVALID_HANDLE_VALUE) + { + dwRC5DataLen = LinkRC5Data("C:\\windows\\system32\\8B97D021-071D-45dd-A592-0ABB3BAEF01A", 0, gameId); + pRC5DataBuf = (unsigned __int8 *)malloc(dwRC5DataLen); + LinkRC5Data("C:\\windows\\system32\\8B97D021-071D-45dd-A592-0ABB3BAEF01A", pRC5DataBuf, gameId); + result = (HANDLE)CryptImportKey(hProv, pRC5DataBuf, dwRC5DataLen, 0, 0, &phKey); + if (result) + { + dword_44DEC0 = 1; + ConnectNamedPipe(hPipe, 0); + v13 = 0; + while (true) + { + while (!ReadFromPipe_410390(hPipe, &pbData, &dwDataLen, &bMode)) + { + Buffer = 0; + WriteFile(hPipe, &Buffer, 4u, &dwRead, 0); + DisconnectNamedPipe(hPipe); + ConnectNamedPipe(hPipe, 0); + } + //LogStuff("Recieved.\n", v12); + v16 = 0; + if (bMode) + { + if (v13) + CryptDestroyKey(hKey); + pbDataTemp = pbData; + CryptImportKey(hProv, pbData, dwDataLen, 0, 0, &hKey); + v13 = 1; + hHeap1 = GetProcessHeap(); + HeapFree(hHeap1, 0, pbDataTemp); + } + else + { + v6 = pbData; + Buffer = CryptImportKey(hProv, pbData, dwDataLen, phKey, 1u, &v16); + hHeap2 = GetProcessHeap(); + HeapFree(hHeap2, 0, v6); + if (Buffer) + { + if (CryptExportKey(v16, hKey, 1u, 0, 0, &pdwDataLen)) + { + v8 = pdwDataLen; + hHeap3 = GetProcessHeap(); + v10 = (BYTE *)HeapAlloc(hHeap3, 0, v8); + CryptExportKey(v16, hKey, 1u, 0, v10, &pdwDataLen); + WriteFile(hPipe, &pdwDataLen, 4u, &dwRead, 0); + WriteFile(hPipe, v10, pdwDataLen, &dwRead, 0); + hHeap4 = GetProcessHeap(); + HeapFree(hHeap4, 0, v10); + } + else + { + Buffer = 0; + //LogStuff("It failed in the export of the key. \n", v12); + WriteFile(hPipe, &Buffer, 4u, &dwRead, 0); + } + if (v16) + CryptDestroyKey(v16); + } + else + { + Buffer = 0; + //LogStuff("It failed in the import of the key. \n", v12); + WriteFile(hPipe, &Buffer, 4u, &dwRead, 0); + } + } + } + } + dword_44DEC0 = 2; + } + else + { + dword_44DEC0 = 2; + } + return result; +} + +unsigned long __stdcall TXAppCryptThread(LPVOID sId) +{ + int id = *static_cast(sId); + PipeStuff_410550(id); + delete sId; + return 1; +} + +void init_CryptoPipe(NesicaKey id) +{ + static NesicaKey gameId = id; + CreateThread(nullptr, 0, TXAppCryptThread, &gameId, 0, nullptr); +} +#endif \ No newline at end of file diff --git a/OpenParrot/src/Functions/Nesica_Libs/CryptoPipe.h b/OpenParrot/src/Functions/Nesica_Libs/CryptoPipe.h new file mode 100644 index 0000000..5844d3e --- /dev/null +++ b/OpenParrot/src/Functions/Nesica_Libs/CryptoPipe.h @@ -0,0 +1,14 @@ +#pragma once +enum class NesicaKey +{ + None = -1, + MagicalBeat = 0, + BlazBlueCentralFriction = 1, + Persona4Arena = 2, + BlazBlueChronoPhantasma = 3, + KOFXIIIClimax = 4, + Persona4Ultimix = 5, + USF4 = 6 +}; + +void init_CryptoPipe(NesicaKey id); \ No newline at end of file diff --git a/OpenParrot/src/Functions/Nesica_Libs/FastIoEmu.cpp b/OpenParrot/src/Functions/Nesica_Libs/FastIoEmu.cpp new file mode 100644 index 0000000..9693f3e --- /dev/null +++ b/OpenParrot/src/Functions/Nesica_Libs/FastIoEmu.cpp @@ -0,0 +1,251 @@ +#include +#include "Utility/InitFunction.h" + +#include + +static uint8_t g_fastIOValues[64]; + +DWORD __cdecl iDmacDrvOpen(int deviceId, LPVOID outBuffer, LPVOID lpSomeFlag) +{ + *(DWORD*)outBuffer = 284; + *(DWORD*)lpSomeFlag = 0; +#ifdef LogFastIO + info(true, "iDmacDrvOpen(deviceId=%d, outBuffer='%08X', lpSomeFlag=%08X) -> result=%08X", deviceId, *(DWORD*)outBuffer, *(DWORD*)lpSomeFlag, 0); + info(true, "--------------------------------------------"); +#endif + return 0; +} + +DWORD __cdecl iDmacDrvClose(int deviceId, LPVOID lpWriteAccess) +{ +#ifdef LogFastIO + info(true, "iDmacDrvClose(deviceId=%d, lpWriteAccess='%08X') -> result=%08X", deviceId, lpWriteAccess, 0); + info(true, "--------------------------------------------"); +#endif + return 0; +} + +int __cdecl iDmacDrvDmaRead(int a1, LPVOID lp, UINT_PTR ucb, LPVOID a4) +{ + return 0; +} + +int __cdecl iDmacDrvDmaWrite(int a1, void *lp, UINT_PTR ucb, LPVOID a4) +{ + return 0; +} + +int __cdecl iDmacDrvRegisterRead(int DeviceId, DWORD CommandCode, LPVOID OutBuffer, LPVOID DeviceResult) +{ + DWORD result = 0; + + switch (CommandCode) + { + case 0x400: + { + result = 0x00010201; + break; + } + case 0x4000: + result = 0x00FF00FF; + break; + case 0x4004: + // 0x00FF0000; + result = 0x00FF0000; + break; + case 0x4120: + // 0x00000010; + //result = FourPackage; + result = g_fastIOValues[0] + ((DWORD)g_fastIOValues[1] * 0x100) + ((DWORD)g_fastIOValues[2] * 0x10000) + ((DWORD)g_fastIOValues[3] * 0x1000000); + break; + case 0x412C: + // 0x00000001; + result = 0x00000000; + break; + case 0x41A4: + case 0x4124: + // 0x01100000; + result = 0x01100000; + break; + case 0x4140: + case 0x41C0: + result = g_fastIOValues[4]; + // For coin not getting stuck. One ping is enough. + //result = CoinPackage; + //if (result != 0) + // CoinPackage = 0; + break; + case 0x4144: + case 0x41C4: + result = g_fastIOValues[5]; + // Dual Fast I/O use, not emu'd atm. + //result = CoinPackageSecond; + //if (result != 0) + // CoinPackageSecond = 0; + break; + case 0x41A0: + result = 0; + break; + case 0x41A8: + result = 0; + break; + case 0x4128: + result = g_fastIOValues[8]; + result += g_fastIOValues[9] * 0x100; + //result = 0x00FF00FF; + break; + case 0x41AC: + result = 0; + break; + case 0x4180: + result = 0; + break; + case 0x4108: + result = 0; + break; + + } + *(DWORD*)OutBuffer = result; + *(DWORD*)DeviceResult = 0; +#ifdef LogFastIO + info(true, "iDmacDrvRegisterRead(DeviceId=%d, CommandCode=%08X, OutBuffer=%08X, DeviceResult=%08X) -> result=%08X", DeviceId, CommandCode, *(DWORD*)OutBuffer, *(DWORD*)DeviceResult, 0); + info(true, "--------------------------------------------"); +#endif + return 0; +} + +int __cdecl iDmacDrvRegisterWrite(int deviceId, DWORD CommandCode, int unused, DWORD *DeviceResult) +{ +#ifdef LogFastIO + info(true, "iDmacDrvRegisterWrite(deviceId=%d, CommandCode='%08X', unused=%08X, DeviceResult=%08X) -> result=%08X", deviceId, CommandCode, unused, *(DWORD*)DeviceResult, 0); + info(true, "--------------------------------------------"); +#endif + + if (CommandCode <= 0x4100) + { + if (CommandCode != 0x4100 && CommandCode != 0x4000 && CommandCode != 0x4004) + return 0; + *DeviceResult = -1; + return 0; + } + + if (CommandCode > 0x410C) + { + switch (CommandCode) + { + case 0x4180: + case 0x4184: + case 0x4188: + case 0x418C: + case 0x410C: + case 0x4104: + { + *DeviceResult = -1; + return 0; + } + case 0x4108: + default: + return 0; + } + } + *DeviceResult = -1; + return 0; +} + +int __cdecl iDmacDrvRegisterBufferRead(int a1, DWORD BytesReturned, LPVOID lp, UINT_PTR ucb, LPVOID a5) +{ + return 0; +} + +int __cdecl iDmacDrvRegisterBufferWrite(int a1, DWORD BytesReturned, void *lp, UINT_PTR ucb, LPVOID a5) +{ + return 0; +} + +int __cdecl iDmacDrvMemoryRead(int a1, DWORD BytesReturned, LPVOID lp, LPVOID a4) +{ + return 0; +} + +int __cdecl iDmacDrvMemoryWrite(int a1, DWORD BytesReturned, int a3, LPVOID lp) +{ + return 0; +} + +int __cdecl iDmacDrvMemoryReadExt(int a1, DWORD BytesReturned, int a3, LPVOID lp, DWORD nOutBufferSize, LPVOID a6) +{ + return 0; +} + +int __cdecl iDmacDrvMemoryWriteExt(int a1, int a2, int a3, void *Src, rsize_t DstSize, LPVOID lp) +{ + return 0; +} + +int __cdecl iDmacDrvMemoryBufferRead(int a1, DWORD BytesReturned, LPVOID lp, UINT_PTR ucb, LPVOID a5) +{ + return 0; +} + +int __cdecl iDmacDrvMemoryBufferWrite(int a1, int a2, void *lp, UINT_PTR ucb, LPVOID a5) +{ + return 0; +} + +void init_FastIoEmu() +{ + MH_Initialize(); +#if _M_IX86 + const char* libName = "idmacdrv32.dll"; + if((DWORD)GetProcAddress(GetModuleHandleA(libName), "iDmacDrvMemoryBufferWrite") != 0) + injector::MakeJMP(GetProcAddress(GetModuleHandleA(libName), "iDmacDrvMemoryBufferWrite"), iDmacDrvMemoryBufferWrite); + if ((DWORD)GetProcAddress(GetModuleHandleA(libName), "iDmacDrvMemoryBufferRead") != 0) + injector::MakeJMP(GetProcAddress(GetModuleHandleA(libName), "iDmacDrvMemoryBufferRead"), iDmacDrvMemoryBufferRead); + if ((DWORD)GetProcAddress(GetModuleHandleA(libName), "iDmacDrvMemoryWriteExt") != 0) + injector::MakeJMP(GetProcAddress(GetModuleHandleA(libName), "iDmacDrvMemoryWriteExt"), iDmacDrvMemoryWriteExt); + if ((DWORD)GetProcAddress(GetModuleHandleA(libName), "iDmacDrvMemoryReadExt") != 0) + injector::MakeJMP(GetProcAddress(GetModuleHandleA(libName), "iDmacDrvMemoryReadExt"), iDmacDrvMemoryReadExt); + if ((DWORD)GetProcAddress(GetModuleHandleA(libName), "iDmacDrvMemoryWrite") != 0) + injector::MakeJMP(GetProcAddress(GetModuleHandleA(libName), "iDmacDrvMemoryWrite"), iDmacDrvMemoryWrite); + if ((DWORD)GetProcAddress(GetModuleHandleA(libName), "iDmacDrvMemoryRead") != 0) + injector::MakeJMP(GetProcAddress(GetModuleHandleA(libName), "iDmacDrvMemoryRead"), iDmacDrvMemoryRead); + if ((DWORD)GetProcAddress(GetModuleHandleA(libName), "iDmacDrvRegisterBufferWrite") != 0) + injector::MakeJMP(GetProcAddress(GetModuleHandleA(libName), "iDmacDrvRegisterBufferWrite"), iDmacDrvRegisterBufferWrite); + if ((DWORD)GetProcAddress(GetModuleHandleA(libName), "iDmacDrvRegisterBufferRead") != 0) + injector::MakeJMP(GetProcAddress(GetModuleHandleA(libName), "iDmacDrvRegisterBufferRead"), iDmacDrvRegisterBufferRead); + if ((DWORD)GetProcAddress(GetModuleHandleA(libName), "iDmacDrvDmaWrite") != 0) + injector::MakeJMP(GetProcAddress(GetModuleHandleA(libName), "iDmacDrvDmaWrite"), iDmacDrvDmaWrite); + if ((DWORD)GetProcAddress(GetModuleHandleA(libName), "iDmacDrvDmaRead") != 0) + injector::MakeJMP(GetProcAddress(GetModuleHandleA(libName), "iDmacDrvDmaRead"), iDmacDrvDmaRead); + if ((DWORD)GetProcAddress(GetModuleHandleA(libName), "iDmacDrvClose") != 0) + injector::MakeJMP(GetProcAddress(GetModuleHandleA(libName), "iDmacDrvClose"), iDmacDrvClose); + if ((DWORD)GetProcAddress(GetModuleHandleA(libName), "iDmacDrvOpen") != 0) + injector::MakeJMP(GetProcAddress(GetModuleHandleA(libName), "iDmacDrvOpen"), iDmacDrvOpen); +#else + const wchar_t* libName = L"idmacdrv64.dll"; + MH_CreateHookApi(libName, "iDmacDrvClose", &iDmacDrvClose, NULL); + MH_CreateHookApi(libName, "iDmacDrvOpen", &iDmacDrvOpen, NULL); + MH_CreateHookApi(libName, "iDmacDrvRegisterWrite", &iDmacDrvRegisterWrite, NULL); + MH_CreateHookApi(libName, "iDmacDrvRegisterRead", &iDmacDrvRegisterRead, NULL); +#endif + MH_EnableHook(MH_ALL_HOOKS); + + memset(g_fastIOValues, 0, 64); + + CreateThread(nullptr, 0, [] (LPVOID) -> DWORD + { + HANDLE hPipe = CreateFileA("\\\\.\\pipe\\TeknoParrotPipe", GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, NULL); + + if (hPipe != INVALID_HANDLE_VALUE) + { + DWORD read; + + while (true) + { + ReadFile(hPipe, g_fastIOValues, sizeof(g_fastIOValues), &read, nullptr); + } + } + + return 0; + }, nullptr, 0, nullptr); +} \ No newline at end of file diff --git a/OpenParrot/src/Functions/Nesica_Libs/FastIoEmu.h b/OpenParrot/src/Functions/Nesica_Libs/FastIoEmu.h new file mode 100644 index 0000000..0a01440 --- /dev/null +++ b/OpenParrot/src/Functions/Nesica_Libs/FastIoEmu.h @@ -0,0 +1,2 @@ +#pragma once +void init_FastIoEmu(); \ No newline at end of file diff --git a/OpenParrot/src/Functions/Nesica_Libs/NesysEmu.cpp b/OpenParrot/src/Functions/Nesica_Libs/NesysEmu.cpp new file mode 100644 index 0000000..d9d99d9 --- /dev/null +++ b/OpenParrot/src/Functions/Nesica_Libs/NesysEmu.cpp @@ -0,0 +1,536 @@ +#include "StdInc.h" +#include "NesysEmu.h" +//#if _M_IX86 +#include "Utility/Utils.h" +#pragma optimize("", off) +NesysEmu::NesysEmu() + : m_initialized(false) +{ + m_commandHandlers[LCOMMAND_CLIENT_START] = [=](const uint8_t* data, size_t length) + { + struct __declspec(align(4)) _LIBRARY_INFO + { + unsigned int pid; + char exePath[261]; + char version[33]; + }; + + const _LIBRARY_INFO* linfo = reinterpret_cast(data); + +#ifdef _DEBUG + info(true, "NESYS CLIENT START: pid %d, exePath %s, version %s", linfo->pid, linfo->exePath, linfo->version); +#endif + + SendResponse(SCOMMAND_CLIENT_START_REPLY, nullptr); + }; + + m_commandHandlers[LCOMMAND_CONNECT_REQUEST] = [=](const uint8_t* data, size_t length) + { + SendResponse(SCOMMAND_CONNECT_REPLY, nullptr); + + + Sleep(100); + + // h + struct __declspec(align(4)) NESYS_TENPO_TABLE + { + int tenpo_id; + char tenpo_name[31]; + char tenpo_addr[33]; + char ticket[33]; + char pref_name[17]; + }; + + struct NESYS_NEWS_TABLE + { + int type; + int size; + char iFilePath[1024]; + }; + + struct nesys_cert_init_response + { + NESYS_TENPO_TABLE tenpo; + NESYS_NEWS_TABLE news; + uint32_t serverSize; + char server[]; + }; + + const char* wat = "card_id=42"; + + nesys_cert_init_response* response = (nesys_cert_init_response*)malloc(sizeof(nesys_cert_init_response) + strlen(wat)); + response->tenpo.tenpo_id = 1337; + strcpy(response->tenpo.tenpo_name, "leet"); + strcpy(response->tenpo.tenpo_addr, "l33t"); + strcpy(response->tenpo.ticket, "teel"); + strcpy(response->tenpo.pref_name, "t33l"); + + response->news.type = 0; + response->news.size = 1337; + strcpy(response->news.iFilePath, "/wat"); + + response->serverSize = strlen(wat); + memcpy(response->server, wat, strlen(wat)); + + SendResponse(SCOMMAND_CERT_INIT_NOTICE, response, sizeof(nesys_cert_init_response) + strlen(wat)); + free(response); + }; + + m_commandHandlers[LCOMMAND_DISCONNECT_REQUEST] = [=](const uint8_t* data, size_t length) + { + SendResponse(SCOMMAND_DISCONNECT_REPLY, nullptr); + }; + + m_commandHandlers[LCOMMAND_GAME_FREE_START_REQUEST] = [=](const uint8_t* data, size_t length) + { + SendResponse(SCOMMAND_GAME_STATUS_REPLY, nullptr); + }; + + m_commandHandlers[LCOMMAND_GAME_FREE_END_REQUEST] = [=](const uint8_t* data, size_t length) + { + SendResponse(SCOMMAND_GAME_STATUS_REPLY, nullptr); + }; + + m_commandHandlers[LCOMMAND_GAME_START_REQUEST] = [=](const uint8_t* data, size_t length) + { + SendResponse(SCOMMAND_GAME_STATUS_REPLY, nullptr); + }; + + m_commandHandlers[LCOMMAND_GAME_END_REQUEST] = [=](const uint8_t* data, size_t length) + { + SendResponse(SCOMMAND_GAME_STATUS_REPLY, nullptr); + }; + + // get card + m_commandHandlers[LCOMMAND_CARD_SELECT_REQUEST] = [=](const uint8_t* dataa, size_t length) + { + struct __declspec(align(4)) _CARD_GETDATA + { + char cardId[16]; + unsigned int dataType; + unsigned int paramSize; + char param[1]; + }; + + const _CARD_GETDATA* card = reinterpret_cast(dataa); + + FILE* f = fopen(va("card_%.16s_%d.bin", card->cardId, card->dataType), "rb"); + + size_t dataSize = 0; + char data[16384]; + + if (f) + { + dataSize = fread(data, 1, 16384, f); + fclose(f); + + data[dataSize] = '\0'; + + ++dataSize; + } + + struct cardstatus + { + uint32_t status; + uint32_t times; + uint32_t days; + uint32_t size; + char data[]; + }; + + cardstatus* s = (cardstatus*)malloc(sizeof(cardstatus) + dataSize); + s->status = 1; + s->times = 0; + s->days = 0; + s->size = dataSize; + memcpy(s->data, data, s->size); + + SendResponse(SCOMMAND_CARD_SELECT_REPLY, s, sizeof(cardstatus) + dataSize); + }; + + struct __declspec(align(4)) _CARD_SENDDATA + { + char cardId[16]; + unsigned int frequency; + unsigned int transferMode; + unsigned int dataType; + unsigned int dataSize; + char data[1]; + }; + + // new card + m_commandHandlers[LCOMMAND_CARD_INSERT_REQUEST] = [=](const uint8_t* data, size_t length) + { + struct cardstatus + { + uint32_t status; + uint32_t times; + uint32_t days; + uint32_t size; + char data[]; + }; + + cardstatus s; + s.status = 1; + s.times = 0; + s.days = 0; + s.size = 0; + + SendResponse(SCOMMAND_CARD_INSERT_REPLY, &s); + }; + + // update card + m_commandHandlers[LCOMMAND_CARD_UPDATE_REQUEST] = [=](const uint8_t* data, size_t length) + { + const _CARD_SENDDATA* card = reinterpret_cast(data); + + FILE* f = fopen(va("card_%s_%d.bin", card->cardId, card->dataType), "wb"); + if (f) + { + fwrite(card->data, 1, card->dataSize, f); + fclose(f); + } + + struct cardstatus + { + uint32_t status; + uint32_t times; + uint32_t days; + uint32_t size; + char data[]; + }; + + cardstatus* s = (cardstatus*)malloc(sizeof(cardstatus) + card->dataSize); + s->status = 1; + s->times = 0; + s->days = 0; + s->size = card->dataSize; + memcpy(s->data, card->data, s->size); + + SendResponse(SCOMMAND_CARD_UPDATE_REPLY, s, sizeof(cardstatus) + card->dataSize); + }; + + m_commandHandlers[LCOMMAND_INCOME_FREE_START_REQUEST] = [=](const uint8_t* data, size_t length) + { + struct reply + { + int playerid; + int status; + } r; + + r.playerid = 0; + r.status = 1; + + SendResponse(SCOMMAND_INCOME_STATUS_REPLY, &r); + }; + + m_commandHandlers[LCOMMAND_INCOME_START_REQUEST] = [=](const uint8_t* data, size_t length) + { + struct reply + { + int playerid; + int status; + } r; + + r.playerid = 0; + r.status = 1; + + SendResponse(SCOMMAND_INCOME_STATUS_REPLY, &r); + }; + + m_commandHandlers[LCOMMAND_RANKING_DATA_REQUEST] = [=](const uint8_t* data, size_t length) + { + struct ranking + { + uint32_t status; + uint32_t size; + char data[]; + }; + + ranking r; + r.status = 1; + r.size = 0; + + SendResponse(SCOMMAND_RANKING_DATA_REPLY, &r); + }; + + m_commandHandlers[LCOMMAND_UPLOAD_CONFIG_REQUEST] = [=](const uint8_t* data, size_t length) + { + struct __declspec(align(4)) _UPLOAD_CONFIG + { + unsigned int dataType; + unsigned int dataSize; + char data[1]; + }; + + const _UPLOAD_CONFIG* config = reinterpret_cast(data); + + int status = 1; + SendResponse(SCOMMAND_UPLOAD_CONFIG_REPLY, &status); + }; + + m_commandHandlers[LCOMMAND_SERVICE_VERSION_REQUEST] = [=](const uint8_t* data, size_t length) + { + struct _SERVICE_VER + { + char version[33]; + }; + + _SERVICE_VER version; + strcpy(version.version, "13.37 1337/01/01"); + + SendResponse(SCOMMAND_SERVICE_VERSION_REPLY, &version); + }; + + m_commandHandlers[LCOMMAND_SET_INCOME_MODE_REQUEST] = [=](const uint8_t* data, size_t length) + { + SendResponse(SCOMMAND_SET_INCOME_MODE_REPLY, nullptr); + }; + + m_commandHandlers[LCOMMAND_GAMESTATUS_RESET_REQUEST] = [=](const uint8_t* data, size_t length) + { + SendResponse(SCOMMAND_GAMESTATUS_RESET_REPLY, nullptr); + }; + + m_commandHandlers[LCOMMAND_LOCALNW_INFO_REQUEST] = [=](const uint8_t* data, size_t length) + { + // may also need 'notice' replies + SendResponse(SCOMMAND_LOCALNW_INFO_REPLY, nullptr); + + Sleep(100); + + struct nesys_nwinfo_advertise_table_t + { + char mac[16]; + char ip[16]; + char dhcp[16]; + char gateway[16]; + int gameid; + int attr; + }; + + struct nwi + { + int s; + int size; + nesys_nwinfo_advertise_table_t data; + }; + + nwi nw; + nw.s = 1; + nw.size = sizeof(nw.data); + + strcpy(nw.data.ip, config["Network"]["Ip"].c_str()); + strcpy(nw.data.gateway, config["Network"]["Gateway"].c_str()); + strcpy(nw.data.dhcp, config["Network"]["Dns1"].c_str()); + strcpy(nw.data.mac, "DEADBABECAFE"); + nw.data.gameid = 42; + nw.data.attr = 0; + + SendResponse(SCOMMAND_LOCALNW_INFO_NOTICE, &nw); + }; + + m_commandHandlers[LCOMMAND_GLOBALADDR_REQUEST] = [=](const uint8_t* data, size_t length) + { + struct nesys_globaladdr_table_t + { + int globaladdrStatus; + int responseTime; + char globaladdrData[32]; + }; + + nesys_globaladdr_table_t globalAddr; + globalAddr.globaladdrStatus = 1; + globalAddr.responseTime = 42; + strcpy(globalAddr.globaladdrData, "127.1.3.37"); + + SendResponse(SCOMMAND_GLOBALADDR_REPLY, &globalAddr); + }; + + m_commandHandlers[LCOMMAND_ADAPTER_INFO_REQUEST] = [=](const uint8_t* data, size_t length) + { + struct NNS_LANINTERFACE + { + int Dhcp_Enabled; + char gateway[32]; + char ipAddr[32]; + char submask[32]; + char dhcpServers[32]; + char dnsServers[32]; + char macAddress[64]; + }; + + struct nesys_laninterface_table_t + { + int interfaceStatus; + NNS_LANINTERFACE interfaceData; + }; + + nesys_laninterface_table_t lan; + lan.interfaceStatus = 1; + + lan.interfaceData.Dhcp_Enabled = strcmp(config["Network"]["Dhcp"].c_str(), "1") == 0; + strcpy(lan.interfaceData.ipAddr, config["Network"]["Ip"].c_str()); + strcpy(lan.interfaceData.submask, config["Network"]["Mask"].c_str()); + strcpy(lan.interfaceData.gateway, config["Network"]["Gateway"].c_str()); + strcpy(lan.interfaceData.dhcpServers, config["Network"]["Dns1"].c_str()); + strcpy(lan.interfaceData.dnsServers, config["Network"]["Dns1"].c_str()); + strcpy(lan.interfaceData.macAddress, "DEADBABECAFE"); + + SendResponse(SCOMMAND_ADAPTER_INFO_REPLY, &lan); + }; +} + +NesysEmu::~NesysEmu() +{ + if (m_initialized) + { + Shutdown(); + } +} + +void NesysEmu::ProcessRequest(const uint8_t* data, size_t length) +{ + uintptr_t endData = reinterpret_cast(data) + length; + + while (reinterpret_cast(data) < endData) + { + auto header = reinterpret_cast(data); + + if (header->command != CCOMMAND_NONE) + { + ProcessRequestInternal(header); + } + + data += sizeof(header) + header->length + 4; + } +} + +void NesysEmu::ProcessRequestInternal(const NesysCommandHeader* header) +{ + auto handler = m_commandHandlers.find(header->command); + + if (handler != m_commandHandlers.end()) + { +#ifdef _DEBUG + info(true, "got nesys command: %d\n", header->command); +#endif + + handler->second(header->data, header->length); + return; + } + +#ifdef _DEBUG + info(true, "got unhandled nesys command: %d\n", header->command); // +#endif +} + +static thread_local HANDLE g_curPipe; + +void NesysEmu::ProcessPipe(HANDLE hPipe) +{ + uint8_t requestBuffer[8192]; + + while (true) + { + DWORD bytesRead; + auto success = ReadFile(hPipe, requestBuffer, sizeof(requestBuffer), &bytesRead, nullptr); + + if (!success || bytesRead == 0) + { + break; + } + + g_curPipe = hPipe; + ProcessRequest(requestBuffer, bytesRead); + + Sleep(150); + } + + CloseHandle(hPipe); +} + +void NesysEmu::SendResponse(nesys_command command, const void* data, size_t dataSize) +{ + size_t outSize = (sizeof(NesysCommandHeader) * 1) + dataSize; + + uint8_t* buffer = (uint8_t*)malloc(outSize); + ((NesysCommandHeader*)buffer)->command = command; + ((NesysCommandHeader*)buffer)->length = dataSize; + + if (dataSize > 0) + { + memcpy(buffer + sizeof(NesysCommandHeader), data, dataSize); + } + + //((NesysCommandHeader*)(buffer + sizeof(NesysCommandHeader) + dataSize))->command = CCOMMAND_NONE; + //((NesysCommandHeader*)(buffer + sizeof(NesysCommandHeader) + dataSize))->length = 0; + + DWORD outWritten; + WriteFile(g_curPipe, buffer, outSize, &outWritten, nullptr); + + free(buffer); +} + +void NesysEmu::Initialize() +{ + std::thread([=]() + { + while (true) + { + auto pipe = CreateNamedPipeW(L"\\\\.\\pipe\\nesys_games", PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 8192, 8192, 0, nullptr); + + if (pipe == INVALID_HANDLE_VALUE) + { + return; + } + + bool connected = ConnectNamedPipe(pipe, nullptr) ? true : GetLastError() == ERROR_PIPE_CONNECTED; + + if (!connected) + { + CloseHandle(pipe); + continue; + } + + std::thread([=]() + { + ProcessPipe(pipe); + }).detach(); + } + }).detach(); + + m_initialized = true; +} + +void NesysEmu::Shutdown() +{ + +} + +static NesysEmu g_nesysEmu; + +#include + +static DWORD(WINAPI* g_origGetIfEntry)(PMIB_IFROW ifRow); + +DWORD WINAPI GetIfEntryFunc( + _Inout_ PMIB_IFROW pIfRow +) +{ + DWORD rv = g_origGetIfEntry(pIfRow); + + pIfRow->dwOperStatus = IF_OPER_STATUS_CONNECTED; + + return 0; +} + +void init_NesysEmu() +{ + MH_Initialize(); + MH_CreateHookApi(L"iphlpapi.dll", "GetIfEntry", GetIfEntryFunc, (void**)&g_origGetIfEntry); + MH_EnableHook(MH_ALL_HOOKS); + + g_nesysEmu.Initialize(); +} +#pragma optimize("", on) \ No newline at end of file diff --git a/OpenParrot/src/Functions/Nesica_Libs/NesysEmu.h b/OpenParrot/src/Functions/Nesica_Libs/NesysEmu.h new file mode 100644 index 0000000..007c5a8 --- /dev/null +++ b/OpenParrot/src/Functions/Nesica_Libs/NesysEmu.h @@ -0,0 +1,144 @@ +#pragma once + +#include + +enum nesys_command : uint32_t +{ + CCOMMAND_ERROR = 0xFFFFFFFF, + CCOMMAND_NONE = 0x0, + LCOMMAND_CLIENT_START = 0x1, + LCOMMAND_CONNECT_REQUEST = 0x2, + LCOMMAND_DISCONNECT_REQUEST = 0x3, + LCOMMAND_GAME_START_REQUEST = 0x4, + LCOMMAND_GAME_END_REQUEST = 0x5, + LCOMMAND_GAME_CONTINUE_REQUEST = 0x6, + LCOMMAND_EVENT_DOWNLOAD_REQUEST = 0x7, + LCOMMAND_EVENT_REQUEST_REQUEST = 0x8, + LCOMMAND_CARD_SELECT_REQUEST = 0x9, + LCOMMAND_CARD_INSERT_REQUEST = 0xA, + LCOMMAND_CARD_UPDATE_REQUEST = 0xB, + LCOMMAND_CARD_BUYS_ITEM_REQUEST = 0xC, + LCOMMAND_CARD_TAKEOVER_REQUEST = 0xD, + LCOMMAND_CARD_FORCE_TAKEOVER_REQUEST = 0xE, + LCOMMAND_CARD_DECREASE_REQUEST = 0xF, + LCOMMAND_CARD_REISSUE_TEST_REQUEST = 0x10, + LCOMMAND_CARD_REISSUE_REQUEST = 0x11, + LCOMMAND_CARD_PLAYED_LIST_REQUEST = 0x12, + LCOMMAND_RANKING_DATA_REQUEST = 0x13, + LCOMMAND_LOCALNW_INFO_REQUEST = 0x14, + LCOMMAND_GLOBALADDR_REQUEST = 0x15, + LCOMMAND_ECHO_REQUEST = 0x16, + LCOMMAND_ADAPTER_INFO_REQUEST = 0x17, + LCOMMAND_SERVICE_VERSION_REQUEST = 0x18, + LCOMMAND_DHCP_RENEW_REQUEST = 0x19, + LCOMMAND_HTTPACCESS_GET_REQUEST = 0x1A, + LCOMMAND_HTTPACCESS_POST_REQUEST = 0x1B, + LCOMMAND_UPLOAD_CONFIG_REQUEST = 0x1C, + LCOMMAND_INCOME_START_REQUEST = 0x1D, + LCOMMAND_INCOME_END_REQUEST = 0x1E, + LCOMMAND_INCOME_CONTINUE_REQUEST = 0x1F, + LCOMMAND_SET_INCOME_MODE_REQUEST = 0x20, + LCOMMAND_DESTROY_MY_SERVICE = 0x21, + LCOMMAND_INCOME_POINT_REQUEST = 0x22, + LCOMMAND_GAMESTATUS_RESET_REQUEST = 0x23, + LCOMMAND_ROW_EVENTDATA_LIST_REQUEST = 0x24, + LCOMMAND_SHOPPING_REQUEST = 0x25, + LCOMMAND_HTTPSACCESS_GET_REQUEST = 0x26, + LCOMMAND_HTTPSACCESS_POST_REQUEST = 0x27, + LCOMMAND_FREE_TICKET_REQUEST = 0x28, + LCOMMAND_GAME_FREE_START_REQUEST = 0x29, + LCOMMAND_GAME_FREE_END_REQUEST = 0x2A, + LCOMMAND_INCOME_FREE_START_REQUEST = 0x2B, + LCOMMAND_INCOME_FREE_END_REQUEST = 0x2C, + LCOMMAND_CLIENT_END = 0xFF, + SCOMMAND_NW_ERROR = 0x101, + SCOMMAND_CERT_ERROR = 0x102, + SCOMMAND_NWRECOVER_NOTICE = 0x103, + SCOMMAND_SOON_MAINTENANCE_NOTICE = 0x104, + SCOMMAND_LINKUP_NOTICE = 0x105, + SCOMMAND_LINKLOCAL_MODE_NOTICE = 0x106, + SCOMMAND_CERT_INIT_NOTICE = 0x107, + SCOMMAND_CERT_REGULAR_NOTICE = 0x108, + SCOMMAND_EFFECTIVE_EVENT_NOTICE = 0x109, + SCOMMAND_INEFFECTIVE_EVENT_NOTICE = 0x10A, + SCOMMAND_DHCP_RENEW_START = 0x10B, + SCOMMAND_DHCP_COMPLETE_NOTICE = 0x10C, + SCOMMAND_CLIENT_START_REPLY = 0x10D, + SCOMMAND_CONNECT_REPLY = 0x10E, + SCOMMAND_DISCONNECT_REPLY = 0x10F, + SCOMMAND_GAME_STATUS_REPLY = 0x110, + SCOMMAND_CARD_SELECT_REPLY = 0x111, + SCOMMAND_CARD_INSERT_REPLY = 0x112, + SCOMMAND_CARD_UPDATE_REPLY = 0x113, + SCOMMAND_CARD_BUYS_ITEM_REPLY = 0x114, + SCOMMAND_CARD_TAKEOVER_REPLY = 0x115, + SCOMMAND_CARD_DECREASE_REPLY = 0x116, + SCOMMAND_CARD_REISSUE_TEST_REPLY = 0x117, + SCOMMAND_CARD_REISSUE_REPLY = 0x118, + SCOMMAND_CARD_PLAYED_LIST_REPLY = 0x119, + SCOMMAND_RANKING_DATA_REPLY = 0x11A, + SCOMMAND_LOCALNW_INFO_REPLY = 0x11B, + SCOMMAND_LOCALNW_INFO_NOTICE = 0x11C, + SCOMMAND_GLOBALADDR_REPLY = 0x11D, + SCOMMAND_ECHO_REPLY = 0x11E, + SCOMMAND_ADAPTER_INFO_REPLY = 0x11F, + SCOMMAND_SERVICE_VERSION_REPLY = 0x120, + SCOMMAND_HTTPACCESS_START = 0x121, + SCOMMAND_HTTPACCESS_REPLY = 0x122, + SCOMMAND_UPLOAD_CONFIG_REPLY = 0x123, + SCOMMAND_INCOME_STATUS_REPLY = 0x124, + SCOMMAND_SET_INCOME_MODE_REPLY = 0x125, + SCOMMAND_DESTROY_MY_SERVICE = 0x126, + SCOMMAND_GAMESTATUS_RESET_REPLY = 0x127, + SCOMMAND_ROW_EVENTDATA_LIST_REPLY = 0x128, + SCOMMAND_SHOPPING_REPLY = 0x129, + SCOMMAND_FREE_TICKET_REPLY = 0x130, + SCOMMAND_CLIENT_END_REPLY = 0x1FF, +}; + +struct NesysCommandHeader +{ + nesys_command command; + uint32_t length; + uint8_t data[]; +}; + +class NesysEmu +{ +public: + NesysEmu(); + + ~NesysEmu(); + + void Initialize(); + + void Shutdown(); + +private: + void ProcessPipe(HANDLE hPipe); + + void ProcessRequest(const uint8_t* requestBuffer, size_t length); + + void ProcessRequestInternal(const NesysCommandHeader* header); + + template + void SendResponse(nesys_command command, T data) + { + SendResponse(command, data, sizeof(*data)); + } + + template<> + void SendResponse(nesys_command command, nullptr_t data) + { + SendResponse(command, nullptr, 0); + } + + void SendResponse(nesys_command command, const void* data, size_t dataSize); + +private: + bool m_initialized; + + std::map> m_commandHandlers; +}; + +void init_NesysEmu(); \ No newline at end of file diff --git a/OpenParrot/src/Functions/Nesica_Libs/RfidEmu.cpp b/OpenParrot/src/Functions/Nesica_Libs/RfidEmu.cpp new file mode 100644 index 0000000..47c9107 --- /dev/null +++ b/OpenParrot/src/Functions/Nesica_Libs/RfidEmu.cpp @@ -0,0 +1,847 @@ +#include + +// ORIGINALL BASED ON ttx_monitor, modified for RFID. https://github.com/zxmarcos/ttx_monitor + +#include "Functions/Types.h" + +#include "Utility/InitFunction.h" +#include + +#define JVS_TRUE 0x01 +#define JVS_FALSE 0x00 +#define JVS_SYNC_CODE 0xE0 +#define JVS_REPORT_CODE 0x01 +#define JVS_COMMAND_REV 0x13 +#define JVS_BOARD_REV 0x30 +#define JVS_COMM_REV 0x10 +#define JVS_ADDR_MASTER 0x00 +#define JVS_STATUS_OK 0x01 +#define JVS_STATUS_UNKNOWN_CMD 0x02 +#define JVS_STATUS_SUM_ERROR 0x03 +#define JVS_STATUS_ACK_OVERFLOW 0x04 +#define JVS_REPORT_OK 0x01 +#define JVS_REPORT_INVAL_PARAM1 0x02 +#define JVS_REPORT_INVAL_PARAM2 0x03 +#define JVS_REPORT_BUSY 0x04 +#define JVS_STREAM_SIZE 1024 + +#define JVS_OP_RESET 0xF0 +#define JVS_OP_ADDRESS 0xF1 +#define JVS_OP_CHECKSUM_ERROR 0x2F + +#define JVS_IOFUNC_SWINPUT 0x01 +#define JVS_IOFUNC_COINTYPE 0x02 +#define JVS_IOFUNC_EXITCODE 0x00 + +#define JVS_SUPPORT_PLAYERS 2 +#define JVS_SUPPORT_SLOTS 2 + +#define LOG_COMMANDS 1 +#if LOG_COMMANDS +#define logcmd logmsg +#else +#define logcmd(str, __VA_LIST__) +#endif + +std::queue replyBuffer; +typedef signed char SINT8; +typedef signed short SINT16; +typedef signed short SINT32; +typedef unsigned char UINT8; +typedef unsigned short UINT16; +HANDLE hConnection = (HANDLE)0x1337; +X2Type gameType; +static uint8_t g_jvsIOValues[64]; +typedef BOOL(__stdcall *LPCloseHandle)(HANDLE hObject); +static LPCloseHandle __CloseHandle = NULL; + +typedef BOOL(__stdcall *LPGetCommModemStatus)(HANDLE hFile, LPDWORD lpModemStat); +static LPGetCommModemStatus __GetCommModemStatus = NULL; + +typedef BOOL(__stdcall *LPEscapeCommFunction)(HANDLE hFile, DWORD dwFunc); +static LPEscapeCommFunction __EscapeCommFunction = NULL; + +typedef BOOL(__stdcall *LPClearCommError)(HANDLE hFile, LPDWORD lpErrors, LPCOMSTAT lpStat); +static LPClearCommError __ClearCommError = NULL; + +typedef BOOL(__stdcall *LPSetupComm)(HANDLE hFile, DWORD dwInQueue, DWORD dwOutQueue); +static LPSetupComm __SetupComm = NULL; + +typedef BOOL(__stdcall *LPGetCommState)(HANDLE hFile, LPDCB lpDCB); +static LPGetCommState __GetCommState = NULL; + +typedef BOOL(__stdcall *LPSetCommState)(HANDLE hFile, LPDCB lpDCB); +static LPSetCommState __SetCommState = NULL; + +typedef BOOL(__stdcall *LPSetCommMask)(HANDLE hFile, DWORD dwEvtMask); +static LPSetCommMask __SetCommMask = NULL; + +typedef BOOL(__stdcall *LPGetCommTimeouts)(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts); +static LPGetCommTimeouts __GetCommTimeouts = NULL; + +typedef BOOL(__stdcall *LPSetCommTimeouts)(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts); +static LPSetCommTimeouts __SetCommTimeouts = NULL; + +typedef BOOL(__stdcall *LPWriteFile)(HANDLE hFile, + LPVOID lpBuffer, + DWORD nNumberOfBytesToWrite, + LPDWORD lpNumberOfBytesWritten, + LPOVERLAPPED lpOverlapped); +static LPWriteFile __WriteFile = NULL; +typedef BOOL(__stdcall *LPReadFile)(HANDLE hFile, + LPVOID lpBuffer, + DWORD nNumberOfBytesToRead, + LPDWORD lpNumberOfBytesRead, + LPOVERLAPPED lpOverlapped); +typedef BOOL(__stdcall *LPCloseHandle)(HANDLE hObject); +static LPReadFile __ReadFile = NULL; + + +typedef HANDLE(__stdcall *LPCreateFileA)(LPCSTR lpFileName, + DWORD dwDesiredAccess, + DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile); +static LPCreateFileA __CreateFileA = NULL; + +typedef HANDLE(__stdcall *LPCreateFileW)(LPCWSTR lpFileName, + DWORD dwDesiredAccess, + DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile); +static LPCreateFileW __CreateFileW = NULL; + +static const char *Rfid_IO_Id = "TAITO CORP.;RFID CTRL P.C.B.;Ver1.00;"; + +void logmsg(const char *format, ...) +{ + +} + +struct jvs_command_def { + UINT8 params; + UINT8 reports; +}; + +#define __ARG__(n) ((DWORD) pfunc[n]) + +class jprot_encoder { + BYTE buffer[1024]; + BYTE *ptr; + DWORD statusaddr; + DWORD sizeaddr; + DWORD sumaddr; + DWORD startaddr; + DWORD xpos; + DWORD size_; + DWORD nreplys; +public: + DWORD size() { + return size_; + } + jprot_encoder() { + memset(buffer, 0, 1024); + xpos = 0; + } + ~jprot_encoder() { + memset(buffer, 0, 1024); + xpos = 0; + } + + void addreply() { + nreplys++; + } + + + void set_status(BYTE v) { + buffer[statusaddr] = v; + } + void clear() + { + memset(buffer, 0, 1024); + size_ = 0; + xpos = 0; + } + void begin_stream() { + + pushz(JVS_SYNC_CODE); + sumaddr = xpos; + pushz(JVS_ADDR_MASTER); + sizeaddr = xpos; + push(0); + statusaddr = xpos; + // STATUS + push(JVS_STATUS_OK); + + } + + void pushz(BYTE v) { + buffer[xpos++] = v; + } + + void push(BYTE v) { +#if 0 + buffer[xpos] = v; + ++xpos; +#else + if (v == 0xD0) { + buffer[xpos++] = 0xD0; + buffer[xpos++] = 0xCF; + } + else + if (v == 0xE0) { + buffer[xpos++] = 0xD0; + buffer[xpos++] = 0xDF; + } + else + buffer[xpos++] = v; +#endif + } + void report(BYTE v) { + push(v); + } + void end_stream() { +#if 0 + if (xpos == (statusaddr + 1)) { + clear(); + return; + } + // codifica o tamanho da stream + buffer[sizeaddr] = (BYTE)xpos - sizeaddr; + + // calcula o checksum + DWORD sum = 0; + for (DWORD i = sumaddr; i size_) + size = size_; + memcpy(dst, &buffer[0], size); + } + + void print() + { + if (size()) { +#ifdef _DEBUG + logmsg("WR: "); + for (DWORD i = 0; ireport(JVS_REPORT_OK); + isAddressed = 1; + + return 2; +} + +int handle0x2F() +{ + return 1; +} + +int handle0x10(jprot_encoder *r) +{ + const char *str = NULL; + r->report(JVS_REPORT_OK); + //if(gameType == X2Type::RFID) + str = Rfid_IO_Id; + //else if(gameType == X2Type::Digital) + // str = IO_Id; + while (*str) { r->push(*str++); } + r->push(0); + return 1; +} + +int handle0x11(jprot_encoder *r) +{ + r->report(JVS_REPORT_OK); + r->push(JVS_COMMAND_REV); + return 1; +} + +int handle0x12(jprot_encoder *r) +{ + r->report(JVS_REPORT_OK); + r->push(JVS_BOARD_REV); + return 1; +} + +int handle0x13(jprot_encoder *r) +{ + r->report(JVS_REPORT_OK); + r->push(JVS_COMM_REV); + return 1; +} + +int handle0x14(jprot_encoder *r) +{ + if (gameType == X2Type::RFID) + { + r->report(JVS_REPORT_OK); + r->push(1); + r->push(7); + r->push(0); + r->push(8); + r->push(0); + r->push(0x12); + r->push(8); + r->push(0); + r->push(0); + r->push(0); + return 1; + } + if(gameType == X2Type::Digital) + { + r->report(JVS_REPORT_OK); + + r->push(JVS_IOFUNC_SWINPUT); + { + r->push(JVS_SUPPORT_PLAYERS); // 2 players + r->push(14); // 14 bot�es + r->push(0); // null + } + r->push(JVS_IOFUNC_COINTYPE); + { + r->push(JVS_SUPPORT_SLOTS); // 2 slots + r->push(0); // null + r->push(0); // null + } + + r->push(JVS_IOFUNC_EXITCODE); + { + r->push(0); + r->push(0); + r->push(0); + } + } + return 1; +} + +int handle0x01(jprot_encoder *r) +{ + r->report(JVS_REPORT_OK); + r->push(1); + r->push(0); + return 2; +} + +int handle0x20(jprot_encoder *r) +{ + r->report(JVS_REPORT_OK); + + if(gameType == X2Type::Digital) + { + if (g_jvsIOValues[24]) + r->push(0x80); + else + r->push(0); + } + else + { + r->push(0); + } + + r->push(0); + r->push(0); + r->push(0); + r->push(0); + return 3; +} + +int handle0x21(jprot_encoder *r) +{ + if(gameType == X2Type::RFID) + { + int currstate = 0;// inputMgr.GetState(P1_COIN); + if (!coinstate[0] && (currstate)) { + ++p1coin; + } + coinstate[0] = currstate; + + currstate = 0;// inputMgr.GetState(P2_COIN); + if (!coinstate[1] && (currstate)) { + ++p2coin; + + } + coinstate[1] = currstate; + + //logcmd("Lendo o ficheiro... \n"); + r->report(JVS_REPORT_OK); + r->push(p1coin >> 8); + r->push(p1coin & 0xFF); + r->push(p2coin >> 8); + r->push(p2coin & 0xFF); + return 2; + } + int currstate = g_jvsIOValues[25]; + if (!coinstate[0] && (currstate)) { + ++p1coin; + } + coinstate[0] = currstate; + + currstate = g_jvsIOValues[26]; + if (!coinstate[1] && (currstate)) { + ++p2coin; + + } + coinstate[1] = currstate; + + //logcmd("Lendo o ficheiro... \n"); + r->report(JVS_REPORT_OK); + r->push(p1coin >> 8); + r->push(p1coin & 0xFF); + r->push(p2coin >> 8); + r->push(p2coin & 0xFF); + return 2; +} + +int handle0x30(jprot_encoder *r, DWORD arg1, DWORD arg2, DWORD arg3) +{ + WORD val = ((arg2 & 0xFF) << 8) | (arg3 & 0xFF); + r->report(JVS_REPORT_OK); +#ifdef _DEBUG + logcmd("-coin %d, %d\n", arg1, val); +#endif + switch (arg1) + { + case 1: + if (val > p1coin) + p1coin = 0; + else + p1coin -= val; + break; + case 2: + if (val > p2coin) + p2coin = 0; + else + p2coin -= val; + } + return 4; +} + +int handle0x31(jprot_encoder *r, DWORD arg1, DWORD arg2, DWORD arg3) +{ + WORD val = ((arg2 & 0xFF) << 8) | (arg3 & 0xFF); + r->report(JVS_REPORT_OK); +#ifdef _DEBUG + logcmd("+coin %d, %d\n", arg1, val); +#endif + switch (arg1) + { + case 1: p1coin += val; break; + case 2: p2coin += val; break; + } + return 4; +} + +unsigned long process_stream(unsigned char *stream, unsigned long srcsize, unsigned char *dst, unsigned long dstsize) +{ + jprot_encoder r; + BYTE *pstr = stream; + BYTE *pfunc = NULL; + BYTE node = 0; + BYTE pktsize = 0; + int pktcount = 0; + WORD pktaddr = 0; + + r.clear(); + + + if (pstr[0] != JVS_SYNC_CODE) { +#ifdef _DEBUG + logmsg("Invalid Sync code!\n"); +#endif + } + node = pstr[1]; + pktsize = pstr[2]; + pfunc = &pstr[3]; + + pktcount = (int)pktsize - 1; + + r.begin_stream(); + + while (pktcount > 0) + { + int increment = 0; + switch (pfunc[0] & 0xFF) + { + case 0xF0: + increment = handle0xF0(); + break; + case 0xF1: + increment = handle0xF1(&r); + break; + case 0x2F: + increment = handle0x2F(); + break; + case 0x10: + increment = handle0x10(&r); + break; + case 0x11: + increment = handle0x11(&r); + break; + case 0x12: + increment = handle0x12(&r); + break; + case 0x13: + increment = handle0x13(&r); + break; + case 0x14: + increment = handle0x14(&r); + break; + case 0x01: + increment = handle0x01(&r); + break; + case 0x20: + increment = handle0x20(&r); + break; + case 0x21: + increment = handle0x21(&r); + break; + case 0x30: + increment = handle0x30(&r, __ARG__(1), __ARG__(2), __ARG__(3)); + break; + + case 0x31: + increment = handle0x31(&r, __ARG__(1), __ARG__(2), __ARG__(3)); + break; + default: +#ifdef _DEBUG + logcmd("Unknown command %X\n", __ARG__(0)); +#endif + r.report(JVS_REPORT_OK); + increment = 1; + break; + } + + pktcount -= increment; + pfunc += increment; + } + + r.set_status(JVS_STATUS_OK); + r.end_stream(); + r.read(dst, dstsize); + return r.size(); +} + +#define __XHOOKn(mod, name) \ + MH_CreateHookApi(L ## mod, #name, &Hookz_##name, (void**)&__##name) + +BOOL __stdcall Hookz_GetCommModemStatus(HANDLE hFile, LPDWORD lpModemStat) +{ + if (hFile != hConnection) { + return __GetCommModemStatus(hFile, lpModemStat); + } + if (is_addressed()) + *lpModemStat = 0x10; + else + *lpModemStat = 0; +#ifdef LogRFID + info(true, "GetCommModemStatus(hFile=%d, lpModemStat=%p) -> result=%08X", hFile, lpModemStat, TRUE); + info(true, "--------------------------------------------"); +#endif + return TRUE; +} +BOOL __stdcall Hookz_EscapeCommFunction(HANDLE hFile, DWORD dwFunc) +{ + if (hFile != hConnection) { + return __EscapeCommFunction(hFile, dwFunc); + } + bool ret = true;// __EscapeCommFunction(hFile, dwFunc); +#ifdef LogRFID + info(true, "EscapeCommFunction(hFile=%d, dwFunc='%08X') -> result=%08X", hFile, dwFunc, ret); + info(true, "--------------------------------------------"); +#endif + return ret; +} + +BOOL __stdcall Hookz_ClearCommError(HANDLE hFile, LPDWORD lpErrors, LPCOMSTAT lpStat) +{ + if (hFile != hConnection) { + return __ClearCommError(hFile, lpErrors, lpStat); + } +#ifdef LogRFID + info(true, "ClearCommError(hFile=%d, lpErrors=%p, lpStat=%p) -> result=%08X", hFile, lpErrors, lpStat, 1); + info(true, "--------------------------------------------"); +#endif + if (lpStat) { + if (!replyBuffer.empty()) + lpStat->cbInQue = replyBuffer.size(); + else + lpStat->cbInQue = 0; + } + return true; +} + +BOOL __stdcall Hookz_SetupComm(HANDLE hFile, DWORD dwInQueue, DWORD dwOutQueue) +{ + + if (hFile != hConnection) { + return __SetupComm(hFile, dwInQueue, dwOutQueue); + } +#ifdef LogRFID + info(true, "SetupComm(hFile=%d, dwInQueue='%08X', dwOutQueue='%08X') -> result=%08X", hFile, dwInQueue, dwOutQueue, 1); + info(true, "--------------------------------------------"); +#endif + return TRUE; +} +BOOL __stdcall Hookz_GetCommState(HANDLE hFile, LPDCB lpDCB) +{ + if (hFile != hConnection) { + return __GetCommState(hFile, lpDCB); + } +#ifdef LogRFID + info(true, "GetCommState(hFile=%d, lpDCB=%p) -> result=%08X", hFile, lpDCB, 1); + info(true, "--------------------------------------------"); +#endif + return TRUE; +} + +BOOL __stdcall Hookz_SetCommState(HANDLE hFile, LPDCB lpDCB) +{ + if (hFile != hConnection) { + return __SetCommState(hFile, lpDCB); + } +#ifdef LogRFID + info(true, "SetCommState(hFile=%d, lpDCB=%p) -> result=%08X", hFile, lpDCB, 1); + info(true, "--------------------------------------------"); +#endif + return TRUE; +} + +BOOL __stdcall Hookz_SetCommMask(HANDLE hFile, DWORD dwEvtMask) +{ + + if (hFile != hConnection) { + return __SetCommMask(hFile, dwEvtMask); + } +#ifdef LogRFID + info(true, "SetCommMask(hFile=%d, dwEvtMask='%08X') -> result=%08X", hFile, dwEvtMask, true); + info(true, "--------------------------------------------"); +#endif + return TRUE; +} + +BOOL __stdcall Hookz_GetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) +{ + + if (hFile != hConnection) { + return __GetCommTimeouts(hFile, lpCommTimeouts); + } +#ifdef LogRFID + info(true, "GetCommTimeouts(hFile=%d, lpCommTimeouts=%p) -> result=%08X", hFile, lpCommTimeouts, TRUE); + info(true, "--------------------------------------------"); +#endif + return TRUE; +} + +BOOL __stdcall Hookz_SetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) +{ + + if (hFile != hConnection) { + return __SetCommTimeouts(hFile, lpCommTimeouts); + } +#ifdef LogRFID + info(true, "SetCommTimeouts(hFile=%d, lpCommTimeouts=%p) -> result=%08X", hFile, lpCommTimeouts, TRUE); + info(true, "--------------------------------------------"); +#endif + return TRUE; +} + +BOOL __stdcall Hookz_WriteFile(HANDLE hFile, + LPVOID lpBuffer, + DWORD nNumberOfBytesToWrite, + LPDWORD lpNumberOfBytesWritten, + LPOVERLAPPED lpOverlapped) +{ + if (hFile != hConnection) { + return __WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped); + } + static BYTE rbuffer[1024]; + + DWORD sz = process_stream((LPBYTE)lpBuffer, nNumberOfBytesToWrite, rbuffer, 1024); + if (sz != 1) { + for (DWORD i = 0; i < sz; i++) + { + replyBuffer.push(rbuffer[i]); + } + } + +#ifdef LogRFID + info(true, ""); + info(true, "--------------------------------------------"); +#endif + return TRUE; +} + +BOOL __stdcall Hookz_ReadFile(HANDLE hFile, + LPVOID lpBuffer, + DWORD nNumberOfBytesToRead, + LPDWORD lpNumberOfBytesRead, + LPOVERLAPPED lpOverlapped) +{ + if (hFile != hConnection) { + return __ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped); + } + +#ifdef LogRFID + info(true, "ReadFile(hFile=%d, lpBuffer='%08X', nNumberOfBytesToRead=%08X) -> result=%08X", hFile, lpBuffer, nNumberOfBytesToRead, TRUE); +#endif + if (replyBuffer.size()) + { + if (nNumberOfBytesToRead >= replyBuffer.size()) + nNumberOfBytesToRead = replyBuffer.size(); + *lpNumberOfBytesRead = nNumberOfBytesToRead; + BYTE *ptr = (BYTE*)lpBuffer; + for (DWORD i = 0; i < nNumberOfBytesToRead; i++) { + if (!replyBuffer.empty()) { + *ptr++ = replyBuffer.front(); + replyBuffer.pop(); + } + else + *ptr++ = 0; + } + } + else { + *lpNumberOfBytesRead = 0; + return TRUE; + } +#ifdef LogRFID + info(true, ""); + info(true, "--------------------------------------------"); +#endif + return TRUE; +} + +BOOL __stdcall Hookz_CloseHandle(HANDLE hObject) +{ + if (hObject != hConnection) { + return __CloseHandle(hObject); + } +#ifdef LogRFID + info(true, "CloseHandle(hObject=%d) -> result=%08X", hObject, TRUE); + info(true, "--------------------------------------------"); +#endif + return TRUE; +} +DWORD priority = 0; +HANDLE __stdcall Hookz_CreateFileA(LPCSTR lpFileName, + DWORD dwDesiredAccess, + DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile) +{ + if (!strcmp(lpFileName, "COM2")) + { +#ifdef LogRFID + info(true, "CreateFile(lpFileName=%s) -> result=%08X", lpFileName, hConnection); + info(true, "--------------------------------------------"); +#endif + return hConnection; + } + + return __CreateFileA(lpFileName, + dwDesiredAccess, + dwShareMode, + lpSecurityAttributes, + dwCreationDisposition, + dwFlagsAndAttributes, + hTemplateFile); +} + +#define __XHOOKn(mod, name) \ + MH_CreateHookApi(L ## mod, #name, &Hookz_##name, (void**)&__##name) + +void init_RfidEmu(X2Type type) +{ + MH_Initialize(); + gameType = X2Type::RFID; + __XHOOKn("kernel32.dll", CreateFileA); + //__XHOOKn("kernel32.dll", CreateFileW); + __XHOOKn("kernel32.dll", WriteFile); + __XHOOKn("kernel32.dll", ReadFile); + __XHOOKn("kernel32.dll", CloseHandle); + __XHOOKn("kernel32.dll", GetCommModemStatus); + __XHOOKn("kernel32.dll", EscapeCommFunction); + __XHOOKn("kernel32.dll", ClearCommError); + __XHOOKn("kernel32.dll", SetCommMask); + __XHOOKn("kernel32.dll", SetupComm); + __XHOOKn("kernel32.dll", GetCommState); + __XHOOKn("kernel32.dll", SetCommState); + __XHOOKn("kernel32.dll", SetCommTimeouts); + __XHOOKn("kernel32.dll", GetCommTimeouts); + MH_EnableHook(MH_ALL_HOOKS); +} \ No newline at end of file diff --git a/OpenParrot/src/Functions/Nesica_Libs/RfidEmu.h b/OpenParrot/src/Functions/Nesica_Libs/RfidEmu.h new file mode 100644 index 0000000..136dba7 --- /dev/null +++ b/OpenParrot/src/Functions/Nesica_Libs/RfidEmu.h @@ -0,0 +1,5 @@ +#pragma once +void reset_addressed(); +unsigned long process_stream(unsigned char *stream, unsigned long srcsize, unsigned char *dst, unsigned long dstsize); +unsigned long process_rfid(unsigned char *stream, unsigned long srcsize, unsigned char *dst, unsigned long dstsize); +void init_RfidEmu(X2Type type); \ No newline at end of file diff --git a/OpenParrot/src/Functions/Ring_amLib/amJvs.cpp b/OpenParrot/src/Functions/Ring_amLib/amJvs.cpp new file mode 100644 index 0000000..38b0499 --- /dev/null +++ b/OpenParrot/src/Functions/Ring_amLib/amJvs.cpp @@ -0,0 +1,358 @@ +#include +#include +#include +#include "amJvs.h" +#pragma optimize("", off) +#include + +typedef BOOL(__stdcall *LPGetCommModemStatus)(HANDLE hFile, LPDWORD lpModemStat); +static LPGetCommModemStatus __GetCommModemStatus = NULL; + +typedef BOOL(WINAPI *LPSetCommState)(HANDLE hFile, LPDCB lpDCB); +static LPSetCommState __SetCommState = NULL; + +typedef BOOL(WINAPI *LPGetCommState)(HANDLE hFile, LPDCB lpDCB); +static LPGetCommState __GetCommState = NULL; + +typedef BOOL(WINAPI *LPGetCommMask)(HANDLE hFile, DWORD* dwEvtMask); +static LPGetCommMask __GetCommMask = NULL; + +typedef BOOL(WINAPI *LPSetCommMask)(HANDLE hFile, DWORD dwEvtMask); +static LPSetCommMask __SetCommMask = NULL; + +typedef BOOL(WINAPI *LPEscapeCommFunction)(HANDLE hFile, DWORD); +static LPEscapeCommFunction __EscapeCommFunction = NULL; + +typedef BOOL(WINAPI *LPSetCommTimeouts)(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts); +static LPSetCommTimeouts __SetCommTimeouts = NULL; + +typedef BOOL(WINAPI *LPGetCommTimeouts)(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts); +static LPGetCommTimeouts __GetCommTimeouts = NULL; + +typedef BOOL(WINAPI *LPSetupComm)(HANDLE hFile, DWORD dwInQueue, DWORD dwOutQueue); +static LPSetupComm __SetupComm = NULL; + +typedef BOOL(WINAPI *LPPurgeComm)(HANDLE hFile, DWORD dwFlags); +static LPPurgeComm __PurgeComm = NULL; + +typedef BOOL(__stdcall *LPClearCommError)(HANDLE hFile, LPDWORD lpErrors, LPCOMSTAT lpStat); +static LPClearCommError __ClearCommError = NULL; + +typedef HANDLE(__stdcall *LPCreateFileA)(LPCSTR lpFileName, + DWORD dwDesiredAccess, + DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile); +static LPCreateFileA __CreateFileA = NULL; + +typedef HANDLE(__stdcall *LPCreateFileW)(LPCWSTR lpFileName, + DWORD dwDesiredAccess, + DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile); +static LPCreateFileW __CreateFileW = NULL; + + +LPCSTR emuPort = "\\\\.\\pipe\\teknoparrot_jvs"; +LPCWSTR emuPortW = L"\\\\.\\pipe\\teknoparrot_jvs"; +LPCSTR hookPort = "COM4"; +DWORD amJvsDataOffset = 0; +HANDLE jvsHandle = (HANDLE)-1; +bool JVSAlreadyTaken = false; + +HANDLE __stdcall Hook_CreateFileA(LPCSTR lpFileName, + DWORD dwDesiredAccess, + DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile) +{ + if (strcmp(lpFileName, hookPort) == 0) + { +#ifdef _DEBUG + info(true, "CreateFileA JVS: %s", lpFileName); + info(true, "--------------------------------------------"); +#endif + + if (jvsHandle != INVALID_HANDLE_VALUE) + { + CloseHandle(jvsHandle); + jvsHandle = INVALID_HANDLE_VALUE; + } + + HANDLE hResult = __CreateFileA(emuPort, + dwDesiredAccess, + dwShareMode, + lpSecurityAttributes, + dwCreationDisposition, + dwFlagsAndAttributes, + hTemplateFile); + jvsHandle = hResult; + + //JVSAlreadyTaken = true; + return hResult; + } + + if (strncmp(lpFileName, "Y:\\", 3) == 0) + { + DWORD len = strlen(lpFileName); + char temp[32]; + memset(temp, 0, 32); + memcpy(temp, ".\\", 2); + memcpy(temp + 2, lpFileName + 3, len - 3); +#ifdef _DEBUG + info(true, "data drive file redirected: %s -> %s", lpFileName, temp); +#endif + HANDLE hResult = __CreateFileA(temp, + dwDesiredAccess, + dwShareMode, + lpSecurityAttributes, + dwCreationDisposition, + dwFlagsAndAttributes, + hTemplateFile); + return hResult; + } + HANDLE hResult = __CreateFileA(lpFileName, + dwDesiredAccess, + dwShareMode, + lpSecurityAttributes, + dwCreationDisposition, + dwFlagsAndAttributes, + hTemplateFile); + return hResult; +} +HANDLE __stdcall Hook_CreateFileW(LPCWSTR lpFileName, + DWORD dwDesiredAccess, + DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile) +{ + if (wcscmp(lpFileName, L"COM4") == 0 && !JVSAlreadyTaken) + { + HANDLE hResult = __CreateFileW(emuPortW, + dwDesiredAccess, + dwShareMode, + lpSecurityAttributes, + dwCreationDisposition, + dwFlagsAndAttributes, + hTemplateFile); + jvsHandle = hResult; + JVSAlreadyTaken = true; + return hResult; + } + + HANDLE hResult = __CreateFileW(lpFileName, + dwDesiredAccess, + dwShareMode, + lpSecurityAttributes, + dwCreationDisposition, + dwFlagsAndAttributes, + hTemplateFile); + return hResult; +} + +static HANDLE hSection = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, 64, L"TeknoParrot_JvsState"); +static int* secData = (int*)MapViewOfFile(hSection, FILE_MAP_ALL_ACCESS, 0, 0, 64); +// Battle gear +int* wheelSection = &secData[1]; +int* ffbOffset = &secData[2]; +int* ffbOffset2 = &secData[3]; +int* ffbOffset3 = &secData[4]; +int* ffbOffset4 = &secData[5]; + +static bool IsCommHooked(HANDLE hFile); + +bool check = false; +BOOL __stdcall Hook_GetCommModemStatus(HANDLE hFile, LPDWORD lpModemStat) +{ + if (!IsCommHooked(hFile)) { + return __GetCommModemStatus(hFile, lpModemStat); + } + + if (hFile != jvsHandle) + { + return TRUE; + } + + if(GameDetect::IsTypeX()) + { + if (*secData) // addressed? + { + *lpModemStat = 0x10; + } + else + { + *lpModemStat = 0x0; + } + } + else + { + if (*secData) // addressed? + { + *lpModemStat = 0x30; // 0x10 + } + else + { + *lpModemStat = 0x10; // 0x0 + } + } + return TRUE; +} + +#include + +static std::set g_commOverrides; + +static bool IsCommHooked(HANDLE hFile) +{ + return (hFile == jvsHandle || g_commOverrides.find(hFile) != g_commOverrides.end()); +} + +void AddCommOverride(HANDLE hFile) +{ + g_commOverrides.insert(hFile); +} + +BOOL __stdcall Hook_SetCommState(HANDLE hFile, LPDCB lpDCB) +{ + if (!IsCommHooked(hFile)) { + return __SetCommState(hFile, lpDCB); + } + + return true; +} + +BOOL __stdcall Hook_GetCommState(HANDLE hFile, LPDCB lpDCB) +{ + if (!IsCommHooked(hFile)) { + return __GetCommState(hFile, lpDCB); + } + + return true; +} + +BOOL __stdcall Hook_SetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) +{ + if (!IsCommHooked(hFile)) { + return __SetCommTimeouts(hFile, lpCommTimeouts); + } + + return true; +} + +BOOL __stdcall Hook_GetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) +{ + if (!IsCommHooked(hFile)) { + return __GetCommTimeouts(hFile, lpCommTimeouts); + } + + return true; +} + +BOOL __stdcall Hook_SetCommMask(HANDLE hFile, DWORD dwEvtMask) +{ + if (!IsCommHooked(hFile)) { + return __SetCommMask(hFile, dwEvtMask); + } + + return true; +} + + +BOOL __stdcall Hook_GetCommMask(HANDLE hFile, DWORD* dwEvtMask) +{ + if (!IsCommHooked(hFile)) { + return __GetCommMask(hFile, dwEvtMask); + } + + return true; +} + +BOOL __stdcall Hook_EscapeCommFunction(HANDLE hFile, DWORD dwFunc) +{ + if (!IsCommHooked(hFile)) { + return __EscapeCommFunction(hFile, dwFunc); + } + + return true; +} + +BOOL WINAPI Hook_SetupComm(HANDLE hFile, DWORD dwInQueue, DWORD dwOutQueue) +{ + if (!IsCommHooked(hFile)) + { + return __SetupComm(hFile, dwInQueue, dwOutQueue); + } + +#if defined(_DEBUG) + info(true, "SetupComm(hFile %x, dwInQueue %x, dwOutQueue %x)", hFile, dwInQueue, dwOutQueue); +#endif + + return true; +} + +BOOL WINAPI Hook_PurgeComm(HANDLE hFile, DWORD dwFlags) +{ + if (!IsCommHooked(hFile)) + { + return __PurgeComm(hFile, dwFlags); + } + +#if defined(WantPurgeCommLogging) + info(true, "PurgeComm(hFile %x, dwFlags %x)", hFile, dwFlags); +#endif + + CancelIoEx(hFile, nullptr); + + return true; +} + +BOOL __stdcall Hook_ClearCommError(HANDLE hFile, LPDWORD lpErrors, LPCOMSTAT lpStat) +{ + if (!IsCommHooked(hFile)) + { + return __ClearCommError(hFile, lpErrors, lpStat); + } + + lpStat->cbInQue = 0x7FFF; + + return true; +} + +#define __XHOOKn(mod, name) \ + MH_CreateHookApi(L ## mod, #name, &Hook_##name, (void**)&__##name) + +static InitFunction jvsInit([]() +{ + if (GameDetect::IsNesicaGame()) + { + return; + } + if (GameDetect::IsTypeX()) + hookPort = "COM2"; + + MH_Initialize(); + __XHOOKn("kernel32.dll", GetCommState); + __XHOOKn("kernel32.dll", SetCommState); + __XHOOKn("kernel32.dll", GetCommTimeouts); + __XHOOKn("kernel32.dll", SetCommTimeouts); + __XHOOKn("kernel32.dll", GetCommMask); + __XHOOKn("kernel32.dll", SetCommMask); + __XHOOKn("kernel32.dll", SetupComm); + __XHOOKn("kernel32.dll", PurgeComm); + __XHOOKn("kernel32.dll", EscapeCommFunction); + __XHOOKn("kernel32.dll", ClearCommError); + + __XHOOKn("kernel32.dll", CreateFileA); + __XHOOKn("kernel32.dll", CreateFileW); + __XHOOKn("kernel32.dll", GetCommModemStatus); + MH_EnableHook(MH_ALL_HOOKS); +}); +#pragma optimize("", on) \ No newline at end of file diff --git a/OpenParrot/src/Functions/Ring_amLib/amJvs.h b/OpenParrot/src/Functions/Ring_amLib/amJvs.h new file mode 100644 index 0000000..7b9637e --- /dev/null +++ b/OpenParrot/src/Functions/Ring_amLib/amJvs.h @@ -0,0 +1 @@ +#pragma once \ No newline at end of file diff --git a/OpenParrot/src/Functions/Types.h b/OpenParrot/src/Functions/Types.h new file mode 100644 index 0000000..b3f47c5 --- /dev/null +++ b/OpenParrot/src/Functions/Types.h @@ -0,0 +1,12 @@ +enum class X2Type { + None, + RFID, + Digital, + Analog, + VRL, + Raiden4, + BG4, + Lupin3, + Generic, + GaiaAttack4 +}; \ No newline at end of file diff --git a/OpenParrot/src/Functions/WindowedDx8.cpp b/OpenParrot/src/Functions/WindowedDx8.cpp new file mode 100644 index 0000000..fceb4c2 --- /dev/null +++ b/OpenParrot/src/Functions/WindowedDx8.cpp @@ -0,0 +1,88 @@ +#define CINTERFACE +#include +#include "Utility/InitFunction.h" +#pragma optimize("", off) +#include "dx8/d3d8.h" +#include "Utility/GameDetect.h" + +IDirect3D8*(WINAPI* g_origDirect3DCreate8)(UINT SDKVersion); + +template +T HookVtableFunction(T* functionPtr, T target) +{ + if (*functionPtr == target) + { + return nullptr; + } + + auto old = *functionPtr; + injector::WriteMemory(functionPtr, target, true); + + return old; +} + +static HRESULT(WINAPI* g_oldReset)(IDirect3DDevice8* self, D3DPRESENT_PARAMETERS* pPresentationParameters); + +HRESULT WINAPI ResetWrap(IDirect3DDevice8* self, D3DPRESENT_PARAMETERS* pPresentationParameters) +{ + pPresentationParameters->Windowed = TRUE; + pPresentationParameters->FullScreen_RefreshRateInHz = 0; + pPresentationParameters->BackBufferWidth = 0; + pPresentationParameters->BackBufferHeight = 0; + pPresentationParameters->Flags = 0; + pPresentationParameters->FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + + return g_oldReset(self, pPresentationParameters); +} + +static HRESULT(WINAPI* g_oldCreateDevice)(IDirect3D8* self, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice8** ppReturnedDeviceInterface); + +HRESULT WINAPI CreateDeviceWrap(IDirect3D8* self, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice8** ppReturnedDeviceInterface) +{ + pPresentationParameters->Windowed = TRUE; + pPresentationParameters->FullScreen_RefreshRateInHz = 0; + pPresentationParameters->BackBufferWidth = 0; + pPresentationParameters->BackBufferHeight = 0; + pPresentationParameters->Flags = 0; + pPresentationParameters->FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + + HRESULT hr = g_oldCreateDevice(self, Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface); + + if (*ppReturnedDeviceInterface) + { + auto old = HookVtableFunction(&(*ppReturnedDeviceInterface)->lpVtbl->Reset, ResetWrap); + g_oldReset = (old) ? old : g_oldReset; + } + + return hr; +} + +IDirect3D8* WINAPI Direct3DCreate8Wrap(UINT SDKVersion) +{ + auto d3d9 = g_origDirect3DCreate8(SDKVersion); + + auto old = HookVtableFunction(&d3d9->lpVtbl->CreateDevice, CreateDeviceWrap); + g_oldCreateDevice = (old) ? old : g_oldCreateDevice; + + return d3d9; +} + +void InitD3D8WindowHook() +{ + MH_Initialize(); + MH_CreateHookApi(L"d3d8.dll", "Direct3DCreate8", Direct3DCreate8Wrap, (void**)&g_origDirect3DCreate8); + MH_EnableHook(MH_ALL_HOOKS); +} + +extern linb::ini config; + +static InitFunction initFunc([]() +{ + if (GameDetect::currentGame == GameID::BG4) + return; + if (ToBool(config["General"]["Windowed"])) + { + InitD3D8WindowHook(); + } +}); +#pragma optimize("", on) \ No newline at end of file diff --git a/OpenParrot/src/Functions/WindowedDx9.cpp b/OpenParrot/src/Functions/WindowedDx9.cpp new file mode 100644 index 0000000..3df28cd --- /dev/null +++ b/OpenParrot/src/Functions/WindowedDx9.cpp @@ -0,0 +1,80 @@ +#define CINTERFACE +#include +#include "Utility/InitFunction.h" +#pragma optimize("", off) +#include "d3d9.h" +#include "Utility/GameDetect.h" + +IDirect3D9*(WINAPI* g_origDirect3DCreate9)(UINT SDKVersion); + +template +T HookVtableFunction(T* functionPtr, T target) +{ + if (*functionPtr == target) + { + return nullptr; + } + + auto old = *functionPtr; + injector::WriteMemory(functionPtr, target, true); + + return old; +} + +static HRESULT(WINAPI* g_oldReset)(IDirect3DDevice9* self, D3DPRESENT_PARAMETERS* pPresentationParameters); + +HRESULT WINAPI ResetWrap(IDirect3DDevice9* self, D3DPRESENT_PARAMETERS* pPresentationParameters) +{ + pPresentationParameters->Windowed = TRUE; + pPresentationParameters->FullScreen_RefreshRateInHz = 0; + + return g_oldReset(self, pPresentationParameters); +} + +static HRESULT(WINAPI* g_oldCreateDevice)(IDirect3D9* self, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface); + +HRESULT WINAPI CreateDeviceWrap(IDirect3D9* self, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface) +{ + pPresentationParameters->Windowed = TRUE; + pPresentationParameters->FullScreen_RefreshRateInHz = 0; + + HRESULT hr = g_oldCreateDevice(self, Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface); + + if (*ppReturnedDeviceInterface) + { + auto old = HookVtableFunction(&(*ppReturnedDeviceInterface)->lpVtbl->Reset, ResetWrap); + g_oldReset = (old) ? old : g_oldReset; + } + + return hr; +} + +IDirect3D9* WINAPI Direct3DCreate9Wrap(UINT SDKVersion) +{ + auto d3d9 = g_origDirect3DCreate9(SDKVersion); + + auto old = HookVtableFunction(&d3d9->lpVtbl->CreateDevice, CreateDeviceWrap); + g_oldCreateDevice = (old) ? old : g_oldCreateDevice; + + return d3d9; +} + +void InitD3D9WindowHook() +{ + MH_Initialize(); + MH_CreateHookApi(L"d3d9.dll", "Direct3DCreate9", Direct3DCreate9Wrap, (void**)&g_origDirect3DCreate9); + MH_EnableHook(MH_ALL_HOOKS); +} + +extern linb::ini config; + +static InitFunction initFunc([]() +{ + if (GameDetect::currentGame == GameID::BG4) + return; + if (ToBool(config["General"]["Windowed"])) + { + InitD3D9WindowHook(); + } +}); +#pragma optimize("", on) \ No newline at end of file diff --git a/OpenParrot/src/Functions/WindowedDxgi.cpp b/OpenParrot/src/Functions/WindowedDxgi.cpp new file mode 100644 index 0000000..9e35a4c --- /dev/null +++ b/OpenParrot/src/Functions/WindowedDxgi.cpp @@ -0,0 +1,251 @@ +#define CINTERFACE +#define D3D11_NO_HELPERS +#define INITGUID +#include +#ifdef _M_AMD64 +#include "Utility/InitFunction.h" +#pragma optimize("", off) +#include "d3d11.h" +#include "dxgi1_6.h" +#include "Utility/GameDetect.h" + +HRESULT(WINAPI* g_origCreateDXGIFactory)(REFIID, void**); + +template +inline T HookVtableFunction(T* functionPtr, T target) +{ + if (*functionPtr == target) + { + return nullptr; + } + + auto old = *functionPtr; + injector::WriteMemory(functionPtr, target, true); + + return old; +} + +HRESULT(WINAPI* g_oldCreateSwapChain)( + IDXGIFactory * This, + /* [annotation][in] */ + _In_ IUnknown *pDevice, + /* [annotation][in] */ + _In_ DXGI_SWAP_CHAIN_DESC *pDesc, + /* [annotation][out] */ + _COM_Outptr_ IDXGISwapChain **ppSwapChain); + +HRESULT(STDMETHODCALLTYPE *g_oldSetFullscreenState)( + IDXGISwapChain * This, + /* [in] */ BOOL Fullscreen, + /* [annotation][in] */ + _In_opt_ IDXGIOutput *pTarget); + +HRESULT STDMETHODCALLTYPE SetFullscreenStateWrap( + IDXGISwapChain * This, + /* [in] */ BOOL Fullscreen, + /* [annotation][in] */ + _In_opt_ IDXGIOutput *pTarget) +{ + return S_OK; +} + +HRESULT WINAPI CreateSwapChainWrap( + IDXGIFactory * This, + /* [annotation][in] */ + _In_ IUnknown *pDevice, + /* [annotation][in] */ + _In_ DXGI_SWAP_CHAIN_DESC *pDesc, + /* [annotation][out] */ + _COM_Outptr_ IDXGISwapChain **ppSwapChain) +{ + pDesc->Windowed = TRUE; + + HRESULT hr = g_oldCreateSwapChain(This, pDevice, pDesc, ppSwapChain); + + if (*ppSwapChain) + { + auto old = HookVtableFunction(&(*ppSwapChain)->lpVtbl->SetFullscreenState, SetFullscreenStateWrap); + g_oldSetFullscreenState = (old) ? old : g_oldSetFullscreenState; + } + + return hr; +} + +HRESULT(STDMETHODCALLTYPE *g_oldSetFullscreenState1)( + IDXGISwapChain1 * This, + /* [in] */ BOOL Fullscreen, + /* [annotation][in] */ + _In_opt_ IDXGIOutput *pTarget); + +HRESULT STDMETHODCALLTYPE SetFullscreenState1Wrap( + IDXGISwapChain1 * This, + /* [in] */ BOOL Fullscreen, + /* [annotation][in] */ + _In_opt_ IDXGIOutput *pTarget) +{ + return S_OK; +} + +HRESULT(STDMETHODCALLTYPE *g_oldCreateSwapChainForHwnd)( + IDXGIFactory2 * This, + /* [annotation][in] */ + _In_ IUnknown *pDevice, + /* [annotation][in] */ + _In_ HWND hWnd, + /* [annotation][in] */ + _In_ const DXGI_SWAP_CHAIN_DESC1 *pDesc, + /* [annotation][in] */ + _In_opt_ const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pFullscreenDesc, + /* [annotation][in] */ + _In_opt_ IDXGIOutput *pRestrictToOutput, + /* [annotation][out] */ + _COM_Outptr_ IDXGISwapChain1 **ppSwapChain); + +HRESULT STDMETHODCALLTYPE CreateSwapChainForHwndWrap( + IDXGIFactory2 * This, + /* [annotation][in] */ + _In_ IUnknown *pDevice, + /* [annotation][in] */ + _In_ HWND hWnd, + /* [annotation][in] */ + _In_ const DXGI_SWAP_CHAIN_DESC1 *pDesc, + /* [annotation][in] */ + _In_opt_ const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pFullscreenDesc, + /* [annotation][in] */ + _In_opt_ IDXGIOutput *pRestrictToOutput, + /* [annotation][out] */ + _COM_Outptr_ IDXGISwapChain1 **ppSwapChain) +{ + HRESULT hr = g_oldCreateSwapChainForHwnd(This, pDevice, hWnd, pDesc, NULL, pRestrictToOutput, ppSwapChain); + + if (*ppSwapChain) + { + auto old = HookVtableFunction(&(*ppSwapChain)->lpVtbl->SetFullscreenState, SetFullscreenState1Wrap); + g_oldSetFullscreenState1 = (old) ? old : g_oldSetFullscreenState1; + } + + return hr; +} + +HRESULT WINAPI CreateDXGIFactoryWrap(REFIID riid, _COM_Outptr_ void **ppFactory) +{ + HRESULT hr = g_origCreateDXGIFactory(riid, ppFactory); + + if (SUCCEEDED(hr)) + { + int factoryType = 0; + + if (IsEqualIID(riid, IID_IDXGIFactory1)) + { + factoryType = 1; + } + else if (IsEqualIID(riid, IID_IDXGIFactory2)) + { + factoryType = 2; + } + else if (IsEqualIID(riid, IID_IDXGIFactory2)) + { + factoryType = 2; + } + else if (IsEqualIID(riid, IID_IDXGIFactory3)) + { + factoryType = 3; + } + else if (IsEqualIID(riid, IID_IDXGIFactory4)) + { + factoryType = 4; + } + else if (IsEqualIID(riid, IID_IDXGIFactory5)) + { + factoryType = 5; + } + + if (factoryType >= 0) + { + IDXGIFactory* factory = (IDXGIFactory*)*ppFactory; + + auto old = HookVtableFunction(&factory->lpVtbl->CreateSwapChain, CreateSwapChainWrap); + g_oldCreateSwapChain = (old) ? old : g_oldCreateSwapChain; + } + + if (factoryType >= 2) + { + IDXGIFactory2* factory = (IDXGIFactory2*)*ppFactory; + + auto old = HookVtableFunction(&factory->lpVtbl->CreateSwapChainForHwnd, CreateSwapChainForHwndWrap); + g_oldCreateSwapChainForHwnd = (old) ? old : g_oldCreateSwapChainForHwnd; + } + } + + return hr; +} + +static HRESULT (WINAPI* g_origD3D11CreateDeviceAndSwapChain)( + _In_opt_ IDXGIAdapter *pAdapter, + D3D_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + _In_opt_ const D3D_FEATURE_LEVEL *pFeatureLevels, + UINT FeatureLevels, + UINT SDKVersion, + _In_opt_ const DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, + _Out_opt_ IDXGISwapChain **ppSwapChain, + _Out_opt_ ID3D11Device **ppDevice, + _Out_opt_ D3D_FEATURE_LEVEL *pFeatureLevel, + _Out_opt_ ID3D11DeviceContext **ppImmediateContext +); + +static HRESULT WINAPI D3D11CreateDeviceAndSwapChainWrap( + _In_opt_ IDXGIAdapter *pAdapter, + D3D_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + _In_opt_ const D3D_FEATURE_LEVEL *pFeatureLevels, + UINT FeatureLevels, + UINT SDKVersion, + _In_opt_ /*const*/ DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, + _Out_opt_ IDXGISwapChain **ppSwapChain, + _Out_opt_ ID3D11Device **ppDevice, + _Out_opt_ D3D_FEATURE_LEVEL *pFeatureLevel, + _Out_opt_ ID3D11DeviceContext **ppImmediateContext +) +{ + pSwapChainDesc->Windowed = TRUE; + + HRESULT hr = g_origD3D11CreateDeviceAndSwapChain(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, pSwapChainDesc, ppSwapChain, ppDevice, pFeatureLevel, ppImmediateContext); + + if (ppSwapChain) + { + auto old = HookVtableFunction(&(*ppSwapChain)->lpVtbl->SetFullscreenState, SetFullscreenStateWrap); + g_oldSetFullscreenState = (old) ? old : g_oldSetFullscreenState; + } + + return hr; +} + +void InitDXGIWindowHook() +{ + MH_Initialize(); + MH_CreateHookApi(L"dxgi.dll", + "CreateDXGIFactory", + CreateDXGIFactoryWrap, + (void**)&g_origCreateDXGIFactory); + + MH_CreateHookApi(L"d3d11.dll", + "D3D11CreateDeviceAndSwapChain", D3D11CreateDeviceAndSwapChainWrap, + (void**)&g_origD3D11CreateDeviceAndSwapChain); + MH_EnableHook(MH_ALL_HOOKS); +} + +extern linb::ini config; + +static InitFunction initFunc([]() +{ + if (GameDetect::currentGame == GameID::SchoolOfRagnarok) + return; + if (ToBool(config["General"]["Windowed"])) + { + InitDXGIWindowHook(); + } +}); +#endif \ No newline at end of file diff --git a/OpenParrot/src/StdInc.cpp b/OpenParrot/src/StdInc.cpp new file mode 100644 index 0000000..9f3e06c --- /dev/null +++ b/OpenParrot/src/StdInc.cpp @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/OpenParrot/src/StdInc.h b/OpenParrot/src/StdInc.h new file mode 100644 index 0000000..18e062f --- /dev/null +++ b/OpenParrot/src/StdInc.h @@ -0,0 +1,19 @@ +#pragma once + +// os includes +#define DEVMODE +#define WIN32_LEAN_AND_MEAN +#include + +#include + +// lib includes +#include + +// our includes +#include "injector/injector.hpp" +#include "injector/calling.hpp" +#include "Utility/Utils.h" +#include "ini_parser.hpp" + +extern linb::ini config; \ No newline at end of file diff --git a/OpenParrot/src/Utility/GameDetect.cpp b/OpenParrot/src/Utility/GameDetect.cpp new file mode 100644 index 0000000..d25caf4 --- /dev/null +++ b/OpenParrot/src/Utility/GameDetect.cpp @@ -0,0 +1,256 @@ +#include +#include "GameDetect.h" +#pragma optimize("", off) +bool GameDetect::isNesica = false; +NesicaKey GameDetect::NesicaKey; +X2Type GameDetect::X2Type = X2Type::None; + +void GameDetect::DetectCurrentGame() +{ + uint32_t crcResult = GetCRC32(GetModuleHandle(nullptr), 0x400); + NesicaKey = NesicaKey::None; + switch (crcResult) + { +#if _M_IX86 + case 0xcb4ab9d6: + currentGame = GameID::Nesica; + NesicaKey = NesicaKey::USF4; + isNesica = true; + break; + case 0x1d396bf2: + currentGame = GameID::Nesica; + NesicaKey = NesicaKey::MagicalBeat; + isNesica = true; + break; + case 0x6e67076f: + currentGame = GameID::Nesica; + NesicaKey = NesicaKey::BlazBlueCentralFriction; + isNesica = true; + break; + case 0xde1b6797: + case 0xaff18f9b: + currentGame = GameID::Nesica; + NesicaKey = NesicaKey::BlazBlueChronoPhantasma; + isNesica = true; + break; + case 0x05e53803: + currentGame = GameID::Nesica; + NesicaKey = NesicaKey::KOFXIIIClimax; + isNesica = true; + break; + case 0x949efa20: + currentGame = GameID::Nesica; + NesicaKey = NesicaKey::Persona4Arena; + isNesica = true; + break; + case 0x6b233485: + case 0xec97cef0: + currentGame = GameID::Nesica; + NesicaKey = NesicaKey::Persona4Ultimix; + isNesica = true; + break; + case 0xffe46764: // Akai Katana Shin + case 0x48362a6a: + currentGame = GameID::Nesica; + NesicaKey = NesicaKey::None; + isNesica = true; + break; + case 0x6DA10E60: + currentGame = GameID::FordRacing; + break; + case 0x2B41A7EA: + currentGame = GameID::SR3; + break; + case 0x47da80e5: // Spica Adventure + currentGame = GameID::SpicaAdventure; + X2Type = X2Type::Generic; + break; + //case 0xcdf01376: // Battle Fantasia + case 0xf9297ecb: // BlazBlue + currentGame = GameID::BlazBlue; + X2Type = X2Type::Generic; + break; + case 0xee568daa: // BlazBlue Continuum Shift II + currentGame = GameID::BlazBlueCS2; + X2Type = X2Type::Generic; + break; + case 0x4414288e: // BlazBlue Continuum Shift + currentGame = GameID::BlazBlueCS; + X2Type = X2Type::Generic; + break; + // case 0xea1984ff: // Deathsmiles II + case 0xe064ed48: // Giga Wing Generations + currentGame = GameID::GigaWingGenerations; + X2Type = X2Type::Generic; + break; + case 0xc336abc8: // King of Fighter 98 Unlimited Match + currentGame = GameID::KOF98UM; + X2Type = X2Type::Generic; + break; + case 0x1782f027: // KOF MIRA + currentGame = GameID::KOFMIRA; + X2Type = X2Type::Generic; + break; + case 0x15c690de: // KOF SkyStage + case 0xc0e5e71c: // KOF SkyStage + currentGame = GameID::KOFSkyStage; + X2Type = X2Type::Generic; + break; + case 0x9603cd6e: // KOF XII + currentGame = GameID::KOFXII; + X2Type = X2Type::Generic; + break; + case 0x3de0a15a: // KOF XIII + currentGame = GameID::KOFXIII; + X2Type = X2Type::Generic; + break; + case 0x777df862: // Power Instinct V + currentGame = GameID::PowerInstinctV; + X2Type = X2Type::Generic; + break; + case 0x4aafd08c: // Raiden III + currentGame = GameID::RaidenIII; + X2Type = X2Type::Generic; + break; + case 0x6c2d2657: // Senko No Ronde Duo + currentGame = GameID::SenkoNoRondeDuo; + X2Type = X2Type::Generic; + break; + case 0xb0e19321: // Shigami 3 + currentGame = GameID::Shigami3; + X2Type = X2Type::Generic; + break; + case 0xddd19e50: // Street Fighter IV + currentGame = GameID::SF4; + X2Type = X2Type::Generic; + break; + case 0x5a5526b2: // Street Fighter IV Arcade Edition + currentGame = GameID::SSFAE; + X2Type = X2Type::Generic; + break; + case 0x282de00f: // Street Fighter IV Arcade Edition EXP + currentGame = GameID::SSFAE_EXP; + X2Type = X2Type::Generic; + break; + case 0xef843fd1: // Super Street Fighter IV Arcade Edition Ver. 2012 + currentGame = GameID::SSFAE2012; + X2Type = X2Type::Generic; + break; + case 0xcb2c2568: // Trouble Witches + currentGame = GameID::TroubleWitches; + X2Type = X2Type::Generic; + break; + case 0xf795d548: // Tetris The Grand Master 3 Terror Instinct + currentGame = GameID::TetrisGM3; + X2Type = X2Type::Generic; + break; + case 0xdca0c880: // Chaos Breaker + currentGame = GameID::ChaosBreaker; + X2Type = X2Type::Generic; + break; + case 0xf2d38452: // Taisen Hot Gimmick 5 + currentGame = GameID::TaisenHotGimmick5; + X2Type = X2Type::Generic; + break; + case 0x9646805d: // Samurai Spirits Sen + currentGame = GameID::SamuraiSpiritsSen; + X2Type = X2Type::Generic; + break; + case 0x185fd019: // Wacky Races + currentGame = GameID::WackyRaces; + X2Type = X2Type::Generic; + break; + case 0x1f2f9497: // Chase HQ 2 + currentGame = GameID::ChaseHq2; + X2Type = X2Type::Generic; + break; + case 0x45121869: // Virtua R-Limit + currentGame = GameID::VirtuaRLimit; + X2Type = X2Type::VRL; + break; + case 0x7b43b0dc: // Raiden IV + currentGame = GameID::RaidenIV; + X2Type = X2Type::Raiden4; + break; + case 0x14eb3c8a: // Battle Gear 4 Tuned Professional + currentGame = GameID::BG4; + X2Type = X2Type::BG4; + break; + case 0xf5d90f01: // Music GunGun 2 + currentGame = GameID::TypeXGeneric; + break; + case 0xabcebc43: // Lupin 3 + currentGame = GameID::TypeXGeneric; + X2Type = X2Type::Lupin3; + break; +#endif + default: + auto moduleBase = (uintptr_t)GetModuleHandle(nullptr); + // SPECIAL BYTE PATTERNS (IF PE CHANGES DUE TO DYNAMIC IMAGEBASE) +#if _M_IX86 + if (*(uint32_t*)(moduleBase + 0x30E838) == 0x6A50016A) + { + currentGame = GameID::MachStorm; + break; + } +#else + // X64 + // School of Ragnarok + if (*(uint32_t *)(moduleBase + 0x396E) == 0x2180B841) + { + currentGame = GameID::SchoolOfRagnarok; + isNesica = true; + } +#endif + +#ifdef _DEBUG + info(true, "%08x not implemented", crcResult); +#endif + break; + } +} +bool GameDetect::IsNesicaGame() +{ + return isNesica; +} + +bool GameDetect::IsTypeX() +{ + switch (GameDetect::currentGame) + { + case GameID::TypeXGeneric: + case GameID::SpicaAdventure: + case GameID::BlazBlue: + case GameID::BlazBlueCS: + case GameID::BlazBlueCS2: + case GameID::GigaWingGenerations: + case GameID::KOF98UM: + case GameID::KOFMIRA: + case GameID::KOFSkyStage: + case GameID::KOFXII: + case GameID::KOFXIII: + case GameID::PowerInstinctV: + case GameID::RaidenIII: + case GameID::SenkoNoRondeDuo: + case GameID::Shigami3: + case GameID::SF4: + case GameID::SSFAE: + case GameID::SSFAE_EXP: + case GameID::SSFAE2012: + case GameID::TroubleWitches: + case GameID::TetrisGM3: + case GameID::ChaosBreaker: + case GameID::TaisenHotGimmick5: + case GameID::SamuraiSpiritsSen: + case GameID::WackyRaces: + case GameID::ChaseHq2: + case GameID::BG4: + case GameID::RaidenIV: + case GameID::VirtuaRLimit: + return true; + default: + return false; + } +} +GameID GameDetect::currentGame; +#pragma optimize("", on) \ No newline at end of file diff --git a/OpenParrot/src/Utility/GameDetect.h b/OpenParrot/src/Utility/GameDetect.h new file mode 100644 index 0000000..1e9f3ed --- /dev/null +++ b/OpenParrot/src/Utility/GameDetect.h @@ -0,0 +1,19 @@ +#include "GameID.h" +#include "Functions/Nesica_Libs/CryptoPipe.h" +#include "Functions/Types.h" + +class GameDetect +{ +public: + static GameID currentGame; + static void DetectCurrentGame(); + static X2Type X2Type; + static bool IsTypeX(); + static bool IsNesicaGame(); + static NesicaKey NesicaKey; + static std::string GetGameName(); + static std::string GameDetect::GetGameName(GameID game); + +private: + static bool isNesica; +}; diff --git a/OpenParrot/src/Utility/GameID.h b/OpenParrot/src/Utility/GameID.h new file mode 100644 index 0000000..febdbd4 --- /dev/null +++ b/OpenParrot/src/Utility/GameID.h @@ -0,0 +1,41 @@ +#pragma once + +enum class GameID +{ + Global, + FordRacing, + SR3, + VRL, + MachStorm, + Nesica, + TypeXGeneric, + SpicaAdventure, + BlazBlue, + BlazBlueCS, + BlazBlueCS2, + GigaWingGenerations, + KOF98UM, + KOFMIRA, + KOFSkyStage, + KOFXII, + KOFXIII, + PowerInstinctV, + RaidenIII, + SenkoNoRondeDuo, + Shigami3, + SF4, + SSFAE, + SSFAE_EXP, + SSFAE2012, + TroubleWitches, + TetrisGM3, + ChaosBreaker, + TaisenHotGimmick5, + SamuraiSpiritsSen, + WackyRaces, + ChaseHq2, + BG4, + RaidenIV, + VirtuaRLimit, + SchoolOfRagnarok, +}; \ No newline at end of file diff --git a/OpenParrot/src/Utility/Hooking.Patterns.cpp b/OpenParrot/src/Utility/Hooking.Patterns.cpp new file mode 100644 index 0000000..405eeba --- /dev/null +++ b/OpenParrot/src/Utility/Hooking.Patterns.cpp @@ -0,0 +1,350 @@ +/* + * This file is part of the CitizenFX project - http://citizen.re/ + * + * See LICENSE and MENTIONS in the root of the source tree for information + * regarding licensing. + */ + +#include "Hooking.Patterns.h" + +#define WIN32_LEAN_AND_MEAN + +#include +#include + +#if PATTERNS_USE_HINTS +#include +#endif + +#if PATTERNS_USE_HINTS + +// from boost someplace +template +struct basic_fnv_1 +{ + std::uint64_t operator()(const char *text) const + { + std::uint64_t hash = OffsetBasis; + + while (*text != 0) + { + hash *= FnvPrime; + hash ^= *(uint8_t *)text; + + ++text; + } + + return hash; + } +}; + +const std::uint64_t fnv_prime = 1099511628211u; +const std::uint64_t fnv_offset_basis = 14695981039346656037u; + +typedef basic_fnv_1 fnv_1; + +#endif + +namespace hook +{ + ptrdiff_t baseAddressDifference; + + // sets the base to the process main base + void set_base() + { + set_base((uintptr_t)GetModuleHandle(nullptr)); + } + + +#if PATTERNS_USE_HINTS +static std::multimap g_hints; +#endif + +static void TransformPattern(const char *pattern, std::vector& data, std::vector& mask) +{ + auto tol = [](char ch) -> uint8_t + { + if (ch >= 'A' && ch <= 'F') return uint8_t(ch - 'A' + 10); + if (ch >= 'a' && ch <= 'f') return uint8_t(ch - 'a' + 10); + return uint8_t(ch - '0'); + }; + + auto is_digit = [](char ch) -> bool + { + return (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f') || (ch >= '0' && ch <= '9'); + }; + + char temp_string[2]{ 0, 0 }; + + data.clear(); + mask.clear(); + + if (!pattern) + { + return; + } + + const char *patit = pattern; + const char *patend = (pattern + strlen(pattern) + 1); + + while (patit != patend) + { + char ch = *patit; + + if (ch == ' ' || ch == 0) + { + if (!temp_string[0] && !temp_string[1]) //Continous delimiter + { + + } + else if (temp_string[0] == '?' && (temp_string[1] == '?' || temp_string[1] == 0)) //?? + { + data.push_back(0); + mask.push_back(0u); + } + else if (temp_string[0] == '?' && is_digit(temp_string[1])) //?x + { + data.push_back(tol(temp_string[1])); + mask.push_back(0x0Fu); + } + else if (temp_string[1] == '?' && is_digit(temp_string[0])) //x? + { + data.push_back(tol(temp_string[0]) << 4); + mask.push_back(0xF0u); + } + else if (is_digit(temp_string[0]) && is_digit(temp_string[1])) //xx + { + data.push_back((tol(temp_string[0]) << 4) | tol(temp_string[1])); + mask.push_back(0xFFu); + } + else + { + data.clear(); + mask.clear(); + return; + } + + temp_string[0] = 0; + temp_string[1] = 0; + } + else + { + if (temp_string[0] == 0) + { + temp_string[0] = ch; + } + else if (temp_string[1] == 0) + { + temp_string[1] = ch; + } + else + { + data.clear(); + mask.clear(); + return; + } + } + + ++patit; + } +} + +class executable_meta +{ +private: + uintptr_t m_begin; + uintptr_t m_end; + +public: + template + TReturn* getRVA(TOffset rva) + { + return (TReturn*)(m_begin + rva); + } + + explicit executable_meta(void* module) + : m_begin((uintptr_t)module), m_end(0) + { + static auto getSection = [](const PIMAGE_NT_HEADERS nt_headers, unsigned section) -> PIMAGE_SECTION_HEADER + { + return reinterpret_cast( + (UCHAR*)nt_headers->OptionalHeader.DataDirectory + + nt_headers->OptionalHeader.NumberOfRvaAndSizes * sizeof(IMAGE_DATA_DIRECTORY) + + section * sizeof(IMAGE_SECTION_HEADER)); + }; + + PIMAGE_DOS_HEADER dosHeader = getRVA(0); + PIMAGE_NT_HEADERS ntHeader = getRVA(dosHeader->e_lfanew); + + for (int i = 0; i < ntHeader->FileHeader.NumberOfSections; i++) + { + auto sec = getSection(ntHeader, i); + auto secSize = sec->SizeOfRawData != 0 ? sec->SizeOfRawData : sec->Misc.VirtualSize; + //if (sec->Characteristics & IMAGE_SCN_MEM_EXECUTE) + m_end = m_begin + sec->VirtualAddress + secSize; + + if ((i == ntHeader->FileHeader.NumberOfSections - 1) && m_end == 0) + m_end = m_begin + sec->PointerToRawData + secSize; + } + } + + executable_meta(uintptr_t begin, uintptr_t end) + : m_begin(begin), m_end(end) + { + } + + inline uintptr_t begin() const { return m_begin; } + inline uintptr_t end() const { return m_end; } +}; + +void pattern::Initialize(const char* pattern) +{ + // get the hash for the base pattern +#if PATTERNS_USE_HINTS + m_hash = fnv_1()(pattern); +#endif + + // transform the base pattern from IDA format to canonical format + TransformPattern(pattern, m_bytes, m_mask); + + m_size = m_mask.size(); + +#if PATTERNS_USE_HINTS + // if there's hints, try those first + if (m_module == GetModuleHandle(nullptr)) + { + auto range = g_hints.equal_range(m_hash); + + if (range.first != range.second) + { + std::for_each(range.first, range.second, [&] (const std::pair& hint) + { + ConsiderMatch(hint.second); + }); + + // if the hints succeeded, we don't need to do anything more + if (!m_matches.empty()) + { + m_matched = true; + return; + } + } + } +#endif +} + +void pattern::EnsureMatches(uint32_t maxCount) +{ + if (m_matched) + return; + + if (!m_rangeStart && !m_rangeEnd && !m_module) + return; + + // scan the executable for code + executable_meta executable = m_rangeStart != 0 && m_rangeEnd != 0 ? executable_meta(m_rangeStart, m_rangeEnd) : executable_meta(m_module); + + auto matchSuccess = [&] (uintptr_t address) + { +#if PATTERNS_USE_HINTS + g_hints.emplace(m_hash, address); +#else + (void)address; +#endif + + return (m_matches.size() == maxCount); + }; + + ptrdiff_t BadCharacter[256]; + + std::ptrdiff_t index; + + const std::uint8_t *pbytes = m_bytes.data(); + const std::uint8_t *pmask = m_mask.data(); + + for (std::uint32_t bc = 0; bc < 256; ++bc) + { + for (index = m_size - 1; index >= 0; --index) + { + if ((pbytes[index] & pmask[index]) == (bc & pmask[index])) + { + break; + } + } + + BadCharacter[bc] = index; + } + + __try + { + for (uintptr_t i = executable.begin(), end = executable.end() - m_size; i <= end;) + { + uint8_t* ptr = reinterpret_cast(i); + + for (index = m_size - 1; index >= 0; --index) + { + if ((pbytes[index] & pmask[index]) != (ptr[index] & pmask[index])) + { + break; + } + } + + if (index == -1) + { + m_matches.emplace_back(ptr); + + if (matchSuccess(i)) + { + break; + } + + i += m_size; + } + else + { + i += max(index - BadCharacter[ptr[index]], 1); + } + } + } + __except ((GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) + { } + m_matched = true; +} + +bool pattern::ConsiderMatch(uintptr_t offset) +{ + const uint8_t* pattern = m_bytes.data(); + const uint8_t* mask = m_mask.data(); + + char* ptr = reinterpret_cast(offset); + + for (size_t i = 0; i < m_size; i++) + { + if ((pattern[i] & mask[i]) != (ptr[i] & mask[i])) + { + return false; + } + } + + m_matches.emplace_back(ptr); + + return true; +} + +#if PATTERNS_USE_HINTS +void pattern::hint(uint64_t hash, uintptr_t address) +{ + auto range = g_hints.equal_range(hash); + + for (auto it = range.first; it != range.second; it++) + { + if (it->second == address) + { + return; + } + } + + g_hints.emplace(hash, address); +} +#endif +} diff --git a/OpenParrot/src/Utility/Hooking.Patterns.h b/OpenParrot/src/Utility/Hooking.Patterns.h new file mode 100644 index 0000000..e082d33 --- /dev/null +++ b/OpenParrot/src/Utility/Hooking.Patterns.h @@ -0,0 +1,242 @@ +/* + * This file is part of the CitizenFX project - http://citizen.re/ + * + * See LICENSE and MENTIONS in the root of the source tree for information + * regarding licensing. + */ + +#pragma once + +#define PATTERNS_USE_HINTS 0 + +#include +#include + +namespace hook +{ + extern ptrdiff_t baseAddressDifference; + + // sets the base address difference based on an obtained pointer + inline void set_base(uintptr_t address) + { +#ifdef _M_IX86 + uintptr_t addressDiff = (address - 0x400000); +#elif defined(_M_AMD64) + uintptr_t addressDiff = (address - 0x140000000); +#endif + + // pointer-style cast to ensure unsigned overflow ends up copied directly into a signed value + baseAddressDifference = *(ptrdiff_t*)&addressDiff; + } + + // sets the base to the process main base + void set_base(); + + template + inline T* getRVA(uintptr_t rva) + { + set_base(); +#ifdef _M_IX86 + return (T*)(baseAddressDifference + 0x400000 + rva); +#elif defined(_M_AMD64) + return (T*)(baseAddressDifference + 0x140000000 + rva); +#endif + } + + class pattern_match + { + private: + void* m_pointer; + + public: + inline pattern_match(void* pointer) + : m_pointer(pointer) + { + } + + template + T* get(ptrdiff_t offset = 0) const + { + char* ptr = reinterpret_cast(m_pointer); + return reinterpret_cast(ptr + offset); + } + }; + + class pattern + { + private: + std::vector m_bytes; + std::vector m_mask; + +#if PATTERNS_USE_HINTS + uint64_t m_hash; +#endif + + size_t m_size; + + std::vector m_matches; + + bool m_matched; + + union + { + void* m_module; + struct + { + uintptr_t m_rangeStart; + uintptr_t m_rangeEnd; + }; + }; + + protected: + inline pattern(void* module) + : m_module(module), m_rangeEnd(0), m_matched(false) + { + } + + inline pattern(uintptr_t begin, uintptr_t end) + : m_rangeStart(begin), m_rangeEnd(end), m_matched(false) + { + } + + void Initialize(const char* pattern); + + private: + bool ConsiderMatch(uintptr_t offset); + + void EnsureMatches(uint32_t maxCount); + + inline const pattern_match& _get_internal(size_t index) + { + return m_matches[index]; + } + + public: + pattern() + : m_matched(true) + { + } + + pattern(const char *pattern) + : pattern(getRVA(0)) + { + Initialize(pattern); + } + + pattern(std::string& pattern) + : pattern(getRVA(0)) + { + Initialize(pattern.c_str()); + } + + inline pattern& count(uint32_t expected) + { + EnsureMatches(expected); + assert(m_matches.size() == expected); + return *this; + } + + inline pattern& count_hint(uint32_t expected) + { + EnsureMatches(expected); + return *this; + } + + inline pattern& clear(void* module = nullptr) + { + if (module) + m_module = module; + m_matches.clear(); + m_matched = false; + return *this; + } + + inline size_t size() + { + EnsureMatches(UINT32_MAX); + return m_matches.size(); + } + + inline bool empty() + { + return size() == 0; + } + + inline const pattern_match& get(size_t index) + { + EnsureMatches(UINT32_MAX); + return _get_internal(index); + } + + inline const pattern_match& get_one() + { + return count(1)._get_internal(0); + } + + template + inline auto get_first(ptrdiff_t offset = 0) + { + return get_one().get(offset); + } + + template + pattern &for_each_result(Fn Pr) + { + EnsureMatches(UINT32_MAX); + + for (auto &result : this->m_matches) + { + Pr(result); + } + + return *this; + } + + public: +#if PATTERNS_USE_HINTS + // define a hint + static void hint(uint64_t hash, uintptr_t address); +#endif + }; + + class module_pattern + : public pattern + { + public: + module_pattern(void* module, const char *pattern) + : pattern(module) + { + Initialize(pattern); + } + + module_pattern(void* module, std::string& pattern) + : pattern(module) + { + Initialize(pattern.c_str()); + } + }; + + class range_pattern + : public pattern + { + public: + range_pattern(uintptr_t begin, uintptr_t end, const char *pattern) + : pattern(begin, end) + { + Initialize(pattern); + } + + range_pattern(uintptr_t begin, uintptr_t end, std::string& pattern) + : pattern(begin, end) + { + Initialize(pattern.c_str()); + } + }; + + + template + auto get_pattern(const char *pattern_string, ptrdiff_t offset = 0) + { + return pattern(pattern_string).get_first(offset); + } +} diff --git a/OpenParrot/src/Utility/InitFunction.cpp b/OpenParrot/src/Utility/InitFunction.cpp new file mode 100644 index 0000000..6b98365 --- /dev/null +++ b/OpenParrot/src/Utility/InitFunction.cpp @@ -0,0 +1,28 @@ +#include +#include "InitFunction.h" + +#include + +std::forward_list* g_initFunctions; + +InitFunction::InitFunction(void(*callback)(), GameID gameID) + : callback(callback), game(gameID) +{ + if (!g_initFunctions) + { + g_initFunctions = new std::forward_list(); + } + + g_initFunctions->push_front(this); +} + +void InitFunction::RunFunctions(GameID game) +{ + for (auto& it : *g_initFunctions) + { + if (it->game == game) + { + it->callback(); + } + } +} \ No newline at end of file diff --git a/OpenParrot/src/Utility/InitFunction.h b/OpenParrot/src/Utility/InitFunction.h new file mode 100644 index 0000000..ef44cda --- /dev/null +++ b/OpenParrot/src/Utility/InitFunction.h @@ -0,0 +1,16 @@ +#pragma once + +#include "GameID.h" + +class InitFunction +{ +public: + InitFunction(void(*callback)(), GameID game = GameID::Global); + + static void RunFunctions(GameID game); + +private: + void(*callback)(); + + GameID game; +}; diff --git a/OpenParrot/src/Utility/Utils.cpp b/OpenParrot/src/Utility/Utils.cpp new file mode 100644 index 0000000..c6b40dc --- /dev/null +++ b/OpenParrot/src/Utility/Utils.cpp @@ -0,0 +1,160 @@ +#include +#include +#include +#include +#include + +#define UPDC32(octet,crc) (crc_32_tab[((crc) ^ ((BYTE)octet)) & 0xff] ^ ((crc) >> 8)) + +uint32_t GetCRC32(const void* pData, int length) +{ + uint32_t _crc = 0xFFFFFFFF; + unsigned char* pCur = (unsigned char*)pData; + int remaining = length; + for (; remaining--; ++pCur) + _crc = (_crc >> 8) ^ kCrc32Table[(_crc ^ *pCur) & 0xff]; + + return _crc ^ 0xFFFFFFFF; +} +#ifdef _DEBUG +void info(bool unused, const char* format, ...) +{ + va_list args; + char buffer[1024]; + + va_start(args, format); + int len = _vsnprintf(buffer, sizeof(buffer), format, args); + va_end(args); + + buffer[len] = '\n'; + buffer[len + 1] = '\0'; + + OutputDebugStringA(buffer); +} +#endif +int strcmp(const char* str1, const char* str2, bool csensitive) +{ + return (csensitive ? ::strcmp(str1, str2) : ::_stricmp(str1, str2)); +} + +int Compare(const std::string& str1, const std::string& str2, bool case_sensitive) +{ + if (str1.length() == str2.length()) + return strcmp(str1.c_str(), str2.c_str(), case_sensitive); + + return (str1.length() < str2.length() ? -1 : 1); +} + +bool ToBool(const std::string& s) +{ + if (s.empty()) + { + return false; + } + + if (s.size() == 1) return s.front() != '0'; + return !!Compare(s, "false", false); +} + +bool IpToByte(const char* ip, char bytes[4]) +{ + return (sscanf(ip, "%hhu.%hhu.%hhu.%hhu", &bytes[0], &bytes[1], &bytes[2], &bytes[3]) == 4); +} + +DWORD crc32buf(unsigned char *buf, size_t len) +{ + register DWORD oldcrc32; + + oldcrc32 = 0xFFFFFFFF; + + for (; len; --len, ++buf) + { + oldcrc32 = UPDC32(*buf, oldcrc32); + } + + return ~oldcrc32; +} + +void GetDesktopResolution(int& x, int& y) +{ + RECT desktop; + const HWND hDesktop = GetDesktopWindow(); + GetWindowRect(hDesktop, &desktop); + x = desktop.right; + y = desktop.bottom; +} + +#define BUFFER_COUNT 8 +#define BUFFER_LENGTH 32768 + +const char* va(const char* string, ...) +{ + static thread_local int currentBuffer; + static thread_local std::vector buffer; + + if (!buffer.size()) + { + buffer.resize(BUFFER_COUNT * BUFFER_LENGTH); + } + + int thisBuffer = currentBuffer; + + va_list ap; + va_start(ap, string); + int length = vsnprintf(&buffer[thisBuffer * BUFFER_LENGTH], BUFFER_LENGTH, string, ap); + va_end(ap); + + if (length >= BUFFER_LENGTH) + { + //GlobalError("Attempted to overrun string in call to va()!"); + return ""; + } + + buffer[(thisBuffer * BUFFER_LENGTH) + BUFFER_LENGTH - 1] = '\0'; + + currentBuffer = (currentBuffer + 1) % BUFFER_COUNT; + + return &buffer[thisBuffer * BUFFER_LENGTH]; +} + +const wchar_t* va(const wchar_t* string, ...) +{ + static thread_local int currentBuffer; + static thread_local std::vector buffer; + + if (!buffer.size()) + { + buffer.resize(BUFFER_COUNT * BUFFER_LENGTH); + } + + int thisBuffer = currentBuffer; + + va_list ap; + va_start(ap, string); + int length = vswprintf(&buffer[thisBuffer * BUFFER_LENGTH], BUFFER_LENGTH, string, ap); + va_end(ap); + + if (length >= BUFFER_LENGTH) + { + //GlobalError("Attempted to overrun string in call to va()!"); + return L""; + } + + buffer[(thisBuffer * BUFFER_LENGTH) + BUFFER_LENGTH - 1] = '\0'; + + currentBuffer = (currentBuffer + 1) % BUFFER_COUNT; + + return &buffer[thisBuffer * BUFFER_LENGTH]; +} + +static std::wstring_convert> m_converter; + +std::string ToNarrow(const std::wstring& wide) +{ + return m_converter.to_bytes(wide); +} + +std::wstring ToWide(const std::string& narrow) +{ + return m_converter.from_bytes(narrow); +} \ No newline at end of file diff --git a/OpenParrot/src/Utility/Utils.h b/OpenParrot/src/Utility/Utils.h new file mode 100644 index 0000000..d46c200 --- /dev/null +++ b/OpenParrot/src/Utility/Utils.h @@ -0,0 +1,149 @@ +#pragma once + +#include +#ifdef _DEBUG +void info(bool unused, const char* format, ...); +#endif +#include + +inline void safeJMP(injector::memory_pointer_tr at, injector::memory_pointer_raw dest, bool vp = true) +{ + if (!at.is_null()) + { +#ifdef _M_IX86 + injector::MakeJMP(at, dest, vp); +#else + MH_Initialize(); + MH_CreateHook((void*)at.as_int(), (void*)dest.as_int(), nullptr); + MH_EnableHook((void*)at.as_int()); +#endif + } +} + +uint32_t GetCRC32(const void* pData, int length); + +DWORD crc32buf(unsigned char *buf, size_t len); + +void GetDesktopResolution(int& x, int& y); + +static const unsigned int kCrc32Table[256] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, +}; // kCrc32Table + +static DWORD crc_32_tab[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; + +bool ToBool(const std::string& s); + +bool IpToByte(const char* ip, char bytes[4]); + +const char* va(const char* string, ...); +const wchar_t* va(const wchar_t* string, ...); + +std::wstring ToWide(const std::string& narrow); +std::string ToNarrow(const std::wstring& wide); \ No newline at end of file diff --git a/OpenParrot/src/dllmain.cpp b/OpenParrot/src/dllmain.cpp new file mode 100644 index 0000000..1b24616 --- /dev/null +++ b/OpenParrot/src/dllmain.cpp @@ -0,0 +1,114 @@ +#include +#include +#include +linb::ini config; +#include + +#pragma optimize("", off) + +static void RunMain(); + +static BYTE originalCode[20]; +extern "C" PBYTE originalEP = 0; + +void Main_UnprotectModule(HMODULE hModule) +{ + PIMAGE_DOS_HEADER header = (PIMAGE_DOS_HEADER)hModule; + PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)hModule + header->e_lfanew); + + // unprotect the entire PE image + SIZE_T size = ntHeader->OptionalHeader.SizeOfImage; + DWORD oldProtect; + VirtualProtect((LPVOID)hModule, size, PAGE_EXECUTE_READWRITE, &oldProtect); +} + +#ifdef _M_AMD64 +extern "C" void Main_DoResume(); +#endif + +static void Main_DoInit() +{ + RunMain(); + + memcpy(originalEP, &originalCode, sizeof(originalCode)); + +#if _M_IX86 + __asm jmp originalEP +#elif defined(_M_AMD64) + Main_DoResume(); +#endif +} + +static void Main_SetSafeInit() +{ + // find the entry point for the executable process, set page access, and replace the EP + HMODULE hModule = GetModuleHandle(NULL); + + if (hModule) + { + PIMAGE_DOS_HEADER header = (PIMAGE_DOS_HEADER)hModule; + PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)hModule + header->e_lfanew); + + Main_UnprotectModule(hModule); + + // back up original code + PBYTE ep = (PBYTE)((DWORD_PTR)hModule + ntHeader->OptionalHeader.AddressOfEntryPoint); + memcpy(originalCode, ep, sizeof(originalCode)); + +#ifdef _M_IX86 + // patch to call our EP + int newEP = (int)Main_DoInit - ((int)ep + 5); + ep[0] = 0xE9; // for some reason this doesn't work properly when run under the debugger + memcpy(&ep[1], &newEP, 4); +#elif defined(_M_AMD64) + ep[0] = 0x48; + ep[1] = 0xB8; + *(uint64_t *)(ep + 2) = (uint64_t)Main_DoInit; + ep[10] = 0xFF; + ep[11] = 0xE0; +#endif + + originalEP = ep; + } +} + +static void RunMain() +{ + static bool initialized; + + if (initialized) + { + return; + } + + initialized = true; + + if (!config.load_file("teknoparrot.ini")) + { + //MessageBoxA(NULL, V("Failed to open config.ini"), V("TeknoParrot",) MB_OK); + //std::_Exit(0); + } + + GameDetect::DetectCurrentGame(); + InitFunction::RunFunctions(GameID::Global); + InitFunction::RunFunctions(GameDetect::currentGame); +} + +BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) +{ + if (ul_reason_for_call == DLL_PROCESS_ATTACH) + { +#ifdef DEVMODE + RunMain(); +#else + Main_SetSafeInit(); +#endif + } + return TRUE; // false +} + +extern "C" __declspec(dllexport) void InitializeASI() +{ + RunMain(); +} +#pragma optimize("", on) \ No newline at end of file diff --git a/OpenParrot/src/win64init.asm b/OpenParrot/src/win64init.asm new file mode 100644 index 0000000..a57bee5 --- /dev/null +++ b/OpenParrot/src/win64init.asm @@ -0,0 +1,17 @@ +_TEXT SEGMENT + +EXTERN originalEP:qword + +PUBLIC Main_DoResume +Main_DoResume PROC + +and rsp, 0FFFFFFFFFFFFFFF0h +mov rax, 0FFFFFFFFFFFFFFFFh +push rax + +mov rax, qword ptr [originalEP] +jmp rax + +Main_DoResume ENDP +_TEXT ENDS +END \ No newline at end of file diff --git a/OpenParrotLoader/premake5.lua b/OpenParrotLoader/premake5.lua new file mode 100644 index 0000000..bda7f31 --- /dev/null +++ b/OpenParrotLoader/premake5.lua @@ -0,0 +1,22 @@ +project "OpenParrotLoader" + targetname "OpenParrotLoader" + language "C++" + kind "ConsoleApp" + + characterset "MBCS" + + files + { + "src/**.cpp", "src/**.h", + "deps_inc/**.cpp", "deps_inc/**.h" + } + + includedirs { "src", "deps_inc" } + libdirs { } + + links { } + + postbuildcommands { } + + filter "platforms:x64" + targetsuffix "64" \ No newline at end of file diff --git a/OpenParrotLoader/src/PE.cpp b/OpenParrotLoader/src/PE.cpp new file mode 100644 index 0000000..c06d51c --- /dev/null +++ b/OpenParrotLoader/src/PE.cpp @@ -0,0 +1,57 @@ +#include "PE.H" +DWORD PEAlign(DWORD dwTarNum, DWORD dwAlignTo); +PEStruct getPEFileInformation(char *filename) +{ + HANDLE hFile; + PEStruct pRetnStruct; + pRetnStruct.fileSize = 0; + DWORD dwBytesRead; + hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (!hFile) + return pRetnStruct; + + pRetnStruct.fileSize = GetFileSize(hFile, 0); + if (!pRetnStruct.fileSize) + return pRetnStruct; + pRetnStruct.fileImage = malloc(pRetnStruct.fileSize); + if (!pRetnStruct.fileImage) + return pRetnStruct; + ReadFile(hFile, pRetnStruct.fileImage, pRetnStruct.fileSize, &dwBytesRead, NULL); + CloseHandle(hFile); + if (!dwBytesRead) + return pRetnStruct; + //copy portions to relevant sections + CopyMemory(&pRetnStruct.image_dos_header, pRetnStruct.fileImage, sizeof(IMAGE_DOS_HEADER)); + CopyMemory(&pRetnStruct.image_nt_headers, + ((BYTE *)pRetnStruct.fileImage + pRetnStruct.image_dos_header.e_lfanew), sizeof(IMAGE_NT_HEADERS)); + //address of first section + pRetnStruct.dwRO_first_section = pRetnStruct.image_dos_header.e_lfanew + sizeof(IMAGE_NT_HEADERS); + pRetnStruct.numOfSecs = pRetnStruct.image_nt_headers.FileHeader.NumberOfSections; + + CopyMemory(&pRetnStruct.image_section_header, ((BYTE *)pRetnStruct.fileImage + pRetnStruct.dwRO_first_section), + pRetnStruct.numOfSecs*sizeof(IMAGE_SECTION_HEADER)); + //now to fill in individual sections (.text .data) + for (int i = 0; i < pRetnStruct.numOfSecs; i++) + { + pRetnStruct.image_section[i] = (char *)malloc(PEAlign(pRetnStruct.image_section_header[i].SizeOfRawData, + pRetnStruct.image_nt_headers.OptionalHeader.FileAlignment)); + CopyMemory(pRetnStruct.image_section[i], ((BYTE *)pRetnStruct.fileImage + pRetnStruct.image_section_header[i].PointerToRawData), + pRetnStruct.image_section_header[i].SizeOfRawData); + } + return pRetnStruct; +} + +//googled function to correct file alignement in PE header. +//Just makes sure the outputted number will align correctly with the rest of the data. +DWORD PEAlign(DWORD dwTarNum, DWORD dwAlignTo) +{ + DWORD dwtemp; + dwtemp = dwTarNum / dwAlignTo; + if ((dwTarNum%dwAlignTo) != 0) + { + dwtemp++; + } + dwtemp = dwtemp*dwAlignTo; + return(dwtemp); +} \ No newline at end of file diff --git a/OpenParrotLoader/src/PE.h b/OpenParrotLoader/src/PE.h new file mode 100644 index 0000000..978bb71 --- /dev/null +++ b/OpenParrotLoader/src/PE.h @@ -0,0 +1,18 @@ +#include +#include +#define MAX_SECTION_NUM 20 + +typedef struct _PEStruct +{ + DWORD dwRO_first_section; + IMAGE_DOS_HEADER image_dos_header; + char *reservedheader; + IMAGE_NT_HEADERS image_nt_headers; + IMAGE_SECTION_HEADER image_section_header[MAX_SECTION_NUM]; + char *image_section[MAX_SECTION_NUM]; + void *fileImage; + DWORD fileSize; + DWORD numOfSecs; +} PEStruct, *PPEStruct; + +PEStruct getPEFileInformation(char *filename); \ No newline at end of file diff --git a/OpenParrotLoader/src/main.cpp b/OpenParrotLoader/src/main.cpp new file mode 100644 index 0000000..0bf99f8 --- /dev/null +++ b/OpenParrotLoader/src/main.cpp @@ -0,0 +1,263 @@ +#define _CRT_SECURE_NO_WARNINGS +#include +#include +#include +#include +#include "PE.h" + +#pragma comment(lib, "ntdll.lib") +#pragma optimize("", off) +STARTUPINFO si; +PROCESS_INFORMATION pi; +_CONTEXT mycontext; +PEStruct FilePEFile; +int RunTo(DWORD_PTR Address, DWORD Mode, DWORD_PTR Eip); +DWORD_PTR MyLoadLibraryA = 0; +#pragma comment (lib, "Advapi32.lib") +int LoadHookDLL(char *dllLocation, DWORD_PTR address) +{ + MyLoadLibraryA = (DWORD_PTR)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"); + DWORD_PTR addy = (DWORD_PTR)VirtualAllocEx(pi.hProcess, 0, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + //printf("addy: %08X", addy); + DWORD_PTR OEP = address; + DWORD_PTR TextLocation = addy + 0x30; + DWORD_PTR CallLoadLibraryA = MyLoadLibraryA - (addy + 10); +#ifdef _M_IX86 + DWORD addyOffset = 10; + //ReadProcessMemory(pi.hProcess, (LPVOID)OEP, backbuf, 256, 0); + WriteProcessMemory(pi.hProcess, (LPVOID)addy, "\x68\x00\x00\x00\x00\xE8\x00\x00\x00\x00\xEB\xFE", 0x0C, 0); + WriteProcessMemory(pi.hProcess, (LPVOID)(addy + 1), &TextLocation, 4, 0); + WriteProcessMemory(pi.hProcess, (LPVOID)(addy + 6), &CallLoadLibraryA, 4, 0); + //printf("%s\n", dllLocation); + WriteProcessMemory(pi.hProcess, (LPVOID)TextLocation, dllLocation, strlen(dllLocation)+1, 0); +#else + DWORD addyOffset = 30; + WriteProcessMemory(pi.hProcess, (LPVOID)addy, "\x48\x83\xEC\x28\x48\xB9\x00\x00\x00\x00\x00\x00\x00\x00\x48\xB8\x11\x11\x11\x11\x01\x00\x00\x00\xFF\xD0\x48\x83\xC4\x28\xEB\xFE", 32, 0); + WriteProcessMemory(pi.hProcess, (LPVOID)(addy + 6), &TextLocation, 8, 0); + WriteProcessMemory(pi.hProcess, (LPVOID)(addy + 16), &MyLoadLibraryA, 8, 0); + //printf("%s\n", dllLocation); + WriteProcessMemory(pi.hProcess, (LPVOID)TextLocation, dllLocation, strlen(dllLocation) + 1, 0); +#endif + GetThreadContext(pi.hThread, &mycontext); + Sleep(1000); + if (!RunTo(addy + addyOffset, 0, addy)) + { + printf("Failed to Load DLL!"); + return 0; + } +#ifdef _M_IX86 + if (mycontext.Eax == 0) +#elif defined(_M_AMD64) + if (mycontext.Rax == 0) +#endif + { + printf("Failed to Load DLL!"); + return 0; + } + GetThreadContext(pi.hThread, &mycontext); + Sleep(100); +#ifdef _M_IX86 + mycontext.Eip = OEP; +#else + mycontext.Rip = OEP; +#endif + Sleep(100); + SetThreadContext(pi.hThread, &mycontext); + Sleep(100); + //WriteProcessMemory(pi.hProcess, (LPVOID)OEP, backbuf, 256, 0); + Sleep(100); + printf("DLL Loaded!\n");// %08x\n", mycontext.Eax); + return 1; +} +int RunTo(DWORD_PTR Address, DWORD Mode, DWORD_PTR Eip) +{ + char tempbuf[4]; + if (Eip != 0) + { + GetThreadContext(pi.hThread, &mycontext); +#ifdef _M_IX86 + mycontext.Eip = Eip; +#elif defined(_M_AMD64) + mycontext.Rip = Eip; +#endif + SetThreadContext(pi.hThread, &mycontext); + } + ReadProcessMemory(pi.hProcess, (LPVOID)Address, tempbuf, 4, 0); + WriteProcessMemory(pi.hProcess, (LPVOID)Address, "\xEB\xFE", 2, 0); + ResumeThread(pi.hThread); + while (GetThreadContext(pi.hThread, &mycontext)) + { + if (Mode == 1) WriteProcessMemory(pi.hProcess, (LPVOID)Address, "\xEB\xFE", 2, 0); +#ifdef _M_IX86 + if (mycontext.Eip == Address) break; +#elif defined(_M_AMD64) + if (mycontext.Rip == Address) break; +#endif + Sleep(100); + } + SuspendThread(pi.hThread); + if (!GetThreadContext(pi.hThread, &mycontext)) return 0; + WriteProcessMemory(pi.hProcess, (LPVOID)Address, tempbuf, 4, 0); + return 1; +} +void lowercase(char string[]) +{ + int i = 0; + + while (string[i]) + { + string[i] = tolower(string[i]); + i++; + } + + return; +} + +DWORD GetVal(HKEY hKey, LPCTSTR lpValue) +{ + DWORD data; DWORD size = sizeof(data); DWORD type = REG_DWORD; + LONG nError = RegQueryValueEx(hKey, lpValue, NULL, &type, (LPBYTE)&data, &size); + + if (nError == ERROR_FILE_NOT_FOUND) + data = 0; // The value will be created and set to data next time SetVal() is called. + else if (nError) + printf("Error: Could not get registry value %s", lpValue); + + return data; +} + +int main(int argc, char *argv[]) +{ + if (argc == 1 || argc > 3) + { + printf("Please use the following format: "); + printf("ParrotLoader.exe c:\\games\\id6\\id6.exe "); + return 0; + } + + char dirBuf[256]; + strcpy(dirBuf, argv[1]); + char *p = strrchr(dirBuf, '\\'); + if (p) p[0] = 0; + + WIN32_FIND_DATA filedata; + HANDLE hFind; + WIN32_FIND_DATA filedata2; + HANDLE hFind2; + char szDir[512]; + char szDir2[512]; + printf("OpenParrot Loader\n"); + printf("http://www.teknogods.com - Modding Gurus!\n"); + printf("Supported OS: Windows XP x86 / x64, Windows Vista x86 / x64, Windows 7 x86 / x64, Windows 8 / 8.1 x86 / x64 Windows 10 x86 / x64\n"); + printf("Code: Reaver, NTAuthority, avail\n"); + GetCurrentDirectoryA(400, szDir); +#if _M_IX86 + sprintf_s(szDir2, "%s\\OpenParrot.dll", szDir); +#else + sprintf_s(szDir2, "%s\\OpenParrot64.dll", szDir); +#endif + hFind = FindFirstFile(argv[1], &filedata); + hFind2 = FindFirstFile(szDir2, &filedata2); + + if (hFind == INVALID_HANDLE_VALUE) + { + printf("Unable to find %s", argv[1]); + _getch(); + return 0; + } + + if (hFind2 == INVALID_HANDLE_VALUE) + { + printf("Unable to find %s", szDir2); + _getch(); + return 0; + } + FilePEFile = getPEFileInformation(argv[1]); + if (argc == 3) + { + char bb[256]; + sprintf(bb, "%s %s", argv[1], argv[2]); + if (!CreateProcess(NULL, // No module name (use command line). + bb, // Command line. + NULL, // Process handle not inheritable. + NULL, // Thread handle not inheritable. + FALSE, // Set handle inheritance to FALSE. + CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP, // suspended creation flags. + NULL, // Use parent's environment block. + dirBuf, // Use parent's starting directory. + &si, // Pointer to STARTUPINFO structure. + &pi) // Pointer to PROCESS_INFORMATION structure. + ) + { + printf("Failed to load process!"); + _getch(); + return 1; + } + } + else if (argc == 2) + { + if (!CreateProcess(argv[1], // No module name (use command line). + "", // Command line. + NULL, // Process handle not inheritable. + NULL, // Thread handle not inheritable. + FALSE, // Set handle inheritance to FALSE. + CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP, // suspended creation flags. + NULL, // Use parent's environment block. + dirBuf, // Use parent's starting directory. + &si, // Pointer to STARTUPINFO structure. + &pi) // Pointer to PROCESS_INFORMATION structure. + ) + { + printf("Failed to load process!"); + _getch(); + return 1; + } + } + + mycontext.ContextFlags = 0x00010000 + 1 + 2 + 4 + 8 + 0x10; + GetThreadContext(pi.hThread, &mycontext); + + PROCESS_BASIC_INFORMATION pbi; + DWORD pbiSize = sizeof(pbi); + + if (!NT_SUCCESS(NtQueryInformationProcess(pi.hProcess, ProcessBasicInformation, &pbi, pbiSize, &pbiSize))) + { + printf("Failed to get process information!"); + _getch(); + return 1; + } + + DWORD_PTR baseAddress; + SIZE_T read = 0; + + ReadProcessMemory(pi.hProcess, (void*)((DWORD_PTR)pbi.PebBaseAddress + (sizeof(DWORD_PTR) * 2)), &baseAddress, sizeof(baseAddress), &read); + + if (read != sizeof(DWORD_PTR)) + { + printf("Failed to get process environment!"); + _getch(); + return 1; + } + + Sleep(1000); + + if (!RunTo(baseAddress + FilePEFile.image_nt_headers.OptionalHeader.AddressOfEntryPoint, 1, 0)) + { + printf("Failed to run the process\n"); + TerminateProcess(pi.hProcess, 0); + _getch(); + return 1; + } + + if (!LoadHookDLL(szDir2, baseAddress + FilePEFile.image_nt_headers.OptionalHeader.AddressOfEntryPoint)) + { + TerminateProcess(pi.hProcess, 0); + _getch(); + return 0; + } + printf("Resuming game!\n"); + Sleep(2000); + ResumeThread(pi.hThread); + while (GetThreadContext(pi.hThread, &mycontext)) Sleep(2000); + return 1; +} diff --git a/OpenParrotLoader/src/main.h b/OpenParrotLoader/src/main.h new file mode 100644 index 0000000..2c8ab8d --- /dev/null +++ b/OpenParrotLoader/src/main.h @@ -0,0 +1,334 @@ +/* +I do not take credit for these stuctures, but rather give all credits to +the NTInternals Team. But, I do take credit for taking the useful things +from the site and putting them into a easy to use place. +thanks and hope someone finds these useful +~sean reed +*/ + +#pragma once + +#include +#include + +typedef void(*PELPEBLOCKROUTINE)(PVOID PebLock); + +typedef struct _ELLSA_UNICODE_STRING { + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; +}ELLSA_UNICODE_STRING, *PELLSA_UNICODE_STRING, ELUNICODE_STRING, *PELUNICODE_STRING; + +typedef struct _ELLIST_ENTRY +{ + struct _ELLIST_ENTRY *Flink; + struct _ELLIST_ENTRY *Blink; +} ELLIST_ENTRY, *PELLIST_ENTRY; + +typedef struct _ELPEB_LDR_DATA +{ + ULONG Length; + BOOLEAN Initialized; + PVOID SsHandle; + ELLIST_ENTRY InLoadOrderModuleList; + ELLIST_ENTRY InMemoryOrderModuleList; + ELLIST_ENTRY InInitializationOrderModuleList; + +} ELPEB_LDR_DATA, *PELPEB_LDR_DATA; + +typedef struct _ELRTL_DRIVE_LETTER_CURDIR +{ + USHORT Flags; + USHORT Length; + ULONG TimeStamp; + ELUNICODE_STRING DosPath; + +} ELRTL_DRIVE_LETTER_CURDIR, *PELRTL_DRIVE_LETTER_CURDIR; + +typedef struct _ELRTL_USER_PROCESS_PARAMETERS +{ + ULONG MaximumLength; + ULONG Length; + ULONG Flags; + ULONG DebugFlags; + PVOID ConsoleHandle; + ULONG ConsoleFlags; + HANDLE StdInputHandle; + HANDLE StdOutputHandle; + HANDLE StdErrorHandle; + ELUNICODE_STRING CurrentDirectoryPath; + HANDLE CurrentDirectoryHandle; + ELUNICODE_STRING DllPath; + ELUNICODE_STRING ImagePathName; + ELUNICODE_STRING CommandLine; + PVOID Environment; + ULONG StartingPositionLeft; + ULONG StartingPositionTop; + ULONG Width; + ULONG Height; + ULONG CharWidth; + ULONG CharHeight; + ULONG ConsoleTextAttributes; + ULONG WindowFlags; + ULONG ShowWindowFlags; + ELUNICODE_STRING WindowTitle; + ELUNICODE_STRING DesktopName; + ELUNICODE_STRING ShellInfo; + ELUNICODE_STRING RuntimeData; + ELRTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20]; + +} ELRTL_USER_PROCESS_PARAMETERS, *PELRTL_USER_PROCESS_PARAMETERS; + +typedef struct _ELPEB_FREE_BLOCK +{ + struct _ELPEB_FREE_BLOCK *Next; + ULONG Size; + +} ELPEB_FREE_BLOCK, *PELPEB_FREE_BLOCK; + +typedef struct _ELLDR_MODULE { + + ELLIST_ENTRY InLoadOrderModuleList; + ELLIST_ENTRY InMemoryOrderModuleList; + ELLIST_ENTRY InInitializationOrderModuleList; + PVOID BaseAddress; + PVOID EntryPoint; + ULONG SizeOfImage; + ELUNICODE_STRING FullDllName; + ELUNICODE_STRING BaseDllName; + ULONG Flags; + SHORT LoadCount; + SHORT TlsIndex; + ELLIST_ENTRY HashTableEntry; + ULONG TimeDateStamp; + +} ELLDR_MODULE, *ELPLDR_MODULE; + + +typedef struct _ELPEB +{ + BOOLEAN InheritedAddressSpace; + BOOLEAN ReadImageFileExecOptions; + BOOLEAN BeingDebugged; + BOOLEAN Spare; + HANDLE Mutant; + PVOID ImageBaseAddress; + PELPEB_LDR_DATA LoaderData; + PELRTL_USER_PROCESS_PARAMETERS ProcessParameters; + PVOID SubSystemData; + PVOID ProcessHeap; + PVOID FastPebLock; + PELPEBLOCKROUTINE FastPebLockRoutine; + PELPEBLOCKROUTINE FastPebUnlockRoutine; + ULONG EnvironmentUpdateCount; + PVOID *KernelCallbackTable; + PVOID EventLogSection; + PVOID EventLog; + PELPEB_FREE_BLOCK FreeList; + ULONG TlsExpansionCounter; + PVOID TlsBitmap; + ULONG TlsBitmapBits[0x2]; + PVOID ReadOnlySharedMemoryBase; + PVOID ReadOnlySharedMemoryHeap; + PVOID *ReadOnlyStaticServerData; + PVOID AnsiCodePageData; + PVOID OemCodePageData; + PVOID UnicodeCaseTableData; + ULONG NumberOfProcessors; + ULONG NtGlobalFlag; + BYTE Spare2[0x4]; + LARGE_INTEGER CriticalSectionTimeout; + ULONG HeapSegmentReserve; + ULONG HeapSegmentCommit; + ULONG HeapDeCommitTotalFreeThreshold; + ULONG HeapDeCommitFreeBlockThreshold; + ULONG NumberOfHeaps; + ULONG MaximumNumberOfHeaps; + PVOID **ProcessHeaps; + PVOID GdiSharedHandleTable; + PVOID ProcessStarterHelper; + PVOID GdiDCAttributeList; + PVOID LoaderLock; + ULONG OSMajorVersion; + ULONG OSMinorVersion; + ULONG OSBuildNumber; + ULONG OSPlatformId; + ULONG ImageSubSystem; + ULONG ImageSubSystemMajorVersion; + ULONG ImageSubSystemMinorVersion; + ULONG GdiHandleBuffer[0x22]; + ULONG PostProcessInitRoutine; + ULONG TlsExpansionBitmap; + BYTE TlsExpansionBitmapBits[0x80]; + ULONG SessionId; + +} ELPEB, *PELPEB; + +typedef struct _ELPROCESS_BASIC_INFORMATION +{ + PVOID Reserved1; + PELPEB PebBaseAddress; + PVOID Reserved2[2]; + ULONG_PTR UniqueProcessId; + PVOID Reserved3; +} ELPROCESS_BASIC_INFORMATION; + +typedef enum _ELPROCESS_INFORMATION_CLASS +{ + ProcessBasicInformation, + ProcessQuotaLimits, + ProcessIoCounters, + ProcessVmCounters, + ProcessTimes, + ProcessBasePriority, + ProcessRaisePriority, + ProcessDebugPort, + ProcessExceptionPort, + ProcessAccessToken, + ProcessLdtInformation, + ProcessLdtSize, + ProcessDefaultHardErrorMode, + ProcessIoPortHandlers, + ProcessPooledUsageAndLimits, + ProcessWorkingSetWatch, + ProcessUserModeIOPL, + ProcessEnableAlignmentFaultFixup, + ProcessPriorityClass, + ProcessWx86Information, + ProcessHandleCount, + ProcessAffinityMask, + ProcessPriorityBoost, + MaxProcessInfoClass +} ELPROCESS_INFORMATION_CLASS, *PELPROCESS_INFORMATION_CLASS; + +typedef struct _CLIENT_ID { + HANDLE UniqueProcess; + HANDLE UniqueThread; +} CLIENT_ID; + +typedef struct _ELSYSTEM_THREAD_INFORMATION { + LARGE_INTEGER KernelTime; + LARGE_INTEGER UserTime; + LARGE_INTEGER CreateTime; + ULONG WaitTime; + PVOID StartAddress; + CLIENT_ID ClientId; + LONG Priority; + LONG BasePriority; + ULONG ContextSwitches; + ULONG ThreadState; + ULONG WaitReason; +} ELSYSTEM_THREAD_INFORMATION, *PELSYSTEM_THREAD_INFORMATION; + +typedef enum _SYSTEM_INFORMATION_CLASS { + + SystemBasicInformation, SystemProcessorInformation, SystemPerformanceInformation, SystemTimeOfDayInformation, SystemPathInformation, SystemProcessInformation, SystemCallCountInformation, SystemDeviceInformation, SystemProcessorPerformanceInformation, SystemFlagsInformation, SystemCallTimeInformation, SystemModuleInformation, SystemLocksInformation, SystemStackTraceInformation, SystemPagedPoolInformation, SystemNonPagedPoolInformation, SystemHandleInformation, SystemObjectInformation, SystemPageFileInformation, SystemVdmInstemulInformation, SystemVdmBopInformation, SystemFileCacheInformation, SystemPoolTagInformation, SystemInterruptInformation, SystemDpcBehaviorInformation, SystemFullMemoryInformation, SystemLoadGdiDriverInformation, SystemUnloadGdiDriverInformation, SystemTimeAdjustmentInformation, SystemSummaryMemoryInformation, SystemNextEventIdInformation, SystemEventIdsInformation, SystemCrashDumpInformation, SystemExceptionInformation, SystemCrashDumpStateInformation, SystemKernelDebuggerInformation, SystemContextSwitchInformation, SystemRegistryQuotaInformation, SystemExtendServiceTableInformation, SystemPrioritySeperation, SystemPlugPlayBusInformation, SystemDockInformation, ELSystemPowerInformation, SystemProcessorSpeedInformation, SystemCurrentTimeZoneInformation, SystemLookasideInformation + +} ELSYSTEM_INFORMATION_CLASS, *PSYSTEM_INFORMATION_CLASS; +typedef enum _KWAIT_REASON +{ + Executive = 0, + FreePage = 1, + PageIn = 2, + PoolAllocation = 3, + DelayExecution = 4, + Suspended = 5, + UserRequest = 6, + WrExecutive = 7, + WrFreePage = 8, + WrPageIn = 9, + WrPoolAllocation = 10, + WrDelayExecution = 11, + WrSuspended = 12, + WrUserRequest = 13, + WrEventPair = 14, + WrQueue = 15, + WrLpcReceive = 16, + WrLpcReply = 17, + WrVirtualMemory = 18, + WrPageOut = 19, + WrRendezvous = 20, + Spare2 = 21, + Spare3 = 22, + Spare4 = 23, + Spare5 = 24, + WrCalloutStack = 25, + WrKernel = 26, + WrResource = 27, + WrPushLock = 28, + WrMutex = 29, + WrQuantumEnd = 30, + WrDispatchInt = 31, + WrPreempted = 32, + WrYieldExecution = 33, + WrFastMutex = 34, + WrGuardedMutex = 35, + WrRundown = 36, + MaximumWaitReason = 37 +} KWAIT_REASON; + +typedef struct _SYSTEM_THREAD { + + LARGE_INTEGER KernelTime; + LARGE_INTEGER UserTime; + LARGE_INTEGER CreateTime; + ULONG WaitTime; + PVOID StartAddress; + CLIENT_ID ClientId; + LONG Priority; + LONG BasePriority; + ULONG ContextSwitchCount; + ULONG State; + KWAIT_REASON WaitReason; + +} SYSTEM_THREAD, *PSYSTEM_THREAD; + +typedef struct _VM_COUNTERS +{ + int PeakVirtualSize; + int VirtualSize; + int PageFaultCount; + int PeakWorkingSetSize; + int WorkingSetSize; + int QuotaPeakPagedPoolUsage; + int QuotaPagedPoolUsage; + int QuotaPeakNonPagedPoolUsage; + int QuotaNonPagedPoolUsage; + int PagefileUsage; + int PeakPagefileUsage; +}VM_COUNTERS; + +typedef struct _SYSTEM_PROCESS_INFORMATION +{ + DWORD NextEntryOffset; + DWORD dThreadCount; + DWORD dReserved01; + DWORD dReserved02; + DWORD dReserved03; + DWORD dReserved04; + DWORD dReserved05; + DWORD dReserved06; + FILETIME ftCreateTime; /* relative to 01-01-1601 */ + FILETIME ftUserTime; /* 100 nsec units */ + FILETIME ftKernelTime; /* 100 nsec units */ + ELUNICODE_STRING ProcessName; + DWORD BasePriority; + DWORD dUniqueProcessId; + DWORD dParentProcessID; + DWORD dHandleCount; + DWORD dReserved07; + DWORD dReserved08; + DWORD VmCounters; + DWORD dCommitCharge; + ELSYSTEM_THREAD_INFORMATION ThreadInfos[1]; +} ELSYSTEM_PROCESS_INFORMATION, *PELSYSTEM_PROCESS_INFORMATION; + + +//Gets the PEB for the current process +PELPEB EL_GetPeb(); + +//prints out the Loaded Modules for the current Peb +DWORD EL_PrintModules(PELPEB peb); + +//hides a module +DWORD EL_HideModule(PELPEB peb, const wchar_t *dll); \ No newline at end of file diff --git a/deps/inc/MinHook.h b/deps/inc/MinHook.h new file mode 100644 index 0000000..15c0a87 --- /dev/null +++ b/deps/inc/MinHook.h @@ -0,0 +1,186 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#if !(defined _M_IX86) && !(defined _M_X64) && !(defined __i386__) && !(defined __x86_64__) + #error MinHook supports only x86 and x64 systems. +#endif + +#include + +// MinHook Error Codes. +typedef enum MH_STATUS +{ + // Unknown error. Should not be returned. + MH_UNKNOWN = -1, + + // Successful. + MH_OK = 0, + + // MinHook is already initialized. + MH_ERROR_ALREADY_INITIALIZED, + + // MinHook is not initialized yet, or already uninitialized. + MH_ERROR_NOT_INITIALIZED, + + // The hook for the specified target function is already created. + MH_ERROR_ALREADY_CREATED, + + // The hook for the specified target function is not created yet. + MH_ERROR_NOT_CREATED, + + // The hook for the specified target function is already enabled. + MH_ERROR_ENABLED, + + // The hook for the specified target function is not enabled yet, or already + // disabled. + MH_ERROR_DISABLED, + + // The specified pointer is invalid. It points the address of non-allocated + // and/or non-executable region. + MH_ERROR_NOT_EXECUTABLE, + + // The specified target function cannot be hooked. + MH_ERROR_UNSUPPORTED_FUNCTION, + + // Failed to allocate memory. + MH_ERROR_MEMORY_ALLOC, + + // Failed to change the memory protection. + MH_ERROR_MEMORY_PROTECT, + + // The specified module is not loaded. + MH_ERROR_MODULE_NOT_FOUND, + + // The specified function is not found. + MH_ERROR_FUNCTION_NOT_FOUND +} +MH_STATUS; + +// Can be passed as a parameter to MH_EnableHook, MH_DisableHook, +// MH_QueueEnableHook or MH_QueueDisableHook. +#define MH_ALL_HOOKS NULL + +#ifdef __cplusplus +extern "C" { +#endif + + // Initialize the MinHook library. You must call this function EXACTLY ONCE + // at the beginning of your program. + MH_STATUS WINAPI MH_Initialize(VOID); + + // Uninitialize the MinHook library. You must call this function EXACTLY + // ONCE at the end of your program. + MH_STATUS WINAPI MH_Uninitialize(VOID); + + // Creates a Hook for the specified target function, in disabled state. + // Parameters: + // pTarget [in] A pointer to the target function, which will be + // overridden by the detour function. + // pDetour [in] A pointer to the detour function, which will override + // the target function. + // ppOriginal [out] A pointer to the trampoline function, which will be + // used to call the original target function. + // This parameter can be NULL. + MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal); + + // Creates a Hook for the specified API function, in disabled state. + // Parameters: + // pszModule [in] A pointer to the loaded module name which contains the + // target function. + // pszTarget [in] A pointer to the target function name, which will be + // overridden by the detour function. + // pDetour [in] A pointer to the detour function, which will override + // the target function. + // ppOriginal [out] A pointer to the trampoline function, which will be + // used to call the original target function. + // This parameter can be NULL. + MH_STATUS WINAPI MH_CreateHookApi( + LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal); + + // Creates a Hook for the specified API function, in disabled state. + // Parameters: + // pszModule [in] A pointer to the loaded module name which contains the + // target function. + // pszTarget [in] A pointer to the target function name, which will be + // overridden by the detour function. + // pDetour [in] A pointer to the detour function, which will override + // the target function. + // ppOriginal [out] A pointer to the trampoline function, which will be + // used to call the original target function. + // This parameter can be NULL. + // ppTarget [out] A pointer to the target function, which will be used + // with other functions. + // This parameter can be NULL. + MH_STATUS WINAPI MH_CreateHookApiEx( + LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal, LPVOID *ppTarget); + + // Removes an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget); + + // Enables an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are + // enabled in one go. + MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget); + + // Disables an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are + // disabled in one go. + MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget); + + // Queues to enable an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are + // queued to be enabled. + MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget); + + // Queues to disable an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are + // queued to be disabled. + MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget); + + // Applies all queued changes in one go. + MH_STATUS WINAPI MH_ApplyQueued(VOID); + + // Translates the MH_STATUS to its name as a string. + const char * WINAPI MH_StatusToString(MH_STATUS status); + +#ifdef __cplusplus +} +#endif + diff --git a/deps/src/buffer.c b/deps/src/buffer.c new file mode 100644 index 0000000..8f9fbce --- /dev/null +++ b/deps/src/buffer.c @@ -0,0 +1,312 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "buffer.h" + +// Size of each memory block. (= page size of VirtualAlloc) +#define MEMORY_BLOCK_SIZE 0x1000 + +// Max range for seeking a memory block. (= 1024MB) +#define MAX_MEMORY_RANGE 0x40000000 + +// Memory protection flags to check the executable address. +#define PAGE_EXECUTE_FLAGS \ + (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY) + +// Memory slot. +typedef struct _MEMORY_SLOT +{ + union + { + struct _MEMORY_SLOT *pNext; + UINT8 buffer[MEMORY_SLOT_SIZE]; + }; +} MEMORY_SLOT, *PMEMORY_SLOT; + +// Memory block info. Placed at the head of each block. +typedef struct _MEMORY_BLOCK +{ + struct _MEMORY_BLOCK *pNext; + PMEMORY_SLOT pFree; // First element of the free slot list. + UINT usedCount; +} MEMORY_BLOCK, *PMEMORY_BLOCK; + +//------------------------------------------------------------------------- +// Global Variables: +//------------------------------------------------------------------------- + +// First element of the memory block list. +PMEMORY_BLOCK g_pMemoryBlocks; + +//------------------------------------------------------------------------- +VOID InitializeBuffer(VOID) +{ + // Nothing to do for now. +} + +//------------------------------------------------------------------------- +VOID UninitializeBuffer(VOID) +{ + PMEMORY_BLOCK pBlock = g_pMemoryBlocks; + g_pMemoryBlocks = NULL; + + while (pBlock) + { + PMEMORY_BLOCK pNext = pBlock->pNext; + VirtualFree(pBlock, 0, MEM_RELEASE); + pBlock = pNext; + } +} + +//------------------------------------------------------------------------- +#if defined(_M_X64) || defined(__x86_64__) +static LPVOID FindPrevFreeRegion(LPVOID pAddress, LPVOID pMinAddr, DWORD dwAllocationGranularity) +{ + ULONG_PTR tryAddr = (ULONG_PTR)pAddress; + + // Round down to the allocation granularity. + tryAddr -= tryAddr % dwAllocationGranularity; + + // Start from the previous allocation granularity multiply. + tryAddr -= dwAllocationGranularity; + + while (tryAddr >= (ULONG_PTR)pMinAddr) + { + MEMORY_BASIC_INFORMATION mbi; + if (VirtualQuery((LPVOID)tryAddr, &mbi, sizeof(mbi)) == 0) + break; + + if (mbi.State == MEM_FREE) + return (LPVOID)tryAddr; + + if ((ULONG_PTR)mbi.AllocationBase < dwAllocationGranularity) + break; + + tryAddr = (ULONG_PTR)mbi.AllocationBase - dwAllocationGranularity; + } + + return NULL; +} +#endif + +//------------------------------------------------------------------------- +#if defined(_M_X64) || defined(__x86_64__) +static LPVOID FindNextFreeRegion(LPVOID pAddress, LPVOID pMaxAddr, DWORD dwAllocationGranularity) +{ + ULONG_PTR tryAddr = (ULONG_PTR)pAddress; + + // Round down to the allocation granularity. + tryAddr -= tryAddr % dwAllocationGranularity; + + // Start from the next allocation granularity multiply. + tryAddr += dwAllocationGranularity; + + while (tryAddr <= (ULONG_PTR)pMaxAddr) + { + MEMORY_BASIC_INFORMATION mbi; + if (VirtualQuery((LPVOID)tryAddr, &mbi, sizeof(mbi)) == 0) + break; + + if (mbi.State == MEM_FREE) + return (LPVOID)tryAddr; + + tryAddr = (ULONG_PTR)mbi.BaseAddress + mbi.RegionSize; + + // Round up to the next allocation granularity. + tryAddr += dwAllocationGranularity - 1; + tryAddr -= tryAddr % dwAllocationGranularity; + } + + return NULL; +} +#endif + +//------------------------------------------------------------------------- +static PMEMORY_BLOCK GetMemoryBlock(LPVOID pOrigin) +{ + PMEMORY_BLOCK pBlock; +#if defined(_M_X64) || defined(__x86_64__) + ULONG_PTR minAddr; + ULONG_PTR maxAddr; + + SYSTEM_INFO si; + GetSystemInfo(&si); + minAddr = (ULONG_PTR)si.lpMinimumApplicationAddress; + maxAddr = (ULONG_PTR)si.lpMaximumApplicationAddress; + + // pOrigin ± 512MB + if ((ULONG_PTR)pOrigin > MAX_MEMORY_RANGE && minAddr < (ULONG_PTR)pOrigin - MAX_MEMORY_RANGE) + minAddr = (ULONG_PTR)pOrigin - MAX_MEMORY_RANGE; + + if (maxAddr > (ULONG_PTR)pOrigin + MAX_MEMORY_RANGE) + maxAddr = (ULONG_PTR)pOrigin + MAX_MEMORY_RANGE; + + // Make room for MEMORY_BLOCK_SIZE bytes. + maxAddr -= MEMORY_BLOCK_SIZE - 1; +#endif + + // Look the registered blocks for a reachable one. + for (pBlock = g_pMemoryBlocks; pBlock != NULL; pBlock = pBlock->pNext) + { +#if defined(_M_X64) || defined(__x86_64__) + // Ignore the blocks too far. + if ((ULONG_PTR)pBlock < minAddr || (ULONG_PTR)pBlock >= maxAddr) + continue; +#endif + // The block has at least one unused slot. + if (pBlock->pFree != NULL) + return pBlock; + } + +#if defined(_M_X64) || defined(__x86_64__) + // Alloc a new block above if not found. + { + LPVOID pAlloc = pOrigin; + while ((ULONG_PTR)pAlloc >= minAddr) + { + pAlloc = FindPrevFreeRegion(pAlloc, (LPVOID)minAddr, si.dwAllocationGranularity); + if (pAlloc == NULL) + break; + + pBlock = (PMEMORY_BLOCK)VirtualAlloc( + pAlloc, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + if (pBlock != NULL) + break; + } + } + + // Alloc a new block below if not found. + if (pBlock == NULL) + { + LPVOID pAlloc = pOrigin; + while ((ULONG_PTR)pAlloc <= maxAddr) + { + pAlloc = FindNextFreeRegion(pAlloc, (LPVOID)maxAddr, si.dwAllocationGranularity); + if (pAlloc == NULL) + break; + + pBlock = (PMEMORY_BLOCK)VirtualAlloc( + pAlloc, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + if (pBlock != NULL) + break; + } + } +#else + // In x86 mode, a memory block can be placed anywhere. + pBlock = (PMEMORY_BLOCK)VirtualAlloc( + NULL, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); +#endif + + if (pBlock != NULL) + { + // Build a linked list of all the slots. + PMEMORY_SLOT pSlot = (PMEMORY_SLOT)pBlock + 1; + pBlock->pFree = NULL; + pBlock->usedCount = 0; + do + { + pSlot->pNext = pBlock->pFree; + pBlock->pFree = pSlot; + pSlot++; + } while ((ULONG_PTR)pSlot - (ULONG_PTR)pBlock <= MEMORY_BLOCK_SIZE - MEMORY_SLOT_SIZE); + + pBlock->pNext = g_pMemoryBlocks; + g_pMemoryBlocks = pBlock; + } + + return pBlock; +} + +//------------------------------------------------------------------------- +LPVOID AllocateBuffer(LPVOID pOrigin) +{ + PMEMORY_SLOT pSlot; + PMEMORY_BLOCK pBlock = GetMemoryBlock(pOrigin); + if (pBlock == NULL) + return NULL; + + // Remove an unused slot from the list. + pSlot = pBlock->pFree; + pBlock->pFree = pSlot->pNext; + pBlock->usedCount++; +#ifdef _DEBUG + // Fill the slot with INT3 for debugging. + memset(pSlot, 0xCC, sizeof(MEMORY_SLOT)); +#endif + return pSlot; +} + +//------------------------------------------------------------------------- +VOID FreeBuffer(LPVOID pBuffer) +{ + PMEMORY_BLOCK pBlock = g_pMemoryBlocks; + PMEMORY_BLOCK pPrev = NULL; + ULONG_PTR pTargetBlock = ((ULONG_PTR)pBuffer / MEMORY_BLOCK_SIZE) * MEMORY_BLOCK_SIZE; + + while (pBlock != NULL) + { + if ((ULONG_PTR)pBlock == pTargetBlock) + { + PMEMORY_SLOT pSlot = (PMEMORY_SLOT)pBuffer; +#ifdef _DEBUG + // Clear the released slot for debugging. + memset(pSlot, 0x00, sizeof(*pSlot)); +#endif + // Restore the released slot to the list. + pSlot->pNext = pBlock->pFree; + pBlock->pFree = pSlot; + pBlock->usedCount--; + + // Free if unused. + if (pBlock->usedCount == 0) + { + if (pPrev) + pPrev->pNext = pBlock->pNext; + else + g_pMemoryBlocks = pBlock->pNext; + + VirtualFree(pBlock, 0, MEM_RELEASE); + } + + break; + } + + pPrev = pBlock; + pBlock = pBlock->pNext; + } +} + +//------------------------------------------------------------------------- +BOOL IsExecutableAddress(LPVOID pAddress) +{ + MEMORY_BASIC_INFORMATION mi; + VirtualQuery(pAddress, &mi, sizeof(mi)); + + return (mi.State == MEM_COMMIT && (mi.Protect & PAGE_EXECUTE_FLAGS)); +} diff --git a/deps/src/buffer.h b/deps/src/buffer.h new file mode 100644 index 0000000..204d551 --- /dev/null +++ b/deps/src/buffer.h @@ -0,0 +1,42 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +// Size of each memory slot. +#if defined(_M_X64) || defined(__x86_64__) + #define MEMORY_SLOT_SIZE 64 +#else + #define MEMORY_SLOT_SIZE 32 +#endif + +VOID InitializeBuffer(VOID); +VOID UninitializeBuffer(VOID); +LPVOID AllocateBuffer(LPVOID pOrigin); +VOID FreeBuffer(LPVOID pBuffer); +BOOL IsExecutableAddress(LPVOID pAddress); diff --git a/deps/src/hde/hde32.c b/deps/src/hde/hde32.c new file mode 100644 index 0000000..08fa25b --- /dev/null +++ b/deps/src/hde/hde32.c @@ -0,0 +1,326 @@ +/* + * Hacker Disassembler Engine 32 C + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + */ + +#if defined(_M_IX86) || defined(__i386__) + +#include "hde32.h" +#include "table32.h" + +unsigned int hde32_disasm(const void *code, hde32s *hs) +{ + uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0; + uint8_t *ht = hde32_table, m_mod, m_reg, m_rm, disp_size = 0; + + // Avoid using memset to reduce the footprint. +#ifndef _MSC_VER + memset((LPBYTE)hs, 0, sizeof(hde32s)); +#else + __stosb((LPBYTE)hs, 0, sizeof(hde32s)); +#endif + + for (x = 16; x; x--) + switch (c = *p++) { + case 0xf3: + hs->p_rep = c; + pref |= PRE_F3; + break; + case 0xf2: + hs->p_rep = c; + pref |= PRE_F2; + break; + case 0xf0: + hs->p_lock = c; + pref |= PRE_LOCK; + break; + case 0x26: case 0x2e: case 0x36: + case 0x3e: case 0x64: case 0x65: + hs->p_seg = c; + pref |= PRE_SEG; + break; + case 0x66: + hs->p_66 = c; + pref |= PRE_66; + break; + case 0x67: + hs->p_67 = c; + pref |= PRE_67; + break; + default: + goto pref_done; + } + pref_done: + + hs->flags = (uint32_t)pref << 23; + + if (!pref) + pref |= PRE_NONE; + + if ((hs->opcode = c) == 0x0f) { + hs->opcode2 = c = *p++; + ht += DELTA_OPCODES; + } else if (c >= 0xa0 && c <= 0xa3) { + if (pref & PRE_67) + pref |= PRE_66; + else + pref &= ~PRE_66; + } + + opcode = c; + cflags = ht[ht[opcode / 4] + (opcode % 4)]; + + if (cflags == C_ERROR) { + hs->flags |= F_ERROR | F_ERROR_OPCODE; + cflags = 0; + if ((opcode & -3) == 0x24) + cflags++; + } + + x = 0; + if (cflags & C_GROUP) { + uint16_t t; + t = *(uint16_t *)(ht + (cflags & 0x7f)); + cflags = (uint8_t)t; + x = (uint8_t)(t >> 8); + } + + if (hs->opcode2) { + ht = hde32_table + DELTA_PREFIXES; + if (ht[ht[opcode / 4] + (opcode % 4)] & pref) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + } + + if (cflags & C_MODRM) { + hs->flags |= F_MODRM; + hs->modrm = c = *p++; + hs->modrm_mod = m_mod = c >> 6; + hs->modrm_rm = m_rm = c & 7; + hs->modrm_reg = m_reg = (c & 0x3f) >> 3; + + if (x && ((x << m_reg) & 0x80)) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + + if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) { + uint8_t t = opcode - 0xd9; + if (m_mod == 3) { + ht = hde32_table + DELTA_FPU_MODRM + t*8; + t = ht[m_reg] << m_rm; + } else { + ht = hde32_table + DELTA_FPU_REG; + t = ht[t] << m_reg; + } + if (t & 0x80) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + } + + if (pref & PRE_LOCK) { + if (m_mod == 3) { + hs->flags |= F_ERROR | F_ERROR_LOCK; + } else { + uint8_t *table_end, op = opcode; + if (hs->opcode2) { + ht = hde32_table + DELTA_OP2_LOCK_OK; + table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK; + } else { + ht = hde32_table + DELTA_OP_LOCK_OK; + table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK; + op &= -2; + } + for (; ht != table_end; ht++) + if (*ht++ == op) { + if (!((*ht << m_reg) & 0x80)) + goto no_lock_error; + else + break; + } + hs->flags |= F_ERROR | F_ERROR_LOCK; + no_lock_error: + ; + } + } + + if (hs->opcode2) { + switch (opcode) { + case 0x20: case 0x22: + m_mod = 3; + if (m_reg > 4 || m_reg == 1) + goto error_operand; + else + goto no_error_operand; + case 0x21: case 0x23: + m_mod = 3; + if (m_reg == 4 || m_reg == 5) + goto error_operand; + else + goto no_error_operand; + } + } else { + switch (opcode) { + case 0x8c: + if (m_reg > 5) + goto error_operand; + else + goto no_error_operand; + case 0x8e: + if (m_reg == 1 || m_reg > 5) + goto error_operand; + else + goto no_error_operand; + } + } + + if (m_mod == 3) { + uint8_t *table_end; + if (hs->opcode2) { + ht = hde32_table + DELTA_OP2_ONLY_MEM; + table_end = ht + sizeof(hde32_table) - DELTA_OP2_ONLY_MEM; + } else { + ht = hde32_table + DELTA_OP_ONLY_MEM; + table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM; + } + for (; ht != table_end; ht += 2) + if (*ht++ == opcode) { + if (*ht++ & pref && !((*ht << m_reg) & 0x80)) + goto error_operand; + else + break; + } + goto no_error_operand; + } else if (hs->opcode2) { + switch (opcode) { + case 0x50: case 0xd7: case 0xf7: + if (pref & (PRE_NONE | PRE_66)) + goto error_operand; + break; + case 0xd6: + if (pref & (PRE_F2 | PRE_F3)) + goto error_operand; + break; + case 0xc5: + goto error_operand; + } + goto no_error_operand; + } else + goto no_error_operand; + + error_operand: + hs->flags |= F_ERROR | F_ERROR_OPERAND; + no_error_operand: + + c = *p++; + if (m_reg <= 1) { + if (opcode == 0xf6) + cflags |= C_IMM8; + else if (opcode == 0xf7) + cflags |= C_IMM_P66; + } + + switch (m_mod) { + case 0: + if (pref & PRE_67) { + if (m_rm == 6) + disp_size = 2; + } else + if (m_rm == 5) + disp_size = 4; + break; + case 1: + disp_size = 1; + break; + case 2: + disp_size = 2; + if (!(pref & PRE_67)) + disp_size <<= 1; + } + + if (m_mod != 3 && m_rm == 4 && !(pref & PRE_67)) { + hs->flags |= F_SIB; + p++; + hs->sib = c; + hs->sib_scale = c >> 6; + hs->sib_index = (c & 0x3f) >> 3; + if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1)) + disp_size = 4; + } + + p--; + switch (disp_size) { + case 1: + hs->flags |= F_DISP8; + hs->disp.disp8 = *p; + break; + case 2: + hs->flags |= F_DISP16; + hs->disp.disp16 = *(uint16_t *)p; + break; + case 4: + hs->flags |= F_DISP32; + hs->disp.disp32 = *(uint32_t *)p; + } + p += disp_size; + } else if (pref & PRE_LOCK) + hs->flags |= F_ERROR | F_ERROR_LOCK; + + if (cflags & C_IMM_P66) { + if (cflags & C_REL32) { + if (pref & PRE_66) { + hs->flags |= F_IMM16 | F_RELATIVE; + hs->imm.imm16 = *(uint16_t *)p; + p += 2; + goto disasm_done; + } + goto rel32_ok; + } + if (pref & PRE_66) { + hs->flags |= F_IMM16; + hs->imm.imm16 = *(uint16_t *)p; + p += 2; + } else { + hs->flags |= F_IMM32; + hs->imm.imm32 = *(uint32_t *)p; + p += 4; + } + } + + if (cflags & C_IMM16) { + if (hs->flags & F_IMM32) { + hs->flags |= F_IMM16; + hs->disp.disp16 = *(uint16_t *)p; + } else if (hs->flags & F_IMM16) { + hs->flags |= F_2IMM16; + hs->disp.disp16 = *(uint16_t *)p; + } else { + hs->flags |= F_IMM16; + hs->imm.imm16 = *(uint16_t *)p; + } + p += 2; + } + if (cflags & C_IMM8) { + hs->flags |= F_IMM8; + hs->imm.imm8 = *p++; + } + + if (cflags & C_REL32) { + rel32_ok: + hs->flags |= F_IMM32 | F_RELATIVE; + hs->imm.imm32 = *(uint32_t *)p; + p += 4; + } else if (cflags & C_REL8) { + hs->flags |= F_IMM8 | F_RELATIVE; + hs->imm.imm8 = *p++; + } + + disasm_done: + + if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) { + hs->flags |= F_ERROR | F_ERROR_LENGTH; + hs->len = 15; + } + + return (unsigned int)hs->len; +} + +#endif // defined(_M_IX86) || defined(__i386__) diff --git a/deps/src/hde/hde32.h b/deps/src/hde/hde32.h new file mode 100644 index 0000000..1112450 --- /dev/null +++ b/deps/src/hde/hde32.h @@ -0,0 +1,105 @@ +/* + * Hacker Disassembler Engine 32 + * Copyright (c) 2006-2009, Vyacheslav Patkov. + * All rights reserved. + * + * hde32.h: C/C++ header file + * + */ + +#ifndef _HDE32_H_ +#define _HDE32_H_ + +/* stdint.h - C99 standard header + * http://en.wikipedia.org/wiki/stdint.h + * + * if your compiler doesn't contain "stdint.h" header (for + * example, Microsoft Visual C++), you can download file: + * http://www.azillionmonkeys.com/qed/pstdint.h + * and change next line to: + * #include "pstdint.h" + */ +#include "pstdint.h" + +#define F_MODRM 0x00000001 +#define F_SIB 0x00000002 +#define F_IMM8 0x00000004 +#define F_IMM16 0x00000008 +#define F_IMM32 0x00000010 +#define F_DISP8 0x00000020 +#define F_DISP16 0x00000040 +#define F_DISP32 0x00000080 +#define F_RELATIVE 0x00000100 +#define F_2IMM16 0x00000800 +#define F_ERROR 0x00001000 +#define F_ERROR_OPCODE 0x00002000 +#define F_ERROR_LENGTH 0x00004000 +#define F_ERROR_LOCK 0x00008000 +#define F_ERROR_OPERAND 0x00010000 +#define F_PREFIX_REPNZ 0x01000000 +#define F_PREFIX_REPX 0x02000000 +#define F_PREFIX_REP 0x03000000 +#define F_PREFIX_66 0x04000000 +#define F_PREFIX_67 0x08000000 +#define F_PREFIX_LOCK 0x10000000 +#define F_PREFIX_SEG 0x20000000 +#define F_PREFIX_ANY 0x3f000000 + +#define PREFIX_SEGMENT_CS 0x2e +#define PREFIX_SEGMENT_SS 0x36 +#define PREFIX_SEGMENT_DS 0x3e +#define PREFIX_SEGMENT_ES 0x26 +#define PREFIX_SEGMENT_FS 0x64 +#define PREFIX_SEGMENT_GS 0x65 +#define PREFIX_LOCK 0xf0 +#define PREFIX_REPNZ 0xf2 +#define PREFIX_REPX 0xf3 +#define PREFIX_OPERAND_SIZE 0x66 +#define PREFIX_ADDRESS_SIZE 0x67 + +#pragma pack(push,1) + +typedef struct { + uint8_t len; + uint8_t p_rep; + uint8_t p_lock; + uint8_t p_seg; + uint8_t p_66; + uint8_t p_67; + uint8_t opcode; + uint8_t opcode2; + uint8_t modrm; + uint8_t modrm_mod; + uint8_t modrm_reg; + uint8_t modrm_rm; + uint8_t sib; + uint8_t sib_scale; + uint8_t sib_index; + uint8_t sib_base; + union { + uint8_t imm8; + uint16_t imm16; + uint32_t imm32; + } imm; + union { + uint8_t disp8; + uint16_t disp16; + uint32_t disp32; + } disp; + uint32_t flags; +} hde32s; + +#pragma pack(pop) + +#ifdef __cplusplus +extern "C" { +#endif + +/* __cdecl */ +unsigned int hde32_disasm(const void *code, hde32s *hs); + +#ifdef __cplusplus +} +#endif + +#endif /* _HDE32_H_ */ diff --git a/deps/src/hde/hde64.c b/deps/src/hde/hde64.c new file mode 100644 index 0000000..c23e2fc --- /dev/null +++ b/deps/src/hde/hde64.c @@ -0,0 +1,337 @@ +/* + * Hacker Disassembler Engine 64 C + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + */ + +#if defined(_M_X64) || defined(__x86_64__) + +#include "hde64.h" +#include "table64.h" + +unsigned int hde64_disasm(const void *code, hde64s *hs) +{ + uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0; + uint8_t *ht = hde64_table, m_mod, m_reg, m_rm, disp_size = 0; + uint8_t op64 = 0; + + // Avoid using memset to reduce the footprint. +#ifndef _MSC_VER + memset((LPBYTE)hs, 0, sizeof(hde64s)); +#else + __stosb((LPBYTE)hs, 0, sizeof(hde64s)); +#endif + + for (x = 16; x; x--) + switch (c = *p++) { + case 0xf3: + hs->p_rep = c; + pref |= PRE_F3; + break; + case 0xf2: + hs->p_rep = c; + pref |= PRE_F2; + break; + case 0xf0: + hs->p_lock = c; + pref |= PRE_LOCK; + break; + case 0x26: case 0x2e: case 0x36: + case 0x3e: case 0x64: case 0x65: + hs->p_seg = c; + pref |= PRE_SEG; + break; + case 0x66: + hs->p_66 = c; + pref |= PRE_66; + break; + case 0x67: + hs->p_67 = c; + pref |= PRE_67; + break; + default: + goto pref_done; + } + pref_done: + + hs->flags = (uint32_t)pref << 23; + + if (!pref) + pref |= PRE_NONE; + + if ((c & 0xf0) == 0x40) { + hs->flags |= F_PREFIX_REX; + if ((hs->rex_w = (c & 0xf) >> 3) && (*p & 0xf8) == 0xb8) + op64++; + hs->rex_r = (c & 7) >> 2; + hs->rex_x = (c & 3) >> 1; + hs->rex_b = c & 1; + if (((c = *p++) & 0xf0) == 0x40) { + opcode = c; + goto error_opcode; + } + } + + if ((hs->opcode = c) == 0x0f) { + hs->opcode2 = c = *p++; + ht += DELTA_OPCODES; + } else if (c >= 0xa0 && c <= 0xa3) { + op64++; + if (pref & PRE_67) + pref |= PRE_66; + else + pref &= ~PRE_66; + } + + opcode = c; + cflags = ht[ht[opcode / 4] + (opcode % 4)]; + + if (cflags == C_ERROR) { + error_opcode: + hs->flags |= F_ERROR | F_ERROR_OPCODE; + cflags = 0; + if ((opcode & -3) == 0x24) + cflags++; + } + + x = 0; + if (cflags & C_GROUP) { + uint16_t t; + t = *(uint16_t *)(ht + (cflags & 0x7f)); + cflags = (uint8_t)t; + x = (uint8_t)(t >> 8); + } + + if (hs->opcode2) { + ht = hde64_table + DELTA_PREFIXES; + if (ht[ht[opcode / 4] + (opcode % 4)] & pref) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + } + + if (cflags & C_MODRM) { + hs->flags |= F_MODRM; + hs->modrm = c = *p++; + hs->modrm_mod = m_mod = c >> 6; + hs->modrm_rm = m_rm = c & 7; + hs->modrm_reg = m_reg = (c & 0x3f) >> 3; + + if (x && ((x << m_reg) & 0x80)) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + + if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) { + uint8_t t = opcode - 0xd9; + if (m_mod == 3) { + ht = hde64_table + DELTA_FPU_MODRM + t*8; + t = ht[m_reg] << m_rm; + } else { + ht = hde64_table + DELTA_FPU_REG; + t = ht[t] << m_reg; + } + if (t & 0x80) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + } + + if (pref & PRE_LOCK) { + if (m_mod == 3) { + hs->flags |= F_ERROR | F_ERROR_LOCK; + } else { + uint8_t *table_end, op = opcode; + if (hs->opcode2) { + ht = hde64_table + DELTA_OP2_LOCK_OK; + table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK; + } else { + ht = hde64_table + DELTA_OP_LOCK_OK; + table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK; + op &= -2; + } + for (; ht != table_end; ht++) + if (*ht++ == op) { + if (!((*ht << m_reg) & 0x80)) + goto no_lock_error; + else + break; + } + hs->flags |= F_ERROR | F_ERROR_LOCK; + no_lock_error: + ; + } + } + + if (hs->opcode2) { + switch (opcode) { + case 0x20: case 0x22: + m_mod = 3; + if (m_reg > 4 || m_reg == 1) + goto error_operand; + else + goto no_error_operand; + case 0x21: case 0x23: + m_mod = 3; + if (m_reg == 4 || m_reg == 5) + goto error_operand; + else + goto no_error_operand; + } + } else { + switch (opcode) { + case 0x8c: + if (m_reg > 5) + goto error_operand; + else + goto no_error_operand; + case 0x8e: + if (m_reg == 1 || m_reg > 5) + goto error_operand; + else + goto no_error_operand; + } + } + + if (m_mod == 3) { + uint8_t *table_end; + if (hs->opcode2) { + ht = hde64_table + DELTA_OP2_ONLY_MEM; + table_end = ht + sizeof(hde64_table) - DELTA_OP2_ONLY_MEM; + } else { + ht = hde64_table + DELTA_OP_ONLY_MEM; + table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM; + } + for (; ht != table_end; ht += 2) + if (*ht++ == opcode) { + if (*ht++ & pref && !((*ht << m_reg) & 0x80)) + goto error_operand; + else + break; + } + goto no_error_operand; + } else if (hs->opcode2) { + switch (opcode) { + case 0x50: case 0xd7: case 0xf7: + if (pref & (PRE_NONE | PRE_66)) + goto error_operand; + break; + case 0xd6: + if (pref & (PRE_F2 | PRE_F3)) + goto error_operand; + break; + case 0xc5: + goto error_operand; + } + goto no_error_operand; + } else + goto no_error_operand; + + error_operand: + hs->flags |= F_ERROR | F_ERROR_OPERAND; + no_error_operand: + + c = *p++; + if (m_reg <= 1) { + if (opcode == 0xf6) + cflags |= C_IMM8; + else if (opcode == 0xf7) + cflags |= C_IMM_P66; + } + + switch (m_mod) { + case 0: + if (pref & PRE_67) { + if (m_rm == 6) + disp_size = 2; + } else + if (m_rm == 5) + disp_size = 4; + break; + case 1: + disp_size = 1; + break; + case 2: + disp_size = 2; + if (!(pref & PRE_67)) + disp_size <<= 1; + } + + if (m_mod != 3 && m_rm == 4) { + hs->flags |= F_SIB; + p++; + hs->sib = c; + hs->sib_scale = c >> 6; + hs->sib_index = (c & 0x3f) >> 3; + if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1)) + disp_size = 4; + } + + p--; + switch (disp_size) { + case 1: + hs->flags |= F_DISP8; + hs->disp.disp8 = *p; + break; + case 2: + hs->flags |= F_DISP16; + hs->disp.disp16 = *(uint16_t *)p; + break; + case 4: + hs->flags |= F_DISP32; + hs->disp.disp32 = *(uint32_t *)p; + } + p += disp_size; + } else if (pref & PRE_LOCK) + hs->flags |= F_ERROR | F_ERROR_LOCK; + + if (cflags & C_IMM_P66) { + if (cflags & C_REL32) { + if (pref & PRE_66) { + hs->flags |= F_IMM16 | F_RELATIVE; + hs->imm.imm16 = *(uint16_t *)p; + p += 2; + goto disasm_done; + } + goto rel32_ok; + } + if (op64) { + hs->flags |= F_IMM64; + hs->imm.imm64 = *(uint64_t *)p; + p += 8; + } else if (!(pref & PRE_66)) { + hs->flags |= F_IMM32; + hs->imm.imm32 = *(uint32_t *)p; + p += 4; + } else + goto imm16_ok; + } + + + if (cflags & C_IMM16) { + imm16_ok: + hs->flags |= F_IMM16; + hs->imm.imm16 = *(uint16_t *)p; + p += 2; + } + if (cflags & C_IMM8) { + hs->flags |= F_IMM8; + hs->imm.imm8 = *p++; + } + + if (cflags & C_REL32) { + rel32_ok: + hs->flags |= F_IMM32 | F_RELATIVE; + hs->imm.imm32 = *(uint32_t *)p; + p += 4; + } else if (cflags & C_REL8) { + hs->flags |= F_IMM8 | F_RELATIVE; + hs->imm.imm8 = *p++; + } + + disasm_done: + + if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) { + hs->flags |= F_ERROR | F_ERROR_LENGTH; + hs->len = 15; + } + + return (unsigned int)hs->len; +} + +#endif // defined(_M_X64) || defined(__x86_64__) diff --git a/deps/src/hde/hde64.h b/deps/src/hde/hde64.h new file mode 100644 index 0000000..ecbf4df --- /dev/null +++ b/deps/src/hde/hde64.h @@ -0,0 +1,112 @@ +/* + * Hacker Disassembler Engine 64 + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + * hde64.h: C/C++ header file + * + */ + +#ifndef _HDE64_H_ +#define _HDE64_H_ + +/* stdint.h - C99 standard header + * http://en.wikipedia.org/wiki/stdint.h + * + * if your compiler doesn't contain "stdint.h" header (for + * example, Microsoft Visual C++), you can download file: + * http://www.azillionmonkeys.com/qed/pstdint.h + * and change next line to: + * #include "pstdint.h" + */ +#include "pstdint.h" + +#define F_MODRM 0x00000001 +#define F_SIB 0x00000002 +#define F_IMM8 0x00000004 +#define F_IMM16 0x00000008 +#define F_IMM32 0x00000010 +#define F_IMM64 0x00000020 +#define F_DISP8 0x00000040 +#define F_DISP16 0x00000080 +#define F_DISP32 0x00000100 +#define F_RELATIVE 0x00000200 +#define F_ERROR 0x00001000 +#define F_ERROR_OPCODE 0x00002000 +#define F_ERROR_LENGTH 0x00004000 +#define F_ERROR_LOCK 0x00008000 +#define F_ERROR_OPERAND 0x00010000 +#define F_PREFIX_REPNZ 0x01000000 +#define F_PREFIX_REPX 0x02000000 +#define F_PREFIX_REP 0x03000000 +#define F_PREFIX_66 0x04000000 +#define F_PREFIX_67 0x08000000 +#define F_PREFIX_LOCK 0x10000000 +#define F_PREFIX_SEG 0x20000000 +#define F_PREFIX_REX 0x40000000 +#define F_PREFIX_ANY 0x7f000000 + +#define PREFIX_SEGMENT_CS 0x2e +#define PREFIX_SEGMENT_SS 0x36 +#define PREFIX_SEGMENT_DS 0x3e +#define PREFIX_SEGMENT_ES 0x26 +#define PREFIX_SEGMENT_FS 0x64 +#define PREFIX_SEGMENT_GS 0x65 +#define PREFIX_LOCK 0xf0 +#define PREFIX_REPNZ 0xf2 +#define PREFIX_REPX 0xf3 +#define PREFIX_OPERAND_SIZE 0x66 +#define PREFIX_ADDRESS_SIZE 0x67 + +#pragma pack(push,1) + +typedef struct { + uint8_t len; + uint8_t p_rep; + uint8_t p_lock; + uint8_t p_seg; + uint8_t p_66; + uint8_t p_67; + uint8_t rex; + uint8_t rex_w; + uint8_t rex_r; + uint8_t rex_x; + uint8_t rex_b; + uint8_t opcode; + uint8_t opcode2; + uint8_t modrm; + uint8_t modrm_mod; + uint8_t modrm_reg; + uint8_t modrm_rm; + uint8_t sib; + uint8_t sib_scale; + uint8_t sib_index; + uint8_t sib_base; + union { + uint8_t imm8; + uint16_t imm16; + uint32_t imm32; + uint64_t imm64; + } imm; + union { + uint8_t disp8; + uint16_t disp16; + uint32_t disp32; + } disp; + uint32_t flags; +} hde64s; + +#pragma pack(pop) + +#ifdef __cplusplus +extern "C" { +#endif + +/* __cdecl */ +unsigned int hde64_disasm(const void *code, hde64s *hs); + +#ifdef __cplusplus +} +#endif + +#endif /* _HDE64_H_ */ diff --git a/deps/src/hde/pstdint.h b/deps/src/hde/pstdint.h new file mode 100644 index 0000000..84d82a0 --- /dev/null +++ b/deps/src/hde/pstdint.h @@ -0,0 +1,39 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include + +// Integer types for HDE. +typedef INT8 int8_t; +typedef INT16 int16_t; +typedef INT32 int32_t; +typedef INT64 int64_t; +typedef UINT8 uint8_t; +typedef UINT16 uint16_t; +typedef UINT32 uint32_t; +typedef UINT64 uint64_t; diff --git a/deps/src/hde/table32.h b/deps/src/hde/table32.h new file mode 100644 index 0000000..7b3e12e --- /dev/null +++ b/deps/src/hde/table32.h @@ -0,0 +1,73 @@ +/* + * Hacker Disassembler Engine 32 C + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + */ + +#define C_NONE 0x00 +#define C_MODRM 0x01 +#define C_IMM8 0x02 +#define C_IMM16 0x04 +#define C_IMM_P66 0x10 +#define C_REL8 0x20 +#define C_REL32 0x40 +#define C_GROUP 0x80 +#define C_ERROR 0xff + +#define PRE_ANY 0x00 +#define PRE_NONE 0x01 +#define PRE_F2 0x02 +#define PRE_F3 0x04 +#define PRE_66 0x08 +#define PRE_67 0x10 +#define PRE_LOCK 0x20 +#define PRE_SEG 0x40 +#define PRE_ALL 0xff + +#define DELTA_OPCODES 0x4a +#define DELTA_FPU_REG 0xf1 +#define DELTA_FPU_MODRM 0xf8 +#define DELTA_PREFIXES 0x130 +#define DELTA_OP_LOCK_OK 0x1a1 +#define DELTA_OP2_LOCK_OK 0x1b9 +#define DELTA_OP_ONLY_MEM 0x1cb +#define DELTA_OP2_ONLY_MEM 0x1da + +unsigned char hde32_table[] = { + 0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3, + 0xa8,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xac,0xaa,0xb2,0xaa,0x9f,0x9f, + 0x9f,0x9f,0xb5,0xa3,0xa3,0xa4,0xaa,0xaa,0xba,0xaa,0x96,0xaa,0xa8,0xaa,0xc3, + 0xc3,0x96,0x96,0xb7,0xae,0xd6,0xbd,0xa3,0xc5,0xa3,0xa3,0x9f,0xc3,0x9c,0xaa, + 0xaa,0xac,0xaa,0xbf,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0x90, + 0x82,0x7d,0x97,0x59,0x59,0x59,0x59,0x59,0x7f,0x59,0x59,0x60,0x7d,0x7f,0x7f, + 0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x9a,0x88,0x7d, + 0x59,0x50,0x50,0x50,0x50,0x59,0x59,0x59,0x59,0x61,0x94,0x61,0x9e,0x59,0x59, + 0x85,0x59,0x92,0xa3,0x60,0x60,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59, + 0x59,0x59,0x9f,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xcc,0x01,0xbc,0x03,0xf0, + 0x10,0x10,0x10,0x10,0x50,0x50,0x50,0x50,0x14,0x20,0x20,0x20,0x20,0x01,0x01, + 0x01,0x01,0xc4,0x02,0x10,0x00,0x00,0x00,0x00,0x01,0x01,0xc0,0xc2,0x10,0x11, + 0x02,0x03,0x11,0x03,0x03,0x04,0x00,0x00,0x14,0x00,0x02,0x00,0x00,0xc6,0xc8, + 0x02,0x02,0x02,0x02,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0xca, + 0x01,0x01,0x01,0x00,0x06,0x00,0x04,0x00,0xc0,0xc2,0x01,0x01,0x03,0x01,0xff, + 0xff,0x01,0x00,0x03,0xc4,0xc4,0xc6,0x03,0x01,0x01,0x01,0xff,0x03,0x03,0x03, + 0xc8,0x40,0x00,0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00, + 0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xff,0xff,0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x7f,0x00,0x00,0xff,0x4a,0x4a,0x4a,0x4a,0x4b,0x52,0x4a,0x4a,0x4a,0x4a,0x4f, + 0x4c,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x55,0x45,0x40,0x4a,0x4a,0x4a, + 0x45,0x59,0x4d,0x46,0x4a,0x5d,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a, + 0x4a,0x4a,0x4a,0x4a,0x4a,0x61,0x63,0x67,0x4e,0x4a,0x4a,0x6b,0x6d,0x4a,0x4a, + 0x45,0x6d,0x4a,0x4a,0x44,0x45,0x4a,0x4a,0x00,0x00,0x00,0x02,0x0d,0x06,0x06, + 0x06,0x06,0x0e,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x00,0x06,0x06,0x02,0x06, + 0x00,0x0a,0x0a,0x07,0x07,0x06,0x02,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04, + 0x04,0x04,0x00,0x00,0x00,0x0e,0x05,0x06,0x06,0x06,0x01,0x06,0x00,0x00,0x08, + 0x00,0x10,0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01, + 0x86,0x00,0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba, + 0xf8,0xbb,0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00, + 0xc4,0xff,0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00, + 0x13,0x09,0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07, + 0xb2,0xff,0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf, + 0xe7,0x08,0x00,0xf0,0x02,0x00 +}; diff --git a/deps/src/hde/table64.h b/deps/src/hde/table64.h new file mode 100644 index 0000000..01d4541 --- /dev/null +++ b/deps/src/hde/table64.h @@ -0,0 +1,74 @@ +/* + * Hacker Disassembler Engine 64 C + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + */ + +#define C_NONE 0x00 +#define C_MODRM 0x01 +#define C_IMM8 0x02 +#define C_IMM16 0x04 +#define C_IMM_P66 0x10 +#define C_REL8 0x20 +#define C_REL32 0x40 +#define C_GROUP 0x80 +#define C_ERROR 0xff + +#define PRE_ANY 0x00 +#define PRE_NONE 0x01 +#define PRE_F2 0x02 +#define PRE_F3 0x04 +#define PRE_66 0x08 +#define PRE_67 0x10 +#define PRE_LOCK 0x20 +#define PRE_SEG 0x40 +#define PRE_ALL 0xff + +#define DELTA_OPCODES 0x4a +#define DELTA_FPU_REG 0xfd +#define DELTA_FPU_MODRM 0x104 +#define DELTA_PREFIXES 0x13c +#define DELTA_OP_LOCK_OK 0x1ae +#define DELTA_OP2_LOCK_OK 0x1c6 +#define DELTA_OP_ONLY_MEM 0x1d8 +#define DELTA_OP2_ONLY_MEM 0x1e7 + +unsigned char hde64_table[] = { + 0xa5,0xaa,0xa5,0xb8,0xa5,0xaa,0xa5,0xaa,0xa5,0xb8,0xa5,0xb8,0xa5,0xb8,0xa5, + 0xb8,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xac,0xc0,0xcc,0xc0,0xa1,0xa1, + 0xa1,0xa1,0xb1,0xa5,0xa5,0xa6,0xc0,0xc0,0xd7,0xda,0xe0,0xc0,0xe4,0xc0,0xea, + 0xea,0xe0,0xe0,0x98,0xc8,0xee,0xf1,0xa5,0xd3,0xa5,0xa5,0xa1,0xea,0x9e,0xc0, + 0xc0,0xc2,0xc0,0xe6,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0xab, + 0x8b,0x90,0x64,0x5b,0x5b,0x5b,0x5b,0x5b,0x92,0x5b,0x5b,0x76,0x90,0x92,0x92, + 0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x6a,0x73,0x90, + 0x5b,0x52,0x52,0x52,0x52,0x5b,0x5b,0x5b,0x5b,0x77,0x7c,0x77,0x85,0x5b,0x5b, + 0x70,0x5b,0x7a,0xaf,0x76,0x76,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b, + 0x5b,0x5b,0x86,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xd5,0x03,0xcc,0x01,0xbc, + 0x03,0xf0,0x03,0x03,0x04,0x00,0x50,0x50,0x50,0x50,0xff,0x20,0x20,0x20,0x20, + 0x01,0x01,0x01,0x01,0xc4,0x02,0x10,0xff,0xff,0xff,0x01,0x00,0x03,0x11,0xff, + 0x03,0xc4,0xc6,0xc8,0x02,0x10,0x00,0xff,0xcc,0x01,0x01,0x01,0x00,0x00,0x00, + 0x00,0x01,0x01,0x03,0x01,0xff,0xff,0xc0,0xc2,0x10,0x11,0x02,0x03,0x01,0x01, + 0x01,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x10, + 0x10,0x10,0x10,0x02,0x10,0x00,0x00,0xc6,0xc8,0x02,0x02,0x02,0x02,0x06,0x00, + 0x04,0x00,0x02,0xff,0x00,0xc0,0xc2,0x01,0x01,0x03,0x03,0x03,0xca,0x40,0x00, + 0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00,0x00,0x00,0x00, + 0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff, + 0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00, + 0xff,0x40,0x40,0x40,0x40,0x41,0x49,0x40,0x40,0x40,0x40,0x4c,0x42,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x40,0x4f,0x44,0x53,0x40,0x40,0x40,0x44,0x57,0x43, + 0x5c,0x40,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x40,0x40,0x64,0x66,0x6e,0x6b,0x40,0x40,0x6a,0x46,0x40,0x40,0x44,0x46,0x40, + 0x40,0x5b,0x44,0x40,0x40,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x01,0x06, + 0x06,0x02,0x06,0x06,0x00,0x06,0x00,0x0a,0x0a,0x00,0x00,0x00,0x02,0x07,0x07, + 0x06,0x02,0x0d,0x06,0x06,0x06,0x0e,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04, + 0x04,0x04,0x05,0x06,0x06,0x06,0x00,0x00,0x00,0x0e,0x00,0x00,0x08,0x00,0x10, + 0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01,0x86,0x00, + 0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba,0xf8,0xbb, + 0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00,0xc4,0xff, + 0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00,0x13,0x09, + 0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07,0xb2,0xff, + 0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf,0xe7,0x08, + 0x00,0xf0,0x02,0x00 +}; diff --git a/deps/src/hook.c b/deps/src/hook.c new file mode 100644 index 0000000..9634df8 --- /dev/null +++ b/deps/src/hook.c @@ -0,0 +1,889 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include "../inc/MinHook.h" +#include "buffer.h" +#include "trampoline.h" + +#ifndef ARRAYSIZE + #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) +#endif + +// Initial capacity of the HOOK_ENTRY buffer. +#define INITIAL_HOOK_CAPACITY 32 + +// Initial capacity of the thread IDs buffer. +#define INITIAL_THREAD_CAPACITY 128 + +// Special hook position values. +#define INVALID_HOOK_POS UINT_MAX +#define ALL_HOOKS_POS UINT_MAX + +// Freeze() action argument defines. +#define ACTION_DISABLE 0 +#define ACTION_ENABLE 1 +#define ACTION_APPLY_QUEUED 2 + +// Thread access rights for suspending/resuming threads. +#define THREAD_ACCESS \ + (THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION | THREAD_SET_CONTEXT) + +// Hook information. +typedef struct _HOOK_ENTRY +{ + LPVOID pTarget; // Address of the target function. + LPVOID pDetour; // Address of the detour or relay function. + LPVOID pTrampoline; // Address of the trampoline function. + UINT8 backup[8]; // Original prologue of the target function. + + UINT8 patchAbove : 1; // Uses the hot patch area. + UINT8 isEnabled : 1; // Enabled. + UINT8 queueEnable : 1; // Queued for enabling/disabling when != isEnabled. + + UINT nIP : 4; // Count of the instruction boundaries. + UINT8 oldIPs[8]; // Instruction boundaries of the target function. + UINT8 newIPs[8]; // Instruction boundaries of the trampoline function. +} HOOK_ENTRY, *PHOOK_ENTRY; + +// Suspended threads for Freeze()/Unfreeze(). +typedef struct _FROZEN_THREADS +{ + LPDWORD pItems; // Data heap + UINT capacity; // Size of allocated data heap, items + UINT size; // Actual number of data items +} FROZEN_THREADS, *PFROZEN_THREADS; + +//------------------------------------------------------------------------- +// Global Variables: +//------------------------------------------------------------------------- + +// Spin lock flag for EnterSpinLock()/LeaveSpinLock(). +volatile LONG g_isLocked = FALSE; + +// Private heap handle. If not NULL, this library is initialized. +HANDLE g_hHeap = NULL; + +// Hook entries. +struct +{ + PHOOK_ENTRY pItems; // Data heap + UINT capacity; // Size of allocated data heap, items + UINT size; // Actual number of data items +} g_hooks; + +//------------------------------------------------------------------------- +// Returns INVALID_HOOK_POS if not found. +static UINT FindHookEntry(LPVOID pTarget) +{ + UINT i; + for (i = 0; i < g_hooks.size; ++i) + { + if ((ULONG_PTR)pTarget == (ULONG_PTR)g_hooks.pItems[i].pTarget) + return i; + } + + return INVALID_HOOK_POS; +} + +//------------------------------------------------------------------------- +static PHOOK_ENTRY AddHookEntry() +{ + if (g_hooks.pItems == NULL) + { + g_hooks.capacity = INITIAL_HOOK_CAPACITY; + g_hooks.pItems = (PHOOK_ENTRY)HeapAlloc( + g_hHeap, 0, g_hooks.capacity * sizeof(HOOK_ENTRY)); + if (g_hooks.pItems == NULL) + return NULL; + } + else if (g_hooks.size >= g_hooks.capacity) + { + PHOOK_ENTRY p = (PHOOK_ENTRY)HeapReAlloc( + g_hHeap, 0, g_hooks.pItems, (g_hooks.capacity * 2) * sizeof(HOOK_ENTRY)); + if (p == NULL) + return NULL; + + g_hooks.capacity *= 2; + g_hooks.pItems = p; + } + + return &g_hooks.pItems[g_hooks.size++]; +} + +//------------------------------------------------------------------------- +static void DeleteHookEntry(UINT pos) +{ + if (pos < g_hooks.size - 1) + g_hooks.pItems[pos] = g_hooks.pItems[g_hooks.size - 1]; + + g_hooks.size--; + + if (g_hooks.capacity / 2 >= INITIAL_HOOK_CAPACITY && g_hooks.capacity / 2 >= g_hooks.size) + { + PHOOK_ENTRY p = (PHOOK_ENTRY)HeapReAlloc( + g_hHeap, 0, g_hooks.pItems, (g_hooks.capacity / 2) * sizeof(HOOK_ENTRY)); + if (p == NULL) + return; + + g_hooks.capacity /= 2; + g_hooks.pItems = p; + } +} + +//------------------------------------------------------------------------- +static DWORD_PTR FindOldIP(PHOOK_ENTRY pHook, DWORD_PTR ip) +{ + UINT i; + + if (pHook->patchAbove && ip == ((DWORD_PTR)pHook->pTarget - sizeof(JMP_REL))) + return (DWORD_PTR)pHook->pTarget; + + for (i = 0; i < pHook->nIP; ++i) + { + if (ip == ((DWORD_PTR)pHook->pTrampoline + pHook->newIPs[i])) + return (DWORD_PTR)pHook->pTarget + pHook->oldIPs[i]; + } + +#if defined(_M_X64) || defined(__x86_64__) + // Check relay function. + if (ip == (DWORD_PTR)pHook->pDetour) + return (DWORD_PTR)pHook->pTarget; +#endif + + return 0; +} + +//------------------------------------------------------------------------- +static DWORD_PTR FindNewIP(PHOOK_ENTRY pHook, DWORD_PTR ip) +{ + UINT i; + for (i = 0; i < pHook->nIP; ++i) + { + if (ip == ((DWORD_PTR)pHook->pTarget + pHook->oldIPs[i])) + return (DWORD_PTR)pHook->pTrampoline + pHook->newIPs[i]; + } + + return 0; +} + +//------------------------------------------------------------------------- +static void ProcessThreadIPs(HANDLE hThread, UINT pos, UINT action) +{ + // If the thread suspended in the overwritten area, + // move IP to the proper address. + + CONTEXT c; +#if defined(_M_X64) || defined(__x86_64__) + DWORD64 *pIP = &c.Rip; +#else + DWORD *pIP = &c.Eip; +#endif + UINT count; + + c.ContextFlags = CONTEXT_CONTROL; + if (!GetThreadContext(hThread, &c)) + return; + + if (pos == ALL_HOOKS_POS) + { + pos = 0; + count = g_hooks.size; + } + else + { + count = pos + 1; + } + + for (; pos < count; ++pos) + { + PHOOK_ENTRY pHook = &g_hooks.pItems[pos]; + BOOL enable; + DWORD_PTR ip; + + switch (action) + { + case ACTION_DISABLE: + enable = FALSE; + break; + + case ACTION_ENABLE: + enable = TRUE; + break; + + default: // ACTION_APPLY_QUEUED + enable = pHook->queueEnable; + break; + } + if (pHook->isEnabled == enable) + continue; + + if (enable) + ip = FindNewIP(pHook, *pIP); + else + ip = FindOldIP(pHook, *pIP); + + if (ip != 0) + { + *pIP = ip; + SetThreadContext(hThread, &c); + } + } +} + +//------------------------------------------------------------------------- +static VOID EnumerateThreads(PFROZEN_THREADS pThreads) +{ + HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); + if (hSnapshot != INVALID_HANDLE_VALUE) + { + THREADENTRY32 te; + te.dwSize = sizeof(THREADENTRY32); + if (Thread32First(hSnapshot, &te)) + { + do + { + if (te.dwSize >= (FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(DWORD)) + && te.th32OwnerProcessID == GetCurrentProcessId() + && te.th32ThreadID != GetCurrentThreadId()) + { + if (pThreads->pItems == NULL) + { + pThreads->capacity = INITIAL_THREAD_CAPACITY; + pThreads->pItems + = (LPDWORD)HeapAlloc(g_hHeap, 0, pThreads->capacity * sizeof(DWORD)); + if (pThreads->pItems == NULL) + break; + } + else if (pThreads->size >= pThreads->capacity) + { + LPDWORD p = (LPDWORD)HeapReAlloc( + g_hHeap, 0, pThreads->pItems, (pThreads->capacity * 2) * sizeof(DWORD)); + if (p == NULL) + break; + + pThreads->capacity *= 2; + pThreads->pItems = p; + } + pThreads->pItems[pThreads->size++] = te.th32ThreadID; + } + + te.dwSize = sizeof(THREADENTRY32); + } while (Thread32Next(hSnapshot, &te)); + } + CloseHandle(hSnapshot); + } +} + +//------------------------------------------------------------------------- +static VOID Freeze(PFROZEN_THREADS pThreads, UINT pos, UINT action) +{ + pThreads->pItems = NULL; + pThreads->capacity = 0; + pThreads->size = 0; + EnumerateThreads(pThreads); + + if (pThreads->pItems != NULL) + { + UINT i; + for (i = 0; i < pThreads->size; ++i) + { + HANDLE hThread = OpenThread(THREAD_ACCESS, FALSE, pThreads->pItems[i]); + if (hThread != NULL) + { + SuspendThread(hThread); + ProcessThreadIPs(hThread, pos, action); + CloseHandle(hThread); + } + } + } +} + +//------------------------------------------------------------------------- +static VOID Unfreeze(PFROZEN_THREADS pThreads) +{ + if (pThreads->pItems != NULL) + { + UINT i; + for (i = 0; i < pThreads->size; ++i) + { + HANDLE hThread = OpenThread(THREAD_ACCESS, FALSE, pThreads->pItems[i]); + if (hThread != NULL) + { + ResumeThread(hThread); + CloseHandle(hThread); + } + } + + HeapFree(g_hHeap, 0, pThreads->pItems); + } +} + +//------------------------------------------------------------------------- +static MH_STATUS EnableHookLL(UINT pos, BOOL enable) +{ + PHOOK_ENTRY pHook = &g_hooks.pItems[pos]; + DWORD oldProtect; + SIZE_T patchSize = sizeof(JMP_REL); + LPBYTE pPatchTarget = (LPBYTE)pHook->pTarget; + + if (pHook->patchAbove) + { + pPatchTarget -= sizeof(JMP_REL); + patchSize += sizeof(JMP_REL_SHORT); + } + + if (!VirtualProtect(pPatchTarget, patchSize, PAGE_EXECUTE_READWRITE, &oldProtect)) + return MH_ERROR_MEMORY_PROTECT; + + if (enable) + { + PJMP_REL pJmp = (PJMP_REL)pPatchTarget; + pJmp->opcode = 0xE9; + pJmp->operand = (UINT32)((LPBYTE)pHook->pDetour - (pPatchTarget + sizeof(JMP_REL))); + + if (pHook->patchAbove) + { + PJMP_REL_SHORT pShortJmp = (PJMP_REL_SHORT)pHook->pTarget; + pShortJmp->opcode = 0xEB; + pShortJmp->operand = (UINT8)(0 - (sizeof(JMP_REL_SHORT) + sizeof(JMP_REL))); + } + } + else + { + if (pHook->patchAbove) + memcpy(pPatchTarget, pHook->backup, sizeof(JMP_REL) + sizeof(JMP_REL_SHORT)); + else + memcpy(pPatchTarget, pHook->backup, sizeof(JMP_REL)); + } + + VirtualProtect(pPatchTarget, patchSize, oldProtect, &oldProtect); + + // Just-in-case measure. + FlushInstructionCache(GetCurrentProcess(), pPatchTarget, patchSize); + + pHook->isEnabled = enable; + pHook->queueEnable = enable; + + return MH_OK; +} + +//------------------------------------------------------------------------- +static MH_STATUS EnableAllHooksLL(BOOL enable) +{ + MH_STATUS status = MH_OK; + UINT i, first = INVALID_HOOK_POS; + + for (i = 0; i < g_hooks.size; ++i) + { + if (g_hooks.pItems[i].isEnabled != enable) + { + first = i; + break; + } + } + + if (first != INVALID_HOOK_POS) + { + FROZEN_THREADS threads; + Freeze(&threads, ALL_HOOKS_POS, enable ? ACTION_ENABLE : ACTION_DISABLE); + + for (i = first; i < g_hooks.size; ++i) + { + if (g_hooks.pItems[i].isEnabled != enable) + { + status = EnableHookLL(i, enable); + if (status != MH_OK) + break; + } + } + + Unfreeze(&threads); + } + + return status; +} + +//------------------------------------------------------------------------- +static VOID EnterSpinLock(VOID) +{ + SIZE_T spinCount = 0; + + // Wait until the flag is FALSE. + while (InterlockedCompareExchange(&g_isLocked, TRUE, FALSE) != FALSE) + { + // No need to generate a memory barrier here, since InterlockedCompareExchange() + // generates a full memory barrier itself. + + // Prevent the loop from being too busy. + if (spinCount < 32) + Sleep(0); + else + Sleep(1); + + spinCount++; + } +} + +//------------------------------------------------------------------------- +static VOID LeaveSpinLock(VOID) +{ + // No need to generate a memory barrier here, since InterlockedExchange() + // generates a full memory barrier itself. + + InterlockedExchange(&g_isLocked, FALSE); +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_Initialize(VOID) +{ + MH_STATUS status = MH_OK; + + EnterSpinLock(); + + if (g_hHeap == NULL) + { + g_hHeap = HeapCreate(0, 0, 0); + if (g_hHeap != NULL) + { + // Initialize the internal function buffer. + InitializeBuffer(); + } + else + { + status = MH_ERROR_MEMORY_ALLOC; + } + } + else + { + status = MH_ERROR_ALREADY_INITIALIZED; + } + + LeaveSpinLock(); + + return status; +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_Uninitialize(VOID) +{ + MH_STATUS status = MH_OK; + + EnterSpinLock(); + + if (g_hHeap != NULL) + { + status = EnableAllHooksLL(FALSE); + if (status == MH_OK) + { + // Free the internal function buffer. + + // HeapFree is actually not required, but some tools detect a false + // memory leak without HeapFree. + + UninitializeBuffer(); + + HeapFree(g_hHeap, 0, g_hooks.pItems); + HeapDestroy(g_hHeap); + + g_hHeap = NULL; + + g_hooks.pItems = NULL; + g_hooks.capacity = 0; + g_hooks.size = 0; + } + } + else + { + status = MH_ERROR_NOT_INITIALIZED; + } + + LeaveSpinLock(); + + return status; +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal) +{ + MH_STATUS status = MH_OK; + + EnterSpinLock(); + + if (g_hHeap != NULL) + { + if (IsExecutableAddress(pTarget) && IsExecutableAddress(pDetour)) + { + UINT pos = FindHookEntry(pTarget); + if (pos == INVALID_HOOK_POS) + { + LPVOID pBuffer = AllocateBuffer(pTarget); + if (pBuffer != NULL) + { + TRAMPOLINE ct; + + ct.pTarget = pTarget; + ct.pDetour = pDetour; + ct.pTrampoline = pBuffer; + if (CreateTrampolineFunction(&ct)) + { + PHOOK_ENTRY pHook = AddHookEntry(); + if (pHook != NULL) + { + pHook->pTarget = ct.pTarget; +#if defined(_M_X64) || defined(__x86_64__) + pHook->pDetour = ct.pRelay; +#else + pHook->pDetour = ct.pDetour; +#endif + pHook->pTrampoline = ct.pTrampoline; + pHook->patchAbove = ct.patchAbove; + pHook->isEnabled = FALSE; + pHook->queueEnable = FALSE; + pHook->nIP = ct.nIP; + memcpy(pHook->oldIPs, ct.oldIPs, ARRAYSIZE(ct.oldIPs)); + memcpy(pHook->newIPs, ct.newIPs, ARRAYSIZE(ct.newIPs)); + + // Back up the target function. + + if (ct.patchAbove) + { + memcpy( + pHook->backup, + (LPBYTE)pTarget - sizeof(JMP_REL), + sizeof(JMP_REL) + sizeof(JMP_REL_SHORT)); + } + else + { + memcpy(pHook->backup, pTarget, sizeof(JMP_REL)); + } + + if (ppOriginal != NULL) + *ppOriginal = pHook->pTrampoline; + } + else + { + status = MH_ERROR_MEMORY_ALLOC; + } + } + else + { + status = MH_ERROR_UNSUPPORTED_FUNCTION; + } + + if (status != MH_OK) + { + FreeBuffer(pBuffer); + } + } + else + { + status = MH_ERROR_MEMORY_ALLOC; + } + } + else + { + status = MH_ERROR_ALREADY_CREATED; + } + } + else + { + status = MH_ERROR_NOT_EXECUTABLE; + } + } + else + { + status = MH_ERROR_NOT_INITIALIZED; + } + + LeaveSpinLock(); + + return status; +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget) +{ + MH_STATUS status = MH_OK; + + EnterSpinLock(); + + if (g_hHeap != NULL) + { + UINT pos = FindHookEntry(pTarget); + if (pos != INVALID_HOOK_POS) + { + if (g_hooks.pItems[pos].isEnabled) + { + FROZEN_THREADS threads; + Freeze(&threads, pos, ACTION_DISABLE); + + status = EnableHookLL(pos, FALSE); + + Unfreeze(&threads); + } + + if (status == MH_OK) + { + FreeBuffer(g_hooks.pItems[pos].pTrampoline); + DeleteHookEntry(pos); + } + } + else + { + status = MH_ERROR_NOT_CREATED; + } + } + else + { + status = MH_ERROR_NOT_INITIALIZED; + } + + LeaveSpinLock(); + + return status; +} + +//------------------------------------------------------------------------- +static MH_STATUS EnableHook(LPVOID pTarget, BOOL enable) +{ + MH_STATUS status = MH_OK; + + EnterSpinLock(); + + if (g_hHeap != NULL) + { + if (pTarget == MH_ALL_HOOKS) + { + status = EnableAllHooksLL(enable); + } + else + { + FROZEN_THREADS threads; + UINT pos = FindHookEntry(pTarget); + if (pos != INVALID_HOOK_POS) + { + if (g_hooks.pItems[pos].isEnabled != enable) + { + Freeze(&threads, pos, ACTION_ENABLE); + + status = EnableHookLL(pos, enable); + + Unfreeze(&threads); + } + else + { + status = enable ? MH_ERROR_ENABLED : MH_ERROR_DISABLED; + } + } + else + { + status = MH_ERROR_NOT_CREATED; + } + } + } + else + { + status = MH_ERROR_NOT_INITIALIZED; + } + + LeaveSpinLock(); + + return status; +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget) +{ + return EnableHook(pTarget, TRUE); +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget) +{ + return EnableHook(pTarget, FALSE); +} + +//------------------------------------------------------------------------- +static MH_STATUS QueueHook(LPVOID pTarget, BOOL queueEnable) +{ + MH_STATUS status = MH_OK; + + EnterSpinLock(); + + if (g_hHeap != NULL) + { + if (pTarget == MH_ALL_HOOKS) + { + UINT i; + for (i = 0; i < g_hooks.size; ++i) + g_hooks.pItems[i].queueEnable = queueEnable; + } + else + { + UINT pos = FindHookEntry(pTarget); + if (pos != INVALID_HOOK_POS) + { + g_hooks.pItems[pos].queueEnable = queueEnable; + } + else + { + status = MH_ERROR_NOT_CREATED; + } + } + } + else + { + status = MH_ERROR_NOT_INITIALIZED; + } + + LeaveSpinLock(); + + return status; +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget) +{ + return QueueHook(pTarget, TRUE); +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget) +{ + return QueueHook(pTarget, FALSE); +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_ApplyQueued(VOID) +{ + MH_STATUS status = MH_OK; + UINT i, first = INVALID_HOOK_POS; + + EnterSpinLock(); + + if (g_hHeap != NULL) + { + for (i = 0; i < g_hooks.size; ++i) + { + if (g_hooks.pItems[i].isEnabled != g_hooks.pItems[i].queueEnable) + { + first = i; + break; + } + } + + if (first != INVALID_HOOK_POS) + { + FROZEN_THREADS threads; + Freeze(&threads, ALL_HOOKS_POS, ACTION_APPLY_QUEUED); + + for (i = first; i < g_hooks.size; ++i) + { + PHOOK_ENTRY pHook = &g_hooks.pItems[i]; + if (pHook->isEnabled != pHook->queueEnable) + { + status = EnableHookLL(i, pHook->queueEnable); + if (status != MH_OK) + break; + } + } + + Unfreeze(&threads); + } + } + else + { + status = MH_ERROR_NOT_INITIALIZED; + } + + LeaveSpinLock(); + + return status; +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_CreateHookApiEx( + LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, + LPVOID *ppOriginal, LPVOID *ppTarget) +{ + HMODULE hModule; + LPVOID pTarget; + + hModule = GetModuleHandleW(pszModule); + if (hModule == NULL) + return MH_ERROR_MODULE_NOT_FOUND; + + pTarget = (LPVOID)GetProcAddress(hModule, pszProcName); + if (pTarget == NULL) + return MH_ERROR_FUNCTION_NOT_FOUND; + + if(ppTarget != NULL) + *ppTarget = pTarget; + + return MH_CreateHook(pTarget, pDetour, ppOriginal); +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_CreateHookApi( + LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal) +{ + return MH_CreateHookApiEx(pszModule, pszProcName, pDetour, ppOriginal, NULL); +} + +//------------------------------------------------------------------------- +const char * WINAPI MH_StatusToString(MH_STATUS status) +{ +#define MH_ST2STR(x) \ + case x: \ + return #x; + + switch (status) { + MH_ST2STR(MH_UNKNOWN) + MH_ST2STR(MH_OK) + MH_ST2STR(MH_ERROR_ALREADY_INITIALIZED) + MH_ST2STR(MH_ERROR_NOT_INITIALIZED) + MH_ST2STR(MH_ERROR_ALREADY_CREATED) + MH_ST2STR(MH_ERROR_NOT_CREATED) + MH_ST2STR(MH_ERROR_ENABLED) + MH_ST2STR(MH_ERROR_DISABLED) + MH_ST2STR(MH_ERROR_NOT_EXECUTABLE) + MH_ST2STR(MH_ERROR_UNSUPPORTED_FUNCTION) + MH_ST2STR(MH_ERROR_MEMORY_ALLOC) + MH_ST2STR(MH_ERROR_MEMORY_PROTECT) + MH_ST2STR(MH_ERROR_MODULE_NOT_FOUND) + MH_ST2STR(MH_ERROR_FUNCTION_NOT_FOUND) + } + +#undef MH_ST2STR + + return "(unknown)"; +} diff --git a/deps/src/trampoline.c b/deps/src/trampoline.c new file mode 100644 index 0000000..ac37f0f --- /dev/null +++ b/deps/src/trampoline.c @@ -0,0 +1,316 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#ifndef ARRAYSIZE + #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) +#endif + +#if defined(_M_X64) || defined(__x86_64__) + #include "./hde/hde64.h" + typedef hde64s HDE; + #define HDE_DISASM(code, hs) hde64_disasm(code, hs) +#else + #include "./hde/hde32.h" + typedef hde32s HDE; + #define HDE_DISASM(code, hs) hde32_disasm(code, hs) +#endif + +#include "trampoline.h" +#include "buffer.h" + +// Maximum size of a trampoline function. +#if defined(_M_X64) || defined(__x86_64__) + #define TRAMPOLINE_MAX_SIZE (MEMORY_SLOT_SIZE - sizeof(JMP_ABS)) +#else + #define TRAMPOLINE_MAX_SIZE MEMORY_SLOT_SIZE +#endif + +//------------------------------------------------------------------------- +static BOOL IsCodePadding(LPBYTE pInst, UINT size) +{ + UINT i; + + if (pInst[0] != 0x00 && pInst[0] != 0x90 && pInst[0] != 0xCC) + return FALSE; + + for (i = 1; i < size; ++i) + { + if (pInst[i] != pInst[0]) + return FALSE; + } + return TRUE; +} + +//------------------------------------------------------------------------- +BOOL CreateTrampolineFunction(PTRAMPOLINE ct) +{ +#if defined(_M_X64) || defined(__x86_64__) + CALL_ABS call = { + 0xFF, 0x15, 0x00000002, // FF15 00000002: CALL [RIP+8] + 0xEB, 0x08, // EB 08: JMP +10 + 0x0000000000000000ULL // Absolute destination address + }; + JMP_ABS jmp = { + 0xFF, 0x25, 0x00000000, // FF25 00000000: JMP [RIP+6] + 0x0000000000000000ULL // Absolute destination address + }; + JCC_ABS jcc = { + 0x70, 0x0E, // 7* 0E: J** +16 + 0xFF, 0x25, 0x00000000, // FF25 00000000: JMP [RIP+6] + 0x0000000000000000ULL // Absolute destination address + }; +#else + CALL_REL call = { + 0xE8, // E8 xxxxxxxx: CALL +5+xxxxxxxx + 0x00000000 // Relative destination address + }; + JMP_REL jmp = { + 0xE9, // E9 xxxxxxxx: JMP +5+xxxxxxxx + 0x00000000 // Relative destination address + }; + JCC_REL jcc = { + 0x0F, 0x80, // 0F8* xxxxxxxx: J** +6+xxxxxxxx + 0x00000000 // Relative destination address + }; +#endif + + UINT8 oldPos = 0; + UINT8 newPos = 0; + ULONG_PTR jmpDest = 0; // Destination address of an internal jump. + BOOL finished = FALSE; // Is the function completed? +#if defined(_M_X64) || defined(__x86_64__) + UINT8 instBuf[16]; +#endif + + ct->patchAbove = FALSE; + ct->nIP = 0; + + do + { + HDE hs; + UINT copySize; + LPVOID pCopySrc; + ULONG_PTR pOldInst = (ULONG_PTR)ct->pTarget + oldPos; + ULONG_PTR pNewInst = (ULONG_PTR)ct->pTrampoline + newPos; + + copySize = HDE_DISASM((LPVOID)pOldInst, &hs); + if (hs.flags & F_ERROR) + return FALSE; + + pCopySrc = (LPVOID)pOldInst; + if (oldPos >= sizeof(JMP_REL)) + { + // The trampoline function is long enough. + // Complete the function with the jump to the target function. +#if defined(_M_X64) || defined(__x86_64__) + jmp.address = pOldInst; +#else + jmp.operand = (UINT32)(pOldInst - (pNewInst + sizeof(jmp))); +#endif + pCopySrc = &jmp; + copySize = sizeof(jmp); + + finished = TRUE; + } +#if defined(_M_X64) || defined(__x86_64__) + else if ((hs.modrm & 0xC7) == 0x05) + { + // Instructions using RIP relative addressing. (ModR/M = 00???101B) + + // Modify the RIP relative address. + PUINT32 pRelAddr; + + // Avoid using memcpy to reduce the footprint. +#ifndef _MSC_VER + memcpy(instBuf, (LPBYTE)pOldInst, copySize); +#else + __movsb(instBuf, (LPBYTE)pOldInst, copySize); +#endif + pCopySrc = instBuf; + + // Relative address is stored at (instruction length - immediate value length - 4). + pRelAddr = (PUINT32)(instBuf + hs.len - ((hs.flags & 0x3C) >> 2) - 4); + *pRelAddr + = (UINT32)((pOldInst + hs.len + (INT32)hs.disp.disp32) - (pNewInst + hs.len)); + + // Complete the function if JMP (FF /4). + if (hs.opcode == 0xFF && hs.modrm_reg == 4) + finished = TRUE; + } +#endif + else if (hs.opcode == 0xE8) + { + // Direct relative CALL + ULONG_PTR dest = pOldInst + hs.len + (INT32)hs.imm.imm32; +#if defined(_M_X64) || defined(__x86_64__) + call.address = dest; +#else + call.operand = (UINT32)(dest - (pNewInst + sizeof(call))); +#endif + pCopySrc = &call; + copySize = sizeof(call); + } + else if ((hs.opcode & 0xFD) == 0xE9) + { + // Direct relative JMP (EB or E9) + ULONG_PTR dest = pOldInst + hs.len; + + if (hs.opcode == 0xEB) // isShort jmp + dest += (INT8)hs.imm.imm8; + else + dest += (INT32)hs.imm.imm32; + + // Simply copy an internal jump. + if ((ULONG_PTR)ct->pTarget <= dest + && dest < ((ULONG_PTR)ct->pTarget + sizeof(JMP_REL))) + { + if (jmpDest < dest) + jmpDest = dest; + } + else + { +#if defined(_M_X64) || defined(__x86_64__) + jmp.address = dest; +#else + jmp.operand = (UINT32)(dest - (pNewInst + sizeof(jmp))); +#endif + pCopySrc = &jmp; + copySize = sizeof(jmp); + + // Exit the function If it is not in the branch + finished = (pOldInst >= jmpDest); + } + } + else if ((hs.opcode & 0xF0) == 0x70 + || (hs.opcode & 0xFC) == 0xE0 + || (hs.opcode2 & 0xF0) == 0x80) + { + // Direct relative Jcc + ULONG_PTR dest = pOldInst + hs.len; + + if ((hs.opcode & 0xF0) == 0x70 // Jcc + || (hs.opcode & 0xFC) == 0xE0) // LOOPNZ/LOOPZ/LOOP/JECXZ + dest += (INT8)hs.imm.imm8; + else + dest += (INT32)hs.imm.imm32; + + // Simply copy an internal jump. + if ((ULONG_PTR)ct->pTarget <= dest + && dest < ((ULONG_PTR)ct->pTarget + sizeof(JMP_REL))) + { + if (jmpDest < dest) + jmpDest = dest; + } + else if ((hs.opcode & 0xFC) == 0xE0) + { + // LOOPNZ/LOOPZ/LOOP/JCXZ/JECXZ to the outside are not supported. + return FALSE; + } + else + { + UINT8 cond = ((hs.opcode != 0x0F ? hs.opcode : hs.opcode2) & 0x0F); +#if defined(_M_X64) || defined(__x86_64__) + // Invert the condition in x64 mode to simplify the conditional jump logic. + jcc.opcode = 0x71 ^ cond; + jcc.address = dest; +#else + jcc.opcode1 = 0x80 | cond; + jcc.operand = (UINT32)(dest - (pNewInst + sizeof(jcc))); +#endif + pCopySrc = &jcc; + copySize = sizeof(jcc); + } + } + else if ((hs.opcode & 0xFE) == 0xC2) + { + // RET (C2 or C3) + + // Complete the function if not in a branch. + finished = (pOldInst >= jmpDest); + } + + // Can't alter the instruction length in a branch. + if (pOldInst < jmpDest && copySize != hs.len) + return FALSE; + + // Trampoline function is too large. + if ((newPos + copySize) > TRAMPOLINE_MAX_SIZE) + return FALSE; + + // Trampoline function has too many instructions. + if (ct->nIP >= ARRAYSIZE(ct->oldIPs)) + return FALSE; + + ct->oldIPs[ct->nIP] = oldPos; + ct->newIPs[ct->nIP] = newPos; + ct->nIP++; + + // Avoid using memcpy to reduce the footprint. +#ifndef _MSC_VER + memcpy((LPBYTE)ct->pTrampoline + newPos, pCopySrc, copySize); +#else + __movsb((LPBYTE)ct->pTrampoline + newPos, pCopySrc, copySize); +#endif + newPos += copySize; + oldPos += hs.len; + } + while (!finished); + + // Is there enough place for a long jump? + if (oldPos < sizeof(JMP_REL) + && !IsCodePadding((LPBYTE)ct->pTarget + oldPos, sizeof(JMP_REL) - oldPos)) + { + // Is there enough place for a short jump? + if (oldPos < sizeof(JMP_REL_SHORT) + && !IsCodePadding((LPBYTE)ct->pTarget + oldPos, sizeof(JMP_REL_SHORT) - oldPos)) + { + return FALSE; + } + + // Can we place the long jump above the function? + if (!IsExecutableAddress((LPBYTE)ct->pTarget - sizeof(JMP_REL))) + return FALSE; + + if (!IsCodePadding((LPBYTE)ct->pTarget - sizeof(JMP_REL), sizeof(JMP_REL))) + return FALSE; + + ct->patchAbove = TRUE; + } + +#if defined(_M_X64) || defined(__x86_64__) + // Create a relay function. + jmp.address = (ULONG_PTR)ct->pDetour; + + ct->pRelay = (LPBYTE)ct->pTrampoline + newPos; + memcpy(ct->pRelay, &jmp, sizeof(jmp)); +#endif + + return TRUE; +} diff --git a/deps/src/trampoline.h b/deps/src/trampoline.h new file mode 100644 index 0000000..bdffdac --- /dev/null +++ b/deps/src/trampoline.h @@ -0,0 +1,105 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#pragma pack(push, 1) + +// Structs for writing x86/x64 instructions. + +// 8-bit relative jump. +typedef struct _JMP_REL_SHORT +{ + UINT8 opcode; // EB xx: JMP +2+xx + UINT8 operand; +} JMP_REL_SHORT, *PJMP_REL_SHORT; + +// 32-bit direct relative jump/call. +typedef struct _JMP_REL +{ + UINT8 opcode; // E9/E8 xxxxxxxx: JMP/CALL +5+xxxxxxxx + UINT32 operand; // Relative destination address +} JMP_REL, *PJMP_REL, CALL_REL; + +// 64-bit indirect absolute jump. +typedef struct _JMP_ABS +{ + UINT8 opcode0; // FF25 00000000: JMP [+6] + UINT8 opcode1; + UINT32 dummy; + UINT64 address; // Absolute destination address +} JMP_ABS, *PJMP_ABS; + +// 64-bit indirect absolute call. +typedef struct _CALL_ABS +{ + UINT8 opcode0; // FF15 00000002: CALL [+6] + UINT8 opcode1; + UINT32 dummy0; + UINT8 dummy1; // EB 08: JMP +10 + UINT8 dummy2; + UINT64 address; // Absolute destination address +} CALL_ABS; + +// 32-bit direct relative conditional jumps. +typedef struct _JCC_REL +{ + UINT8 opcode0; // 0F8* xxxxxxxx: J** +6+xxxxxxxx + UINT8 opcode1; + UINT32 operand; // Relative destination address +} JCC_REL; + +// 64bit indirect absolute conditional jumps that x64 lacks. +typedef struct _JCC_ABS +{ + UINT8 opcode; // 7* 0E: J** +16 + UINT8 dummy0; + UINT8 dummy1; // FF25 00000000: JMP [+6] + UINT8 dummy2; + UINT32 dummy3; + UINT64 address; // Absolute destination address +} JCC_ABS; + +#pragma pack(pop) + +typedef struct _TRAMPOLINE +{ + LPVOID pTarget; // [In] Address of the target function. + LPVOID pDetour; // [In] Address of the detour function. + LPVOID pTrampoline; // [In] Buffer address for the trampoline and relay function. + +#if defined(_M_X64) || defined(__x86_64__) + LPVOID pRelay; // [Out] Address of the relay function. +#endif + BOOL patchAbove; // [Out] Should use the hot patch area? + UINT nIP; // [Out] Number of the instruction boundaries. + UINT8 oldIPs[8]; // [Out] Instruction boundaries of the target function. + UINT8 newIPs[8]; // [Out] Instruction boundaries of the trampoline function. +} TRAMPOLINE, *PTRAMPOLINE; + +BOOL CreateTrampolineFunction(PTRAMPOLINE ct); diff --git a/deps/udis86/libudis86/decode.c b/deps/udis86/libudis86/decode.c new file mode 100644 index 0000000..036b9ed --- /dev/null +++ b/deps/udis86/libudis86/decode.c @@ -0,0 +1,1266 @@ +/* udis86 - libudis86/decode.c + * + * Copyright (c) 2002-2009 Vivek Thampi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "udint.h" +#include "types.h" +#include "extern.h" +#include "decode.h" + +#ifndef __UD_STANDALONE__ +# include +#endif /* __UD_STANDALONE__ */ + +/* The max number of prefixes to an instruction */ +#define MAX_PREFIXES 15 + +/* rex prefix bits */ +#define REX_W(r) ( ( 0xF & ( r ) ) >> 3 ) +#define REX_R(r) ( ( 0x7 & ( r ) ) >> 2 ) +#define REX_X(r) ( ( 0x3 & ( r ) ) >> 1 ) +#define REX_B(r) ( ( 0x1 & ( r ) ) >> 0 ) +#define REX_PFX_MASK(n) ( ( P_REXW(n) << 3 ) | \ + ( P_REXR(n) << 2 ) | \ + ( P_REXX(n) << 1 ) | \ + ( P_REXB(n) << 0 ) ) + +/* scable-index-base bits */ +#define SIB_S(b) ( ( b ) >> 6 ) +#define SIB_I(b) ( ( ( b ) >> 3 ) & 7 ) +#define SIB_B(b) ( ( b ) & 7 ) + +/* modrm bits */ +#define MODRM_REG(b) ( ( ( b ) >> 3 ) & 7 ) +#define MODRM_NNN(b) ( ( ( b ) >> 3 ) & 7 ) +#define MODRM_MOD(b) ( ( ( b ) >> 6 ) & 3 ) +#define MODRM_RM(b) ( ( b ) & 7 ) + +static int decode_ext(struct ud *u, uint16_t ptr); +static int decode_opcode(struct ud *u); + +enum reg_class { /* register classes */ + REGCLASS_GPR, + REGCLASS_MMX, + REGCLASS_CR, + REGCLASS_DB, + REGCLASS_SEG, + REGCLASS_XMM +}; + + /* + * inp_start + * Should be called before each de-code operation. + */ +static void +inp_start(struct ud *u) +{ + u->inp_ctr = 0; +} + +static uint8_t +inp_peek(struct ud *u) +{ + if (u->inp_end == 0) { + if (u->inp_buf != NULL) { + if (u->inp_buf_index < u->inp_buf_size) { + return u->inp_buf[u->inp_buf_index]; + } + } else if (u->inp_peek != UD_EOI) { + return u->inp_peek; + } else { + int c; + if ((c = u->inp_hook(u)) != UD_EOI) { + u->inp_peek = c; + return u->inp_peek; + } + } + } + u->inp_end = 1; + UDERR(u, "byte expected, eoi received\n"); + return 0; +} + +static uint8_t +inp_next(struct ud *u) +{ + if (u->inp_end == 0) { + if (u->inp_buf != NULL) { + if (u->inp_buf_index < u->inp_buf_size) { + u->inp_ctr++; + return (u->inp_curr = u->inp_buf[u->inp_buf_index++]); + } + } else { + int c = u->inp_peek; + if (c != UD_EOI || (c = u->inp_hook(u)) != UD_EOI) { + u->inp_peek = UD_EOI; + u->inp_curr = c; + u->inp_sess[u->inp_ctr++] = u->inp_curr; + return u->inp_curr; + } + } + } + u->inp_end = 1; + UDERR(u, "byte expected, eoi received\n"); + return 0; +} + +static uint8_t +inp_curr(struct ud *u) +{ + return u->inp_curr; +} + + +/* + * inp_uint8 + * int_uint16 + * int_uint32 + * int_uint64 + * Load little-endian values from input + */ +static uint8_t +inp_uint8(struct ud* u) +{ + return inp_next(u); +} + +static uint16_t +inp_uint16(struct ud* u) +{ + uint16_t r, ret; + + ret = inp_next(u); + r = inp_next(u); + return ret | (r << 8); +} + +static uint32_t +inp_uint32(struct ud* u) +{ + uint32_t r, ret; + + ret = inp_next(u); + r = inp_next(u); + ret = ret | (r << 8); + r = inp_next(u); + ret = ret | (r << 16); + r = inp_next(u); + return ret | (r << 24); +} + +static uint64_t +inp_uint64(struct ud* u) +{ + uint64_t r, ret; + + ret = inp_next(u); + r = inp_next(u); + ret = ret | (r << 8); + r = inp_next(u); + ret = ret | (r << 16); + r = inp_next(u); + ret = ret | (r << 24); + r = inp_next(u); + ret = ret | (r << 32); + r = inp_next(u); + ret = ret | (r << 40); + r = inp_next(u); + ret = ret | (r << 48); + r = inp_next(u); + return ret | (r << 56); +} + + +static UD_INLINE int +eff_opr_mode(int dis_mode, int rex_w, int pfx_opr) +{ + if (dis_mode == 64) { + return rex_w ? 64 : (pfx_opr ? 16 : 32); + } else if (dis_mode == 32) { + return pfx_opr ? 16 : 32; + } else { + UD_ASSERT(dis_mode == 16); + return pfx_opr ? 32 : 16; + } +} + + +static UD_INLINE int +eff_adr_mode(int dis_mode, int pfx_adr) +{ + if (dis_mode == 64) { + return pfx_adr ? 32 : 64; + } else if (dis_mode == 32) { + return pfx_adr ? 16 : 32; + } else { + UD_ASSERT(dis_mode == 16); + return pfx_adr ? 32 : 16; + } +} + + +/* + * decode_prefixes + * + * Extracts instruction prefixes. + */ +static int +decode_prefixes(struct ud *u) +{ + int done = 0; + uint8_t curr = 0, last = 0; + UD_RETURN_ON_ERROR(u); + + do { + last = curr; + curr = inp_next(u); + UD_RETURN_ON_ERROR(u); + if (u->inp_ctr == MAX_INSN_LENGTH) { + UD_RETURN_WITH_ERROR(u, "max instruction length"); + } + + switch (curr) + { + case 0x2E: + u->pfx_seg = UD_R_CS; + break; + case 0x36: + u->pfx_seg = UD_R_SS; + break; + case 0x3E: + u->pfx_seg = UD_R_DS; + break; + case 0x26: + u->pfx_seg = UD_R_ES; + break; + case 0x64: + u->pfx_seg = UD_R_FS; + break; + case 0x65: + u->pfx_seg = UD_R_GS; + break; + case 0x67: /* adress-size override prefix */ + u->pfx_adr = 0x67; + break; + case 0xF0: + u->pfx_lock = 0xF0; + break; + case 0x66: + u->pfx_opr = 0x66; + break; + case 0xF2: + u->pfx_str = 0xf2; + break; + case 0xF3: + u->pfx_str = 0xf3; + break; + default: + /* consume if rex */ + done = (u->dis_mode == 64 && (curr & 0xF0) == 0x40) ? 0 : 1; + break; + } + } while (!done); + /* rex prefixes in 64bit mode, must be the last prefix */ + if (u->dis_mode == 64 && (last & 0xF0) == 0x40) { + u->pfx_rex = last; + } + return 0; +} + + +/* + * vex_l, vex_w + * Return the vex.L and vex.W bits + */ +static UD_INLINE uint8_t +vex_l(const struct ud *u) +{ + UD_ASSERT(u->vex_op != 0); + return ((u->vex_op == 0xc4 ? u->vex_b2 : u->vex_b1) >> 2) & 1; +} + +static UD_INLINE uint8_t +vex_w(const struct ud *u) +{ + UD_ASSERT(u->vex_op != 0); + return u->vex_op == 0xc4 ? ((u->vex_b2 >> 7) & 1) : 0; +} + + +static UD_INLINE uint8_t +modrm(struct ud * u) +{ + if ( !u->have_modrm ) { + u->modrm = inp_next( u ); + u->modrm_offset = (uint8_t) (u->inp_ctr - 1); + u->have_modrm = 1; + } + return u->modrm; +} + + +static unsigned int +resolve_operand_size(const struct ud* u, ud_operand_size_t osize) +{ + switch (osize) { + case SZ_V: + return u->opr_mode; + case SZ_Z: + return u->opr_mode == 16 ? 16 : 32; + case SZ_Y: + return u->opr_mode == 16 ? 32 : u->opr_mode; + case SZ_RDQ: + return u->dis_mode == 64 ? 64 : 32; + case SZ_X: + UD_ASSERT(u->vex_op != 0); + return (P_VEXL(u->itab_entry->prefix) && vex_l(u)) ? SZ_QQ : SZ_DQ; + default: + return osize; + } +} + + +static int resolve_mnemonic( struct ud* u ) +{ + /* resolve 3dnow weirdness. */ + if ( u->mnemonic == UD_I3dnow ) { + u->mnemonic = ud_itab[ u->le->table[ inp_curr( u ) ] ].mnemonic; + } + /* SWAPGS is only valid in 64bits mode */ + if ( u->mnemonic == UD_Iswapgs && u->dis_mode != 64 ) { + UDERR(u, "swapgs invalid in 64bits mode\n"); + return -1; + } + + if (u->mnemonic == UD_Ixchg) { + if ((u->operand[0].type == UD_OP_REG && u->operand[0].base == UD_R_AX && + u->operand[1].type == UD_OP_REG && u->operand[1].base == UD_R_AX) || + (u->operand[0].type == UD_OP_REG && u->operand[0].base == UD_R_EAX && + u->operand[1].type == UD_OP_REG && u->operand[1].base == UD_R_EAX)) { + u->operand[0].type = UD_NONE; + u->operand[1].type = UD_NONE; + u->mnemonic = UD_Inop; + } + } + + if (u->mnemonic == UD_Inop && u->pfx_repe) { + u->pfx_repe = 0; + u->mnemonic = UD_Ipause; + } + return 0; +} + + +/* ----------------------------------------------------------------------------- + * decode_a()- Decodes operands of the type seg:offset + * ----------------------------------------------------------------------------- + */ +static void +decode_a(struct ud* u, struct ud_operand *op) +{ + if (u->opr_mode == 16) { + /* seg16:off16 */ + op->type = UD_OP_PTR; + op->size = 32; + op->lval.ptr.off = inp_uint16(u); + op->lval.ptr.seg = inp_uint16(u); + } else { + /* seg16:off32 */ + op->type = UD_OP_PTR; + op->size = 48; + op->lval.ptr.off = inp_uint32(u); + op->lval.ptr.seg = inp_uint16(u); + } +} + +/* ----------------------------------------------------------------------------- + * decode_gpr() - Returns decoded General Purpose Register + * ----------------------------------------------------------------------------- + */ +static enum ud_type +decode_gpr(register struct ud* u, unsigned int s, unsigned char rm) +{ + switch (s) { + case 64: + return UD_R_RAX + rm; + case 32: + return UD_R_EAX + rm; + case 16: + return UD_R_AX + rm; + case 8: + if (u->dis_mode == 64 && u->pfx_rex) { + if (rm >= 4) + return UD_R_SPL + (rm-4); + return UD_R_AL + rm; + } else return UD_R_AL + rm; + case 0: + /* invalid size in case of a decode error */ + UD_ASSERT(u->error); + return UD_NONE; + default: + UD_ASSERT(!"invalid operand size"); + return UD_NONE; + } +} + +static void +decode_reg(struct ud *u, + struct ud_operand *opr, + int type, + int num, + int size) +{ + int reg; + size = resolve_operand_size(u, size); + switch (type) { + case REGCLASS_GPR : reg = decode_gpr(u, size, num); break; + case REGCLASS_MMX : reg = UD_R_MM0 + (num & 7); break; + case REGCLASS_XMM : + reg = num + (size == SZ_QQ ? UD_R_YMM0 : UD_R_XMM0); + break; + case REGCLASS_CR : reg = UD_R_CR0 + num; break; + case REGCLASS_DB : reg = UD_R_DR0 + num; break; + case REGCLASS_SEG : { + /* + * Only 6 segment registers, anything else is an error. + */ + if ((num & 7) > 5) { + UDERR(u, "invalid segment register value\n"); + return; + } else { + reg = UD_R_ES + (num & 7); + } + break; + } + default: + UD_ASSERT(!"invalid register type"); + return; + } + opr->type = UD_OP_REG; + opr->base = reg; + opr->size = size; +} + + +/* + * decode_imm + * + * Decode Immediate values. + */ +static void +decode_imm(struct ud* u, unsigned int size, struct ud_operand *op) +{ + op->size = resolve_operand_size(u, size); + op->type = UD_OP_IMM; + + switch (op->size) { + case 8: op->lval.sbyte = inp_uint8(u); break; + case 16: op->lval.uword = inp_uint16(u); break; + case 32: op->lval.udword = inp_uint32(u); break; + case 64: op->lval.uqword = inp_uint64(u); break; + default: return; + } +} + + +/* + * decode_mem_disp + * + * Decode mem address displacement. + */ +static void +decode_mem_disp(struct ud* u, unsigned int size, struct ud_operand *op) +{ + switch (size) { + case 8: + op->offset = 8; + op->lval.ubyte = inp_uint8(u); + break; + case 16: + op->offset = 16; + op->lval.uword = inp_uint16(u); + break; + case 32: + op->offset = 32; + op->lval.udword = inp_uint32(u); + break; + case 64: + op->offset = 64; + op->lval.uqword = inp_uint64(u); + break; + default: + return; + } +} + + +/* + * decode_modrm_reg + * + * Decodes reg field of mod/rm byte + * + */ +static UD_INLINE void +decode_modrm_reg(struct ud *u, + struct ud_operand *operand, + unsigned int type, + unsigned int size) +{ + uint8_t reg = (REX_R(u->_rex) << 3) | MODRM_REG(modrm(u)); + decode_reg(u, operand, type, reg, size); +} + + +/* + * decode_modrm_rm + * + * Decodes rm field of mod/rm byte + * + */ +static void +decode_modrm_rm(struct ud *u, + struct ud_operand *op, + unsigned char type, /* register type */ + unsigned int size) /* operand size */ + +{ + size_t offset = 0; + unsigned char mod, rm; + + /* get mod, r/m and reg fields */ + mod = MODRM_MOD(modrm(u)); + rm = (REX_B(u->_rex) << 3) | MODRM_RM(modrm(u)); + + /* + * If mod is 11b, then the modrm.rm specifies a register. + * + */ + if (mod == 3) { + decode_reg(u, op, type, rm, size); + return; + } + + /* + * !11b => Memory Address + */ + op->type = UD_OP_MEM; + op->size = resolve_operand_size(u, size); + + if (u->adr_mode == 64) { + op->base = UD_R_RAX + rm; + if (mod == 1) { + offset = 8; + } else if (mod == 2) { + offset = 32; + } else if (mod == 0 && (rm & 7) == 5) { + op->base = UD_R_RIP; + offset = 32; + } else { + offset = 0; + } + /* + * Scale-Index-Base (SIB) + */ + if ((rm & 7) == 4) { + inp_next(u); + + op->base = UD_R_RAX + (SIB_B(inp_curr(u)) | (REX_B(u->_rex) << 3)); + op->index = UD_R_RAX + (SIB_I(inp_curr(u)) | (REX_X(u->_rex) << 3)); + /* special conditions for base reference */ + if (op->index == UD_R_RSP) { + op->index = UD_NONE; + op->scale = UD_NONE; + } else { + op->scale = (1 << SIB_S(inp_curr(u))) & ~1; + } + + if (op->base == UD_R_RBP || op->base == UD_R_R13) { + if (mod == 0) { + op->base = UD_NONE; + } + if (mod == 1) { + offset = 8; + } else { + offset = 32; + } + } + } else { + op->scale = UD_NONE; + op->index = UD_NONE; + } + } else if (u->adr_mode == 32) { + op->base = UD_R_EAX + rm; + if (mod == 1) { + offset = 8; + } else if (mod == 2) { + offset = 32; + } else if (mod == 0 && rm == 5) { + op->base = UD_NONE; + offset = 32; + } else { + offset = 0; + } + + /* Scale-Index-Base (SIB) */ + if ((rm & 7) == 4) { + inp_next(u); + + op->scale = (1 << SIB_S(inp_curr(u))) & ~1; + op->index = UD_R_EAX + (SIB_I(inp_curr(u)) | (REX_X(u->pfx_rex) << 3)); + op->base = UD_R_EAX + (SIB_B(inp_curr(u)) | (REX_B(u->pfx_rex) << 3)); + + if (op->index == UD_R_ESP) { + op->index = UD_NONE; + op->scale = UD_NONE; + } + + /* special condition for base reference */ + if (op->base == UD_R_EBP) { + if (mod == 0) { + op->base = UD_NONE; + } + if (mod == 1) { + offset = 8; + } else { + offset = 32; + } + } + } else { + op->scale = UD_NONE; + op->index = UD_NONE; + } + } else { + const unsigned int bases[] = { UD_R_BX, UD_R_BX, UD_R_BP, UD_R_BP, + UD_R_SI, UD_R_DI, UD_R_BP, UD_R_BX }; + const unsigned int indices[] = { UD_R_SI, UD_R_DI, UD_R_SI, UD_R_DI, + UD_NONE, UD_NONE, UD_NONE, UD_NONE }; + op->base = bases[rm & 7]; + op->index = indices[rm & 7]; + op->scale = UD_NONE; + if (mod == 0 && rm == 6) { + offset = 16; + op->base = UD_NONE; + } else if (mod == 1) { + offset = 8; + } else if (mod == 2) { + offset = 16; + } + } + + if (offset) { + decode_mem_disp(u, offset, op); + } else { + op->offset = 0; + } +} + + +/* + * decode_moffset + * Decode offset-only memory operand + */ +static void +decode_moffset(struct ud *u, unsigned int size, struct ud_operand *opr) +{ + opr->type = UD_OP_MEM; + opr->base = UD_NONE; + opr->index = UD_NONE; + opr->scale = UD_NONE; + opr->size = resolve_operand_size(u, size); + decode_mem_disp(u, u->adr_mode, opr); +} + + +static void +decode_vex_vvvv(struct ud *u, struct ud_operand *opr, unsigned size) +{ + uint8_t vvvv; + UD_ASSERT(u->vex_op != 0); + vvvv = ((u->vex_op == 0xc4 ? u->vex_b2 : u->vex_b1) >> 3) & 0xf; + decode_reg(u, opr, REGCLASS_XMM, (0xf & ~vvvv), size); +} + + +/* + * decode_vex_immreg + * Decode source operand encoded in immediate byte [7:4] + */ +static int +decode_vex_immreg(struct ud *u, struct ud_operand *opr, unsigned size) +{ + uint8_t imm = inp_next(u); + uint8_t mask = u->dis_mode == 64 ? 0xf : 0x7; + UD_RETURN_ON_ERROR(u); + UD_ASSERT(u->vex_op != 0); + decode_reg(u, opr, REGCLASS_XMM, mask & (imm >> 4), size); + return 0; +} + + +/* + * decode_operand + * + * Decodes a single operand. + * Returns the type of the operand (UD_NONE if none) + */ +static int +decode_operand(struct ud *u, + struct ud_operand *operand, + enum ud_operand_code type, + unsigned int size) +{ + operand->type = UD_NONE; + operand->_oprcode = type; + + switch (type) { + case OP_A : + decode_a(u, operand); + break; + case OP_MR: + decode_modrm_rm(u, operand, REGCLASS_GPR, + MODRM_MOD(modrm(u)) == 3 ? + Mx_reg_size(size) : Mx_mem_size(size)); + break; + case OP_F: + u->br_far = 1; + /* intended fall through */ + case OP_M: + if (MODRM_MOD(modrm(u)) == 3) { + UDERR(u, "expected modrm.mod != 3\n"); + } + /* intended fall through */ + case OP_E: + decode_modrm_rm(u, operand, REGCLASS_GPR, size); + break; + case OP_G: + decode_modrm_reg(u, operand, REGCLASS_GPR, size); + break; + case OP_sI: + case OP_I: + decode_imm(u, size, operand); + break; + case OP_I1: + operand->type = UD_OP_CONST; + operand->lval.udword = 1; + break; + case OP_N: + if (MODRM_MOD(modrm(u)) != 3) { + UDERR(u, "expected modrm.mod == 3\n"); + } + /* intended fall through */ + case OP_Q: + decode_modrm_rm(u, operand, REGCLASS_MMX, size); + break; + case OP_P: + decode_modrm_reg(u, operand, REGCLASS_MMX, size); + break; + case OP_U: + if (MODRM_MOD(modrm(u)) != 3) { + UDERR(u, "expected modrm.mod == 3\n"); + } + /* intended fall through */ + case OP_W: + decode_modrm_rm(u, operand, REGCLASS_XMM, size); + break; + case OP_V: + decode_modrm_reg(u, operand, REGCLASS_XMM, size); + break; + case OP_H: + decode_vex_vvvv(u, operand, size); + break; + case OP_MU: + decode_modrm_rm(u, operand, REGCLASS_XMM, + MODRM_MOD(modrm(u)) == 3 ? + Mx_reg_size(size) : Mx_mem_size(size)); + break; + case OP_S: + decode_modrm_reg(u, operand, REGCLASS_SEG, size); + break; + case OP_O: + decode_moffset(u, size, operand); + break; + case OP_R0: + case OP_R1: + case OP_R2: + case OP_R3: + case OP_R4: + case OP_R5: + case OP_R6: + case OP_R7: + decode_reg(u, operand, REGCLASS_GPR, + (REX_B(u->_rex) << 3) | (type - OP_R0), size); + break; + case OP_AL: + case OP_AX: + case OP_eAX: + case OP_rAX: + decode_reg(u, operand, REGCLASS_GPR, 0, size); + break; + case OP_CL: + case OP_CX: + case OP_eCX: + decode_reg(u, operand, REGCLASS_GPR, 1, size); + break; + case OP_DL: + case OP_DX: + case OP_eDX: + decode_reg(u, operand, REGCLASS_GPR, 2, size); + break; + case OP_ES: + case OP_CS: + case OP_DS: + case OP_SS: + case OP_FS: + case OP_GS: + /* in 64bits mode, only fs and gs are allowed */ + if (u->dis_mode == 64) { + if (type != OP_FS && type != OP_GS) { + UDERR(u, "invalid segment register in 64bits\n"); + } + } + operand->type = UD_OP_REG; + operand->base = (type - OP_ES) + UD_R_ES; + operand->size = 16; + break; + case OP_J : + decode_imm(u, size, operand); + operand->type = UD_OP_JIMM; + break ; + case OP_R : + if (MODRM_MOD(modrm(u)) != 3) { + UDERR(u, "expected modrm.mod == 3\n"); + } + decode_modrm_rm(u, operand, REGCLASS_GPR, size); + break; + case OP_C: + decode_modrm_reg(u, operand, REGCLASS_CR, size); + break; + case OP_D: + decode_modrm_reg(u, operand, REGCLASS_DB, size); + break; + case OP_I3 : + operand->type = UD_OP_CONST; + operand->lval.sbyte = 3; + break; + case OP_ST0: + case OP_ST1: + case OP_ST2: + case OP_ST3: + case OP_ST4: + case OP_ST5: + case OP_ST6: + case OP_ST7: + operand->type = UD_OP_REG; + operand->base = (type - OP_ST0) + UD_R_ST0; + operand->size = 80; + break; + case OP_L: + decode_vex_immreg(u, operand, size); + break; + default : + operand->type = UD_NONE; + break; + } + return operand->type; +} + + +/* + * decode_operands + * + * Disassemble upto 3 operands of the current instruction being + * disassembled. By the end of the function, the operand fields + * of the ud structure will have been filled. + */ +static int +decode_operands(struct ud* u) +{ + decode_operand(u, &u->operand[0], + u->itab_entry->operand1.type, + u->itab_entry->operand1.size); + if (u->operand[0].type != UD_NONE) { + decode_operand(u, &u->operand[1], + u->itab_entry->operand2.type, + u->itab_entry->operand2.size); + } + if (u->operand[1].type != UD_NONE) { + decode_operand(u, &u->operand[2], + u->itab_entry->operand3.type, + u->itab_entry->operand3.size); + } + if (u->operand[2].type != UD_NONE) { + decode_operand(u, &u->operand[3], + u->itab_entry->operand4.type, + u->itab_entry->operand4.size); + } + return 0; +} + +/* ----------------------------------------------------------------------------- + * clear_insn() - clear instruction structure + * ----------------------------------------------------------------------------- + */ +static void +clear_insn(register struct ud* u) +{ + u->error = 0; + u->pfx_seg = 0; + u->pfx_opr = 0; + u->pfx_adr = 0; + u->pfx_lock = 0; + u->pfx_repne = 0; + u->pfx_rep = 0; + u->pfx_repe = 0; + u->pfx_rex = 0; + u->pfx_str = 0; + u->mnemonic = UD_Inone; + u->itab_entry = NULL; + u->have_modrm = 0; + u->br_far = 0; + u->vex_op = 0; + u->_rex = 0; + u->operand[0].type = UD_NONE; + u->operand[1].type = UD_NONE; + u->operand[2].type = UD_NONE; + u->operand[3].type = UD_NONE; +} + + +static UD_INLINE int +resolve_pfx_str(struct ud* u) +{ + if (u->pfx_str == 0xf3) { + if (P_STR(u->itab_entry->prefix)) { + u->pfx_rep = 0xf3; + } else { + u->pfx_repe = 0xf3; + } + } else if (u->pfx_str == 0xf2) { + u->pfx_repne = 0xf3; + } + return 0; +} + + +static int +resolve_mode( struct ud* u ) +{ + int default64; + /* if in error state, bail out */ + if ( u->error ) return -1; + + /* propagate prefix effects */ + if ( u->dis_mode == 64 ) { /* set 64bit-mode flags */ + + /* Check validity of instruction m64 */ + if ( P_INV64( u->itab_entry->prefix ) ) { + UDERR(u, "instruction invalid in 64bits\n"); + return -1; + } + + /* compute effective rex based on, + * - vex prefix (if any) + * - rex prefix (if any, and not vex) + * - allowed prefixes specified by the opcode map + */ + if (u->vex_op == 0xc4) { + /* vex has rex.rxb in 1's complement */ + u->_rex = ((~(u->vex_b1 >> 5) & 0x7) /* rex.0rxb */ | + ((u->vex_b2 >> 4) & 0x8) /* rex.w000 */); + } else if (u->vex_op == 0xc5) { + /* vex has rex.r in 1's complement */ + u->_rex = (~(u->vex_b1 >> 5)) & 4; + } else { + UD_ASSERT(u->vex_op == 0); + u->_rex = u->pfx_rex; + } + u->_rex &= REX_PFX_MASK(u->itab_entry->prefix); + + /* whether this instruction has a default operand size of + * 64bit, also hardcoded into the opcode map. + */ + default64 = P_DEF64( u->itab_entry->prefix ); + /* calculate effective operand size */ + if (REX_W(u->_rex)) { + u->opr_mode = 64; + } else if ( u->pfx_opr ) { + u->opr_mode = 16; + } else { + /* unless the default opr size of instruction is 64, + * the effective operand size in the absence of rex.w + * prefix is 32. + */ + u->opr_mode = default64 ? 64 : 32; + } + + /* calculate effective address size */ + u->adr_mode = (u->pfx_adr) ? 32 : 64; + } else if ( u->dis_mode == 32 ) { /* set 32bit-mode flags */ + u->opr_mode = ( u->pfx_opr ) ? 16 : 32; + u->adr_mode = ( u->pfx_adr ) ? 16 : 32; + } else if ( u->dis_mode == 16 ) { /* set 16bit-mode flags */ + u->opr_mode = ( u->pfx_opr ) ? 32 : 16; + u->adr_mode = ( u->pfx_adr ) ? 32 : 16; + } + + return 0; +} + + +static UD_INLINE int +decode_insn(struct ud *u, uint16_t ptr) +{ + UD_ASSERT((ptr & 0x8000) == 0); + u->itab_entry = &ud_itab[ ptr ]; + u->mnemonic = u->itab_entry->mnemonic; + return (resolve_pfx_str(u) == 0 && + resolve_mode(u) == 0 && + decode_operands(u) == 0 && + resolve_mnemonic(u) == 0) ? 0 : -1; +} + + +/* + * decode_3dnow() + * + * Decoding 3dnow is a little tricky because of its strange opcode + * structure. The final opcode disambiguation depends on the last + * byte that comes after the operands have been decoded. Fortunately, + * all 3dnow instructions have the same set of operand types. So we + * go ahead and decode the instruction by picking an arbitrarily chosen + * valid entry in the table, decode the operands, and read the final + * byte to resolve the menmonic. + */ +static UD_INLINE int +decode_3dnow(struct ud* u) +{ + uint16_t ptr; + UD_ASSERT(u->le->type == UD_TAB__OPC_3DNOW); + UD_ASSERT(u->le->table[0xc] != 0); + decode_insn(u, u->le->table[0xc]); + inp_next(u); + if (u->error) { + return -1; + } + ptr = u->le->table[inp_curr(u)]; + UD_ASSERT((ptr & 0x8000) == 0); + u->mnemonic = ud_itab[ptr].mnemonic; + return 0; +} + + +static int +decode_ssepfx(struct ud *u) +{ + uint8_t idx; + uint8_t pfx; + + /* + * String prefixes (f2, f3) take precedence over operand + * size prefix (66). + */ + pfx = u->pfx_str; + if (pfx == 0) { + pfx = u->pfx_opr; + } + idx = ((pfx & 0xf) + 1) / 2; + if (u->le->table[idx] == 0) { + idx = 0; + } + if (idx && u->le->table[idx] != 0) { + /* + * "Consume" the prefix as a part of the opcode, so it is no + * longer exported as an instruction prefix. + */ + u->pfx_str = 0; + if (pfx == 0x66) { + /* + * consume "66" only if it was used for decoding, leaving + * it to be used as an operands size override for some + * simd instructions. + */ + u->pfx_opr = 0; + } + } + return decode_ext(u, u->le->table[idx]); +} + + +static int +decode_vex(struct ud *u) +{ + uint8_t index; + if (u->dis_mode != 64 && MODRM_MOD(inp_peek(u)) != 0x3) { + index = 0; + } else { + u->vex_op = inp_curr(u); + u->vex_b1 = inp_next(u); + if (u->vex_op == 0xc4) { + uint8_t pp, m; + /* 3-byte vex */ + u->vex_b2 = inp_next(u); + UD_RETURN_ON_ERROR(u); + m = u->vex_b1 & 0x1f; + if (m == 0 || m > 3) { + UD_RETURN_WITH_ERROR(u, "reserved vex.m-mmmm value"); + } + pp = u->vex_b2 & 0x3; + index = (pp << 2) | m; + } else { + /* 2-byte vex */ + UD_ASSERT(u->vex_op == 0xc5); + index = 0x1 | ((u->vex_b1 & 0x3) << 2); + } + } + return decode_ext(u, u->le->table[index]); +} + + +/* + * decode_ext() + * + * Decode opcode extensions (if any) + */ +static int +decode_ext(struct ud *u, uint16_t ptr) +{ + uint8_t idx = 0; + if ((ptr & 0x8000) == 0) { + return decode_insn(u, ptr); + } + u->le = &ud_lookup_table_list[(~0x8000 & ptr)]; + if (u->le->type == UD_TAB__OPC_3DNOW) { + return decode_3dnow(u); + } + + switch (u->le->type) { + case UD_TAB__OPC_MOD: + /* !11 = 0, 11 = 1 */ + idx = (MODRM_MOD(modrm(u)) + 1) / 4; + break; + /* disassembly mode/operand size/address size based tables. + * 16 = 0,, 32 = 1, 64 = 2 + */ + case UD_TAB__OPC_MODE: + idx = u->dis_mode != 64 ? 0 : 1; + break; + case UD_TAB__OPC_OSIZE: + idx = eff_opr_mode(u->dis_mode, REX_W(u->pfx_rex), u->pfx_opr) / 32; + break; + case UD_TAB__OPC_ASIZE: + idx = eff_adr_mode(u->dis_mode, u->pfx_adr) / 32; + break; + case UD_TAB__OPC_X87: + idx = modrm(u) - 0xC0; + break; + case UD_TAB__OPC_VENDOR: + if (u->vendor == UD_VENDOR_ANY) { + /* choose a valid entry */ + idx = (u->le->table[idx] != 0) ? 0 : 1; + } else if (u->vendor == UD_VENDOR_AMD) { + idx = 0; + } else { + idx = 1; + } + break; + case UD_TAB__OPC_RM: + idx = MODRM_RM(modrm(u)); + break; + case UD_TAB__OPC_REG: + idx = MODRM_REG(modrm(u)); + break; + case UD_TAB__OPC_SSE: + return decode_ssepfx(u); + case UD_TAB__OPC_VEX: + return decode_vex(u); + case UD_TAB__OPC_VEX_W: + idx = vex_w(u); + break; + case UD_TAB__OPC_VEX_L: + idx = vex_l(u); + break; + case UD_TAB__OPC_TABLE: + inp_next(u); + return decode_opcode(u); + default: + UD_ASSERT(!"not reached"); + break; + } + + return decode_ext(u, u->le->table[idx]); +} + + +static int +decode_opcode(struct ud *u) +{ + uint16_t ptr; + UD_ASSERT(u->le->type == UD_TAB__OPC_TABLE); + UD_RETURN_ON_ERROR(u); + ptr = u->le->table[inp_curr(u)]; + return decode_ext(u, ptr); +} + + +/* ============================================================================= + * ud_decode() - Instruction decoder. Returns the number of bytes decoded. + * ============================================================================= + */ +unsigned int +ud_decode(struct ud *u) +{ + inp_start(u); + clear_insn(u); + u->le = &ud_lookup_table_list[0]; + u->error = decode_prefixes(u) == -1 || + decode_opcode(u) == -1 || + u->error; + /* Handle decode error. */ + if (u->error) { + /* clear out the decode data. */ + clear_insn(u); + /* mark the sequence of bytes as invalid. */ + u->itab_entry = &ud_itab[0]; /* entry 0 is invalid */ + u->mnemonic = u->itab_entry->mnemonic; + } + + /* maybe this stray segment override byte + * should be spewed out? + */ + if ( !P_SEG( u->itab_entry->prefix ) && + u->operand[0].type != UD_OP_MEM && + u->operand[1].type != UD_OP_MEM ) + u->pfx_seg = 0; + + u->insn_offset = u->pc; /* set offset of instruction */ + u->asm_buf_fill = 0; /* set translation buffer index to 0 */ + u->pc += u->inp_ctr; /* move program counter by bytes decoded */ + + /* return number of bytes disassembled. */ + return u->inp_ctr; +} + +/* +vim: set ts=2 sw=2 expandtab +*/ diff --git a/deps/udis86/libudis86/decode.h b/deps/udis86/libudis86/decode.h new file mode 100644 index 0000000..3949c4e --- /dev/null +++ b/deps/udis86/libudis86/decode.h @@ -0,0 +1,197 @@ +/* udis86 - libudis86/decode.h + * + * Copyright (c) 2002-2009 Vivek Thampi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef UD_DECODE_H +#define UD_DECODE_H + +#include "types.h" +#include "udint.h" +#include "itab.h" + +#define MAX_INSN_LENGTH 15 + +/* itab prefix bits */ +#define P_none ( 0 ) + +#define P_inv64 ( 1 << 0 ) +#define P_INV64(n) ( ( n >> 0 ) & 1 ) +#define P_def64 ( 1 << 1 ) +#define P_DEF64(n) ( ( n >> 1 ) & 1 ) + +#define P_oso ( 1 << 2 ) +#define P_OSO(n) ( ( n >> 2 ) & 1 ) +#define P_aso ( 1 << 3 ) +#define P_ASO(n) ( ( n >> 3 ) & 1 ) + +#define P_rexb ( 1 << 4 ) +#define P_REXB(n) ( ( n >> 4 ) & 1 ) +#define P_rexw ( 1 << 5 ) +#define P_REXW(n) ( ( n >> 5 ) & 1 ) +#define P_rexr ( 1 << 6 ) +#define P_REXR(n) ( ( n >> 6 ) & 1 ) +#define P_rexx ( 1 << 7 ) +#define P_REXX(n) ( ( n >> 7 ) & 1 ) + +#define P_seg ( 1 << 8 ) +#define P_SEG(n) ( ( n >> 8 ) & 1 ) + +#define P_vexl ( 1 << 9 ) +#define P_VEXL(n) ( ( n >> 9 ) & 1 ) +#define P_vexw ( 1 << 10 ) +#define P_VEXW(n) ( ( n >> 10 ) & 1 ) + +#define P_str ( 1 << 11 ) +#define P_STR(n) ( ( n >> 11 ) & 1 ) +#define P_strz ( 1 << 12 ) +#define P_STR_ZF(n) ( ( n >> 12 ) & 1 ) + +/* operand type constants -- order is important! */ + +enum ud_operand_code { + OP_NONE, + + OP_A, OP_E, OP_M, OP_G, + OP_I, OP_F, + + OP_R0, OP_R1, OP_R2, OP_R3, + OP_R4, OP_R5, OP_R6, OP_R7, + + OP_AL, OP_CL, OP_DL, + OP_AX, OP_CX, OP_DX, + OP_eAX, OP_eCX, OP_eDX, + OP_rAX, OP_rCX, OP_rDX, + + OP_ES, OP_CS, OP_SS, OP_DS, + OP_FS, OP_GS, + + OP_ST0, OP_ST1, OP_ST2, OP_ST3, + OP_ST4, OP_ST5, OP_ST6, OP_ST7, + + OP_J, OP_S, OP_O, + OP_I1, OP_I3, OP_sI, + + OP_V, OP_W, OP_Q, OP_P, + OP_U, OP_N, OP_MU, OP_H, + OP_L, + + OP_R, OP_C, OP_D, + + OP_MR +} UD_ATTR_PACKED; + + +/* + * Operand size constants + * + * Symbolic constants for various operand sizes. Some of these constants + * are given a value equal to the width of the data (SZ_B == 8), such + * that they maybe used interchangeably in the internals. Modifying them + * will most certainly break things! + */ +typedef uint16_t ud_operand_size_t; + +#define SZ_NA 0 +#define SZ_Z 1 +#define SZ_V 2 +#define SZ_Y 3 +#define SZ_X 4 +#define SZ_RDQ 7 +#define SZ_B 8 +#define SZ_W 16 +#define SZ_D 32 +#define SZ_Q 64 +#define SZ_T 80 +#define SZ_O 12 +#define SZ_DQ 128 /* double quad */ +#define SZ_QQ 256 /* quad quad */ + +/* + * Complex size types; that encode sizes for operands of type MR (memory or + * register); for internal use only. Id space above 256. + */ +#define SZ_BD ((SZ_B << 8) | SZ_D) +#define SZ_BV ((SZ_B << 8) | SZ_V) +#define SZ_WD ((SZ_W << 8) | SZ_D) +#define SZ_WV ((SZ_W << 8) | SZ_V) +#define SZ_WY ((SZ_W << 8) | SZ_Y) +#define SZ_DY ((SZ_D << 8) | SZ_Y) +#define SZ_WO ((SZ_W << 8) | SZ_O) +#define SZ_DO ((SZ_D << 8) | SZ_O) +#define SZ_QO ((SZ_Q << 8) | SZ_O) + + +/* resolve complex size type. + */ +static UD_INLINE ud_operand_size_t +Mx_mem_size(ud_operand_size_t size) +{ + return (size >> 8) & 0xff; +} + +static UD_INLINE ud_operand_size_t +Mx_reg_size(ud_operand_size_t size) +{ + return size & 0xff; +} + +/* A single operand of an entry in the instruction table. + * (internal use only) + */ +struct ud_itab_entry_operand +{ + enum ud_operand_code type; + ud_operand_size_t size; +}; + + +/* A single entry in an instruction table. + *(internal use only) + */ +struct ud_itab_entry +{ + enum ud_mnemonic_code mnemonic; + struct ud_itab_entry_operand operand1; + struct ud_itab_entry_operand operand2; + struct ud_itab_entry_operand operand3; + struct ud_itab_entry_operand operand4; + uint32_t prefix; +}; + +struct ud_lookup_table_list_entry { + const uint16_t *table; + enum ud_table_type type; + const char *meta; +}; + +extern struct ud_itab_entry ud_itab[]; +extern struct ud_lookup_table_list_entry ud_lookup_table_list[]; + +#endif /* UD_DECODE_H */ + +/* vim:cindent + * vim:expandtab + * vim:ts=4 + * vim:sw=4 + */ diff --git a/deps/udis86/libudis86/extern.h b/deps/udis86/libudis86/extern.h new file mode 100644 index 0000000..71a01fd --- /dev/null +++ b/deps/udis86/libudis86/extern.h @@ -0,0 +1,113 @@ +/* udis86 - libudis86/extern.h + * + * Copyright (c) 2002-2009, 2013 Vivek Thampi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef UD_EXTERN_H +#define UD_EXTERN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "types.h" + +#if defined(_MSC_VER) && defined(_USRDLL) +# ifdef LIBUDIS86_EXPORTS +# define LIBUDIS86_DLLEXTERN __declspec(dllexport) +# else +# define LIBUDIS86_DLLEXTERN __declspec(dllimport) +# endif +#else +# define LIBUDIS86_DLLEXTERN +#endif + +/* ============================= PUBLIC API ================================= */ + +extern LIBUDIS86_DLLEXTERN void ud_init(struct ud*); + +extern LIBUDIS86_DLLEXTERN void ud_set_mode(struct ud*, uint8_t); + +extern LIBUDIS86_DLLEXTERN void ud_set_pc(struct ud*, uint64_t); + +extern LIBUDIS86_DLLEXTERN void ud_set_input_hook(struct ud*, int (*)(struct ud*)); + +extern LIBUDIS86_DLLEXTERN void ud_set_input_buffer(struct ud*, const uint8_t*, size_t); + +#ifndef __UD_STANDALONE__ +extern LIBUDIS86_DLLEXTERN void ud_set_input_file(struct ud*, FILE*); +#endif /* __UD_STANDALONE__ */ + +extern LIBUDIS86_DLLEXTERN void ud_set_vendor(struct ud*, unsigned); + +extern LIBUDIS86_DLLEXTERN void ud_set_syntax(struct ud*, void (*)(struct ud*)); + +extern LIBUDIS86_DLLEXTERN void ud_input_skip(struct ud*, size_t); + +extern LIBUDIS86_DLLEXTERN int ud_input_end(const struct ud*); + +extern LIBUDIS86_DLLEXTERN unsigned int ud_decode(struct ud*); + +extern LIBUDIS86_DLLEXTERN unsigned int ud_disassemble(struct ud*); + +extern LIBUDIS86_DLLEXTERN void ud_translate_intel(struct ud*); + +extern LIBUDIS86_DLLEXTERN void ud_translate_att(struct ud*); + +extern LIBUDIS86_DLLEXTERN const char* ud_insn_asm(const struct ud* u); + +extern LIBUDIS86_DLLEXTERN const uint8_t* ud_insn_ptr(const struct ud* u); + +extern LIBUDIS86_DLLEXTERN uint64_t ud_insn_off(const struct ud*); + +extern LIBUDIS86_DLLEXTERN const char* ud_insn_hex(struct ud*); + +extern LIBUDIS86_DLLEXTERN unsigned int ud_insn_len(const struct ud* u); + +extern LIBUDIS86_DLLEXTERN const struct ud_operand* ud_insn_opr(const struct ud *u, unsigned int n); + +extern LIBUDIS86_DLLEXTERN int ud_opr_is_sreg(const struct ud_operand *opr); + +extern LIBUDIS86_DLLEXTERN int ud_opr_is_gpr(const struct ud_operand *opr); + +extern LIBUDIS86_DLLEXTERN enum ud_mnemonic_code ud_insn_mnemonic(const struct ud *u); + +extern LIBUDIS86_DLLEXTERN const char* ud_lookup_mnemonic(enum ud_mnemonic_code c); + +extern LIBUDIS86_DLLEXTERN void ud_set_user_opaque_data(struct ud*, void*); + +extern LIBUDIS86_DLLEXTERN void* ud_get_user_opaque_data(const struct ud*); + +extern LIBUDIS86_DLLEXTERN void ud_set_asm_buffer(struct ud *u, char *buf, size_t size); + +extern LIBUDIS86_DLLEXTERN void ud_set_sym_resolver(struct ud *u, + const char* (*resolver)(struct ud*, + uint64_t addr, + int64_t *offset)); + +/* ========================================================================== */ + +#ifdef __cplusplus +} +#endif +#endif /* UD_EXTERN_H */ diff --git a/deps/udis86/libudis86/itab.c b/deps/udis86/libudis86/itab.c new file mode 100644 index 0000000..953f3e5 --- /dev/null +++ b/deps/udis86/libudis86/itab.c @@ -0,0 +1,5946 @@ +/* itab.c -- generated by udis86:scripts/ud_itab.py, do no edit */ +#include "decode.h" + +#define GROUP(n) (0x8000 | (n)) +#define INVALID 0 + + +const uint16_t ud_itab__0[] = { + /* 0 */ 15, 16, 17, 18, + /* 4 */ 19, 20, GROUP(1), GROUP(2), + /* 8 */ 964, 965, 966, 967, + /* c */ 968, 969, GROUP(3), GROUP(4), + /* 10 */ 5, 6, 7, 8, + /* 14 */ 9, 10, GROUP(284), GROUP(285), + /* 18 */ 1336, 1337, 1338, 1339, + /* 1c */ 1340, 1341, GROUP(286), GROUP(287), + /* 20 */ 49, 50, 51, 52, + /* 24 */ 53, 54, INVALID, GROUP(288), + /* 28 */ 1407, 1408, 1409, 1410, + /* 2c */ 1411, 1412, INVALID, GROUP(289), + /* 30 */ 1487, 1488, 1489, 1490, + /* 34 */ 1491, 1492, INVALID, GROUP(290), + /* 38 */ 100, 101, 102, 103, + /* 3c */ 104, 105, INVALID, GROUP(291), + /* 40 */ 699, 700, 701, 702, + /* 44 */ 703, 704, 705, 706, + /* 48 */ 175, 176, 177, 178, + /* 4c */ 179, 180, 181, 182, + /* 50 */ 1246, 1247, 1248, 1249, + /* 54 */ 1250, 1251, 1252, 1253, + /* 58 */ 1101, 1102, 1103, 1104, + /* 5c */ 1105, 1106, 1107, 1108, + /* 60 */ GROUP(292), GROUP(295), GROUP(298), GROUP(299), + /* 64 */ INVALID, INVALID, INVALID, INVALID, + /* 68 */ 1254, 697, 1256, 698, + /* 6c */ 709, GROUP(300), 982, GROUP(301), + /* 70 */ 726, 728, 730, 732, + /* 74 */ 734, 736, 738, 740, + /* 78 */ 742, 744, 746, 748, + /* 7c */ 750, 752, 754, 756, + /* 80 */ GROUP(302), GROUP(303), GROUP(304), GROUP(313), + /* 84 */ 1433, 1434, 1475, 1476, + /* 88 */ 828, 829, 830, 831, + /* 8c */ 832, 770, 833, GROUP(314), + /* 90 */ 1477, 1478, 1479, 1480, + /* 94 */ 1481, 1482, 1483, 1484, + /* 98 */ GROUP(315), GROUP(316), GROUP(317), 1470, + /* 9c */ GROUP(318), GROUP(322), 1310, 766, + /* a0 */ 834, 835, 836, 837, + /* a4 */ 922, GROUP(326), 114, GROUP(327), + /* a8 */ 1435, 1436, 1402, GROUP(328), + /* ac */ 790, GROUP(329), 1346, GROUP(330), + /* b0 */ 838, 839, 840, 841, + /* b4 */ 842, 843, 844, 845, + /* b8 */ 846, 847, 848, 849, + /* bc */ 850, 851, 852, 853, + /* c0 */ GROUP(331), GROUP(332), 1301, 1302, + /* c4 */ GROUP(333), GROUP(403), GROUP(405), GROUP(406), + /* c8 */ 200, 776, 1303, 1304, + /* cc */ 713, 714, GROUP(407), GROUP(408), + /* d0 */ GROUP(409), GROUP(410), GROUP(411), GROUP(412), + /* d4 */ GROUP(413), GROUP(414), GROUP(415), 1486, + /* d8 */ GROUP(416), GROUP(419), GROUP(422), GROUP(425), + /* dc */ GROUP(428), GROUP(431), GROUP(434), GROUP(437), + /* e0 */ 794, 795, 796, GROUP(440), + /* e4 */ 690, 691, 978, 979, + /* e8 */ 72, 763, GROUP(441), 765, + /* ec */ 692, 693, 980, 981, + /* f0 */ 789, 712, 1299, 1300, + /* f4 */ 687, 83, GROUP(442), GROUP(443), + /* f8 */ 77, 1395, 81, 1398, + /* fc */ 78, 1396, GROUP(444), GROUP(445), +}; + +static const uint16_t ud_itab__1[] = { + /* 0 */ 1240, INVALID, +}; + +static const uint16_t ud_itab__2[] = { + /* 0 */ 1096, INVALID, +}; + +static const uint16_t ud_itab__3[] = { + /* 0 */ 1241, INVALID, +}; + +static const uint16_t ud_itab__4[] = { + /* 0 */ GROUP(5), GROUP(6), 767, 797, + /* 4 */ INVALID, 1426, 82, 1431, + /* 8 */ 716, 1471, INVALID, 1444, + /* c */ INVALID, GROUP(27), 430, GROUP(28), + /* 10 */ GROUP(29), GROUP(30), GROUP(31), GROUP(34), + /* 14 */ GROUP(35), GROUP(36), GROUP(37), GROUP(40), + /* 18 */ GROUP(41), 955, 956, 957, + /* 1c */ 958, 959, 960, 961, + /* 20 */ 854, 855, 856, 857, + /* 24 */ INVALID, INVALID, INVALID, INVALID, + /* 28 */ GROUP(42), GROUP(43), GROUP(44), GROUP(45), + /* 2c */ GROUP(46), GROUP(47), GROUP(48), GROUP(49), + /* 30 */ 1472, 1297, 1295, 1296, + /* 34 */ GROUP(50), GROUP(52), INVALID, 1514, + /* 38 */ GROUP(54), INVALID, GROUP(116), INVALID, + /* 3c */ INVALID, INVALID, INVALID, INVALID, + /* 40 */ 84, 85, 86, 87, + /* 44 */ 88, 89, 90, 91, + /* 48 */ 92, 93, 94, 95, + /* 4c */ 96, 97, 98, 99, + /* 50 */ GROUP(143), GROUP(144), GROUP(145), GROUP(146), + /* 54 */ GROUP(147), GROUP(148), GROUP(149), GROUP(150), + /* 58 */ GROUP(151), GROUP(152), GROUP(153), GROUP(154), + /* 5c */ GROUP(155), GROUP(156), GROUP(157), GROUP(158), + /* 60 */ GROUP(159), GROUP(160), GROUP(161), GROUP(162), + /* 64 */ GROUP(163), GROUP(164), GROUP(165), GROUP(166), + /* 68 */ GROUP(167), GROUP(168), GROUP(169), GROUP(170), + /* 6c */ GROUP(171), GROUP(172), GROUP(173), GROUP(176), + /* 70 */ GROUP(177), GROUP(178), GROUP(182), GROUP(186), + /* 74 */ GROUP(191), GROUP(192), GROUP(193), 199, + /* 78 */ GROUP(194), GROUP(195), INVALID, INVALID, + /* 7c */ GROUP(196), GROUP(197), GROUP(198), GROUP(201), + /* 80 */ 727, 729, 731, 733, + /* 84 */ 735, 737, 739, 741, + /* 88 */ 743, 745, 747, 749, + /* 8c */ 751, 753, 755, 757, + /* 90 */ 1350, 1351, 1352, 1353, + /* 94 */ 1354, 1355, 1356, 1357, + /* 98 */ 1358, 1359, 1360, 1361, + /* 9c */ 1362, 1363, 1364, 1365, + /* a0 */ 1245, 1100, 131, 1670, + /* a4 */ 1375, 1376, GROUP(202), GROUP(207), + /* a8 */ 1244, 1099, 1305, 1675, + /* ac */ 1377, 1378, GROUP(215), 694, + /* b0 */ 122, 123, 775, 1673, + /* b4 */ 772, 773, 940, 941, + /* b8 */ GROUP(221), INVALID, GROUP(222), 1671, + /* bc */ 1659, 1660, 930, 931, + /* c0 */ 1473, 1474, GROUP(223), 904, + /* c4 */ GROUP(224), GROUP(225), GROUP(226), GROUP(227), + /* c8 */ 1661, 1662, 1663, 1664, + /* cc */ 1665, 1666, 1667, 1668, + /* d0 */ GROUP(236), GROUP(237), GROUP(238), GROUP(239), + /* d4 */ GROUP(240), GROUP(241), GROUP(242), GROUP(243), + /* d8 */ GROUP(244), GROUP(245), GROUP(246), GROUP(247), + /* dc */ GROUP(248), GROUP(249), GROUP(250), GROUP(251), + /* e0 */ GROUP(252), GROUP(253), GROUP(254), GROUP(255), + /* e4 */ GROUP(256), GROUP(257), GROUP(258), GROUP(259), + /* e8 */ GROUP(260), GROUP(261), GROUP(262), GROUP(263), + /* ec */ GROUP(264), GROUP(265), GROUP(266), GROUP(267), + /* f0 */ GROUP(268), GROUP(269), GROUP(270), GROUP(271), + /* f4 */ GROUP(272), GROUP(273), GROUP(274), GROUP(275), + /* f8 */ GROUP(277), GROUP(278), GROUP(279), GROUP(280), + /* fc */ GROUP(281), GROUP(282), GROUP(283), INVALID, +}; + +static const uint16_t ud_itab__5[] = { + /* 0 */ 1384, 1406, 786, 798, + /* 4 */ 1453, 1454, INVALID, INVALID, +}; + +static const uint16_t ud_itab__6[] = { + /* 0 */ GROUP(7), GROUP(8), +}; + +static const uint16_t ud_itab__7[] = { + /* 0 */ 1374, 1383, 785, 774, + /* 4 */ 1385, INVALID, 787, 719, +}; + +static const uint16_t ud_itab__8[] = { + /* 0 */ GROUP(9), GROUP(14), GROUP(15), GROUP(16), + /* 4 */ 1386, INVALID, 788, GROUP(25), +}; + +static const uint16_t ud_itab__9[] = { + /* 0 */ INVALID, GROUP(10), GROUP(11), GROUP(12), + /* 4 */ GROUP(13), INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__10[] = { + /* 0 */ INVALID, 1455, INVALID, +}; + +static const uint16_t ud_itab__11[] = { + /* 0 */ INVALID, 1461, INVALID, +}; + +static const uint16_t ud_itab__12[] = { + /* 0 */ INVALID, 1462, INVALID, +}; + +static const uint16_t ud_itab__13[] = { + /* 0 */ INVALID, 1463, INVALID, +}; + +static const uint16_t ud_itab__14[] = { + /* 0 */ 824, 952, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__15[] = { + /* 0 */ 1485, 1508, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__16[] = { + /* 0 */ GROUP(17), GROUP(18), GROUP(19), GROUP(20), + /* 4 */ GROUP(21), GROUP(22), GROUP(23), GROUP(24), +}; + +static const uint16_t ud_itab__17[] = { + /* 0 */ 1466, INVALID, INVALID, +}; + +static const uint16_t ud_itab__18[] = { + /* 0 */ 1467, INVALID, INVALID, +}; + +static const uint16_t ud_itab__19[] = { + /* 0 */ 1468, INVALID, INVALID, +}; + +static const uint16_t ud_itab__20[] = { + /* 0 */ 1469, INVALID, INVALID, +}; + +static const uint16_t ud_itab__21[] = { + /* 0 */ 1397, INVALID, INVALID, +}; + +static const uint16_t ud_itab__22[] = { + /* 0 */ 80, INVALID, INVALID, +}; + +static const uint16_t ud_itab__23[] = { + /* 0 */ 1399, INVALID, INVALID, +}; + +static const uint16_t ud_itab__24[] = { + /* 0 */ 720, INVALID, INVALID, +}; + +static const uint16_t ud_itab__25[] = { + /* 0 */ 1425, GROUP(26), INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__26[] = { + /* 0 */ 1298, INVALID, INVALID, +}; + +static const uint16_t ud_itab__27[] = { + /* 0 */ 1119, 1120, 1121, 1122, + /* 4 */ 1123, 1124, 1125, 1126, +}; + +static const uint16_t ud_itab__28[] = { + /* 0 */ INVALID, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, + /* 8 */ INVALID, INVALID, INVALID, INVALID, + /* c */ 1216, 1217, INVALID, INVALID, + /* 10 */ INVALID, INVALID, INVALID, INVALID, + /* 14 */ INVALID, INVALID, INVALID, INVALID, + /* 18 */ INVALID, INVALID, INVALID, INVALID, + /* 1c */ 1218, 1219, INVALID, INVALID, + /* 20 */ INVALID, INVALID, INVALID, INVALID, + /* 24 */ INVALID, INVALID, INVALID, INVALID, + /* 28 */ INVALID, INVALID, INVALID, INVALID, + /* 2c */ INVALID, INVALID, INVALID, INVALID, + /* 30 */ INVALID, INVALID, INVALID, INVALID, + /* 34 */ INVALID, INVALID, INVALID, INVALID, + /* 38 */ INVALID, INVALID, INVALID, INVALID, + /* 3c */ INVALID, INVALID, INVALID, INVALID, + /* 40 */ INVALID, INVALID, INVALID, INVALID, + /* 44 */ INVALID, INVALID, INVALID, INVALID, + /* 48 */ INVALID, INVALID, INVALID, INVALID, + /* 4c */ INVALID, INVALID, INVALID, INVALID, + /* 50 */ INVALID, INVALID, INVALID, INVALID, + /* 54 */ INVALID, INVALID, INVALID, INVALID, + /* 58 */ INVALID, INVALID, INVALID, INVALID, + /* 5c */ INVALID, INVALID, INVALID, INVALID, + /* 60 */ INVALID, INVALID, INVALID, INVALID, + /* 64 */ INVALID, INVALID, INVALID, INVALID, + /* 68 */ INVALID, INVALID, INVALID, INVALID, + /* 6c */ INVALID, INVALID, INVALID, INVALID, + /* 70 */ INVALID, INVALID, INVALID, INVALID, + /* 74 */ INVALID, INVALID, INVALID, INVALID, + /* 78 */ INVALID, INVALID, INVALID, INVALID, + /* 7c */ INVALID, INVALID, INVALID, INVALID, + /* 80 */ INVALID, INVALID, INVALID, INVALID, + /* 84 */ INVALID, INVALID, INVALID, INVALID, + /* 88 */ INVALID, INVALID, 1220, INVALID, + /* 8c */ INVALID, INVALID, 1221, INVALID, + /* 90 */ 1222, INVALID, INVALID, INVALID, + /* 94 */ 1223, INVALID, 1224, 1225, + /* 98 */ INVALID, INVALID, 1226, INVALID, + /* 9c */ INVALID, INVALID, 1227, INVALID, + /* a0 */ 1228, INVALID, INVALID, INVALID, + /* a4 */ 1229, INVALID, 1230, 1231, + /* a8 */ INVALID, INVALID, 1232, INVALID, + /* ac */ INVALID, INVALID, 1233, INVALID, + /* b0 */ 1234, INVALID, INVALID, INVALID, + /* b4 */ 1235, INVALID, 1236, 1237, + /* b8 */ INVALID, INVALID, INVALID, 1238, + /* bc */ INVALID, INVALID, INVALID, 1239, + /* c0 */ INVALID, INVALID, INVALID, INVALID, + /* c4 */ INVALID, INVALID, INVALID, INVALID, + /* c8 */ INVALID, INVALID, INVALID, INVALID, + /* cc */ INVALID, INVALID, INVALID, INVALID, + /* d0 */ INVALID, INVALID, INVALID, INVALID, + /* d4 */ INVALID, INVALID, INVALID, INVALID, + /* d8 */ INVALID, INVALID, INVALID, INVALID, + /* dc */ INVALID, INVALID, INVALID, INVALID, + /* e0 */ INVALID, INVALID, INVALID, INVALID, + /* e4 */ INVALID, INVALID, INVALID, INVALID, + /* e8 */ INVALID, INVALID, INVALID, INVALID, + /* ec */ INVALID, INVALID, INVALID, INVALID, + /* f0 */ INVALID, INVALID, INVALID, INVALID, + /* f4 */ INVALID, INVALID, INVALID, INVALID, + /* f8 */ INVALID, INVALID, INVALID, INVALID, + /* fc */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__29[] = { + /* 0 */ 936, 925, 928, 932, +}; + +static const uint16_t ud_itab__30[] = { + /* 0 */ 938, 926, 929, 934, +}; + +static const uint16_t ud_itab__31[] = { + /* 0 */ GROUP(32), GROUP(33), +}; + +static const uint16_t ud_itab__32[] = { + /* 0 */ 892, 1563, 1571, 888, +}; + +static const uint16_t ud_itab__33[] = { + /* 0 */ 896, 1561, 1569, INVALID, +}; + +static const uint16_t ud_itab__34[] = { + /* 0 */ 894, INVALID, INVALID, 890, +}; + +static const uint16_t ud_itab__35[] = { + /* 0 */ 1449, INVALID, INVALID, 1451, +}; + +static const uint16_t ud_itab__36[] = { + /* 0 */ 1447, INVALID, INVALID, 1445, +}; + +static const uint16_t ud_itab__37[] = { + /* 0 */ GROUP(38), GROUP(39), +}; + +static const uint16_t ud_itab__38[] = { + /* 0 */ 882, INVALID, 1567, 878, +}; + +static const uint16_t ud_itab__39[] = { + /* 0 */ 886, INVALID, 1565, INVALID, +}; + +static const uint16_t ud_itab__40[] = { + /* 0 */ 884, INVALID, INVALID, 880, +}; + +static const uint16_t ud_itab__41[] = { + /* 0 */ 1127, 1128, 1129, 1130, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__42[] = { + /* 0 */ 862, INVALID, INVALID, 858, +}; + +static const uint16_t ud_itab__43[] = { + /* 0 */ 864, INVALID, INVALID, 860, +}; + +static const uint16_t ud_itab__44[] = { + /* 0 */ 141, 152, 154, 142, +}; + +static const uint16_t ud_itab__45[] = { + /* 0 */ 907, INVALID, INVALID, 905, +}; + +static const uint16_t ud_itab__46[] = { + /* 0 */ 165, 166, 168, 162, +}; + +static const uint16_t ud_itab__47[] = { + /* 0 */ 147, 148, 158, 138, +}; + +static const uint16_t ud_itab__48[] = { + /* 0 */ 1442, INVALID, INVALID, 1440, +}; + +static const uint16_t ud_itab__49[] = { + /* 0 */ 129, INVALID, INVALID, 127, +}; + +static const uint16_t ud_itab__50[] = { + /* 0 */ 1427, GROUP(51), +}; + +static const uint16_t ud_itab__51[] = { + /* 0 */ INVALID, 1428, INVALID, +}; + +static const uint16_t ud_itab__52[] = { + /* 0 */ 1429, GROUP(53), +}; + +static const uint16_t ud_itab__53[] = { + /* 0 */ INVALID, 1430, INVALID, +}; + +static const uint16_t ud_itab__54[] = { + /* 0 */ GROUP(67), GROUP(68), GROUP(63), GROUP(64), + /* 4 */ GROUP(65), GROUP(66), GROUP(86), GROUP(90), + /* 8 */ GROUP(69), GROUP(70), GROUP(71), GROUP(72), + /* c */ INVALID, INVALID, INVALID, INVALID, + /* 10 */ GROUP(73), INVALID, INVALID, INVALID, + /* 14 */ GROUP(75), GROUP(76), INVALID, GROUP(77), + /* 18 */ INVALID, INVALID, INVALID, INVALID, + /* 1c */ GROUP(78), GROUP(79), GROUP(80), INVALID, + /* 20 */ GROUP(81), GROUP(82), GROUP(83), GROUP(84), + /* 24 */ GROUP(85), GROUP(108), INVALID, INVALID, + /* 28 */ GROUP(87), GROUP(88), GROUP(89), GROUP(74), + /* 2c */ INVALID, INVALID, INVALID, INVALID, + /* 30 */ GROUP(91), GROUP(92), GROUP(93), GROUP(94), + /* 34 */ GROUP(95), GROUP(96), INVALID, GROUP(97), + /* 38 */ GROUP(98), GROUP(99), GROUP(100), GROUP(101), + /* 3c */ GROUP(102), GROUP(103), GROUP(104), GROUP(105), + /* 40 */ GROUP(106), GROUP(107), INVALID, INVALID, + /* 44 */ INVALID, INVALID, INVALID, INVALID, + /* 48 */ INVALID, INVALID, INVALID, INVALID, + /* 4c */ INVALID, INVALID, INVALID, INVALID, + /* 50 */ INVALID, INVALID, INVALID, INVALID, + /* 54 */ INVALID, INVALID, INVALID, INVALID, + /* 58 */ INVALID, INVALID, INVALID, INVALID, + /* 5c */ INVALID, INVALID, INVALID, INVALID, + /* 60 */ INVALID, INVALID, INVALID, INVALID, + /* 64 */ INVALID, INVALID, INVALID, INVALID, + /* 68 */ INVALID, INVALID, INVALID, INVALID, + /* 6c */ INVALID, INVALID, INVALID, INVALID, + /* 70 */ INVALID, INVALID, INVALID, INVALID, + /* 74 */ INVALID, INVALID, INVALID, INVALID, + /* 78 */ INVALID, INVALID, INVALID, INVALID, + /* 7c */ INVALID, INVALID, INVALID, INVALID, + /* 80 */ GROUP(55), GROUP(59), INVALID, INVALID, + /* 84 */ INVALID, INVALID, INVALID, INVALID, + /* 88 */ INVALID, INVALID, INVALID, INVALID, + /* 8c */ INVALID, INVALID, INVALID, INVALID, + /* 90 */ INVALID, INVALID, INVALID, INVALID, + /* 94 */ INVALID, INVALID, INVALID, INVALID, + /* 98 */ INVALID, INVALID, INVALID, INVALID, + /* 9c */ INVALID, INVALID, INVALID, INVALID, + /* a0 */ INVALID, INVALID, INVALID, INVALID, + /* a4 */ INVALID, INVALID, INVALID, INVALID, + /* a8 */ INVALID, INVALID, INVALID, INVALID, + /* ac */ INVALID, INVALID, INVALID, INVALID, + /* b0 */ INVALID, INVALID, INVALID, INVALID, + /* b4 */ INVALID, INVALID, INVALID, INVALID, + /* b8 */ INVALID, INVALID, INVALID, INVALID, + /* bc */ INVALID, INVALID, INVALID, INVALID, + /* c0 */ INVALID, INVALID, INVALID, INVALID, + /* c4 */ INVALID, INVALID, INVALID, INVALID, + /* c8 */ INVALID, INVALID, INVALID, INVALID, + /* cc */ INVALID, INVALID, INVALID, INVALID, + /* d0 */ INVALID, INVALID, INVALID, INVALID, + /* d4 */ INVALID, INVALID, INVALID, INVALID, + /* d8 */ INVALID, INVALID, INVALID, GROUP(109), + /* dc */ GROUP(110), GROUP(111), GROUP(112), GROUP(113), + /* e0 */ INVALID, INVALID, INVALID, INVALID, + /* e4 */ INVALID, INVALID, INVALID, INVALID, + /* e8 */ INVALID, INVALID, INVALID, INVALID, + /* ec */ INVALID, INVALID, INVALID, INVALID, + /* f0 */ GROUP(114), GROUP(115), INVALID, INVALID, + /* f4 */ INVALID, INVALID, INVALID, INVALID, + /* f8 */ INVALID, INVALID, INVALID, INVALID, + /* fc */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__55[] = { + /* 0 */ INVALID, INVALID, INVALID, GROUP(56), +}; + +static const uint16_t ud_itab__56[] = { + /* 0 */ GROUP(57), GROUP(58), +}; + +static const uint16_t ud_itab__57[] = { + /* 0 */ INVALID, 717, INVALID, +}; + +static const uint16_t ud_itab__58[] = { + /* 0 */ INVALID, 718, INVALID, +}; + +static const uint16_t ud_itab__59[] = { + /* 0 */ INVALID, INVALID, INVALID, GROUP(60), +}; + +static const uint16_t ud_itab__60[] = { + /* 0 */ GROUP(61), GROUP(62), +}; + +static const uint16_t ud_itab__61[] = { + /* 0 */ INVALID, 721, INVALID, +}; + +static const uint16_t ud_itab__62[] = { + /* 0 */ INVALID, 722, INVALID, +}; + +static const uint16_t ud_itab__63[] = { + /* 0 */ 1588, INVALID, INVALID, 1589, +}; + +static const uint16_t ud_itab__64[] = { + /* 0 */ 1591, INVALID, INVALID, 1592, +}; + +static const uint16_t ud_itab__65[] = { + /* 0 */ 1594, INVALID, INVALID, 1595, +}; + +static const uint16_t ud_itab__66[] = { + /* 0 */ 1597, INVALID, INVALID, 1598, +}; + +static const uint16_t ud_itab__67[] = { + /* 0 */ 1582, INVALID, INVALID, 1583, +}; + +static const uint16_t ud_itab__68[] = { + /* 0 */ 1585, INVALID, INVALID, 1586, +}; + +static const uint16_t ud_itab__69[] = { + /* 0 */ 1606, INVALID, INVALID, 1607, +}; + +static const uint16_t ud_itab__70[] = { + /* 0 */ 1612, INVALID, INVALID, 1613, +}; + +static const uint16_t ud_itab__71[] = { + /* 0 */ 1609, INVALID, INVALID, 1610, +}; + +static const uint16_t ud_itab__72[] = { + /* 0 */ 1615, INVALID, INVALID, 1616, +}; + +static const uint16_t ud_itab__73[] = { + /* 0 */ INVALID, INVALID, INVALID, 1621, +}; + +static const uint16_t ud_itab__74[] = { + /* 0 */ INVALID, INVALID, INVALID, 1683, +}; + +static const uint16_t ud_itab__75[] = { + /* 0 */ INVALID, INVALID, INVALID, 1657, +}; + +static const uint16_t ud_itab__76[] = { + /* 0 */ INVALID, INVALID, INVALID, 1656, +}; + +static const uint16_t ud_itab__77[] = { + /* 0 */ INVALID, INVALID, INVALID, 1711, +}; + +static const uint16_t ud_itab__78[] = { + /* 0 */ 1573, INVALID, INVALID, 1574, +}; + +static const uint16_t ud_itab__79[] = { + /* 0 */ 1576, INVALID, INVALID, 1577, +}; + +static const uint16_t ud_itab__80[] = { + /* 0 */ 1579, INVALID, INVALID, 1580, +}; + +static const uint16_t ud_itab__81[] = { + /* 0 */ INVALID, INVALID, INVALID, 1685, +}; + +static const uint16_t ud_itab__82[] = { + /* 0 */ INVALID, INVALID, INVALID, 1687, +}; + +static const uint16_t ud_itab__83[] = { + /* 0 */ INVALID, INVALID, INVALID, 1689, +}; + +static const uint16_t ud_itab__84[] = { + /* 0 */ INVALID, INVALID, INVALID, 1691, +}; + +static const uint16_t ud_itab__85[] = { + /* 0 */ INVALID, INVALID, INVALID, 1693, +}; + +static const uint16_t ud_itab__86[] = { + /* 0 */ 1600, INVALID, INVALID, 1601, +}; + +static const uint16_t ud_itab__87[] = { + /* 0 */ INVALID, INVALID, INVALID, 1622, +}; + +static const uint16_t ud_itab__88[] = { + /* 0 */ INVALID, INVALID, INVALID, 1708, +}; + +static const uint16_t ud_itab__89[] = { + /* 0 */ INVALID, INVALID, INVALID, 1681, +}; + +static const uint16_t ud_itab__90[] = { + /* 0 */ 1603, INVALID, INVALID, 1604, +}; + +static const uint16_t ud_itab__91[] = { + /* 0 */ INVALID, INVALID, INVALID, 1696, +}; + +static const uint16_t ud_itab__92[] = { + /* 0 */ INVALID, INVALID, INVALID, 1698, +}; + +static const uint16_t ud_itab__93[] = { + /* 0 */ INVALID, INVALID, INVALID, 1700, +}; + +static const uint16_t ud_itab__94[] = { + /* 0 */ INVALID, INVALID, INVALID, 1702, +}; + +static const uint16_t ud_itab__95[] = { + /* 0 */ INVALID, INVALID, INVALID, 1704, +}; + +static const uint16_t ud_itab__96[] = { + /* 0 */ INVALID, INVALID, INVALID, 1706, +}; + +static const uint16_t ud_itab__97[] = { + /* 0 */ INVALID, INVALID, INVALID, 1717, +}; + +static const uint16_t ud_itab__98[] = { + /* 0 */ INVALID, INVALID, INVALID, 1624, +}; + +static const uint16_t ud_itab__99[] = { + /* 0 */ INVALID, INVALID, INVALID, 1626, +}; + +static const uint16_t ud_itab__100[] = { + /* 0 */ INVALID, INVALID, INVALID, 1628, +}; + +static const uint16_t ud_itab__101[] = { + /* 0 */ INVALID, INVALID, INVALID, 1630, +}; + +static const uint16_t ud_itab__102[] = { + /* 0 */ INVALID, INVALID, INVALID, 1632, +}; + +static const uint16_t ud_itab__103[] = { + /* 0 */ INVALID, INVALID, INVALID, 1634, +}; + +static const uint16_t ud_itab__104[] = { + /* 0 */ INVALID, INVALID, INVALID, 1638, +}; + +static const uint16_t ud_itab__105[] = { + /* 0 */ INVALID, INVALID, INVALID, 1636, +}; + +static const uint16_t ud_itab__106[] = { + /* 0 */ INVALID, INVALID, INVALID, 1640, +}; + +static const uint16_t ud_itab__107[] = { + /* 0 */ INVALID, INVALID, INVALID, 1642, +}; + +static const uint16_t ud_itab__108[] = { + /* 0 */ INVALID, INVALID, INVALID, 1695, +}; + +static const uint16_t ud_itab__109[] = { + /* 0 */ INVALID, INVALID, INVALID, 45, +}; + +static const uint16_t ud_itab__110[] = { + /* 0 */ INVALID, INVALID, INVALID, 41, +}; + +static const uint16_t ud_itab__111[] = { + /* 0 */ INVALID, INVALID, INVALID, 43, +}; + +static const uint16_t ud_itab__112[] = { + /* 0 */ INVALID, INVALID, INVALID, 37, +}; + +static const uint16_t ud_itab__113[] = { + /* 0 */ INVALID, INVALID, INVALID, 39, +}; + +static const uint16_t ud_itab__114[] = { + /* 0 */ 1723, 1725, INVALID, INVALID, +}; + +static const uint16_t ud_itab__115[] = { + /* 0 */ 1724, 1726, INVALID, INVALID, +}; + +static const uint16_t ud_itab__116[] = { + /* 0 */ INVALID, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, + /* 8 */ GROUP(117), GROUP(118), GROUP(119), GROUP(120), + /* c */ GROUP(121), GROUP(122), GROUP(123), GROUP(124), + /* 10 */ INVALID, INVALID, INVALID, INVALID, + /* 14 */ GROUP(125), GROUP(126), GROUP(127), GROUP(129), + /* 18 */ INVALID, INVALID, INVALID, INVALID, + /* 1c */ INVALID, INVALID, INVALID, INVALID, + /* 20 */ GROUP(130), GROUP(131), GROUP(132), INVALID, + /* 24 */ INVALID, INVALID, INVALID, INVALID, + /* 28 */ INVALID, INVALID, INVALID, INVALID, + /* 2c */ INVALID, INVALID, INVALID, INVALID, + /* 30 */ INVALID, INVALID, INVALID, INVALID, + /* 34 */ INVALID, INVALID, INVALID, INVALID, + /* 38 */ INVALID, INVALID, INVALID, INVALID, + /* 3c */ INVALID, INVALID, INVALID, INVALID, + /* 40 */ GROUP(134), GROUP(135), GROUP(136), INVALID, + /* 44 */ GROUP(137), INVALID, INVALID, INVALID, + /* 48 */ INVALID, INVALID, INVALID, INVALID, + /* 4c */ INVALID, INVALID, INVALID, INVALID, + /* 50 */ INVALID, INVALID, INVALID, INVALID, + /* 54 */ INVALID, INVALID, INVALID, INVALID, + /* 58 */ INVALID, INVALID, INVALID, INVALID, + /* 5c */ INVALID, INVALID, INVALID, INVALID, + /* 60 */ GROUP(139), GROUP(140), GROUP(141), GROUP(142), + /* 64 */ INVALID, INVALID, INVALID, INVALID, + /* 68 */ INVALID, INVALID, INVALID, INVALID, + /* 6c */ INVALID, INVALID, INVALID, INVALID, + /* 70 */ INVALID, INVALID, INVALID, INVALID, + /* 74 */ INVALID, INVALID, INVALID, INVALID, + /* 78 */ INVALID, INVALID, INVALID, INVALID, + /* 7c */ INVALID, INVALID, INVALID, INVALID, + /* 80 */ INVALID, INVALID, INVALID, INVALID, + /* 84 */ INVALID, INVALID, INVALID, INVALID, + /* 88 */ INVALID, INVALID, INVALID, INVALID, + /* 8c */ INVALID, INVALID, INVALID, INVALID, + /* 90 */ INVALID, INVALID, INVALID, INVALID, + /* 94 */ INVALID, INVALID, INVALID, INVALID, + /* 98 */ INVALID, INVALID, INVALID, INVALID, + /* 9c */ INVALID, INVALID, INVALID, INVALID, + /* a0 */ INVALID, INVALID, INVALID, INVALID, + /* a4 */ INVALID, INVALID, INVALID, INVALID, + /* a8 */ INVALID, INVALID, INVALID, INVALID, + /* ac */ INVALID, INVALID, INVALID, INVALID, + /* b0 */ INVALID, INVALID, INVALID, INVALID, + /* b4 */ INVALID, INVALID, INVALID, INVALID, + /* b8 */ INVALID, INVALID, INVALID, INVALID, + /* bc */ INVALID, INVALID, INVALID, INVALID, + /* c0 */ INVALID, INVALID, INVALID, INVALID, + /* c4 */ INVALID, INVALID, INVALID, INVALID, + /* c8 */ INVALID, INVALID, INVALID, INVALID, + /* cc */ INVALID, INVALID, INVALID, INVALID, + /* d0 */ INVALID, INVALID, INVALID, INVALID, + /* d4 */ INVALID, INVALID, INVALID, INVALID, + /* d8 */ INVALID, INVALID, INVALID, INVALID, + /* dc */ INVALID, INVALID, INVALID, GROUP(138), + /* e0 */ INVALID, INVALID, INVALID, INVALID, + /* e4 */ INVALID, INVALID, INVALID, INVALID, + /* e8 */ INVALID, INVALID, INVALID, INVALID, + /* ec */ INVALID, INVALID, INVALID, INVALID, + /* f0 */ INVALID, INVALID, INVALID, INVALID, + /* f4 */ INVALID, INVALID, INVALID, INVALID, + /* f8 */ INVALID, INVALID, INVALID, INVALID, + /* fc */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__117[] = { + /* 0 */ INVALID, INVALID, INVALID, 1644, +}; + +static const uint16_t ud_itab__118[] = { + /* 0 */ INVALID, INVALID, INVALID, 1646, +}; + +static const uint16_t ud_itab__119[] = { + /* 0 */ INVALID, INVALID, INVALID, 1648, +}; + +static const uint16_t ud_itab__120[] = { + /* 0 */ INVALID, INVALID, INVALID, 1650, +}; + +static const uint16_t ud_itab__121[] = { + /* 0 */ INVALID, INVALID, INVALID, 1654, +}; + +static const uint16_t ud_itab__122[] = { + /* 0 */ INVALID, INVALID, INVALID, 1652, +}; + +static const uint16_t ud_itab__123[] = { + /* 0 */ INVALID, INVALID, INVALID, 1677, +}; + +static const uint16_t ud_itab__124[] = { + /* 0 */ 1618, INVALID, INVALID, 1619, +}; + +static const uint16_t ud_itab__125[] = { + /* 0 */ INVALID, INVALID, INVALID, 1045, +}; + +static const uint16_t ud_itab__126[] = { + /* 0 */ INVALID, INVALID, INVALID, 1056, +}; + +static const uint16_t ud_itab__127[] = { + /* 0 */ INVALID, INVALID, INVALID, GROUP(128), +}; + +static const uint16_t ud_itab__128[] = { + /* 0 */ 1047, 1049, 1051, +}; + +static const uint16_t ud_itab__129[] = { + /* 0 */ INVALID, INVALID, INVALID, 201, +}; + +static const uint16_t ud_itab__130[] = { + /* 0 */ INVALID, INVALID, INVALID, 1058, +}; + +static const uint16_t ud_itab__131[] = { + /* 0 */ INVALID, INVALID, INVALID, 1557, +}; + +static const uint16_t ud_itab__132[] = { + /* 0 */ INVALID, INVALID, INVALID, GROUP(133), +}; + +static const uint16_t ud_itab__133[] = { + /* 0 */ 1062, 1063, 1064, +}; + +static const uint16_t ud_itab__134[] = { + /* 0 */ INVALID, INVALID, INVALID, 197, +}; + +static const uint16_t ud_itab__135[] = { + /* 0 */ INVALID, INVALID, INVALID, 195, +}; + +static const uint16_t ud_itab__136[] = { + /* 0 */ INVALID, INVALID, INVALID, 1679, +}; + +static const uint16_t ud_itab__137[] = { + /* 0 */ INVALID, INVALID, INVALID, 1512, +}; + +static const uint16_t ud_itab__138[] = { + /* 0 */ INVALID, INVALID, INVALID, 47, +}; + +static const uint16_t ud_itab__139[] = { + /* 0 */ INVALID, INVALID, INVALID, 1715, +}; + +static const uint16_t ud_itab__140[] = { + /* 0 */ INVALID, INVALID, INVALID, 1713, +}; + +static const uint16_t ud_itab__141[] = { + /* 0 */ INVALID, INVALID, INVALID, 1721, +}; + +static const uint16_t ud_itab__142[] = { + /* 0 */ INVALID, INVALID, INVALID, 1719, +}; + +static const uint16_t ud_itab__143[] = { + /* 0 */ 900, INVALID, INVALID, 898, +}; + +static const uint16_t ud_itab__144[] = { + /* 0 */ 1387, 1391, 1393, 1389, +}; + +static const uint16_t ud_itab__145[] = { + /* 0 */ 1306, INVALID, 1308, INVALID, +}; + +static const uint16_t ud_itab__146[] = { + /* 0 */ 1291, INVALID, 1293, INVALID, +}; + +static const uint16_t ud_itab__147[] = { + /* 0 */ 61, INVALID, INVALID, 59, +}; + +static const uint16_t ud_itab__148[] = { + /* 0 */ 65, INVALID, INVALID, 63, +}; + +static const uint16_t ud_itab__149[] = { + /* 0 */ 976, INVALID, INVALID, 974, +}; + +static const uint16_t ud_itab__150[] = { + /* 0 */ 1499, INVALID, INVALID, 1497, +}; + +static const uint16_t ud_itab__151[] = { + /* 0 */ 27, 29, 31, 25, +}; + +static const uint16_t ud_itab__152[] = { + /* 0 */ 946, 948, 950, 944, +}; + +static const uint16_t ud_itab__153[] = { + /* 0 */ 145, 150, 156, 139, +}; + +static const uint16_t ud_itab__154[] = { + /* 0 */ 134, INVALID, 163, 143, +}; + +static const uint16_t ud_itab__155[] = { + /* 0 */ 1419, 1421, 1423, 1417, +}; + +static const uint16_t ud_itab__156[] = { + /* 0 */ 818, 820, 822, 816, +}; + +static const uint16_t ud_itab__157[] = { + /* 0 */ 189, 191, 193, 187, +}; + +static const uint16_t ud_itab__158[] = { + /* 0 */ 802, 804, 806, 800, +}; + +static const uint16_t ud_itab__159[] = { + /* 0 */ 1209, INVALID, INVALID, 1207, +}; + +static const uint16_t ud_itab__160[] = { + /* 0 */ 1212, INVALID, INVALID, 1210, +}; + +static const uint16_t ud_itab__161[] = { + /* 0 */ 1215, INVALID, INVALID, 1213, +}; + +static const uint16_t ud_itab__162[] = { + /* 0 */ 987, INVALID, INVALID, 985, +}; + +static const uint16_t ud_itab__163[] = { + /* 0 */ 1038, INVALID, INVALID, 1036, +}; + +static const uint16_t ud_itab__164[] = { + /* 0 */ 1041, INVALID, INVALID, 1039, +}; + +static const uint16_t ud_itab__165[] = { + /* 0 */ 1044, INVALID, INVALID, 1042, +}; + +static const uint16_t ud_itab__166[] = { + /* 0 */ 993, INVALID, INVALID, 991, +}; + +static const uint16_t ud_itab__167[] = { + /* 0 */ 1200, INVALID, INVALID, 1198, +}; + +static const uint16_t ud_itab__168[] = { + /* 0 */ 1203, INVALID, INVALID, 1201, +}; + +static const uint16_t ud_itab__169[] = { + /* 0 */ 1206, INVALID, INVALID, 1204, +}; + +static const uint16_t ud_itab__170[] = { + /* 0 */ 990, INVALID, INVALID, 988, +}; + +static const uint16_t ud_itab__171[] = { + /* 0 */ INVALID, INVALID, INVALID, 1547, +}; + +static const uint16_t ud_itab__172[] = { + /* 0 */ INVALID, INVALID, INVALID, 1545, +}; + +static const uint16_t ud_itab__173[] = { + /* 0 */ GROUP(174), INVALID, INVALID, GROUP(175), +}; + +static const uint16_t ud_itab__174[] = { + /* 0 */ 866, 867, 910, +}; + +static const uint16_t ud_itab__175[] = { + /* 0 */ 868, 870, 911, +}; + +static const uint16_t ud_itab__176[] = { + /* 0 */ 920, INVALID, 1522, 1517, +}; + +static const uint16_t ud_itab__177[] = { + /* 0 */ 1134, 1537, 1535, 1539, +}; + +static const uint16_t ud_itab__178[] = { + /* 0 */ INVALID, INVALID, GROUP(179), INVALID, + /* 4 */ GROUP(180), INVALID, GROUP(181), INVALID, +}; + +static const uint16_t ud_itab__179[] = { + /* 0 */ 1159, INVALID, INVALID, 1163, +}; + +static const uint16_t ud_itab__180[] = { + /* 0 */ 1152, INVALID, INVALID, 1150, +}; + +static const uint16_t ud_itab__181[] = { + /* 0 */ 1138, INVALID, INVALID, 1137, +}; + +static const uint16_t ud_itab__182[] = { + /* 0 */ INVALID, INVALID, GROUP(183), INVALID, + /* 4 */ GROUP(184), INVALID, GROUP(185), INVALID, +}; + +static const uint16_t ud_itab__183[] = { + /* 0 */ 1165, INVALID, INVALID, 1169, +}; + +static const uint16_t ud_itab__184[] = { + /* 0 */ 1153, INVALID, INVALID, 1157, +}; + +static const uint16_t ud_itab__185[] = { + /* 0 */ 1142, INVALID, INVALID, 1141, +}; + +static const uint16_t ud_itab__186[] = { + /* 0 */ INVALID, INVALID, GROUP(187), GROUP(188), + /* 4 */ INVALID, INVALID, GROUP(189), GROUP(190), +}; + +static const uint16_t ud_itab__187[] = { + /* 0 */ 1171, INVALID, INVALID, 1175, +}; + +static const uint16_t ud_itab__188[] = { + /* 0 */ INVALID, INVALID, INVALID, 1543, +}; + +static const uint16_t ud_itab__189[] = { + /* 0 */ 1146, INVALID, INVALID, 1145, +}; + +static const uint16_t ud_itab__190[] = { + /* 0 */ INVALID, INVALID, INVALID, 1541, +}; + +static const uint16_t ud_itab__191[] = { + /* 0 */ 1027, INVALID, INVALID, 1028, +}; + +static const uint16_t ud_itab__192[] = { + /* 0 */ 1030, INVALID, INVALID, 1031, +}; + +static const uint16_t ud_itab__193[] = { + /* 0 */ 1033, INVALID, INVALID, 1034, +}; + +static const uint16_t ud_itab__194[] = { + /* 0 */ INVALID, 1464, INVALID, +}; + +static const uint16_t ud_itab__195[] = { + /* 0 */ INVALID, 1465, INVALID, +}; + +static const uint16_t ud_itab__196[] = { + /* 0 */ INVALID, 1551, INVALID, 1549, +}; + +static const uint16_t ud_itab__197[] = { + /* 0 */ INVALID, 1555, INVALID, 1553, +}; + +static const uint16_t ud_itab__198[] = { + /* 0 */ GROUP(199), INVALID, 916, GROUP(200), +}; + +static const uint16_t ud_itab__199[] = { + /* 0 */ 872, 873, 913, +}; + +static const uint16_t ud_itab__200[] = { + /* 0 */ 874, 876, 914, +}; + +static const uint16_t ud_itab__201[] = { + /* 0 */ 921, INVALID, 1524, 1515, +}; + +static const uint16_t ud_itab__202[] = { + /* 0 */ INVALID, GROUP(203), +}; + +static const uint16_t ud_itab__203[] = { + /* 0 */ GROUP(204), GROUP(205), GROUP(206), INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__204[] = { + /* 0 */ 825, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__205[] = { + /* 0 */ 1509, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__206[] = { + /* 0 */ 1510, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__207[] = { + /* 0 */ INVALID, GROUP(208), +}; + +static const uint16_t ud_itab__208[] = { + /* 0 */ GROUP(209), GROUP(210), GROUP(211), GROUP(212), + /* 4 */ GROUP(213), GROUP(214), INVALID, INVALID, +}; + +static const uint16_t ud_itab__209[] = { + /* 0 */ 1511, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__210[] = { + /* 0 */ 1501, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__211[] = { + /* 0 */ 1502, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__212[] = { + /* 0 */ 1503, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__213[] = { + /* 0 */ 1504, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__214[] = { + /* 0 */ 1505, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__215[] = { + /* 0 */ GROUP(216), GROUP(217), +}; + +static const uint16_t ud_itab__216[] = { + /* 0 */ 683, 682, 768, 1400, + /* 4 */ 1507, 1506, INVALID, 79, +}; + +static const uint16_t ud_itab__217[] = { + /* 0 */ INVALID, INVALID, INVALID, INVALID, + /* 4 */ INVALID, GROUP(218), GROUP(219), GROUP(220), +}; + +static const uint16_t ud_itab__218[] = { + /* 0 */ 777, 778, 779, 780, + /* 4 */ 781, 782, 783, 784, +}; + +static const uint16_t ud_itab__219[] = { + /* 0 */ 808, 809, 810, 811, + /* 4 */ 812, 813, 814, 815, +}; + +static const uint16_t ud_itab__220[] = { + /* 0 */ 1366, 1367, 1368, 1369, + /* 4 */ 1370, 1371, 1372, 1373, +}; + +static const uint16_t ud_itab__221[] = { + /* 0 */ INVALID, INVALID, 1710, INVALID, +}; + +static const uint16_t ud_itab__222[] = { + /* 0 */ INVALID, INVALID, INVALID, INVALID, + /* 4 */ 1669, 1676, 1674, 1672, +}; + +static const uint16_t ud_itab__223[] = { + /* 0 */ 112, 117, 120, 110, +}; + +static const uint16_t ud_itab__224[] = { + /* 0 */ 1059, INVALID, INVALID, 1060, +}; + +static const uint16_t ud_itab__225[] = { + /* 0 */ 1055, INVALID, INVALID, 1053, +}; + +static const uint16_t ud_itab__226[] = { + /* 0 */ 1381, INVALID, INVALID, 1379, +}; + +static const uint16_t ud_itab__227[] = { + /* 0 */ GROUP(228), GROUP(235), +}; + +static const uint16_t ud_itab__228[] = { + /* 0 */ INVALID, GROUP(229), INVALID, INVALID, + /* 4 */ INVALID, INVALID, GROUP(230), GROUP(234), +}; + +static const uint16_t ud_itab__229[] = { + /* 0 */ 124, 125, 126, +}; + +static const uint16_t ud_itab__230[] = { + /* 0 */ GROUP(231), INVALID, GROUP(232), GROUP(233), +}; + +static const uint16_t ud_itab__231[] = { + /* 0 */ INVALID, 1459, INVALID, +}; + +static const uint16_t ud_itab__232[] = { + /* 0 */ INVALID, 1458, INVALID, +}; + +static const uint16_t ud_itab__233[] = { + /* 0 */ INVALID, 1457, INVALID, +}; + +static const uint16_t ud_itab__234[] = { + /* 0 */ INVALID, 1460, INVALID, +}; + +static const uint16_t ud_itab__235[] = { + /* 0 */ INVALID, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, 1456, INVALID, +}; + +static const uint16_t ud_itab__236[] = { + /* 0 */ INVALID, 35, INVALID, 33, +}; + +static const uint16_t ud_itab__237[] = { + /* 0 */ 1160, INVALID, INVALID, 1161, +}; + +static const uint16_t ud_itab__238[] = { + /* 0 */ 1166, INVALID, INVALID, 1167, +}; + +static const uint16_t ud_itab__239[] = { + /* 0 */ 1172, INVALID, INVALID, 1173, +}; + +static const uint16_t ud_itab__240[] = { + /* 0 */ 1527, INVALID, INVALID, 1528, +}; + +static const uint16_t ud_itab__241[] = { + /* 0 */ 1093, INVALID, INVALID, 1094, +}; + +static const uint16_t ud_itab__242[] = { + /* 0 */ INVALID, 1521, 1526, 918, +}; + +static const uint16_t ud_itab__243[] = { + /* 0 */ 1086, INVALID, INVALID, 1084, +}; + +static const uint16_t ud_itab__244[] = { + /* 0 */ 1192, INVALID, INVALID, 1193, +}; + +static const uint16_t ud_itab__245[] = { + /* 0 */ 1195, INVALID, INVALID, 1196, +}; + +static const uint16_t ud_itab__246[] = { + /* 0 */ 1083, INVALID, INVALID, 1081, +}; + +static const uint16_t ud_itab__247[] = { + /* 0 */ 1017, INVALID, INVALID, 1015, +}; + +static const uint16_t ud_itab__248[] = { + /* 0 */ 1009, INVALID, INVALID, 1010, +}; + +static const uint16_t ud_itab__249[] = { + /* 0 */ 1012, INVALID, INVALID, 1013, +}; + +static const uint16_t ud_itab__250[] = { + /* 0 */ 1075, INVALID, INVALID, 1076, +}; + +static const uint16_t ud_itab__251[] = { + /* 0 */ 1020, INVALID, INVALID, 1018, +}; + +static const uint16_t ud_itab__252[] = { + /* 0 */ 1023, INVALID, INVALID, 1021, +}; + +static const uint16_t ud_itab__253[] = { + /* 0 */ 1147, INVALID, INVALID, 1148, +}; + +static const uint16_t ud_itab__254[] = { + /* 0 */ 1156, INVALID, INVALID, 1154, +}; + +static const uint16_t ud_itab__255[] = { + /* 0 */ 1026, INVALID, INVALID, 1024, +}; + +static const uint16_t ud_itab__256[] = { + /* 0 */ 1087, INVALID, INVALID, 1088, +}; + +static const uint16_t ud_itab__257[] = { + /* 0 */ 1092, INVALID, INVALID, 1090, +}; + +static const uint16_t ud_itab__258[] = { + /* 0 */ INVALID, 136, 132, 160, +}; + +static const uint16_t ud_itab__259[] = { + /* 0 */ 909, INVALID, INVALID, 902, +}; + +static const uint16_t ud_itab__260[] = { + /* 0 */ 1186, INVALID, INVALID, 1187, +}; + +static const uint16_t ud_itab__261[] = { + /* 0 */ 1189, INVALID, INVALID, 1190, +}; + +static const uint16_t ud_itab__262[] = { + /* 0 */ 1080, INVALID, INVALID, 1078, +}; + +static const uint16_t ud_itab__263[] = { + /* 0 */ 1118, INVALID, INVALID, 1116, +}; + +static const uint16_t ud_itab__264[] = { + /* 0 */ 1003, INVALID, INVALID, 1004, +}; + +static const uint16_t ud_itab__265[] = { + /* 0 */ 1006, INVALID, INVALID, 1007, +}; + +static const uint16_t ud_itab__266[] = { + /* 0 */ 1074, INVALID, INVALID, 1072, +}; + +static const uint16_t ud_itab__267[] = { + /* 0 */ 1266, INVALID, INVALID, 1264, +}; + +static const uint16_t ud_itab__268[] = { + /* 0 */ INVALID, 1559, INVALID, INVALID, +}; + +static const uint16_t ud_itab__269[] = { + /* 0 */ 1136, INVALID, INVALID, 1135, +}; + +static const uint16_t ud_itab__270[] = { + /* 0 */ 1140, INVALID, INVALID, 1139, +}; + +static const uint16_t ud_itab__271[] = { + /* 0 */ 1144, INVALID, INVALID, 1143, +}; + +static const uint16_t ud_itab__272[] = { + /* 0 */ 1533, INVALID, INVALID, 1534, +}; + +static const uint16_t ud_itab__273[] = { + /* 0 */ 1069, INVALID, INVALID, 1070, +}; + +static const uint16_t ud_itab__274[] = { + /* 0 */ 1133, INVALID, INVALID, 1131, +}; + +static const uint16_t ud_itab__275[] = { + /* 0 */ INVALID, GROUP(276), +}; + +static const uint16_t ud_itab__276[] = { + /* 0 */ 799, INVALID, INVALID, 1519, +}; + +static const uint16_t ud_itab__277[] = { + /* 0 */ 1179, INVALID, INVALID, 1177, +}; + +static const uint16_t ud_itab__278[] = { + /* 0 */ 1182, INVALID, INVALID, 1180, +}; + +static const uint16_t ud_itab__279[] = { + /* 0 */ 1183, INVALID, INVALID, 1184, +}; + +static const uint16_t ud_itab__280[] = { + /* 0 */ 1532, INVALID, INVALID, 1530, +}; + +static const uint16_t ud_itab__281[] = { + /* 0 */ 996, INVALID, INVALID, 994, +}; + +static const uint16_t ud_itab__282[] = { + /* 0 */ 997, INVALID, INVALID, 998, +}; + +static const uint16_t ud_itab__283[] = { + /* 0 */ 1000, INVALID, INVALID, 1001, +}; + +static const uint16_t ud_itab__284[] = { + /* 0 */ 1242, INVALID, +}; + +static const uint16_t ud_itab__285[] = { + /* 0 */ 1097, INVALID, +}; + +static const uint16_t ud_itab__286[] = { + /* 0 */ 1243, INVALID, +}; + +static const uint16_t ud_itab__287[] = { + /* 0 */ 1098, INVALID, +}; + +static const uint16_t ud_itab__288[] = { + /* 0 */ 173, INVALID, +}; + +static const uint16_t ud_itab__289[] = { + /* 0 */ 174, INVALID, +}; + +static const uint16_t ud_itab__290[] = { + /* 0 */ 1, INVALID, +}; + +static const uint16_t ud_itab__291[] = { + /* 0 */ 4, INVALID, +}; + +static const uint16_t ud_itab__292[] = { + /* 0 */ GROUP(293), GROUP(294), INVALID, +}; + +static const uint16_t ud_itab__293[] = { + /* 0 */ 1257, INVALID, +}; + +static const uint16_t ud_itab__294[] = { + /* 0 */ 1258, INVALID, +}; + +static const uint16_t ud_itab__295[] = { + /* 0 */ GROUP(296), GROUP(297), INVALID, +}; + +static const uint16_t ud_itab__296[] = { + /* 0 */ 1110, INVALID, +}; + +static const uint16_t ud_itab__297[] = { + /* 0 */ 1111, INVALID, +}; + +static const uint16_t ud_itab__298[] = { + /* 0 */ 1658, INVALID, +}; + +static const uint16_t ud_itab__299[] = { + /* 0 */ 67, 68, +}; + +static const uint16_t ud_itab__300[] = { + /* 0 */ 710, 711, INVALID, +}; + +static const uint16_t ud_itab__301[] = { + /* 0 */ 983, 984, INVALID, +}; + +static const uint16_t ud_itab__302[] = { + /* 0 */ 21, 970, 11, 1342, + /* 4 */ 55, 1413, 1493, 106, +}; + +static const uint16_t ud_itab__303[] = { + /* 0 */ 23, 971, 13, 1343, + /* 4 */ 57, 1414, 1494, 108, +}; + +static const uint16_t ud_itab__304[] = { + /* 0 */ GROUP(305), GROUP(306), GROUP(307), GROUP(308), + /* 4 */ GROUP(309), GROUP(310), GROUP(311), GROUP(312), +}; + +static const uint16_t ud_itab__305[] = { + /* 0 */ 22, INVALID, +}; + +static const uint16_t ud_itab__306[] = { + /* 0 */ 972, INVALID, +}; + +static const uint16_t ud_itab__307[] = { + /* 0 */ 12, INVALID, +}; + +static const uint16_t ud_itab__308[] = { + /* 0 */ 1344, INVALID, +}; + +static const uint16_t ud_itab__309[] = { + /* 0 */ 56, INVALID, +}; + +static const uint16_t ud_itab__310[] = { + /* 0 */ 1415, INVALID, +}; + +static const uint16_t ud_itab__311[] = { + /* 0 */ 1495, INVALID, +}; + +static const uint16_t ud_itab__312[] = { + /* 0 */ 107, INVALID, +}; + +static const uint16_t ud_itab__313[] = { + /* 0 */ 24, 973, 14, 1345, + /* 4 */ 58, 1416, 1496, 109, +}; + +static const uint16_t ud_itab__314[] = { + /* 0 */ 1109, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__315[] = { + /* 0 */ 74, 75, 76, +}; + +static const uint16_t ud_itab__316[] = { + /* 0 */ 170, 171, 172, +}; + +static const uint16_t ud_itab__317[] = { + /* 0 */ 73, INVALID, +}; + +static const uint16_t ud_itab__318[] = { + /* 0 */ GROUP(319), GROUP(320), GROUP(321), +}; + +static const uint16_t ud_itab__319[] = { + /* 0 */ 1259, 1260, +}; + +static const uint16_t ud_itab__320[] = { + /* 0 */ 1261, 1262, +}; + +static const uint16_t ud_itab__321[] = { + /* 0 */ INVALID, 1263, +}; + +static const uint16_t ud_itab__322[] = { + /* 0 */ GROUP(323), GROUP(324), GROUP(325), +}; + +static const uint16_t ud_itab__323[] = { + /* 0 */ 1112, INVALID, +}; + +static const uint16_t ud_itab__324[] = { + /* 0 */ 1113, 1114, +}; + +static const uint16_t ud_itab__325[] = { + /* 0 */ INVALID, 1115, +}; + +static const uint16_t ud_itab__326[] = { + /* 0 */ 923, 924, 927, +}; + +static const uint16_t ud_itab__327[] = { + /* 0 */ 115, 116, 119, +}; + +static const uint16_t ud_itab__328[] = { + /* 0 */ 1403, 1404, 1405, +}; + +static const uint16_t ud_itab__329[] = { + /* 0 */ 791, 792, 793, +}; + +static const uint16_t ud_itab__330[] = { + /* 0 */ 1347, 1348, 1349, +}; + +static const uint16_t ud_itab__331[] = { + /* 0 */ 1279, 1286, 1267, 1275, + /* 4 */ 1327, 1334, 1318, 1313, +}; + +static const uint16_t ud_itab__332[] = { + /* 0 */ 1284, 1287, 1268, 1274, + /* 4 */ 1323, 1330, 1319, 1315, +}; + +static const uint16_t ud_itab__333[] = { + /* 0 */ GROUP(334), GROUP(335), INVALID, INVALID, + /* 4 */ INVALID, GROUP(341), GROUP(357), GROUP(369), + /* 8 */ INVALID, GROUP(394), INVALID, INVALID, + /* c */ INVALID, GROUP(399), INVALID, INVALID, +}; + +static const uint16_t ud_itab__334[] = { + /* 0 */ 771, INVALID, +}; + +static const uint16_t ud_itab__335[] = { + /* 0 */ INVALID, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, + /* 8 */ INVALID, INVALID, INVALID, INVALID, + /* c */ INVALID, INVALID, INVALID, INVALID, + /* 10 */ 937, 939, GROUP(336), 895, + /* 14 */ 1450, 1448, GROUP(337), 885, + /* 18 */ INVALID, INVALID, INVALID, INVALID, + /* 1c */ INVALID, INVALID, INVALID, INVALID, + /* 20 */ INVALID, INVALID, INVALID, INVALID, + /* 24 */ INVALID, INVALID, INVALID, INVALID, + /* 28 */ 863, 865, INVALID, 908, + /* 2c */ INVALID, INVALID, 1443, 130, + /* 30 */ INVALID, INVALID, INVALID, INVALID, + /* 34 */ INVALID, INVALID, INVALID, INVALID, + /* 38 */ INVALID, INVALID, INVALID, INVALID, + /* 3c */ INVALID, INVALID, INVALID, INVALID, + /* 40 */ INVALID, INVALID, INVALID, INVALID, + /* 44 */ INVALID, INVALID, INVALID, INVALID, + /* 48 */ INVALID, INVALID, INVALID, INVALID, + /* 4c */ INVALID, INVALID, INVALID, INVALID, + /* 50 */ 901, 1388, 1307, 1292, + /* 54 */ 62, 66, 977, 1500, + /* 58 */ 28, 947, 146, 135, + /* 5c */ 1420, 819, 190, 803, + /* 60 */ INVALID, INVALID, INVALID, INVALID, + /* 64 */ INVALID, INVALID, INVALID, INVALID, + /* 68 */ INVALID, INVALID, INVALID, INVALID, + /* 6c */ INVALID, INVALID, INVALID, INVALID, + /* 70 */ INVALID, INVALID, INVALID, INVALID, + /* 74 */ INVALID, INVALID, INVALID, GROUP(340), + /* 78 */ INVALID, INVALID, INVALID, INVALID, + /* 7c */ INVALID, INVALID, INVALID, INVALID, + /* 80 */ INVALID, INVALID, INVALID, INVALID, + /* 84 */ INVALID, INVALID, INVALID, INVALID, + /* 88 */ INVALID, INVALID, INVALID, INVALID, + /* 8c */ INVALID, INVALID, INVALID, INVALID, + /* 90 */ INVALID, INVALID, INVALID, INVALID, + /* 94 */ INVALID, INVALID, INVALID, INVALID, + /* 98 */ INVALID, INVALID, INVALID, INVALID, + /* 9c */ INVALID, INVALID, INVALID, INVALID, + /* a0 */ INVALID, INVALID, INVALID, INVALID, + /* a4 */ INVALID, INVALID, INVALID, INVALID, + /* a8 */ INVALID, INVALID, INVALID, INVALID, + /* ac */ INVALID, INVALID, GROUP(338), INVALID, + /* b0 */ INVALID, INVALID, INVALID, INVALID, + /* b4 */ INVALID, INVALID, INVALID, INVALID, + /* b8 */ INVALID, INVALID, INVALID, INVALID, + /* bc */ INVALID, INVALID, INVALID, INVALID, + /* c0 */ INVALID, INVALID, 113, INVALID, + /* c4 */ INVALID, INVALID, 1382, INVALID, + /* c8 */ INVALID, INVALID, INVALID, INVALID, + /* cc */ INVALID, INVALID, INVALID, INVALID, + /* d0 */ INVALID, INVALID, INVALID, INVALID, + /* d4 */ INVALID, INVALID, INVALID, INVALID, + /* d8 */ INVALID, INVALID, INVALID, INVALID, + /* dc */ INVALID, INVALID, INVALID, INVALID, + /* e0 */ INVALID, INVALID, INVALID, INVALID, + /* e4 */ INVALID, INVALID, INVALID, INVALID, + /* e8 */ INVALID, INVALID, INVALID, INVALID, + /* ec */ INVALID, INVALID, INVALID, INVALID, + /* f0 */ INVALID, INVALID, INVALID, INVALID, + /* f4 */ INVALID, INVALID, INVALID, INVALID, + /* f8 */ INVALID, INVALID, INVALID, INVALID, + /* fc */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__336[] = { + /* 0 */ 893, 897, +}; + +static const uint16_t ud_itab__337[] = { + /* 0 */ 883, 887, +}; + +static const uint16_t ud_itab__338[] = { + /* 0 */ GROUP(339), INVALID, +}; + +static const uint16_t ud_itab__339[] = { + /* 0 */ INVALID, INVALID, INVALID, 1401, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__340[] = { + /* 0 */ 1742, 1743, +}; + +static const uint16_t ud_itab__341[] = { + /* 0 */ INVALID, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, + /* 8 */ INVALID, INVALID, INVALID, INVALID, + /* c */ INVALID, INVALID, INVALID, INVALID, + /* 10 */ 933, 935, GROUP(342), 891, + /* 14 */ 1452, 1446, GROUP(343), 881, + /* 18 */ INVALID, INVALID, INVALID, INVALID, + /* 1c */ INVALID, INVALID, INVALID, INVALID, + /* 20 */ INVALID, INVALID, INVALID, INVALID, + /* 24 */ INVALID, INVALID, INVALID, INVALID, + /* 28 */ 859, 861, INVALID, 906, + /* 2c */ INVALID, INVALID, 1441, 128, + /* 30 */ INVALID, INVALID, INVALID, INVALID, + /* 34 */ INVALID, INVALID, INVALID, INVALID, + /* 38 */ INVALID, INVALID, INVALID, INVALID, + /* 3c */ INVALID, INVALID, INVALID, INVALID, + /* 40 */ INVALID, INVALID, INVALID, INVALID, + /* 44 */ INVALID, INVALID, INVALID, INVALID, + /* 48 */ INVALID, INVALID, INVALID, INVALID, + /* 4c */ INVALID, INVALID, INVALID, INVALID, + /* 50 */ 899, 1390, INVALID, INVALID, + /* 54 */ 60, 64, 975, 1498, + /* 58 */ 26, 945, 140, 144, + /* 5c */ 1418, 817, 188, 801, + /* 60 */ 1208, 1211, 1214, 986, + /* 64 */ 1037, 1040, 1043, 992, + /* 68 */ 1199, 1202, 1205, 989, + /* 6c */ 1548, 1546, GROUP(344), 1518, + /* 70 */ 1540, GROUP(345), GROUP(347), GROUP(349), + /* 74 */ 1029, 1032, 1035, INVALID, + /* 78 */ INVALID, INVALID, INVALID, INVALID, + /* 7c */ 1550, 1554, GROUP(351), 1516, + /* 80 */ INVALID, INVALID, INVALID, INVALID, + /* 84 */ INVALID, INVALID, INVALID, INVALID, + /* 88 */ INVALID, INVALID, INVALID, INVALID, + /* 8c */ INVALID, INVALID, INVALID, INVALID, + /* 90 */ INVALID, INVALID, INVALID, INVALID, + /* 94 */ INVALID, INVALID, INVALID, INVALID, + /* 98 */ INVALID, INVALID, INVALID, INVALID, + /* 9c */ INVALID, INVALID, INVALID, INVALID, + /* a0 */ INVALID, INVALID, INVALID, INVALID, + /* a4 */ INVALID, INVALID, INVALID, INVALID, + /* a8 */ INVALID, INVALID, INVALID, INVALID, + /* ac */ INVALID, INVALID, INVALID, INVALID, + /* b0 */ INVALID, INVALID, INVALID, INVALID, + /* b4 */ INVALID, INVALID, INVALID, INVALID, + /* b8 */ INVALID, INVALID, INVALID, INVALID, + /* bc */ INVALID, INVALID, INVALID, INVALID, + /* c0 */ INVALID, INVALID, 111, INVALID, + /* c4 */ 1061, 1054, 1380, INVALID, + /* c8 */ INVALID, INVALID, INVALID, INVALID, + /* cc */ INVALID, INVALID, INVALID, INVALID, + /* d0 */ 34, 1162, 1168, 1174, + /* d4 */ 1529, 1095, 919, GROUP(352), + /* d8 */ 1194, 1197, 1082, 1016, + /* dc */ 1011, 1014, 1077, 1019, + /* e0 */ 1022, 1149, 1155, 1025, + /* e4 */ 1089, 1091, 161, 903, + /* e8 */ 1188, 1191, 1079, 1117, + /* ec */ 1005, 1008, 1073, 1265, + /* f0 */ INVALID, GROUP(353), GROUP(354), GROUP(355), + /* f4 */ INVALID, 1071, 1132, GROUP(356), + /* f8 */ 1178, 1181, 1185, 1531, + /* fc */ 995, 999, 1002, INVALID, +}; + +static const uint16_t ud_itab__342[] = { + /* 0 */ 889, INVALID, +}; + +static const uint16_t ud_itab__343[] = { + /* 0 */ 879, INVALID, +}; + +static const uint16_t ud_itab__344[] = { + /* 0 */ 869, 871, 912, +}; + +static const uint16_t ud_itab__345[] = { + /* 0 */ INVALID, INVALID, 1164, INVALID, + /* 4 */ 1151, INVALID, GROUP(346), INVALID, +}; + +static const uint16_t ud_itab__346[] = { + /* 0 */ 1756, INVALID, +}; + +static const uint16_t ud_itab__347[] = { + /* 0 */ INVALID, INVALID, 1170, INVALID, + /* 4 */ 1158, INVALID, GROUP(348), INVALID, +}; + +static const uint16_t ud_itab__348[] = { + /* 0 */ 1758, INVALID, +}; + +static const uint16_t ud_itab__349[] = { + /* 0 */ INVALID, INVALID, 1176, 1544, + /* 4 */ INVALID, INVALID, GROUP(350), 1542, +}; + +static const uint16_t ud_itab__350[] = { + /* 0 */ 1760, INVALID, +}; + +static const uint16_t ud_itab__351[] = { + /* 0 */ 875, 877, 915, +}; + +static const uint16_t ud_itab__352[] = { + /* 0 */ 1085, INVALID, +}; + +static const uint16_t ud_itab__353[] = { + /* 0 */ 1755, INVALID, +}; + +static const uint16_t ud_itab__354[] = { + /* 0 */ 1757, INVALID, +}; + +static const uint16_t ud_itab__355[] = { + /* 0 */ 1759, INVALID, +}; + +static const uint16_t ud_itab__356[] = { + /* 0 */ INVALID, 1520, +}; + +static const uint16_t ud_itab__357[] = { + /* 0 */ 1584, 1587, 1590, 1593, + /* 4 */ 1596, 1599, 1602, 1605, + /* 8 */ 1608, 1614, 1611, 1617, + /* c */ GROUP(358), GROUP(359), GROUP(360), GROUP(361), + /* 10 */ INVALID, INVALID, INVALID, INVALID, + /* 14 */ INVALID, INVALID, INVALID, 1712, + /* 18 */ GROUP(362), GROUP(363), INVALID, INVALID, + /* 1c */ 1575, 1578, 1581, INVALID, + /* 20 */ 1686, 1688, 1690, 1692, + /* 24 */ 1694, INVALID, INVALID, INVALID, + /* 28 */ 1623, 1709, 1682, 1684, + /* 2c */ GROUP(365), GROUP(366), GROUP(367), GROUP(368), + /* 30 */ 1697, 1699, 1701, 1703, + /* 34 */ 1705, 1707, INVALID, 1718, + /* 38 */ 1625, 1627, 1629, 1631, + /* 3c */ 1633, 1635, 1639, 1637, + /* 40 */ 1641, 1643, INVALID, INVALID, + /* 44 */ INVALID, INVALID, INVALID, INVALID, + /* 48 */ INVALID, INVALID, INVALID, INVALID, + /* 4c */ INVALID, INVALID, INVALID, INVALID, + /* 50 */ INVALID, INVALID, INVALID, INVALID, + /* 54 */ INVALID, INVALID, INVALID, INVALID, + /* 58 */ INVALID, INVALID, INVALID, INVALID, + /* 5c */ INVALID, INVALID, INVALID, INVALID, + /* 60 */ INVALID, INVALID, INVALID, INVALID, + /* 64 */ INVALID, INVALID, INVALID, INVALID, + /* 68 */ INVALID, INVALID, INVALID, INVALID, + /* 6c */ INVALID, INVALID, INVALID, INVALID, + /* 70 */ INVALID, INVALID, INVALID, INVALID, + /* 74 */ INVALID, INVALID, INVALID, INVALID, + /* 78 */ INVALID, INVALID, INVALID, INVALID, + /* 7c */ INVALID, INVALID, INVALID, INVALID, + /* 80 */ INVALID, INVALID, INVALID, INVALID, + /* 84 */ INVALID, INVALID, INVALID, INVALID, + /* 88 */ INVALID, INVALID, INVALID, INVALID, + /* 8c */ INVALID, INVALID, INVALID, INVALID, + /* 90 */ INVALID, INVALID, INVALID, INVALID, + /* 94 */ INVALID, INVALID, INVALID, INVALID, + /* 98 */ INVALID, INVALID, INVALID, INVALID, + /* 9c */ INVALID, INVALID, INVALID, INVALID, + /* a0 */ INVALID, INVALID, INVALID, INVALID, + /* a4 */ INVALID, INVALID, INVALID, INVALID, + /* a8 */ INVALID, INVALID, INVALID, INVALID, + /* ac */ INVALID, INVALID, INVALID, INVALID, + /* b0 */ INVALID, INVALID, INVALID, INVALID, + /* b4 */ INVALID, INVALID, INVALID, INVALID, + /* b8 */ INVALID, INVALID, INVALID, INVALID, + /* bc */ INVALID, INVALID, INVALID, INVALID, + /* c0 */ INVALID, INVALID, INVALID, INVALID, + /* c4 */ INVALID, INVALID, INVALID, INVALID, + /* c8 */ INVALID, INVALID, INVALID, INVALID, + /* cc */ INVALID, INVALID, INVALID, INVALID, + /* d0 */ INVALID, INVALID, INVALID, INVALID, + /* d4 */ INVALID, INVALID, INVALID, INVALID, + /* d8 */ INVALID, INVALID, INVALID, 46, + /* dc */ 42, 44, 38, 40, + /* e0 */ INVALID, INVALID, INVALID, INVALID, + /* e4 */ INVALID, INVALID, INVALID, INVALID, + /* e8 */ INVALID, INVALID, INVALID, INVALID, + /* ec */ INVALID, INVALID, INVALID, INVALID, + /* f0 */ INVALID, INVALID, INVALID, INVALID, + /* f4 */ INVALID, INVALID, INVALID, INVALID, + /* f8 */ INVALID, INVALID, INVALID, INVALID, + /* fc */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__358[] = { + /* 0 */ 1737, INVALID, +}; + +static const uint16_t ud_itab__359[] = { + /* 0 */ 1735, INVALID, +}; + +static const uint16_t ud_itab__360[] = { + /* 0 */ 1740, INVALID, +}; + +static const uint16_t ud_itab__361[] = { + /* 0 */ 1741, INVALID, +}; + +static const uint16_t ud_itab__362[] = { + /* 0 */ 1727, INVALID, +}; + +static const uint16_t ud_itab__363[] = { + /* 0 */ GROUP(364), INVALID, +}; + +static const uint16_t ud_itab__364[] = { + /* 0 */ INVALID, 1728, +}; + +static const uint16_t ud_itab__365[] = { + /* 0 */ 1731, INVALID, +}; + +static const uint16_t ud_itab__366[] = { + /* 0 */ 1733, INVALID, +}; + +static const uint16_t ud_itab__367[] = { + /* 0 */ 1732, INVALID, +}; + +static const uint16_t ud_itab__368[] = { + /* 0 */ 1734, INVALID, +}; + +static const uint16_t ud_itab__369[] = { + /* 0 */ INVALID, INVALID, INVALID, INVALID, + /* 4 */ GROUP(370), GROUP(371), GROUP(372), INVALID, + /* 8 */ 1645, 1647, 1649, 1651, + /* c */ 1655, 1653, 1678, 1620, + /* 10 */ INVALID, INVALID, INVALID, INVALID, + /* 14 */ GROUP(374), 1057, GROUP(375), 202, + /* 18 */ GROUP(379), GROUP(381), INVALID, INVALID, + /* 1c */ INVALID, INVALID, INVALID, INVALID, + /* 20 */ GROUP(383), 1558, GROUP(385), INVALID, + /* 24 */ INVALID, INVALID, INVALID, INVALID, + /* 28 */ INVALID, INVALID, INVALID, INVALID, + /* 2c */ INVALID, INVALID, INVALID, INVALID, + /* 30 */ INVALID, INVALID, INVALID, INVALID, + /* 34 */ INVALID, INVALID, INVALID, INVALID, + /* 38 */ INVALID, INVALID, INVALID, INVALID, + /* 3c */ INVALID, INVALID, INVALID, INVALID, + /* 40 */ 198, 196, 1680, INVALID, + /* 44 */ 1513, INVALID, INVALID, INVALID, + /* 48 */ INVALID, INVALID, GROUP(391), GROUP(392), + /* 4c */ GROUP(393), INVALID, INVALID, INVALID, + /* 50 */ INVALID, INVALID, INVALID, INVALID, + /* 54 */ INVALID, INVALID, INVALID, INVALID, + /* 58 */ INVALID, INVALID, INVALID, INVALID, + /* 5c */ INVALID, INVALID, INVALID, INVALID, + /* 60 */ 1716, 1714, 1722, 1720, + /* 64 */ INVALID, INVALID, INVALID, INVALID, + /* 68 */ INVALID, INVALID, INVALID, INVALID, + /* 6c */ INVALID, INVALID, INVALID, INVALID, + /* 70 */ INVALID, INVALID, INVALID, INVALID, + /* 74 */ INVALID, INVALID, INVALID, INVALID, + /* 78 */ INVALID, INVALID, INVALID, INVALID, + /* 7c */ INVALID, INVALID, INVALID, INVALID, + /* 80 */ INVALID, INVALID, INVALID, INVALID, + /* 84 */ INVALID, INVALID, INVALID, INVALID, + /* 88 */ INVALID, INVALID, INVALID, INVALID, + /* 8c */ INVALID, INVALID, INVALID, INVALID, + /* 90 */ INVALID, INVALID, INVALID, INVALID, + /* 94 */ INVALID, INVALID, INVALID, INVALID, + /* 98 */ INVALID, INVALID, INVALID, INVALID, + /* 9c */ INVALID, INVALID, INVALID, INVALID, + /* a0 */ INVALID, INVALID, INVALID, INVALID, + /* a4 */ INVALID, INVALID, INVALID, INVALID, + /* a8 */ INVALID, INVALID, INVALID, INVALID, + /* ac */ INVALID, INVALID, INVALID, INVALID, + /* b0 */ INVALID, INVALID, INVALID, INVALID, + /* b4 */ INVALID, INVALID, INVALID, INVALID, + /* b8 */ INVALID, INVALID, INVALID, INVALID, + /* bc */ INVALID, INVALID, INVALID, INVALID, + /* c0 */ INVALID, INVALID, INVALID, INVALID, + /* c4 */ INVALID, INVALID, INVALID, INVALID, + /* c8 */ INVALID, INVALID, INVALID, INVALID, + /* cc */ INVALID, INVALID, INVALID, INVALID, + /* d0 */ INVALID, INVALID, INVALID, INVALID, + /* d4 */ INVALID, INVALID, INVALID, INVALID, + /* d8 */ INVALID, INVALID, INVALID, INVALID, + /* dc */ INVALID, INVALID, INVALID, 48, + /* e0 */ INVALID, INVALID, INVALID, INVALID, + /* e4 */ INVALID, INVALID, INVALID, INVALID, + /* e8 */ INVALID, INVALID, INVALID, INVALID, + /* ec */ INVALID, INVALID, INVALID, INVALID, + /* f0 */ INVALID, INVALID, INVALID, INVALID, + /* f4 */ INVALID, INVALID, INVALID, INVALID, + /* f8 */ INVALID, INVALID, INVALID, INVALID, + /* fc */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__370[] = { + /* 0 */ 1738, INVALID, +}; + +static const uint16_t ud_itab__371[] = { + /* 0 */ 1736, INVALID, +}; + +static const uint16_t ud_itab__372[] = { + /* 0 */ GROUP(373), INVALID, +}; + +static const uint16_t ud_itab__373[] = { + /* 0 */ INVALID, 1739, +}; + +static const uint16_t ud_itab__374[] = { + /* 0 */ 1046, INVALID, +}; + +static const uint16_t ud_itab__375[] = { + /* 0 */ GROUP(376), GROUP(377), GROUP(378), +}; + +static const uint16_t ud_itab__376[] = { + /* 0 */ 1048, INVALID, +}; + +static const uint16_t ud_itab__377[] = { + /* 0 */ 1050, INVALID, +}; + +static const uint16_t ud_itab__378[] = { + /* 0 */ INVALID, 1052, +}; + +static const uint16_t ud_itab__379[] = { + /* 0 */ GROUP(380), INVALID, +}; + +static const uint16_t ud_itab__380[] = { + /* 0 */ INVALID, 1730, +}; + +static const uint16_t ud_itab__381[] = { + /* 0 */ GROUP(382), INVALID, +}; + +static const uint16_t ud_itab__382[] = { + /* 0 */ INVALID, 1729, +}; + +static const uint16_t ud_itab__383[] = { + /* 0 */ GROUP(384), INVALID, +}; + +static const uint16_t ud_itab__384[] = { + /* 0 */ 1065, INVALID, +}; + +static const uint16_t ud_itab__385[] = { + /* 0 */ GROUP(386), GROUP(388), +}; + +static const uint16_t ud_itab__386[] = { + /* 0 */ GROUP(387), INVALID, +}; + +static const uint16_t ud_itab__387[] = { + /* 0 */ 1066, INVALID, +}; + +static const uint16_t ud_itab__388[] = { + /* 0 */ GROUP(389), GROUP(390), +}; + +static const uint16_t ud_itab__389[] = { + /* 0 */ 1067, INVALID, +}; + +static const uint16_t ud_itab__390[] = { + /* 0 */ 1068, INVALID, +}; + +static const uint16_t ud_itab__391[] = { + /* 0 */ 1745, INVALID, +}; + +static const uint16_t ud_itab__392[] = { + /* 0 */ 1744, INVALID, +}; + +static const uint16_t ud_itab__393[] = { + /* 0 */ 1754, INVALID, +}; + +static const uint16_t ud_itab__394[] = { + /* 0 */ INVALID, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, + /* 8 */ INVALID, INVALID, INVALID, INVALID, + /* c */ INVALID, INVALID, INVALID, INVALID, + /* 10 */ GROUP(395), GROUP(396), GROUP(397), INVALID, + /* 14 */ INVALID, INVALID, GROUP(398), INVALID, + /* 18 */ INVALID, INVALID, INVALID, INVALID, + /* 1c */ INVALID, INVALID, INVALID, INVALID, + /* 20 */ INVALID, INVALID, INVALID, INVALID, + /* 24 */ INVALID, INVALID, INVALID, INVALID, + /* 28 */ INVALID, INVALID, 155, INVALID, + /* 2c */ 169, 159, INVALID, INVALID, + /* 30 */ INVALID, INVALID, INVALID, INVALID, + /* 34 */ INVALID, INVALID, INVALID, INVALID, + /* 38 */ INVALID, INVALID, INVALID, INVALID, + /* 3c */ INVALID, INVALID, INVALID, INVALID, + /* 40 */ INVALID, INVALID, INVALID, INVALID, + /* 44 */ INVALID, INVALID, INVALID, INVALID, + /* 48 */ INVALID, INVALID, INVALID, INVALID, + /* 4c */ INVALID, INVALID, INVALID, INVALID, + /* 50 */ INVALID, 1394, 1309, 1294, + /* 54 */ INVALID, INVALID, INVALID, INVALID, + /* 58 */ 32, 951, 157, 164, + /* 5c */ 1424, 823, 194, 807, + /* 60 */ INVALID, INVALID, INVALID, INVALID, + /* 64 */ INVALID, INVALID, INVALID, INVALID, + /* 68 */ INVALID, INVALID, INVALID, INVALID, + /* 6c */ INVALID, INVALID, INVALID, 1523, + /* 70 */ 1536, INVALID, INVALID, INVALID, + /* 74 */ INVALID, INVALID, INVALID, INVALID, + /* 78 */ INVALID, INVALID, INVALID, INVALID, + /* 7c */ INVALID, INVALID, 917, 1525, + /* 80 */ INVALID, INVALID, INVALID, INVALID, + /* 84 */ INVALID, INVALID, INVALID, INVALID, + /* 88 */ INVALID, INVALID, INVALID, INVALID, + /* 8c */ INVALID, INVALID, INVALID, INVALID, + /* 90 */ INVALID, INVALID, INVALID, INVALID, + /* 94 */ INVALID, INVALID, INVALID, INVALID, + /* 98 */ INVALID, INVALID, INVALID, INVALID, + /* 9c */ INVALID, INVALID, INVALID, INVALID, + /* a0 */ INVALID, INVALID, INVALID, INVALID, + /* a4 */ INVALID, INVALID, INVALID, INVALID, + /* a8 */ INVALID, INVALID, INVALID, INVALID, + /* ac */ INVALID, INVALID, INVALID, INVALID, + /* b0 */ INVALID, INVALID, INVALID, INVALID, + /* b4 */ INVALID, INVALID, INVALID, INVALID, + /* b8 */ INVALID, INVALID, INVALID, INVALID, + /* bc */ INVALID, INVALID, INVALID, INVALID, + /* c0 */ INVALID, INVALID, 121, INVALID, + /* c4 */ INVALID, INVALID, INVALID, INVALID, + /* c8 */ INVALID, INVALID, INVALID, INVALID, + /* cc */ INVALID, INVALID, INVALID, INVALID, + /* d0 */ INVALID, INVALID, INVALID, INVALID, + /* d4 */ INVALID, INVALID, INVALID, INVALID, + /* d8 */ INVALID, INVALID, INVALID, INVALID, + /* dc */ INVALID, INVALID, INVALID, INVALID, + /* e0 */ INVALID, INVALID, INVALID, INVALID, + /* e4 */ INVALID, INVALID, 133, INVALID, + /* e8 */ INVALID, INVALID, INVALID, INVALID, + /* ec */ INVALID, INVALID, INVALID, INVALID, + /* f0 */ INVALID, INVALID, INVALID, INVALID, + /* f4 */ INVALID, INVALID, INVALID, INVALID, + /* f8 */ INVALID, INVALID, INVALID, INVALID, + /* fc */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__395[] = { + /* 0 */ 1751, 1750, +}; + +static const uint16_t ud_itab__396[] = { + /* 0 */ 1753, 1752, +}; + +static const uint16_t ud_itab__397[] = { + /* 0 */ 1572, 1570, +}; + +static const uint16_t ud_itab__398[] = { + /* 0 */ 1568, 1566, +}; + +static const uint16_t ud_itab__399[] = { + /* 0 */ INVALID, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, + /* 8 */ INVALID, INVALID, INVALID, INVALID, + /* c */ INVALID, INVALID, INVALID, INVALID, + /* 10 */ GROUP(402), GROUP(400), GROUP(401), INVALID, + /* 14 */ INVALID, INVALID, INVALID, INVALID, + /* 18 */ INVALID, INVALID, INVALID, INVALID, + /* 1c */ INVALID, INVALID, INVALID, INVALID, + /* 20 */ INVALID, INVALID, INVALID, INVALID, + /* 24 */ INVALID, INVALID, INVALID, INVALID, + /* 28 */ INVALID, INVALID, 153, INVALID, + /* 2c */ 167, 149, INVALID, INVALID, + /* 30 */ INVALID, INVALID, INVALID, INVALID, + /* 34 */ INVALID, INVALID, INVALID, INVALID, + /* 38 */ INVALID, INVALID, INVALID, INVALID, + /* 3c */ INVALID, INVALID, INVALID, INVALID, + /* 40 */ INVALID, INVALID, INVALID, INVALID, + /* 44 */ INVALID, INVALID, INVALID, INVALID, + /* 48 */ INVALID, INVALID, INVALID, INVALID, + /* 4c */ INVALID, INVALID, INVALID, INVALID, + /* 50 */ INVALID, 1392, INVALID, INVALID, + /* 54 */ INVALID, INVALID, INVALID, INVALID, + /* 58 */ 30, 949, 151, INVALID, + /* 5c */ 1422, 821, 192, 805, + /* 60 */ INVALID, INVALID, INVALID, INVALID, + /* 64 */ INVALID, INVALID, INVALID, INVALID, + /* 68 */ INVALID, INVALID, INVALID, INVALID, + /* 6c */ INVALID, INVALID, INVALID, INVALID, + /* 70 */ 1538, INVALID, INVALID, INVALID, + /* 74 */ INVALID, INVALID, INVALID, INVALID, + /* 78 */ INVALID, INVALID, INVALID, INVALID, + /* 7c */ 1552, 1556, INVALID, INVALID, + /* 80 */ INVALID, INVALID, INVALID, INVALID, + /* 84 */ INVALID, INVALID, INVALID, INVALID, + /* 88 */ INVALID, INVALID, INVALID, INVALID, + /* 8c */ INVALID, INVALID, INVALID, INVALID, + /* 90 */ INVALID, INVALID, INVALID, INVALID, + /* 94 */ INVALID, INVALID, INVALID, INVALID, + /* 98 */ INVALID, INVALID, INVALID, INVALID, + /* 9c */ INVALID, INVALID, INVALID, INVALID, + /* a0 */ INVALID, INVALID, INVALID, INVALID, + /* a4 */ INVALID, INVALID, INVALID, INVALID, + /* a8 */ INVALID, INVALID, INVALID, INVALID, + /* ac */ INVALID, INVALID, INVALID, INVALID, + /* b0 */ INVALID, INVALID, INVALID, INVALID, + /* b4 */ INVALID, INVALID, INVALID, INVALID, + /* b8 */ INVALID, INVALID, INVALID, INVALID, + /* bc */ INVALID, INVALID, INVALID, INVALID, + /* c0 */ INVALID, INVALID, 118, INVALID, + /* c4 */ INVALID, INVALID, INVALID, INVALID, + /* c8 */ INVALID, INVALID, INVALID, INVALID, + /* cc */ INVALID, INVALID, INVALID, INVALID, + /* d0 */ 36, INVALID, INVALID, INVALID, + /* d4 */ INVALID, INVALID, INVALID, INVALID, + /* d8 */ INVALID, INVALID, INVALID, INVALID, + /* dc */ INVALID, INVALID, INVALID, INVALID, + /* e0 */ INVALID, INVALID, INVALID, INVALID, + /* e4 */ INVALID, INVALID, 137, INVALID, + /* e8 */ INVALID, INVALID, INVALID, INVALID, + /* ec */ INVALID, INVALID, INVALID, INVALID, + /* f0 */ 1560, INVALID, INVALID, INVALID, + /* f4 */ INVALID, INVALID, INVALID, INVALID, + /* f8 */ INVALID, INVALID, INVALID, INVALID, + /* fc */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__400[] = { + /* 0 */ 1749, 1748, +}; + +static const uint16_t ud_itab__401[] = { + /* 0 */ 1564, 1562, +}; + +static const uint16_t ud_itab__402[] = { + /* 0 */ 1747, 1746, +}; + +static const uint16_t ud_itab__403[] = { + /* 0 */ GROUP(404), GROUP(335), INVALID, INVALID, + /* 4 */ INVALID, GROUP(341), GROUP(357), GROUP(369), + /* 8 */ INVALID, GROUP(394), INVALID, INVALID, + /* c */ INVALID, GROUP(399), INVALID, INVALID, +}; + +static const uint16_t ud_itab__404[] = { + /* 0 */ 769, INVALID, +}; + +static const uint16_t ud_itab__405[] = { + /* 0 */ 826, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__406[] = { + /* 0 */ 827, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__407[] = { + /* 0 */ 715, INVALID, +}; + +static const uint16_t ud_itab__408[] = { + /* 0 */ 723, 724, 725, +}; + +static const uint16_t ud_itab__409[] = { + /* 0 */ 1280, 1285, 1269, 1273, + /* 4 */ 1326, 1333, 1320, 1314, +}; + +static const uint16_t ud_itab__410[] = { + /* 0 */ 1281, 1288, 1272, 1276, + /* 4 */ 1325, 1332, 1329, 1312, +}; + +static const uint16_t ud_itab__411[] = { + /* 0 */ 1282, 1289, 1270, 1277, + /* 4 */ 1324, 1331, 1321, 1316, +}; + +static const uint16_t ud_itab__412[] = { + /* 0 */ 1283, 1290, 1271, 1278, + /* 4 */ 1328, 1335, 1322, 1317, +}; + +static const uint16_t ud_itab__413[] = { + /* 0 */ 3, INVALID, +}; + +static const uint16_t ud_itab__414[] = { + /* 0 */ 2, INVALID, +}; + +static const uint16_t ud_itab__415[] = { + /* 0 */ 1311, INVALID, +}; + +static const uint16_t ud_itab__416[] = { + /* 0 */ GROUP(417), GROUP(418), +}; + +static const uint16_t ud_itab__417[] = { + /* 0 */ 206, 503, 307, 357, + /* 4 */ 587, 630, 387, 413, +}; + +static const uint16_t ud_itab__418[] = { + /* 0 */ 215, 216, 217, 218, + /* 4 */ 219, 220, 221, 222, + /* 8 */ 504, 505, 506, 507, + /* c */ 508, 509, 510, 511, + /* 10 */ 309, 310, 311, 312, + /* 14 */ 313, 314, 315, 316, + /* 18 */ 359, 360, 361, 362, + /* 1c */ 363, 364, 365, 366, + /* 20 */ 589, 590, 591, 592, + /* 24 */ 593, 594, 595, 596, + /* 28 */ 614, 615, 616, 617, + /* 2c */ 618, 619, 620, 621, + /* 30 */ 388, 389, 390, 391, + /* 34 */ 392, 393, 394, 395, + /* 38 */ 414, 415, 416, 417, + /* 3c */ 418, 419, 420, 421, +}; + +static const uint16_t ud_itab__419[] = { + /* 0 */ GROUP(420), GROUP(421), +}; + +static const uint16_t ud_itab__420[] = { + /* 0 */ 476, INVALID, 573, 540, + /* 4 */ 493, 492, 584, 583, +}; + +static const uint16_t ud_itab__421[] = { + /* 0 */ 477, 478, 479, 480, + /* 4 */ 481, 482, 483, 484, + /* 8 */ 658, 659, 660, 661, + /* c */ 662, 663, 664, 665, + /* 10 */ 522, INVALID, INVALID, INVALID, + /* 14 */ INVALID, INVALID, INVALID, INVALID, + /* 18 */ 549, 550, 551, 552, + /* 1c */ 553, 554, 555, 556, + /* 20 */ 233, 204, INVALID, INVALID, + /* 24 */ 639, 657, INVALID, INVALID, + /* 28 */ 485, 486, 487, 488, + /* 2c */ 489, 490, 491, INVALID, + /* 30 */ 203, 685, 529, 526, + /* 34 */ 684, 528, 377, 454, + /* 38 */ 527, 686, 537, 536, + /* 3c */ 530, 534, 535, 376, +}; + +static const uint16_t ud_itab__422[] = { + /* 0 */ GROUP(423), GROUP(424), +}; + +static const uint16_t ud_itab__423[] = { + /* 0 */ 456, 520, 448, 450, + /* 4 */ 462, 464, 460, 458, +}; + +static const uint16_t ud_itab__424[] = { + /* 0 */ 235, 236, 237, 238, + /* 4 */ 239, 240, 241, 242, + /* 8 */ 243, 244, 245, 246, + /* c */ 247, 248, 249, 250, + /* 10 */ 251, 252, 253, 254, + /* 14 */ 255, 256, 257, 258, + /* 18 */ 259, 260, 261, 262, + /* 1c */ 263, 264, 265, 266, + /* 20 */ INVALID, INVALID, INVALID, INVALID, + /* 24 */ INVALID, INVALID, INVALID, INVALID, + /* 28 */ INVALID, 656, INVALID, INVALID, + /* 2c */ INVALID, INVALID, INVALID, INVALID, + /* 30 */ INVALID, INVALID, INVALID, INVALID, + /* 34 */ INVALID, INVALID, INVALID, INVALID, + /* 38 */ INVALID, INVALID, INVALID, INVALID, + /* 3c */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__425[] = { + /* 0 */ GROUP(426), GROUP(427), +}; + +static const uint16_t ud_itab__426[] = { + /* 0 */ 453, 471, 467, 470, + /* 4 */ INVALID, 474, INVALID, 538, +}; + +static const uint16_t ud_itab__427[] = { + /* 0 */ 267, 268, 269, 270, + /* 4 */ 271, 272, 273, 274, + /* 8 */ 275, 276, 277, 278, + /* c */ 279, 280, 281, 282, + /* 10 */ 283, 284, 285, 286, + /* 14 */ 287, 288, 289, 290, + /* 18 */ 291, 292, 293, 294, + /* 1c */ 295, 296, 297, 298, + /* 20 */ 524, 523, 234, 455, + /* 24 */ 525, 532, INVALID, INVALID, + /* 28 */ 299, 300, 301, 302, + /* 2c */ 303, 304, 305, 306, + /* 30 */ 333, 334, 335, 336, + /* 34 */ 337, 338, 339, 340, + /* 38 */ INVALID, INVALID, INVALID, INVALID, + /* 3c */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__428[] = { + /* 0 */ GROUP(429), GROUP(430), +}; + +static const uint16_t ud_itab__429[] = { + /* 0 */ 205, 494, 308, 358, + /* 4 */ 588, 613, 378, 404, +}; + +static const uint16_t ud_itab__430[] = { + /* 0 */ 207, 208, 209, 210, + /* 4 */ 211, 212, 213, 214, + /* 8 */ 495, 496, 497, 498, + /* c */ 499, 500, 501, 502, + /* 10 */ 317, 318, 319, 320, + /* 14 */ 321, 322, 323, 324, + /* 18 */ 325, 326, 327, 328, + /* 1c */ 329, 330, 331, 332, + /* 20 */ 622, 623, 624, 625, + /* 24 */ 626, 627, 628, 629, + /* 28 */ 597, 598, 599, 600, + /* 2c */ 601, 602, 603, 604, + /* 30 */ 405, 406, 407, 408, + /* 34 */ 409, 410, 411, 412, + /* 38 */ 379, 380, 381, 382, + /* 3c */ 383, 384, 385, 386, +}; + +static const uint16_t ud_itab__431[] = { + /* 0 */ GROUP(432), GROUP(433), +}; + +static const uint16_t ud_itab__432[] = { + /* 0 */ 475, 472, 574, 539, + /* 4 */ 531, INVALID, 533, 585, +}; + +static const uint16_t ud_itab__433[] = { + /* 0 */ 431, 432, 433, 434, + /* 4 */ 435, 436, 437, 438, + /* 8 */ 666, 667, 668, 669, + /* c */ 670, 671, 672, 673, + /* 10 */ 575, 576, 577, 578, + /* 14 */ 579, 580, 581, 582, + /* 18 */ 541, 542, 543, 544, + /* 1c */ 545, 546, 547, 548, + /* 20 */ 640, 641, 642, 643, + /* 24 */ 644, 645, 646, 647, + /* 28 */ 648, 649, 650, 651, + /* 2c */ 652, 653, 654, 655, + /* 30 */ INVALID, INVALID, INVALID, INVALID, + /* 34 */ INVALID, INVALID, INVALID, INVALID, + /* 38 */ INVALID, INVALID, INVALID, INVALID, + /* 3c */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__434[] = { + /* 0 */ GROUP(435), GROUP(436), +}; + +static const uint16_t ud_itab__435[] = { + /* 0 */ 457, 521, 447, 449, + /* 4 */ 463, 465, 461, 459, +}; + +static const uint16_t ud_itab__436[] = { + /* 0 */ 223, 224, 225, 226, + /* 4 */ 227, 228, 229, 230, + /* 8 */ 512, 513, 514, 515, + /* c */ 516, 517, 518, 519, + /* 10 */ 367, 368, 369, 370, + /* 14 */ 371, 372, 373, 374, + /* 18 */ INVALID, 375, INVALID, INVALID, + /* 1c */ INVALID, INVALID, INVALID, INVALID, + /* 20 */ 631, 632, 633, 634, + /* 24 */ 635, 636, 637, 638, + /* 28 */ 605, 606, 607, 608, + /* 2c */ 609, 610, 611, 612, + /* 30 */ 422, 423, 424, 425, + /* 34 */ 426, 427, 428, 429, + /* 38 */ 396, 397, 398, 399, + /* 3c */ 400, 401, 402, 403, +}; + +static const uint16_t ud_itab__437[] = { + /* 0 */ GROUP(438), GROUP(439), +}; + +static const uint16_t ud_itab__438[] = { + /* 0 */ 451, 473, 466, 468, + /* 4 */ 231, 452, 232, 469, +}; + +static const uint16_t ud_itab__439[] = { + /* 0 */ 439, 440, 441, 442, + /* 4 */ 443, 444, 445, 446, + /* 8 */ 674, 675, 676, 677, + /* c */ 678, 679, 680, 681, + /* 10 */ 557, 558, 559, 560, + /* 14 */ 561, 562, 563, 564, + /* 18 */ 565, 566, 567, 568, + /* 1c */ 569, 570, 571, 572, + /* 20 */ 586, INVALID, INVALID, INVALID, + /* 24 */ INVALID, INVALID, INVALID, INVALID, + /* 28 */ 341, 342, 343, 344, + /* 2c */ 345, 346, 347, 348, + /* 30 */ 349, 350, 351, 352, + /* 34 */ 353, 354, 355, 356, + /* 38 */ INVALID, INVALID, INVALID, INVALID, + /* 3c */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__440[] = { + /* 0 */ 758, 759, 760, +}; + +static const uint16_t ud_itab__441[] = { + /* 0 */ 764, INVALID, +}; + +static const uint16_t ud_itab__442[] = { + /* 0 */ 1432, 1437, 962, 953, + /* 4 */ 942, 695, 186, 689, +}; + +static const uint16_t ud_itab__443[] = { + /* 0 */ 1438, 1439, 963, 954, + /* 4 */ 943, 696, 185, 688, +}; + +static const uint16_t ud_itab__444[] = { + /* 0 */ 708, 183, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__445[] = { + /* 0 */ 707, 184, GROUP(446), 71, + /* 4 */ 761, 762, 1255, INVALID, +}; + +static const uint16_t ud_itab__446[] = { + /* 0 */ 69, 70, +}; + + +struct ud_lookup_table_list_entry ud_lookup_table_list[] = { + /* 000 */ { ud_itab__0, UD_TAB__OPC_TABLE, "opctbl" }, + /* 001 */ { ud_itab__1, UD_TAB__OPC_MODE, "/m" }, + /* 002 */ { ud_itab__2, UD_TAB__OPC_MODE, "/m" }, + /* 003 */ { ud_itab__3, UD_TAB__OPC_MODE, "/m" }, + /* 004 */ { ud_itab__4, UD_TAB__OPC_TABLE, "opctbl" }, + /* 005 */ { ud_itab__5, UD_TAB__OPC_REG, "/reg" }, + /* 006 */ { ud_itab__6, UD_TAB__OPC_MOD, "/mod" }, + /* 007 */ { ud_itab__7, UD_TAB__OPC_REG, "/reg" }, + /* 008 */ { ud_itab__8, UD_TAB__OPC_REG, "/reg" }, + /* 009 */ { ud_itab__9, UD_TAB__OPC_RM, "/rm" }, + /* 010 */ { ud_itab__10, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 011 */ { ud_itab__11, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 012 */ { ud_itab__12, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 013 */ { ud_itab__13, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 014 */ { ud_itab__14, UD_TAB__OPC_RM, "/rm" }, + /* 015 */ { ud_itab__15, UD_TAB__OPC_RM, "/rm" }, + /* 016 */ { ud_itab__16, UD_TAB__OPC_RM, "/rm" }, + /* 017 */ { ud_itab__17, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 018 */ { ud_itab__18, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 019 */ { ud_itab__19, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 020 */ { ud_itab__20, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 021 */ { ud_itab__21, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 022 */ { ud_itab__22, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 023 */ { ud_itab__23, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 024 */ { ud_itab__24, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 025 */ { ud_itab__25, UD_TAB__OPC_RM, "/rm" }, + /* 026 */ { ud_itab__26, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 027 */ { ud_itab__27, UD_TAB__OPC_REG, "/reg" }, + /* 028 */ { ud_itab__28, UD_TAB__OPC_3DNOW, "/3dnow" }, + /* 029 */ { ud_itab__29, UD_TAB__OPC_SSE, "/sse" }, + /* 030 */ { ud_itab__30, UD_TAB__OPC_SSE, "/sse" }, + /* 031 */ { ud_itab__31, UD_TAB__OPC_MOD, "/mod" }, + /* 032 */ { ud_itab__32, UD_TAB__OPC_SSE, "/sse" }, + /* 033 */ { ud_itab__33, UD_TAB__OPC_SSE, "/sse" }, + /* 034 */ { ud_itab__34, UD_TAB__OPC_SSE, "/sse" }, + /* 035 */ { ud_itab__35, UD_TAB__OPC_SSE, "/sse" }, + /* 036 */ { ud_itab__36, UD_TAB__OPC_SSE, "/sse" }, + /* 037 */ { ud_itab__37, UD_TAB__OPC_MOD, "/mod" }, + /* 038 */ { ud_itab__38, UD_TAB__OPC_SSE, "/sse" }, + /* 039 */ { ud_itab__39, UD_TAB__OPC_SSE, "/sse" }, + /* 040 */ { ud_itab__40, UD_TAB__OPC_SSE, "/sse" }, + /* 041 */ { ud_itab__41, UD_TAB__OPC_REG, "/reg" }, + /* 042 */ { ud_itab__42, UD_TAB__OPC_SSE, "/sse" }, + /* 043 */ { ud_itab__43, UD_TAB__OPC_SSE, "/sse" }, + /* 044 */ { ud_itab__44, UD_TAB__OPC_SSE, "/sse" }, + /* 045 */ { ud_itab__45, UD_TAB__OPC_SSE, "/sse" }, + /* 046 */ { ud_itab__46, UD_TAB__OPC_SSE, "/sse" }, + /* 047 */ { ud_itab__47, UD_TAB__OPC_SSE, "/sse" }, + /* 048 */ { ud_itab__48, UD_TAB__OPC_SSE, "/sse" }, + /* 049 */ { ud_itab__49, UD_TAB__OPC_SSE, "/sse" }, + /* 050 */ { ud_itab__50, UD_TAB__OPC_MODE, "/m" }, + /* 051 */ { ud_itab__51, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 052 */ { ud_itab__52, UD_TAB__OPC_MODE, "/m" }, + /* 053 */ { ud_itab__53, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 054 */ { ud_itab__54, UD_TAB__OPC_TABLE, "opctbl" }, + /* 055 */ { ud_itab__55, UD_TAB__OPC_SSE, "/sse" }, + /* 056 */ { ud_itab__56, UD_TAB__OPC_MODE, "/m" }, + /* 057 */ { ud_itab__57, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 058 */ { ud_itab__58, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 059 */ { ud_itab__59, UD_TAB__OPC_SSE, "/sse" }, + /* 060 */ { ud_itab__60, UD_TAB__OPC_MODE, "/m" }, + /* 061 */ { ud_itab__61, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 062 */ { ud_itab__62, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 063 */ { ud_itab__63, UD_TAB__OPC_SSE, "/sse" }, + /* 064 */ { ud_itab__64, UD_TAB__OPC_SSE, "/sse" }, + /* 065 */ { ud_itab__65, UD_TAB__OPC_SSE, "/sse" }, + /* 066 */ { ud_itab__66, UD_TAB__OPC_SSE, "/sse" }, + /* 067 */ { ud_itab__67, UD_TAB__OPC_SSE, "/sse" }, + /* 068 */ { ud_itab__68, UD_TAB__OPC_SSE, "/sse" }, + /* 069 */ { ud_itab__69, UD_TAB__OPC_SSE, "/sse" }, + /* 070 */ { ud_itab__70, UD_TAB__OPC_SSE, "/sse" }, + /* 071 */ { ud_itab__71, UD_TAB__OPC_SSE, "/sse" }, + /* 072 */ { ud_itab__72, UD_TAB__OPC_SSE, "/sse" }, + /* 073 */ { ud_itab__73, UD_TAB__OPC_SSE, "/sse" }, + /* 074 */ { ud_itab__74, UD_TAB__OPC_SSE, "/sse" }, + /* 075 */ { ud_itab__75, UD_TAB__OPC_SSE, "/sse" }, + /* 076 */ { ud_itab__76, UD_TAB__OPC_SSE, "/sse" }, + /* 077 */ { ud_itab__77, UD_TAB__OPC_SSE, "/sse" }, + /* 078 */ { ud_itab__78, UD_TAB__OPC_SSE, "/sse" }, + /* 079 */ { ud_itab__79, UD_TAB__OPC_SSE, "/sse" }, + /* 080 */ { ud_itab__80, UD_TAB__OPC_SSE, "/sse" }, + /* 081 */ { ud_itab__81, UD_TAB__OPC_SSE, "/sse" }, + /* 082 */ { ud_itab__82, UD_TAB__OPC_SSE, "/sse" }, + /* 083 */ { ud_itab__83, UD_TAB__OPC_SSE, "/sse" }, + /* 084 */ { ud_itab__84, UD_TAB__OPC_SSE, "/sse" }, + /* 085 */ { ud_itab__85, UD_TAB__OPC_SSE, "/sse" }, + /* 086 */ { ud_itab__86, UD_TAB__OPC_SSE, "/sse" }, + /* 087 */ { ud_itab__87, UD_TAB__OPC_SSE, "/sse" }, + /* 088 */ { ud_itab__88, UD_TAB__OPC_SSE, "/sse" }, + /* 089 */ { ud_itab__89, UD_TAB__OPC_SSE, "/sse" }, + /* 090 */ { ud_itab__90, UD_TAB__OPC_SSE, "/sse" }, + /* 091 */ { ud_itab__91, UD_TAB__OPC_SSE, "/sse" }, + /* 092 */ { ud_itab__92, UD_TAB__OPC_SSE, "/sse" }, + /* 093 */ { ud_itab__93, UD_TAB__OPC_SSE, "/sse" }, + /* 094 */ { ud_itab__94, UD_TAB__OPC_SSE, "/sse" }, + /* 095 */ { ud_itab__95, UD_TAB__OPC_SSE, "/sse" }, + /* 096 */ { ud_itab__96, UD_TAB__OPC_SSE, "/sse" }, + /* 097 */ { ud_itab__97, UD_TAB__OPC_SSE, "/sse" }, + /* 098 */ { ud_itab__98, UD_TAB__OPC_SSE, "/sse" }, + /* 099 */ { ud_itab__99, UD_TAB__OPC_SSE, "/sse" }, + /* 100 */ { ud_itab__100, UD_TAB__OPC_SSE, "/sse" }, + /* 101 */ { ud_itab__101, UD_TAB__OPC_SSE, "/sse" }, + /* 102 */ { ud_itab__102, UD_TAB__OPC_SSE, "/sse" }, + /* 103 */ { ud_itab__103, UD_TAB__OPC_SSE, "/sse" }, + /* 104 */ { ud_itab__104, UD_TAB__OPC_SSE, "/sse" }, + /* 105 */ { ud_itab__105, UD_TAB__OPC_SSE, "/sse" }, + /* 106 */ { ud_itab__106, UD_TAB__OPC_SSE, "/sse" }, + /* 107 */ { ud_itab__107, UD_TAB__OPC_SSE, "/sse" }, + /* 108 */ { ud_itab__108, UD_TAB__OPC_SSE, "/sse" }, + /* 109 */ { ud_itab__109, UD_TAB__OPC_SSE, "/sse" }, + /* 110 */ { ud_itab__110, UD_TAB__OPC_SSE, "/sse" }, + /* 111 */ { ud_itab__111, UD_TAB__OPC_SSE, "/sse" }, + /* 112 */ { ud_itab__112, UD_TAB__OPC_SSE, "/sse" }, + /* 113 */ { ud_itab__113, UD_TAB__OPC_SSE, "/sse" }, + /* 114 */ { ud_itab__114, UD_TAB__OPC_SSE, "/sse" }, + /* 115 */ { ud_itab__115, UD_TAB__OPC_SSE, "/sse" }, + /* 116 */ { ud_itab__116, UD_TAB__OPC_TABLE, "opctbl" }, + /* 117 */ { ud_itab__117, UD_TAB__OPC_SSE, "/sse" }, + /* 118 */ { ud_itab__118, UD_TAB__OPC_SSE, "/sse" }, + /* 119 */ { ud_itab__119, UD_TAB__OPC_SSE, "/sse" }, + /* 120 */ { ud_itab__120, UD_TAB__OPC_SSE, "/sse" }, + /* 121 */ { ud_itab__121, UD_TAB__OPC_SSE, "/sse" }, + /* 122 */ { ud_itab__122, UD_TAB__OPC_SSE, "/sse" }, + /* 123 */ { ud_itab__123, UD_TAB__OPC_SSE, "/sse" }, + /* 124 */ { ud_itab__124, UD_TAB__OPC_SSE, "/sse" }, + /* 125 */ { ud_itab__125, UD_TAB__OPC_SSE, "/sse" }, + /* 126 */ { ud_itab__126, UD_TAB__OPC_SSE, "/sse" }, + /* 127 */ { ud_itab__127, UD_TAB__OPC_SSE, "/sse" }, + /* 128 */ { ud_itab__128, UD_TAB__OPC_OSIZE, "/o" }, + /* 129 */ { ud_itab__129, UD_TAB__OPC_SSE, "/sse" }, + /* 130 */ { ud_itab__130, UD_TAB__OPC_SSE, "/sse" }, + /* 131 */ { ud_itab__131, UD_TAB__OPC_SSE, "/sse" }, + /* 132 */ { ud_itab__132, UD_TAB__OPC_SSE, "/sse" }, + /* 133 */ { ud_itab__133, UD_TAB__OPC_OSIZE, "/o" }, + /* 134 */ { ud_itab__134, UD_TAB__OPC_SSE, "/sse" }, + /* 135 */ { ud_itab__135, UD_TAB__OPC_SSE, "/sse" }, + /* 136 */ { ud_itab__136, UD_TAB__OPC_SSE, "/sse" }, + /* 137 */ { ud_itab__137, UD_TAB__OPC_SSE, "/sse" }, + /* 138 */ { ud_itab__138, UD_TAB__OPC_SSE, "/sse" }, + /* 139 */ { ud_itab__139, UD_TAB__OPC_SSE, "/sse" }, + /* 140 */ { ud_itab__140, UD_TAB__OPC_SSE, "/sse" }, + /* 141 */ { ud_itab__141, UD_TAB__OPC_SSE, "/sse" }, + /* 142 */ { ud_itab__142, UD_TAB__OPC_SSE, "/sse" }, + /* 143 */ { ud_itab__143, UD_TAB__OPC_SSE, "/sse" }, + /* 144 */ { ud_itab__144, UD_TAB__OPC_SSE, "/sse" }, + /* 145 */ { ud_itab__145, UD_TAB__OPC_SSE, "/sse" }, + /* 146 */ { ud_itab__146, UD_TAB__OPC_SSE, "/sse" }, + /* 147 */ { ud_itab__147, UD_TAB__OPC_SSE, "/sse" }, + /* 148 */ { ud_itab__148, UD_TAB__OPC_SSE, "/sse" }, + /* 149 */ { ud_itab__149, UD_TAB__OPC_SSE, "/sse" }, + /* 150 */ { ud_itab__150, UD_TAB__OPC_SSE, "/sse" }, + /* 151 */ { ud_itab__151, UD_TAB__OPC_SSE, "/sse" }, + /* 152 */ { ud_itab__152, UD_TAB__OPC_SSE, "/sse" }, + /* 153 */ { ud_itab__153, UD_TAB__OPC_SSE, "/sse" }, + /* 154 */ { ud_itab__154, UD_TAB__OPC_SSE, "/sse" }, + /* 155 */ { ud_itab__155, UD_TAB__OPC_SSE, "/sse" }, + /* 156 */ { ud_itab__156, UD_TAB__OPC_SSE, "/sse" }, + /* 157 */ { ud_itab__157, UD_TAB__OPC_SSE, "/sse" }, + /* 158 */ { ud_itab__158, UD_TAB__OPC_SSE, "/sse" }, + /* 159 */ { ud_itab__159, UD_TAB__OPC_SSE, "/sse" }, + /* 160 */ { ud_itab__160, UD_TAB__OPC_SSE, "/sse" }, + /* 161 */ { ud_itab__161, UD_TAB__OPC_SSE, "/sse" }, + /* 162 */ { ud_itab__162, UD_TAB__OPC_SSE, "/sse" }, + /* 163 */ { ud_itab__163, UD_TAB__OPC_SSE, "/sse" }, + /* 164 */ { ud_itab__164, UD_TAB__OPC_SSE, "/sse" }, + /* 165 */ { ud_itab__165, UD_TAB__OPC_SSE, "/sse" }, + /* 166 */ { ud_itab__166, UD_TAB__OPC_SSE, "/sse" }, + /* 167 */ { ud_itab__167, UD_TAB__OPC_SSE, "/sse" }, + /* 168 */ { ud_itab__168, UD_TAB__OPC_SSE, "/sse" }, + /* 169 */ { ud_itab__169, UD_TAB__OPC_SSE, "/sse" }, + /* 170 */ { ud_itab__170, UD_TAB__OPC_SSE, "/sse" }, + /* 171 */ { ud_itab__171, UD_TAB__OPC_SSE, "/sse" }, + /* 172 */ { ud_itab__172, UD_TAB__OPC_SSE, "/sse" }, + /* 173 */ { ud_itab__173, UD_TAB__OPC_SSE, "/sse" }, + /* 174 */ { ud_itab__174, UD_TAB__OPC_OSIZE, "/o" }, + /* 175 */ { ud_itab__175, UD_TAB__OPC_OSIZE, "/o" }, + /* 176 */ { ud_itab__176, UD_TAB__OPC_SSE, "/sse" }, + /* 177 */ { ud_itab__177, UD_TAB__OPC_SSE, "/sse" }, + /* 178 */ { ud_itab__178, UD_TAB__OPC_REG, "/reg" }, + /* 179 */ { ud_itab__179, UD_TAB__OPC_SSE, "/sse" }, + /* 180 */ { ud_itab__180, UD_TAB__OPC_SSE, "/sse" }, + /* 181 */ { ud_itab__181, UD_TAB__OPC_SSE, "/sse" }, + /* 182 */ { ud_itab__182, UD_TAB__OPC_REG, "/reg" }, + /* 183 */ { ud_itab__183, UD_TAB__OPC_SSE, "/sse" }, + /* 184 */ { ud_itab__184, UD_TAB__OPC_SSE, "/sse" }, + /* 185 */ { ud_itab__185, UD_TAB__OPC_SSE, "/sse" }, + /* 186 */ { ud_itab__186, UD_TAB__OPC_REG, "/reg" }, + /* 187 */ { ud_itab__187, UD_TAB__OPC_SSE, "/sse" }, + /* 188 */ { ud_itab__188, UD_TAB__OPC_SSE, "/sse" }, + /* 189 */ { ud_itab__189, UD_TAB__OPC_SSE, "/sse" }, + /* 190 */ { ud_itab__190, UD_TAB__OPC_SSE, "/sse" }, + /* 191 */ { ud_itab__191, UD_TAB__OPC_SSE, "/sse" }, + /* 192 */ { ud_itab__192, UD_TAB__OPC_SSE, "/sse" }, + /* 193 */ { ud_itab__193, UD_TAB__OPC_SSE, "/sse" }, + /* 194 */ { ud_itab__194, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 195 */ { ud_itab__195, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 196 */ { ud_itab__196, UD_TAB__OPC_SSE, "/sse" }, + /* 197 */ { ud_itab__197, UD_TAB__OPC_SSE, "/sse" }, + /* 198 */ { ud_itab__198, UD_TAB__OPC_SSE, "/sse" }, + /* 199 */ { ud_itab__199, UD_TAB__OPC_OSIZE, "/o" }, + /* 200 */ { ud_itab__200, UD_TAB__OPC_OSIZE, "/o" }, + /* 201 */ { ud_itab__201, UD_TAB__OPC_SSE, "/sse" }, + /* 202 */ { ud_itab__202, UD_TAB__OPC_MOD, "/mod" }, + /* 203 */ { ud_itab__203, UD_TAB__OPC_REG, "/reg" }, + /* 204 */ { ud_itab__204, UD_TAB__OPC_RM, "/rm" }, + /* 205 */ { ud_itab__205, UD_TAB__OPC_RM, "/rm" }, + /* 206 */ { ud_itab__206, UD_TAB__OPC_RM, "/rm" }, + /* 207 */ { ud_itab__207, UD_TAB__OPC_MOD, "/mod" }, + /* 208 */ { ud_itab__208, UD_TAB__OPC_REG, "/reg" }, + /* 209 */ { ud_itab__209, UD_TAB__OPC_RM, "/rm" }, + /* 210 */ { ud_itab__210, UD_TAB__OPC_RM, "/rm" }, + /* 211 */ { ud_itab__211, UD_TAB__OPC_RM, "/rm" }, + /* 212 */ { ud_itab__212, UD_TAB__OPC_RM, "/rm" }, + /* 213 */ { ud_itab__213, UD_TAB__OPC_RM, "/rm" }, + /* 214 */ { ud_itab__214, UD_TAB__OPC_RM, "/rm" }, + /* 215 */ { ud_itab__215, UD_TAB__OPC_MOD, "/mod" }, + /* 216 */ { ud_itab__216, UD_TAB__OPC_REG, "/reg" }, + /* 217 */ { ud_itab__217, UD_TAB__OPC_REG, "/reg" }, + /* 218 */ { ud_itab__218, UD_TAB__OPC_RM, "/rm" }, + /* 219 */ { ud_itab__219, UD_TAB__OPC_RM, "/rm" }, + /* 220 */ { ud_itab__220, UD_TAB__OPC_RM, "/rm" }, + /* 221 */ { ud_itab__221, UD_TAB__OPC_SSE, "/sse" }, + /* 222 */ { ud_itab__222, UD_TAB__OPC_REG, "/reg" }, + /* 223 */ { ud_itab__223, UD_TAB__OPC_SSE, "/sse" }, + /* 224 */ { ud_itab__224, UD_TAB__OPC_SSE, "/sse" }, + /* 225 */ { ud_itab__225, UD_TAB__OPC_SSE, "/sse" }, + /* 226 */ { ud_itab__226, UD_TAB__OPC_SSE, "/sse" }, + /* 227 */ { ud_itab__227, UD_TAB__OPC_MOD, "/mod" }, + /* 228 */ { ud_itab__228, UD_TAB__OPC_REG, "/reg" }, + /* 229 */ { ud_itab__229, UD_TAB__OPC_OSIZE, "/o" }, + /* 230 */ { ud_itab__230, UD_TAB__OPC_SSE, "/sse" }, + /* 231 */ { ud_itab__231, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 232 */ { ud_itab__232, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 233 */ { ud_itab__233, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 234 */ { ud_itab__234, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 235 */ { ud_itab__235, UD_TAB__OPC_REG, "/reg" }, + /* 236 */ { ud_itab__236, UD_TAB__OPC_SSE, "/sse" }, + /* 237 */ { ud_itab__237, UD_TAB__OPC_SSE, "/sse" }, + /* 238 */ { ud_itab__238, UD_TAB__OPC_SSE, "/sse" }, + /* 239 */ { ud_itab__239, UD_TAB__OPC_SSE, "/sse" }, + /* 240 */ { ud_itab__240, UD_TAB__OPC_SSE, "/sse" }, + /* 241 */ { ud_itab__241, UD_TAB__OPC_SSE, "/sse" }, + /* 242 */ { ud_itab__242, UD_TAB__OPC_SSE, "/sse" }, + /* 243 */ { ud_itab__243, UD_TAB__OPC_SSE, "/sse" }, + /* 244 */ { ud_itab__244, UD_TAB__OPC_SSE, "/sse" }, + /* 245 */ { ud_itab__245, UD_TAB__OPC_SSE, "/sse" }, + /* 246 */ { ud_itab__246, UD_TAB__OPC_SSE, "/sse" }, + /* 247 */ { ud_itab__247, UD_TAB__OPC_SSE, "/sse" }, + /* 248 */ { ud_itab__248, UD_TAB__OPC_SSE, "/sse" }, + /* 249 */ { ud_itab__249, UD_TAB__OPC_SSE, "/sse" }, + /* 250 */ { ud_itab__250, UD_TAB__OPC_SSE, "/sse" }, + /* 251 */ { ud_itab__251, UD_TAB__OPC_SSE, "/sse" }, + /* 252 */ { ud_itab__252, UD_TAB__OPC_SSE, "/sse" }, + /* 253 */ { ud_itab__253, UD_TAB__OPC_SSE, "/sse" }, + /* 254 */ { ud_itab__254, UD_TAB__OPC_SSE, "/sse" }, + /* 255 */ { ud_itab__255, UD_TAB__OPC_SSE, "/sse" }, + /* 256 */ { ud_itab__256, UD_TAB__OPC_SSE, "/sse" }, + /* 257 */ { ud_itab__257, UD_TAB__OPC_SSE, "/sse" }, + /* 258 */ { ud_itab__258, UD_TAB__OPC_SSE, "/sse" }, + /* 259 */ { ud_itab__259, UD_TAB__OPC_SSE, "/sse" }, + /* 260 */ { ud_itab__260, UD_TAB__OPC_SSE, "/sse" }, + /* 261 */ { ud_itab__261, UD_TAB__OPC_SSE, "/sse" }, + /* 262 */ { ud_itab__262, UD_TAB__OPC_SSE, "/sse" }, + /* 263 */ { ud_itab__263, UD_TAB__OPC_SSE, "/sse" }, + /* 264 */ { ud_itab__264, UD_TAB__OPC_SSE, "/sse" }, + /* 265 */ { ud_itab__265, UD_TAB__OPC_SSE, "/sse" }, + /* 266 */ { ud_itab__266, UD_TAB__OPC_SSE, "/sse" }, + /* 267 */ { ud_itab__267, UD_TAB__OPC_SSE, "/sse" }, + /* 268 */ { ud_itab__268, UD_TAB__OPC_SSE, "/sse" }, + /* 269 */ { ud_itab__269, UD_TAB__OPC_SSE, "/sse" }, + /* 270 */ { ud_itab__270, UD_TAB__OPC_SSE, "/sse" }, + /* 271 */ { ud_itab__271, UD_TAB__OPC_SSE, "/sse" }, + /* 272 */ { ud_itab__272, UD_TAB__OPC_SSE, "/sse" }, + /* 273 */ { ud_itab__273, UD_TAB__OPC_SSE, "/sse" }, + /* 274 */ { ud_itab__274, UD_TAB__OPC_SSE, "/sse" }, + /* 275 */ { ud_itab__275, UD_TAB__OPC_MOD, "/mod" }, + /* 276 */ { ud_itab__276, UD_TAB__OPC_SSE, "/sse" }, + /* 277 */ { ud_itab__277, UD_TAB__OPC_SSE, "/sse" }, + /* 278 */ { ud_itab__278, UD_TAB__OPC_SSE, "/sse" }, + /* 279 */ { ud_itab__279, UD_TAB__OPC_SSE, "/sse" }, + /* 280 */ { ud_itab__280, UD_TAB__OPC_SSE, "/sse" }, + /* 281 */ { ud_itab__281, UD_TAB__OPC_SSE, "/sse" }, + /* 282 */ { ud_itab__282, UD_TAB__OPC_SSE, "/sse" }, + /* 283 */ { ud_itab__283, UD_TAB__OPC_SSE, "/sse" }, + /* 284 */ { ud_itab__284, UD_TAB__OPC_MODE, "/m" }, + /* 285 */ { ud_itab__285, UD_TAB__OPC_MODE, "/m" }, + /* 286 */ { ud_itab__286, UD_TAB__OPC_MODE, "/m" }, + /* 287 */ { ud_itab__287, UD_TAB__OPC_MODE, "/m" }, + /* 288 */ { ud_itab__288, UD_TAB__OPC_MODE, "/m" }, + /* 289 */ { ud_itab__289, UD_TAB__OPC_MODE, "/m" }, + /* 290 */ { ud_itab__290, UD_TAB__OPC_MODE, "/m" }, + /* 291 */ { ud_itab__291, UD_TAB__OPC_MODE, "/m" }, + /* 292 */ { ud_itab__292, UD_TAB__OPC_OSIZE, "/o" }, + /* 293 */ { ud_itab__293, UD_TAB__OPC_MODE, "/m" }, + /* 294 */ { ud_itab__294, UD_TAB__OPC_MODE, "/m" }, + /* 295 */ { ud_itab__295, UD_TAB__OPC_OSIZE, "/o" }, + /* 296 */ { ud_itab__296, UD_TAB__OPC_MODE, "/m" }, + /* 297 */ { ud_itab__297, UD_TAB__OPC_MODE, "/m" }, + /* 298 */ { ud_itab__298, UD_TAB__OPC_MODE, "/m" }, + /* 299 */ { ud_itab__299, UD_TAB__OPC_MODE, "/m" }, + /* 300 */ { ud_itab__300, UD_TAB__OPC_OSIZE, "/o" }, + /* 301 */ { ud_itab__301, UD_TAB__OPC_OSIZE, "/o" }, + /* 302 */ { ud_itab__302, UD_TAB__OPC_REG, "/reg" }, + /* 303 */ { ud_itab__303, UD_TAB__OPC_REG, "/reg" }, + /* 304 */ { ud_itab__304, UD_TAB__OPC_REG, "/reg" }, + /* 305 */ { ud_itab__305, UD_TAB__OPC_MODE, "/m" }, + /* 306 */ { ud_itab__306, UD_TAB__OPC_MODE, "/m" }, + /* 307 */ { ud_itab__307, UD_TAB__OPC_MODE, "/m" }, + /* 308 */ { ud_itab__308, UD_TAB__OPC_MODE, "/m" }, + /* 309 */ { ud_itab__309, UD_TAB__OPC_MODE, "/m" }, + /* 310 */ { ud_itab__310, UD_TAB__OPC_MODE, "/m" }, + /* 311 */ { ud_itab__311, UD_TAB__OPC_MODE, "/m" }, + /* 312 */ { ud_itab__312, UD_TAB__OPC_MODE, "/m" }, + /* 313 */ { ud_itab__313, UD_TAB__OPC_REG, "/reg" }, + /* 314 */ { ud_itab__314, UD_TAB__OPC_REG, "/reg" }, + /* 315 */ { ud_itab__315, UD_TAB__OPC_OSIZE, "/o" }, + /* 316 */ { ud_itab__316, UD_TAB__OPC_OSIZE, "/o" }, + /* 317 */ { ud_itab__317, UD_TAB__OPC_MODE, "/m" }, + /* 318 */ { ud_itab__318, UD_TAB__OPC_OSIZE, "/o" }, + /* 319 */ { ud_itab__319, UD_TAB__OPC_MODE, "/m" }, + /* 320 */ { ud_itab__320, UD_TAB__OPC_MODE, "/m" }, + /* 321 */ { ud_itab__321, UD_TAB__OPC_MODE, "/m" }, + /* 322 */ { ud_itab__322, UD_TAB__OPC_OSIZE, "/o" }, + /* 323 */ { ud_itab__323, UD_TAB__OPC_MODE, "/m" }, + /* 324 */ { ud_itab__324, UD_TAB__OPC_MODE, "/m" }, + /* 325 */ { ud_itab__325, UD_TAB__OPC_MODE, "/m" }, + /* 326 */ { ud_itab__326, UD_TAB__OPC_OSIZE, "/o" }, + /* 327 */ { ud_itab__327, UD_TAB__OPC_OSIZE, "/o" }, + /* 328 */ { ud_itab__328, UD_TAB__OPC_OSIZE, "/o" }, + /* 329 */ { ud_itab__329, UD_TAB__OPC_OSIZE, "/o" }, + /* 330 */ { ud_itab__330, UD_TAB__OPC_OSIZE, "/o" }, + /* 331 */ { ud_itab__331, UD_TAB__OPC_REG, "/reg" }, + /* 332 */ { ud_itab__332, UD_TAB__OPC_REG, "/reg" }, + /* 333 */ { ud_itab__333, UD_TAB__OPC_VEX, "/vex" }, + /* 334 */ { ud_itab__334, UD_TAB__OPC_MODE, "/m" }, + /* 335 */ { ud_itab__335, UD_TAB__OPC_TABLE, "opctbl" }, + /* 336 */ { ud_itab__336, UD_TAB__OPC_MOD, "/mod" }, + /* 337 */ { ud_itab__337, UD_TAB__OPC_MOD, "/mod" }, + /* 338 */ { ud_itab__338, UD_TAB__OPC_MOD, "/mod" }, + /* 339 */ { ud_itab__339, UD_TAB__OPC_REG, "/reg" }, + /* 340 */ { ud_itab__340, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 341 */ { ud_itab__341, UD_TAB__OPC_TABLE, "opctbl" }, + /* 342 */ { ud_itab__342, UD_TAB__OPC_MOD, "/mod" }, + /* 343 */ { ud_itab__343, UD_TAB__OPC_MOD, "/mod" }, + /* 344 */ { ud_itab__344, UD_TAB__OPC_OSIZE, "/o" }, + /* 345 */ { ud_itab__345, UD_TAB__OPC_REG, "/reg" }, + /* 346 */ { ud_itab__346, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 347 */ { ud_itab__347, UD_TAB__OPC_REG, "/reg" }, + /* 348 */ { ud_itab__348, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 349 */ { ud_itab__349, UD_TAB__OPC_REG, "/reg" }, + /* 350 */ { ud_itab__350, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 351 */ { ud_itab__351, UD_TAB__OPC_OSIZE, "/o" }, + /* 352 */ { ud_itab__352, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 353 */ { ud_itab__353, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 354 */ { ud_itab__354, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 355 */ { ud_itab__355, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 356 */ { ud_itab__356, UD_TAB__OPC_MOD, "/mod" }, + /* 357 */ { ud_itab__357, UD_TAB__OPC_TABLE, "opctbl" }, + /* 358 */ { ud_itab__358, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 359 */ { ud_itab__359, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 360 */ { ud_itab__360, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 361 */ { ud_itab__361, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 362 */ { ud_itab__362, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 363 */ { ud_itab__363, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 364 */ { ud_itab__364, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 365 */ { ud_itab__365, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 366 */ { ud_itab__366, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 367 */ { ud_itab__367, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 368 */ { ud_itab__368, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 369 */ { ud_itab__369, UD_TAB__OPC_TABLE, "opctbl" }, + /* 370 */ { ud_itab__370, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 371 */ { ud_itab__371, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 372 */ { ud_itab__372, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 373 */ { ud_itab__373, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 374 */ { ud_itab__374, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 375 */ { ud_itab__375, UD_TAB__OPC_OSIZE, "/o" }, + /* 376 */ { ud_itab__376, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 377 */ { ud_itab__377, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 378 */ { ud_itab__378, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 379 */ { ud_itab__379, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 380 */ { ud_itab__380, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 381 */ { ud_itab__381, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 382 */ { ud_itab__382, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 383 */ { ud_itab__383, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 384 */ { ud_itab__384, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 385 */ { ud_itab__385, UD_TAB__OPC_MODE, "/m" }, + /* 386 */ { ud_itab__386, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 387 */ { ud_itab__387, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 388 */ { ud_itab__388, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 389 */ { ud_itab__389, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 390 */ { ud_itab__390, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 391 */ { ud_itab__391, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 392 */ { ud_itab__392, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 393 */ { ud_itab__393, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 394 */ { ud_itab__394, UD_TAB__OPC_TABLE, "opctbl" }, + /* 395 */ { ud_itab__395, UD_TAB__OPC_MOD, "/mod" }, + /* 396 */ { ud_itab__396, UD_TAB__OPC_MOD, "/mod" }, + /* 397 */ { ud_itab__397, UD_TAB__OPC_MOD, "/mod" }, + /* 398 */ { ud_itab__398, UD_TAB__OPC_MOD, "/mod" }, + /* 399 */ { ud_itab__399, UD_TAB__OPC_TABLE, "opctbl" }, + /* 400 */ { ud_itab__400, UD_TAB__OPC_MOD, "/mod" }, + /* 401 */ { ud_itab__401, UD_TAB__OPC_MOD, "/mod" }, + /* 402 */ { ud_itab__402, UD_TAB__OPC_MOD, "/mod" }, + /* 403 */ { ud_itab__403, UD_TAB__OPC_VEX, "/vex" }, + /* 404 */ { ud_itab__404, UD_TAB__OPC_MODE, "/m" }, + /* 405 */ { ud_itab__405, UD_TAB__OPC_REG, "/reg" }, + /* 406 */ { ud_itab__406, UD_TAB__OPC_REG, "/reg" }, + /* 407 */ { ud_itab__407, UD_TAB__OPC_MODE, "/m" }, + /* 408 */ { ud_itab__408, UD_TAB__OPC_OSIZE, "/o" }, + /* 409 */ { ud_itab__409, UD_TAB__OPC_REG, "/reg" }, + /* 410 */ { ud_itab__410, UD_TAB__OPC_REG, "/reg" }, + /* 411 */ { ud_itab__411, UD_TAB__OPC_REG, "/reg" }, + /* 412 */ { ud_itab__412, UD_TAB__OPC_REG, "/reg" }, + /* 413 */ { ud_itab__413, UD_TAB__OPC_MODE, "/m" }, + /* 414 */ { ud_itab__414, UD_TAB__OPC_MODE, "/m" }, + /* 415 */ { ud_itab__415, UD_TAB__OPC_MODE, "/m" }, + /* 416 */ { ud_itab__416, UD_TAB__OPC_MOD, "/mod" }, + /* 417 */ { ud_itab__417, UD_TAB__OPC_REG, "/reg" }, + /* 418 */ { ud_itab__418, UD_TAB__OPC_X87, "/x87" }, + /* 419 */ { ud_itab__419, UD_TAB__OPC_MOD, "/mod" }, + /* 420 */ { ud_itab__420, UD_TAB__OPC_REG, "/reg" }, + /* 421 */ { ud_itab__421, UD_TAB__OPC_X87, "/x87" }, + /* 422 */ { ud_itab__422, UD_TAB__OPC_MOD, "/mod" }, + /* 423 */ { ud_itab__423, UD_TAB__OPC_REG, "/reg" }, + /* 424 */ { ud_itab__424, UD_TAB__OPC_X87, "/x87" }, + /* 425 */ { ud_itab__425, UD_TAB__OPC_MOD, "/mod" }, + /* 426 */ { ud_itab__426, UD_TAB__OPC_REG, "/reg" }, + /* 427 */ { ud_itab__427, UD_TAB__OPC_X87, "/x87" }, + /* 428 */ { ud_itab__428, UD_TAB__OPC_MOD, "/mod" }, + /* 429 */ { ud_itab__429, UD_TAB__OPC_REG, "/reg" }, + /* 430 */ { ud_itab__430, UD_TAB__OPC_X87, "/x87" }, + /* 431 */ { ud_itab__431, UD_TAB__OPC_MOD, "/mod" }, + /* 432 */ { ud_itab__432, UD_TAB__OPC_REG, "/reg" }, + /* 433 */ { ud_itab__433, UD_TAB__OPC_X87, "/x87" }, + /* 434 */ { ud_itab__434, UD_TAB__OPC_MOD, "/mod" }, + /* 435 */ { ud_itab__435, UD_TAB__OPC_REG, "/reg" }, + /* 436 */ { ud_itab__436, UD_TAB__OPC_X87, "/x87" }, + /* 437 */ { ud_itab__437, UD_TAB__OPC_MOD, "/mod" }, + /* 438 */ { ud_itab__438, UD_TAB__OPC_REG, "/reg" }, + /* 439 */ { ud_itab__439, UD_TAB__OPC_X87, "/x87" }, + /* 440 */ { ud_itab__440, UD_TAB__OPC_ASIZE, "/a" }, + /* 441 */ { ud_itab__441, UD_TAB__OPC_MODE, "/m" }, + /* 442 */ { ud_itab__442, UD_TAB__OPC_REG, "/reg" }, + /* 443 */ { ud_itab__443, UD_TAB__OPC_REG, "/reg" }, + /* 444 */ { ud_itab__444, UD_TAB__OPC_REG, "/reg" }, + /* 445 */ { ud_itab__445, UD_TAB__OPC_REG, "/reg" }, + /* 446 */ { ud_itab__446, UD_TAB__OPC_MODE, "/m" }, +}; + +/* itab entry operand definitions (for readability) */ +#define O_AL { OP_AL, SZ_B } +#define O_AX { OP_AX, SZ_W } +#define O_Av { OP_A, SZ_V } +#define O_C { OP_C, SZ_NA } +#define O_CL { OP_CL, SZ_B } +#define O_CS { OP_CS, SZ_NA } +#define O_CX { OP_CX, SZ_W } +#define O_D { OP_D, SZ_NA } +#define O_DL { OP_DL, SZ_B } +#define O_DS { OP_DS, SZ_NA } +#define O_DX { OP_DX, SZ_W } +#define O_E { OP_E, SZ_NA } +#define O_ES { OP_ES, SZ_NA } +#define O_Eb { OP_E, SZ_B } +#define O_Ed { OP_E, SZ_D } +#define O_Eq { OP_E, SZ_Q } +#define O_Ev { OP_E, SZ_V } +#define O_Ew { OP_E, SZ_W } +#define O_Ey { OP_E, SZ_Y } +#define O_Ez { OP_E, SZ_Z } +#define O_FS { OP_FS, SZ_NA } +#define O_Fv { OP_F, SZ_V } +#define O_G { OP_G, SZ_NA } +#define O_GS { OP_GS, SZ_NA } +#define O_Gb { OP_G, SZ_B } +#define O_Gd { OP_G, SZ_D } +#define O_Gq { OP_G, SZ_Q } +#define O_Gv { OP_G, SZ_V } +#define O_Gw { OP_G, SZ_W } +#define O_Gy { OP_G, SZ_Y } +#define O_Gz { OP_G, SZ_Z } +#define O_H { OP_H, SZ_X } +#define O_Hqq { OP_H, SZ_QQ } +#define O_Hx { OP_H, SZ_X } +#define O_I1 { OP_I1, SZ_NA } +#define O_I3 { OP_I3, SZ_NA } +#define O_Ib { OP_I, SZ_B } +#define O_Iv { OP_I, SZ_V } +#define O_Iw { OP_I, SZ_W } +#define O_Iz { OP_I, SZ_Z } +#define O_Jb { OP_J, SZ_B } +#define O_Jv { OP_J, SZ_V } +#define O_Jz { OP_J, SZ_Z } +#define O_L { OP_L, SZ_O } +#define O_Lx { OP_L, SZ_X } +#define O_M { OP_M, SZ_NA } +#define O_Mb { OP_M, SZ_B } +#define O_MbRd { OP_MR, SZ_BD } +#define O_MbRv { OP_MR, SZ_BV } +#define O_Md { OP_M, SZ_D } +#define O_MdRy { OP_MR, SZ_DY } +#define O_MdU { OP_MU, SZ_DO } +#define O_Mdq { OP_M, SZ_DQ } +#define O_Mo { OP_M, SZ_O } +#define O_Mq { OP_M, SZ_Q } +#define O_MqU { OP_MU, SZ_QO } +#define O_Ms { OP_M, SZ_W } +#define O_Mt { OP_M, SZ_T } +#define O_Mv { OP_M, SZ_V } +#define O_Mw { OP_M, SZ_W } +#define O_MwRd { OP_MR, SZ_WD } +#define O_MwRv { OP_MR, SZ_WV } +#define O_MwRy { OP_MR, SZ_WY } +#define O_MwU { OP_MU, SZ_WO } +#define O_N { OP_N, SZ_Q } +#define O_NONE { OP_NONE, SZ_NA } +#define O_Ob { OP_O, SZ_B } +#define O_Ov { OP_O, SZ_V } +#define O_Ow { OP_O, SZ_W } +#define O_P { OP_P, SZ_Q } +#define O_Q { OP_Q, SZ_Q } +#define O_R { OP_R, SZ_RDQ } +#define O_R0b { OP_R0, SZ_B } +#define O_R0v { OP_R0, SZ_V } +#define O_R0w { OP_R0, SZ_W } +#define O_R0y { OP_R0, SZ_Y } +#define O_R0z { OP_R0, SZ_Z } +#define O_R1b { OP_R1, SZ_B } +#define O_R1v { OP_R1, SZ_V } +#define O_R1w { OP_R1, SZ_W } +#define O_R1y { OP_R1, SZ_Y } +#define O_R1z { OP_R1, SZ_Z } +#define O_R2b { OP_R2, SZ_B } +#define O_R2v { OP_R2, SZ_V } +#define O_R2w { OP_R2, SZ_W } +#define O_R2y { OP_R2, SZ_Y } +#define O_R2z { OP_R2, SZ_Z } +#define O_R3b { OP_R3, SZ_B } +#define O_R3v { OP_R3, SZ_V } +#define O_R3w { OP_R3, SZ_W } +#define O_R3y { OP_R3, SZ_Y } +#define O_R3z { OP_R3, SZ_Z } +#define O_R4b { OP_R4, SZ_B } +#define O_R4v { OP_R4, SZ_V } +#define O_R4w { OP_R4, SZ_W } +#define O_R4y { OP_R4, SZ_Y } +#define O_R4z { OP_R4, SZ_Z } +#define O_R5b { OP_R5, SZ_B } +#define O_R5v { OP_R5, SZ_V } +#define O_R5w { OP_R5, SZ_W } +#define O_R5y { OP_R5, SZ_Y } +#define O_R5z { OP_R5, SZ_Z } +#define O_R6b { OP_R6, SZ_B } +#define O_R6v { OP_R6, SZ_V } +#define O_R6w { OP_R6, SZ_W } +#define O_R6y { OP_R6, SZ_Y } +#define O_R6z { OP_R6, SZ_Z } +#define O_R7b { OP_R7, SZ_B } +#define O_R7v { OP_R7, SZ_V } +#define O_R7w { OP_R7, SZ_W } +#define O_R7y { OP_R7, SZ_Y } +#define O_R7z { OP_R7, SZ_Z } +#define O_S { OP_S, SZ_W } +#define O_SS { OP_SS, SZ_NA } +#define O_ST0 { OP_ST0, SZ_NA } +#define O_ST1 { OP_ST1, SZ_NA } +#define O_ST2 { OP_ST2, SZ_NA } +#define O_ST3 { OP_ST3, SZ_NA } +#define O_ST4 { OP_ST4, SZ_NA } +#define O_ST5 { OP_ST5, SZ_NA } +#define O_ST6 { OP_ST6, SZ_NA } +#define O_ST7 { OP_ST7, SZ_NA } +#define O_U { OP_U, SZ_O } +#define O_Ux { OP_U, SZ_X } +#define O_V { OP_V, SZ_DQ } +#define O_Vdq { OP_V, SZ_DQ } +#define O_Vqq { OP_V, SZ_QQ } +#define O_Vsd { OP_V, SZ_Q } +#define O_Vx { OP_V, SZ_X } +#define O_W { OP_W, SZ_DQ } +#define O_Wdq { OP_W, SZ_DQ } +#define O_Wqq { OP_W, SZ_QQ } +#define O_Wsd { OP_W, SZ_Q } +#define O_Wx { OP_W, SZ_X } +#define O_eAX { OP_eAX, SZ_Z } +#define O_eCX { OP_eCX, SZ_Z } +#define O_eDX { OP_eDX, SZ_Z } +#define O_rAX { OP_rAX, SZ_V } +#define O_rCX { OP_rCX, SZ_V } +#define O_rDX { OP_rDX, SZ_V } +#define O_sIb { OP_sI, SZ_B } +#define O_sIv { OP_sI, SZ_V } +#define O_sIz { OP_sI, SZ_Z } + +struct ud_itab_entry ud_itab[] = { + /* 0000 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0001 */ { UD_Iaaa, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0002 */ { UD_Iaad, O_Ib, O_NONE, O_NONE, O_NONE, P_none }, + /* 0003 */ { UD_Iaam, O_Ib, O_NONE, O_NONE, O_NONE, P_none }, + /* 0004 */ { UD_Iaas, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0005 */ { UD_Iadc, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0006 */ { UD_Iadc, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0007 */ { UD_Iadc, O_Gb, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0008 */ { UD_Iadc, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0009 */ { UD_Iadc, O_AL, O_Ib, O_NONE, O_NONE, P_none }, + /* 0010 */ { UD_Iadc, O_rAX, O_sIz, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0011 */ { UD_Iadc, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0012 */ { UD_Iadc, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_inv64 }, + /* 0013 */ { UD_Iadc, O_Ev, O_sIz, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0014 */ { UD_Iadc, O_Ev, O_sIb, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0015 */ { UD_Iadd, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0016 */ { UD_Iadd, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0017 */ { UD_Iadd, O_Gb, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0018 */ { UD_Iadd, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0019 */ { UD_Iadd, O_AL, O_Ib, O_NONE, O_NONE, P_none }, + /* 0020 */ { UD_Iadd, O_rAX, O_sIz, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0021 */ { UD_Iadd, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0022 */ { UD_Iadd, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_inv64 }, + /* 0023 */ { UD_Iadd, O_Ev, O_sIz, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0024 */ { UD_Iadd, O_Ev, O_sIb, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0025 */ { UD_Iaddpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0026 */ { UD_Ivaddpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0027 */ { UD_Iaddps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0028 */ { UD_Ivaddps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0029 */ { UD_Iaddsd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0030 */ { UD_Ivaddsd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0031 */ { UD_Iaddss, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0032 */ { UD_Ivaddss, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0033 */ { UD_Iaddsubpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0034 */ { UD_Ivaddsubpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0035 */ { UD_Iaddsubps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0036 */ { UD_Ivaddsubps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0037 */ { UD_Iaesdec, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0038 */ { UD_Ivaesdec, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0039 */ { UD_Iaesdeclast, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0040 */ { UD_Ivaesdeclast, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0041 */ { UD_Iaesenc, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0042 */ { UD_Ivaesenc, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0043 */ { UD_Iaesenclast, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0044 */ { UD_Ivaesenclast, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0045 */ { UD_Iaesimc, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0046 */ { UD_Ivaesimc, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0047 */ { UD_Iaeskeygenassist, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0048 */ { UD_Ivaeskeygenassist, O_Vx, O_Wx, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0049 */ { UD_Iand, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0050 */ { UD_Iand, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0051 */ { UD_Iand, O_Gb, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0052 */ { UD_Iand, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0053 */ { UD_Iand, O_AL, O_Ib, O_NONE, O_NONE, P_none }, + /* 0054 */ { UD_Iand, O_rAX, O_sIz, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0055 */ { UD_Iand, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0056 */ { UD_Iand, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_inv64 }, + /* 0057 */ { UD_Iand, O_Ev, O_sIz, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0058 */ { UD_Iand, O_Ev, O_sIb, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0059 */ { UD_Iandpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0060 */ { UD_Ivandpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0061 */ { UD_Iandps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0062 */ { UD_Ivandps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0063 */ { UD_Iandnpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0064 */ { UD_Ivandnpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0065 */ { UD_Iandnps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0066 */ { UD_Ivandnps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0067 */ { UD_Iarpl, O_Ew, O_Gw, O_NONE, O_NONE, P_aso }, + /* 0068 */ { UD_Imovsxd, O_Gq, O_Ed, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexx|P_rexr|P_rexb }, + /* 0069 */ { UD_Icall, O_Ev, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0070 */ { UD_Icall, O_Eq, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb|P_def64 }, + /* 0071 */ { UD_Icall, O_Fv, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0072 */ { UD_Icall, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0073 */ { UD_Icall, O_Av, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0074 */ { UD_Icbw, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0075 */ { UD_Icwde, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0076 */ { UD_Icdqe, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0077 */ { UD_Iclc, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0078 */ { UD_Icld, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0079 */ { UD_Iclflush, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0080 */ { UD_Iclgi, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0081 */ { UD_Icli, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0082 */ { UD_Iclts, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0083 */ { UD_Icmc, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0084 */ { UD_Icmovo, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0085 */ { UD_Icmovno, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0086 */ { UD_Icmovb, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0087 */ { UD_Icmovae, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0088 */ { UD_Icmovz, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0089 */ { UD_Icmovnz, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0090 */ { UD_Icmovbe, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0091 */ { UD_Icmova, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0092 */ { UD_Icmovs, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0093 */ { UD_Icmovns, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0094 */ { UD_Icmovp, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0095 */ { UD_Icmovnp, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0096 */ { UD_Icmovl, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0097 */ { UD_Icmovge, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0098 */ { UD_Icmovle, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0099 */ { UD_Icmovg, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0100 */ { UD_Icmp, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0101 */ { UD_Icmp, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0102 */ { UD_Icmp, O_Gb, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0103 */ { UD_Icmp, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0104 */ { UD_Icmp, O_AL, O_Ib, O_NONE, O_NONE, P_none }, + /* 0105 */ { UD_Icmp, O_rAX, O_sIz, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0106 */ { UD_Icmp, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0107 */ { UD_Icmp, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_inv64 }, + /* 0108 */ { UD_Icmp, O_Ev, O_sIz, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0109 */ { UD_Icmp, O_Ev, O_sIb, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0110 */ { UD_Icmppd, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0111 */ { UD_Ivcmppd, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0112 */ { UD_Icmpps, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0113 */ { UD_Ivcmpps, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0114 */ { UD_Icmpsb, O_NONE, O_NONE, O_NONE, O_NONE, P_strz|P_seg }, + /* 0115 */ { UD_Icmpsw, O_NONE, O_NONE, O_NONE, O_NONE, P_strz|P_oso|P_rexw|P_seg }, + /* 0116 */ { UD_Icmpsd, O_NONE, O_NONE, O_NONE, O_NONE, P_strz|P_oso|P_rexw|P_seg }, + /* 0117 */ { UD_Icmpsd, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0118 */ { UD_Ivcmpsd, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0119 */ { UD_Icmpsq, O_NONE, O_NONE, O_NONE, O_NONE, P_strz|P_oso|P_rexw|P_seg }, + /* 0120 */ { UD_Icmpss, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0121 */ { UD_Ivcmpss, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0122 */ { UD_Icmpxchg, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0123 */ { UD_Icmpxchg, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0124 */ { UD_Icmpxchg8b, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0125 */ { UD_Icmpxchg8b, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0126 */ { UD_Icmpxchg16b, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0127 */ { UD_Icomisd, O_Vsd, O_Wsd, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0128 */ { UD_Ivcomisd, O_Vsd, O_Wsd, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0129 */ { UD_Icomiss, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0130 */ { UD_Ivcomiss, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0131 */ { UD_Icpuid, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0132 */ { UD_Icvtdq2pd, O_V, O_Wdq, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0133 */ { UD_Ivcvtdq2pd, O_Vx, O_Wdq, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0134 */ { UD_Icvtdq2ps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0135 */ { UD_Ivcvtdq2ps, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0136 */ { UD_Icvtpd2dq, O_Vdq, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0137 */ { UD_Ivcvtpd2dq, O_Vdq, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0138 */ { UD_Icvtpd2pi, O_P, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0139 */ { UD_Icvtpd2ps, O_Vdq, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0140 */ { UD_Ivcvtpd2ps, O_Vdq, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0141 */ { UD_Icvtpi2ps, O_V, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0142 */ { UD_Icvtpi2pd, O_V, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0143 */ { UD_Icvtps2dq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0144 */ { UD_Ivcvtps2dq, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0145 */ { UD_Icvtps2pd, O_V, O_Wdq, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0146 */ { UD_Ivcvtps2pd, O_Vx, O_Wdq, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0147 */ { UD_Icvtps2pi, O_P, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0148 */ { UD_Icvtsd2si, O_Gy, O_MqU, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0149 */ { UD_Ivcvtsd2si, O_Gy, O_MqU, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0150 */ { UD_Icvtsd2ss, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0151 */ { UD_Ivcvtsd2ss, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0152 */ { UD_Icvtsi2sd, O_V, O_Ey, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0153 */ { UD_Ivcvtsi2sd, O_Vx, O_Hx, O_Ey, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0154 */ { UD_Icvtsi2ss, O_V, O_Ey, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0155 */ { UD_Ivcvtsi2ss, O_Vx, O_Hx, O_Ey, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0156 */ { UD_Icvtss2sd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0157 */ { UD_Ivcvtss2sd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0158 */ { UD_Icvtss2si, O_Gy, O_MdU, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0159 */ { UD_Ivcvtss2si, O_Gy, O_MdU, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0160 */ { UD_Icvttpd2dq, O_Vdq, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0161 */ { UD_Ivcvttpd2dq, O_Vdq, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0162 */ { UD_Icvttpd2pi, O_P, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0163 */ { UD_Icvttps2dq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0164 */ { UD_Ivcvttps2dq, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0165 */ { UD_Icvttps2pi, O_P, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0166 */ { UD_Icvttsd2si, O_Gy, O_MqU, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0167 */ { UD_Ivcvttsd2si, O_Gy, O_MqU, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0168 */ { UD_Icvttss2si, O_Gy, O_MdU, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0169 */ { UD_Ivcvttss2si, O_Gy, O_MdU, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0170 */ { UD_Icwd, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0171 */ { UD_Icdq, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0172 */ { UD_Icqo, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0173 */ { UD_Idaa, O_NONE, O_NONE, O_NONE, O_NONE, P_inv64 }, + /* 0174 */ { UD_Idas, O_NONE, O_NONE, O_NONE, O_NONE, P_inv64 }, + /* 0175 */ { UD_Idec, O_R0z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0176 */ { UD_Idec, O_R1z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0177 */ { UD_Idec, O_R2z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0178 */ { UD_Idec, O_R3z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0179 */ { UD_Idec, O_R4z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0180 */ { UD_Idec, O_R5z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0181 */ { UD_Idec, O_R6z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0182 */ { UD_Idec, O_R7z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0183 */ { UD_Idec, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0184 */ { UD_Idec, O_Ev, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0185 */ { UD_Idiv, O_Ev, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0186 */ { UD_Idiv, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0187 */ { UD_Idivpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0188 */ { UD_Ivdivpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0189 */ { UD_Idivps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0190 */ { UD_Ivdivps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0191 */ { UD_Idivsd, O_V, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0192 */ { UD_Ivdivsd, O_Vx, O_Hx, O_MqU, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0193 */ { UD_Idivss, O_V, O_MdU, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0194 */ { UD_Ivdivss, O_Vx, O_Hx, O_MdU, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0195 */ { UD_Idppd, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0196 */ { UD_Ivdppd, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0197 */ { UD_Idpps, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0198 */ { UD_Ivdpps, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0199 */ { UD_Iemms, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0200 */ { UD_Ienter, O_Iw, O_Ib, O_NONE, O_NONE, P_def64 }, + /* 0201 */ { UD_Iextractps, O_MdRy, O_V, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 0202 */ { UD_Ivextractps, O_MdRy, O_Vx, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 0203 */ { UD_If2xm1, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0204 */ { UD_Ifabs, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0205 */ { UD_Ifadd, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0206 */ { UD_Ifadd, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0207 */ { UD_Ifadd, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0208 */ { UD_Ifadd, O_ST1, O_ST0, O_NONE, O_NONE, P_none }, + /* 0209 */ { UD_Ifadd, O_ST2, O_ST0, O_NONE, O_NONE, P_none }, + /* 0210 */ { UD_Ifadd, O_ST3, O_ST0, O_NONE, O_NONE, P_none }, + /* 0211 */ { UD_Ifadd, O_ST4, O_ST0, O_NONE, O_NONE, P_none }, + /* 0212 */ { UD_Ifadd, O_ST5, O_ST0, O_NONE, O_NONE, P_none }, + /* 0213 */ { UD_Ifadd, O_ST6, O_ST0, O_NONE, O_NONE, P_none }, + /* 0214 */ { UD_Ifadd, O_ST7, O_ST0, O_NONE, O_NONE, P_none }, + /* 0215 */ { UD_Ifadd, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0216 */ { UD_Ifadd, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0217 */ { UD_Ifadd, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0218 */ { UD_Ifadd, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0219 */ { UD_Ifadd, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0220 */ { UD_Ifadd, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0221 */ { UD_Ifadd, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0222 */ { UD_Ifadd, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0223 */ { UD_Ifaddp, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0224 */ { UD_Ifaddp, O_ST1, O_ST0, O_NONE, O_NONE, P_none }, + /* 0225 */ { UD_Ifaddp, O_ST2, O_ST0, O_NONE, O_NONE, P_none }, + /* 0226 */ { UD_Ifaddp, O_ST3, O_ST0, O_NONE, O_NONE, P_none }, + /* 0227 */ { UD_Ifaddp, O_ST4, O_ST0, O_NONE, O_NONE, P_none }, + /* 0228 */ { UD_Ifaddp, O_ST5, O_ST0, O_NONE, O_NONE, P_none }, + /* 0229 */ { UD_Ifaddp, O_ST6, O_ST0, O_NONE, O_NONE, P_none }, + /* 0230 */ { UD_Ifaddp, O_ST7, O_ST0, O_NONE, O_NONE, P_none }, + /* 0231 */ { UD_Ifbld, O_Mt, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0232 */ { UD_Ifbstp, O_Mt, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0233 */ { UD_Ifchs, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0234 */ { UD_Ifclex, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0235 */ { UD_Ifcmovb, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0236 */ { UD_Ifcmovb, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0237 */ { UD_Ifcmovb, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0238 */ { UD_Ifcmovb, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0239 */ { UD_Ifcmovb, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0240 */ { UD_Ifcmovb, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0241 */ { UD_Ifcmovb, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0242 */ { UD_Ifcmovb, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0243 */ { UD_Ifcmove, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0244 */ { UD_Ifcmove, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0245 */ { UD_Ifcmove, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0246 */ { UD_Ifcmove, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0247 */ { UD_Ifcmove, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0248 */ { UD_Ifcmove, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0249 */ { UD_Ifcmove, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0250 */ { UD_Ifcmove, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0251 */ { UD_Ifcmovbe, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0252 */ { UD_Ifcmovbe, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0253 */ { UD_Ifcmovbe, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0254 */ { UD_Ifcmovbe, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0255 */ { UD_Ifcmovbe, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0256 */ { UD_Ifcmovbe, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0257 */ { UD_Ifcmovbe, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0258 */ { UD_Ifcmovbe, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0259 */ { UD_Ifcmovu, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0260 */ { UD_Ifcmovu, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0261 */ { UD_Ifcmovu, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0262 */ { UD_Ifcmovu, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0263 */ { UD_Ifcmovu, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0264 */ { UD_Ifcmovu, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0265 */ { UD_Ifcmovu, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0266 */ { UD_Ifcmovu, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0267 */ { UD_Ifcmovnb, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0268 */ { UD_Ifcmovnb, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0269 */ { UD_Ifcmovnb, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0270 */ { UD_Ifcmovnb, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0271 */ { UD_Ifcmovnb, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0272 */ { UD_Ifcmovnb, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0273 */ { UD_Ifcmovnb, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0274 */ { UD_Ifcmovnb, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0275 */ { UD_Ifcmovne, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0276 */ { UD_Ifcmovne, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0277 */ { UD_Ifcmovne, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0278 */ { UD_Ifcmovne, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0279 */ { UD_Ifcmovne, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0280 */ { UD_Ifcmovne, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0281 */ { UD_Ifcmovne, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0282 */ { UD_Ifcmovne, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0283 */ { UD_Ifcmovnbe, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0284 */ { UD_Ifcmovnbe, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0285 */ { UD_Ifcmovnbe, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0286 */ { UD_Ifcmovnbe, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0287 */ { UD_Ifcmovnbe, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0288 */ { UD_Ifcmovnbe, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0289 */ { UD_Ifcmovnbe, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0290 */ { UD_Ifcmovnbe, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0291 */ { UD_Ifcmovnu, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0292 */ { UD_Ifcmovnu, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0293 */ { UD_Ifcmovnu, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0294 */ { UD_Ifcmovnu, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0295 */ { UD_Ifcmovnu, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0296 */ { UD_Ifcmovnu, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0297 */ { UD_Ifcmovnu, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0298 */ { UD_Ifcmovnu, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0299 */ { UD_Ifucomi, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0300 */ { UD_Ifucomi, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0301 */ { UD_Ifucomi, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0302 */ { UD_Ifucomi, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0303 */ { UD_Ifucomi, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0304 */ { UD_Ifucomi, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0305 */ { UD_Ifucomi, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0306 */ { UD_Ifucomi, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0307 */ { UD_Ifcom, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0308 */ { UD_Ifcom, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0309 */ { UD_Ifcom, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0310 */ { UD_Ifcom, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0311 */ { UD_Ifcom, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0312 */ { UD_Ifcom, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0313 */ { UD_Ifcom, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0314 */ { UD_Ifcom, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0315 */ { UD_Ifcom, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0316 */ { UD_Ifcom, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0317 */ { UD_Ifcom2, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0318 */ { UD_Ifcom2, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0319 */ { UD_Ifcom2, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0320 */ { UD_Ifcom2, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0321 */ { UD_Ifcom2, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0322 */ { UD_Ifcom2, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0323 */ { UD_Ifcom2, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0324 */ { UD_Ifcom2, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0325 */ { UD_Ifcomp3, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0326 */ { UD_Ifcomp3, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0327 */ { UD_Ifcomp3, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0328 */ { UD_Ifcomp3, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0329 */ { UD_Ifcomp3, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0330 */ { UD_Ifcomp3, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0331 */ { UD_Ifcomp3, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0332 */ { UD_Ifcomp3, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0333 */ { UD_Ifcomi, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0334 */ { UD_Ifcomi, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0335 */ { UD_Ifcomi, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0336 */ { UD_Ifcomi, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0337 */ { UD_Ifcomi, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0338 */ { UD_Ifcomi, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0339 */ { UD_Ifcomi, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0340 */ { UD_Ifcomi, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0341 */ { UD_Ifucomip, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0342 */ { UD_Ifucomip, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0343 */ { UD_Ifucomip, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0344 */ { UD_Ifucomip, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0345 */ { UD_Ifucomip, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0346 */ { UD_Ifucomip, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0347 */ { UD_Ifucomip, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0348 */ { UD_Ifucomip, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0349 */ { UD_Ifcomip, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0350 */ { UD_Ifcomip, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0351 */ { UD_Ifcomip, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0352 */ { UD_Ifcomip, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0353 */ { UD_Ifcomip, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0354 */ { UD_Ifcomip, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0355 */ { UD_Ifcomip, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0356 */ { UD_Ifcomip, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0357 */ { UD_Ifcomp, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0358 */ { UD_Ifcomp, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0359 */ { UD_Ifcomp, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0360 */ { UD_Ifcomp, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0361 */ { UD_Ifcomp, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0362 */ { UD_Ifcomp, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0363 */ { UD_Ifcomp, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0364 */ { UD_Ifcomp, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0365 */ { UD_Ifcomp, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0366 */ { UD_Ifcomp, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0367 */ { UD_Ifcomp5, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0368 */ { UD_Ifcomp5, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0369 */ { UD_Ifcomp5, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0370 */ { UD_Ifcomp5, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0371 */ { UD_Ifcomp5, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0372 */ { UD_Ifcomp5, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0373 */ { UD_Ifcomp5, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0374 */ { UD_Ifcomp5, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0375 */ { UD_Ifcompp, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0376 */ { UD_Ifcos, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0377 */ { UD_Ifdecstp, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0378 */ { UD_Ifdiv, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0379 */ { UD_Ifdiv, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0380 */ { UD_Ifdiv, O_ST1, O_ST0, O_NONE, O_NONE, P_none }, + /* 0381 */ { UD_Ifdiv, O_ST2, O_ST0, O_NONE, O_NONE, P_none }, + /* 0382 */ { UD_Ifdiv, O_ST3, O_ST0, O_NONE, O_NONE, P_none }, + /* 0383 */ { UD_Ifdiv, O_ST4, O_ST0, O_NONE, O_NONE, P_none }, + /* 0384 */ { UD_Ifdiv, O_ST5, O_ST0, O_NONE, O_NONE, P_none }, + /* 0385 */ { UD_Ifdiv, O_ST6, O_ST0, O_NONE, O_NONE, P_none }, + /* 0386 */ { UD_Ifdiv, O_ST7, O_ST0, O_NONE, O_NONE, P_none }, + /* 0387 */ { UD_Ifdiv, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0388 */ { UD_Ifdiv, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0389 */ { UD_Ifdiv, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0390 */ { UD_Ifdiv, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0391 */ { UD_Ifdiv, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0392 */ { UD_Ifdiv, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0393 */ { UD_Ifdiv, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0394 */ { UD_Ifdiv, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0395 */ { UD_Ifdiv, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0396 */ { UD_Ifdivp, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0397 */ { UD_Ifdivp, O_ST1, O_ST0, O_NONE, O_NONE, P_none }, + /* 0398 */ { UD_Ifdivp, O_ST2, O_ST0, O_NONE, O_NONE, P_none }, + /* 0399 */ { UD_Ifdivp, O_ST3, O_ST0, O_NONE, O_NONE, P_none }, + /* 0400 */ { UD_Ifdivp, O_ST4, O_ST0, O_NONE, O_NONE, P_none }, + /* 0401 */ { UD_Ifdivp, O_ST5, O_ST0, O_NONE, O_NONE, P_none }, + /* 0402 */ { UD_Ifdivp, O_ST6, O_ST0, O_NONE, O_NONE, P_none }, + /* 0403 */ { UD_Ifdivp, O_ST7, O_ST0, O_NONE, O_NONE, P_none }, + /* 0404 */ { UD_Ifdivr, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0405 */ { UD_Ifdivr, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0406 */ { UD_Ifdivr, O_ST1, O_ST0, O_NONE, O_NONE, P_none }, + /* 0407 */ { UD_Ifdivr, O_ST2, O_ST0, O_NONE, O_NONE, P_none }, + /* 0408 */ { UD_Ifdivr, O_ST3, O_ST0, O_NONE, O_NONE, P_none }, + /* 0409 */ { UD_Ifdivr, O_ST4, O_ST0, O_NONE, O_NONE, P_none }, + /* 0410 */ { UD_Ifdivr, O_ST5, O_ST0, O_NONE, O_NONE, P_none }, + /* 0411 */ { UD_Ifdivr, O_ST6, O_ST0, O_NONE, O_NONE, P_none }, + /* 0412 */ { UD_Ifdivr, O_ST7, O_ST0, O_NONE, O_NONE, P_none }, + /* 0413 */ { UD_Ifdivr, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0414 */ { UD_Ifdivr, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0415 */ { UD_Ifdivr, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0416 */ { UD_Ifdivr, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0417 */ { UD_Ifdivr, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0418 */ { UD_Ifdivr, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0419 */ { UD_Ifdivr, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0420 */ { UD_Ifdivr, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0421 */ { UD_Ifdivr, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0422 */ { UD_Ifdivrp, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0423 */ { UD_Ifdivrp, O_ST1, O_ST0, O_NONE, O_NONE, P_none }, + /* 0424 */ { UD_Ifdivrp, O_ST2, O_ST0, O_NONE, O_NONE, P_none }, + /* 0425 */ { UD_Ifdivrp, O_ST3, O_ST0, O_NONE, O_NONE, P_none }, + /* 0426 */ { UD_Ifdivrp, O_ST4, O_ST0, O_NONE, O_NONE, P_none }, + /* 0427 */ { UD_Ifdivrp, O_ST5, O_ST0, O_NONE, O_NONE, P_none }, + /* 0428 */ { UD_Ifdivrp, O_ST6, O_ST0, O_NONE, O_NONE, P_none }, + /* 0429 */ { UD_Ifdivrp, O_ST7, O_ST0, O_NONE, O_NONE, P_none }, + /* 0430 */ { UD_Ifemms, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0431 */ { UD_Iffree, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0432 */ { UD_Iffree, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0433 */ { UD_Iffree, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0434 */ { UD_Iffree, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0435 */ { UD_Iffree, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0436 */ { UD_Iffree, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0437 */ { UD_Iffree, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0438 */ { UD_Iffree, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0439 */ { UD_Iffreep, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0440 */ { UD_Iffreep, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0441 */ { UD_Iffreep, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0442 */ { UD_Iffreep, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0443 */ { UD_Iffreep, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0444 */ { UD_Iffreep, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0445 */ { UD_Iffreep, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0446 */ { UD_Iffreep, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0447 */ { UD_Ificom, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0448 */ { UD_Ificom, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0449 */ { UD_Ificomp, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0450 */ { UD_Ificomp, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0451 */ { UD_Ifild, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0452 */ { UD_Ifild, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0453 */ { UD_Ifild, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0454 */ { UD_Ifincstp, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0455 */ { UD_Ifninit, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0456 */ { UD_Ifiadd, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0457 */ { UD_Ifiadd, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0458 */ { UD_Ifidivr, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0459 */ { UD_Ifidivr, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0460 */ { UD_Ifidiv, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0461 */ { UD_Ifidiv, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0462 */ { UD_Ifisub, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0463 */ { UD_Ifisub, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0464 */ { UD_Ifisubr, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0465 */ { UD_Ifisubr, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0466 */ { UD_Ifist, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0467 */ { UD_Ifist, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0468 */ { UD_Ifistp, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0469 */ { UD_Ifistp, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0470 */ { UD_Ifistp, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0471 */ { UD_Ifisttp, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0472 */ { UD_Ifisttp, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0473 */ { UD_Ifisttp, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0474 */ { UD_Ifld, O_Mt, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0475 */ { UD_Ifld, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0476 */ { UD_Ifld, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0477 */ { UD_Ifld, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0478 */ { UD_Ifld, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0479 */ { UD_Ifld, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0480 */ { UD_Ifld, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0481 */ { UD_Ifld, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0482 */ { UD_Ifld, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0483 */ { UD_Ifld, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0484 */ { UD_Ifld, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0485 */ { UD_Ifld1, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0486 */ { UD_Ifldl2t, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0487 */ { UD_Ifldl2e, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0488 */ { UD_Ifldpi, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0489 */ { UD_Ifldlg2, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0490 */ { UD_Ifldln2, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0491 */ { UD_Ifldz, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0492 */ { UD_Ifldcw, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0493 */ { UD_Ifldenv, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0494 */ { UD_Ifmul, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0495 */ { UD_Ifmul, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0496 */ { UD_Ifmul, O_ST1, O_ST0, O_NONE, O_NONE, P_none }, + /* 0497 */ { UD_Ifmul, O_ST2, O_ST0, O_NONE, O_NONE, P_none }, + /* 0498 */ { UD_Ifmul, O_ST3, O_ST0, O_NONE, O_NONE, P_none }, + /* 0499 */ { UD_Ifmul, O_ST4, O_ST0, O_NONE, O_NONE, P_none }, + /* 0500 */ { UD_Ifmul, O_ST5, O_ST0, O_NONE, O_NONE, P_none }, + /* 0501 */ { UD_Ifmul, O_ST6, O_ST0, O_NONE, O_NONE, P_none }, + /* 0502 */ { UD_Ifmul, O_ST7, O_ST0, O_NONE, O_NONE, P_none }, + /* 0503 */ { UD_Ifmul, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0504 */ { UD_Ifmul, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0505 */ { UD_Ifmul, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0506 */ { UD_Ifmul, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0507 */ { UD_Ifmul, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0508 */ { UD_Ifmul, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0509 */ { UD_Ifmul, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0510 */ { UD_Ifmul, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0511 */ { UD_Ifmul, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0512 */ { UD_Ifmulp, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0513 */ { UD_Ifmulp, O_ST1, O_ST0, O_NONE, O_NONE, P_none }, + /* 0514 */ { UD_Ifmulp, O_ST2, O_ST0, O_NONE, O_NONE, P_none }, + /* 0515 */ { UD_Ifmulp, O_ST3, O_ST0, O_NONE, O_NONE, P_none }, + /* 0516 */ { UD_Ifmulp, O_ST4, O_ST0, O_NONE, O_NONE, P_none }, + /* 0517 */ { UD_Ifmulp, O_ST5, O_ST0, O_NONE, O_NONE, P_none }, + /* 0518 */ { UD_Ifmulp, O_ST6, O_ST0, O_NONE, O_NONE, P_none }, + /* 0519 */ { UD_Ifmulp, O_ST7, O_ST0, O_NONE, O_NONE, P_none }, + /* 0520 */ { UD_Ifimul, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0521 */ { UD_Ifimul, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0522 */ { UD_Ifnop, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0523 */ { UD_Ifndisi, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0524 */ { UD_Ifneni, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0525 */ { UD_Ifnsetpm, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0526 */ { UD_Ifpatan, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0527 */ { UD_Ifprem, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0528 */ { UD_Ifprem1, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0529 */ { UD_Ifptan, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0530 */ { UD_Ifrndint, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0531 */ { UD_Ifrstor, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0532 */ { UD_Ifrstpm, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0533 */ { UD_Ifnsave, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0534 */ { UD_Ifscale, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0535 */ { UD_Ifsin, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0536 */ { UD_Ifsincos, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0537 */ { UD_Ifsqrt, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0538 */ { UD_Ifstp, O_Mt, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0539 */ { UD_Ifstp, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0540 */ { UD_Ifstp, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0541 */ { UD_Ifstp, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0542 */ { UD_Ifstp, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0543 */ { UD_Ifstp, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0544 */ { UD_Ifstp, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0545 */ { UD_Ifstp, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0546 */ { UD_Ifstp, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0547 */ { UD_Ifstp, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0548 */ { UD_Ifstp, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0549 */ { UD_Ifstp1, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0550 */ { UD_Ifstp1, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0551 */ { UD_Ifstp1, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0552 */ { UD_Ifstp1, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0553 */ { UD_Ifstp1, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0554 */ { UD_Ifstp1, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0555 */ { UD_Ifstp1, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0556 */ { UD_Ifstp1, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0557 */ { UD_Ifstp8, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0558 */ { UD_Ifstp8, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0559 */ { UD_Ifstp8, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0560 */ { UD_Ifstp8, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0561 */ { UD_Ifstp8, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0562 */ { UD_Ifstp8, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0563 */ { UD_Ifstp8, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0564 */ { UD_Ifstp8, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0565 */ { UD_Ifstp9, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0566 */ { UD_Ifstp9, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0567 */ { UD_Ifstp9, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0568 */ { UD_Ifstp9, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0569 */ { UD_Ifstp9, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0570 */ { UD_Ifstp9, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0571 */ { UD_Ifstp9, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0572 */ { UD_Ifstp9, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0573 */ { UD_Ifst, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0574 */ { UD_Ifst, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0575 */ { UD_Ifst, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0576 */ { UD_Ifst, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0577 */ { UD_Ifst, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0578 */ { UD_Ifst, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0579 */ { UD_Ifst, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0580 */ { UD_Ifst, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0581 */ { UD_Ifst, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0582 */ { UD_Ifst, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0583 */ { UD_Ifnstcw, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0584 */ { UD_Ifnstenv, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0585 */ { UD_Ifnstsw, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0586 */ { UD_Ifnstsw, O_AX, O_NONE, O_NONE, O_NONE, P_none }, + /* 0587 */ { UD_Ifsub, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0588 */ { UD_Ifsub, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0589 */ { UD_Ifsub, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0590 */ { UD_Ifsub, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0591 */ { UD_Ifsub, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0592 */ { UD_Ifsub, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0593 */ { UD_Ifsub, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0594 */ { UD_Ifsub, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0595 */ { UD_Ifsub, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0596 */ { UD_Ifsub, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0597 */ { UD_Ifsub, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0598 */ { UD_Ifsub, O_ST1, O_ST0, O_NONE, O_NONE, P_none }, + /* 0599 */ { UD_Ifsub, O_ST2, O_ST0, O_NONE, O_NONE, P_none }, + /* 0600 */ { UD_Ifsub, O_ST3, O_ST0, O_NONE, O_NONE, P_none }, + /* 0601 */ { UD_Ifsub, O_ST4, O_ST0, O_NONE, O_NONE, P_none }, + /* 0602 */ { UD_Ifsub, O_ST5, O_ST0, O_NONE, O_NONE, P_none }, + /* 0603 */ { UD_Ifsub, O_ST6, O_ST0, O_NONE, O_NONE, P_none }, + /* 0604 */ { UD_Ifsub, O_ST7, O_ST0, O_NONE, O_NONE, P_none }, + /* 0605 */ { UD_Ifsubp, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0606 */ { UD_Ifsubp, O_ST1, O_ST0, O_NONE, O_NONE, P_none }, + /* 0607 */ { UD_Ifsubp, O_ST2, O_ST0, O_NONE, O_NONE, P_none }, + /* 0608 */ { UD_Ifsubp, O_ST3, O_ST0, O_NONE, O_NONE, P_none }, + /* 0609 */ { UD_Ifsubp, O_ST4, O_ST0, O_NONE, O_NONE, P_none }, + /* 0610 */ { UD_Ifsubp, O_ST5, O_ST0, O_NONE, O_NONE, P_none }, + /* 0611 */ { UD_Ifsubp, O_ST6, O_ST0, O_NONE, O_NONE, P_none }, + /* 0612 */ { UD_Ifsubp, O_ST7, O_ST0, O_NONE, O_NONE, P_none }, + /* 0613 */ { UD_Ifsubr, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0614 */ { UD_Ifsubr, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0615 */ { UD_Ifsubr, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0616 */ { UD_Ifsubr, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0617 */ { UD_Ifsubr, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0618 */ { UD_Ifsubr, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0619 */ { UD_Ifsubr, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0620 */ { UD_Ifsubr, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0621 */ { UD_Ifsubr, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0622 */ { UD_Ifsubr, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0623 */ { UD_Ifsubr, O_ST1, O_ST0, O_NONE, O_NONE, P_none }, + /* 0624 */ { UD_Ifsubr, O_ST2, O_ST0, O_NONE, O_NONE, P_none }, + /* 0625 */ { UD_Ifsubr, O_ST3, O_ST0, O_NONE, O_NONE, P_none }, + /* 0626 */ { UD_Ifsubr, O_ST4, O_ST0, O_NONE, O_NONE, P_none }, + /* 0627 */ { UD_Ifsubr, O_ST5, O_ST0, O_NONE, O_NONE, P_none }, + /* 0628 */ { UD_Ifsubr, O_ST6, O_ST0, O_NONE, O_NONE, P_none }, + /* 0629 */ { UD_Ifsubr, O_ST7, O_ST0, O_NONE, O_NONE, P_none }, + /* 0630 */ { UD_Ifsubr, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0631 */ { UD_Ifsubrp, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0632 */ { UD_Ifsubrp, O_ST1, O_ST0, O_NONE, O_NONE, P_none }, + /* 0633 */ { UD_Ifsubrp, O_ST2, O_ST0, O_NONE, O_NONE, P_none }, + /* 0634 */ { UD_Ifsubrp, O_ST3, O_ST0, O_NONE, O_NONE, P_none }, + /* 0635 */ { UD_Ifsubrp, O_ST4, O_ST0, O_NONE, O_NONE, P_none }, + /* 0636 */ { UD_Ifsubrp, O_ST5, O_ST0, O_NONE, O_NONE, P_none }, + /* 0637 */ { UD_Ifsubrp, O_ST6, O_ST0, O_NONE, O_NONE, P_none }, + /* 0638 */ { UD_Ifsubrp, O_ST7, O_ST0, O_NONE, O_NONE, P_none }, + /* 0639 */ { UD_Iftst, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0640 */ { UD_Ifucom, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0641 */ { UD_Ifucom, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0642 */ { UD_Ifucom, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0643 */ { UD_Ifucom, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0644 */ { UD_Ifucom, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0645 */ { UD_Ifucom, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0646 */ { UD_Ifucom, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0647 */ { UD_Ifucom, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0648 */ { UD_Ifucomp, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0649 */ { UD_Ifucomp, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0650 */ { UD_Ifucomp, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0651 */ { UD_Ifucomp, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0652 */ { UD_Ifucomp, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0653 */ { UD_Ifucomp, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0654 */ { UD_Ifucomp, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0655 */ { UD_Ifucomp, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0656 */ { UD_Ifucompp, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0657 */ { UD_Ifxam, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0658 */ { UD_Ifxch, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0659 */ { UD_Ifxch, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0660 */ { UD_Ifxch, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0661 */ { UD_Ifxch, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0662 */ { UD_Ifxch, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0663 */ { UD_Ifxch, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0664 */ { UD_Ifxch, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0665 */ { UD_Ifxch, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0666 */ { UD_Ifxch4, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0667 */ { UD_Ifxch4, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0668 */ { UD_Ifxch4, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0669 */ { UD_Ifxch4, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0670 */ { UD_Ifxch4, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0671 */ { UD_Ifxch4, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0672 */ { UD_Ifxch4, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0673 */ { UD_Ifxch4, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0674 */ { UD_Ifxch7, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0675 */ { UD_Ifxch7, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0676 */ { UD_Ifxch7, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0677 */ { UD_Ifxch7, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0678 */ { UD_Ifxch7, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0679 */ { UD_Ifxch7, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0680 */ { UD_Ifxch7, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0681 */ { UD_Ifxch7, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0682 */ { UD_Ifxrstor, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0683 */ { UD_Ifxsave, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0684 */ { UD_Ifxtract, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0685 */ { UD_Ifyl2x, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0686 */ { UD_Ifyl2xp1, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0687 */ { UD_Ihlt, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0688 */ { UD_Iidiv, O_Ev, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0689 */ { UD_Iidiv, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0690 */ { UD_Iin, O_AL, O_Ib, O_NONE, O_NONE, P_none }, + /* 0691 */ { UD_Iin, O_eAX, O_Ib, O_NONE, O_NONE, P_oso }, + /* 0692 */ { UD_Iin, O_AL, O_DX, O_NONE, O_NONE, P_none }, + /* 0693 */ { UD_Iin, O_eAX, O_DX, O_NONE, O_NONE, P_oso }, + /* 0694 */ { UD_Iimul, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0695 */ { UD_Iimul, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0696 */ { UD_Iimul, O_Ev, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0697 */ { UD_Iimul, O_Gv, O_Ev, O_Iz, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0698 */ { UD_Iimul, O_Gv, O_Ev, O_sIb, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0699 */ { UD_Iinc, O_R0z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0700 */ { UD_Iinc, O_R1z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0701 */ { UD_Iinc, O_R2z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0702 */ { UD_Iinc, O_R3z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0703 */ { UD_Iinc, O_R4z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0704 */ { UD_Iinc, O_R5z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0705 */ { UD_Iinc, O_R6z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0706 */ { UD_Iinc, O_R7z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0707 */ { UD_Iinc, O_Ev, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0708 */ { UD_Iinc, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0709 */ { UD_Iinsb, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg }, + /* 0710 */ { UD_Iinsw, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_oso|P_seg }, + /* 0711 */ { UD_Iinsd, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_oso|P_seg }, + /* 0712 */ { UD_Iint1, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0713 */ { UD_Iint3, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0714 */ { UD_Iint, O_Ib, O_NONE, O_NONE, O_NONE, P_none }, + /* 0715 */ { UD_Iinto, O_NONE, O_NONE, O_NONE, O_NONE, P_inv64 }, + /* 0716 */ { UD_Iinvd, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0717 */ { UD_Iinvept, O_Gd, O_Mo, O_NONE, O_NONE, P_none }, + /* 0718 */ { UD_Iinvept, O_Gq, O_Mo, O_NONE, O_NONE, P_none }, + /* 0719 */ { UD_Iinvlpg, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0720 */ { UD_Iinvlpga, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0721 */ { UD_Iinvvpid, O_Gd, O_Mo, O_NONE, O_NONE, P_none }, + /* 0722 */ { UD_Iinvvpid, O_Gq, O_Mo, O_NONE, O_NONE, P_none }, + /* 0723 */ { UD_Iiretw, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0724 */ { UD_Iiretd, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0725 */ { UD_Iiretq, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0726 */ { UD_Ijo, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0727 */ { UD_Ijo, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0728 */ { UD_Ijno, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0729 */ { UD_Ijno, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0730 */ { UD_Ijb, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0731 */ { UD_Ijb, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0732 */ { UD_Ijae, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0733 */ { UD_Ijae, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0734 */ { UD_Ijz, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0735 */ { UD_Ijz, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0736 */ { UD_Ijnz, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0737 */ { UD_Ijnz, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0738 */ { UD_Ijbe, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0739 */ { UD_Ijbe, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0740 */ { UD_Ija, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0741 */ { UD_Ija, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0742 */ { UD_Ijs, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0743 */ { UD_Ijs, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0744 */ { UD_Ijns, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0745 */ { UD_Ijns, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0746 */ { UD_Ijp, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0747 */ { UD_Ijp, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0748 */ { UD_Ijnp, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0749 */ { UD_Ijnp, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0750 */ { UD_Ijl, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0751 */ { UD_Ijl, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0752 */ { UD_Ijge, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0753 */ { UD_Ijge, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0754 */ { UD_Ijle, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0755 */ { UD_Ijle, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0756 */ { UD_Ijg, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0757 */ { UD_Ijg, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0758 */ { UD_Ijcxz, O_Jb, O_NONE, O_NONE, O_NONE, P_aso }, + /* 0759 */ { UD_Ijecxz, O_Jb, O_NONE, O_NONE, O_NONE, P_aso }, + /* 0760 */ { UD_Ijrcxz, O_Jb, O_NONE, O_NONE, O_NONE, P_aso }, + /* 0761 */ { UD_Ijmp, O_Ev, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb|P_def64 }, + /* 0762 */ { UD_Ijmp, O_Fv, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0763 */ { UD_Ijmp, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0764 */ { UD_Ijmp, O_Av, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0765 */ { UD_Ijmp, O_Jb, O_NONE, O_NONE, O_NONE, P_def64 }, + /* 0766 */ { UD_Ilahf, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0767 */ { UD_Ilar, O_Gv, O_Ew, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0768 */ { UD_Ildmxcsr, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0769 */ { UD_Ilds, O_Gv, O_M, O_NONE, O_NONE, P_aso|P_oso }, + /* 0770 */ { UD_Ilea, O_Gv, O_M, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0771 */ { UD_Iles, O_Gv, O_M, O_NONE, O_NONE, P_aso|P_oso }, + /* 0772 */ { UD_Ilfs, O_Gz, O_M, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0773 */ { UD_Ilgs, O_Gz, O_M, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0774 */ { UD_Ilidt, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0775 */ { UD_Ilss, O_Gv, O_M, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0776 */ { UD_Ileave, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0777 */ { UD_Ilfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0778 */ { UD_Ilfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0779 */ { UD_Ilfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0780 */ { UD_Ilfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0781 */ { UD_Ilfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0782 */ { UD_Ilfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0783 */ { UD_Ilfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0784 */ { UD_Ilfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0785 */ { UD_Ilgdt, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0786 */ { UD_Illdt, O_Ew, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0787 */ { UD_Ilmsw, O_Ew, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0788 */ { UD_Ilmsw, O_Ew, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0789 */ { UD_Ilock, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0790 */ { UD_Ilodsb, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg }, + /* 0791 */ { UD_Ilodsw, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg|P_oso|P_rexw }, + /* 0792 */ { UD_Ilodsd, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg|P_oso|P_rexw }, + /* 0793 */ { UD_Ilodsq, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg|P_oso|P_rexw }, + /* 0794 */ { UD_Iloopne, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0795 */ { UD_Iloope, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0796 */ { UD_Iloop, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0797 */ { UD_Ilsl, O_Gv, O_Ew, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0798 */ { UD_Iltr, O_Ew, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0799 */ { UD_Imaskmovq, O_P, O_N, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0800 */ { UD_Imaxpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0801 */ { UD_Ivmaxpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0802 */ { UD_Imaxps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0803 */ { UD_Ivmaxps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0804 */ { UD_Imaxsd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0805 */ { UD_Ivmaxsd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0806 */ { UD_Imaxss, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0807 */ { UD_Ivmaxss, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0808 */ { UD_Imfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0809 */ { UD_Imfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0810 */ { UD_Imfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0811 */ { UD_Imfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0812 */ { UD_Imfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0813 */ { UD_Imfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0814 */ { UD_Imfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0815 */ { UD_Imfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0816 */ { UD_Iminpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0817 */ { UD_Ivminpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0818 */ { UD_Iminps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0819 */ { UD_Ivminps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0820 */ { UD_Iminsd, O_V, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0821 */ { UD_Ivminsd, O_Vx, O_Hx, O_MqU, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0822 */ { UD_Iminss, O_V, O_MdU, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0823 */ { UD_Ivminss, O_Vx, O_Hx, O_MdU, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0824 */ { UD_Imonitor, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0825 */ { UD_Imontmul, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0826 */ { UD_Imov, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0827 */ { UD_Imov, O_Ev, O_sIz, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0828 */ { UD_Imov, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0829 */ { UD_Imov, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0830 */ { UD_Imov, O_Gb, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0831 */ { UD_Imov, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0832 */ { UD_Imov, O_MwRv, O_S, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0833 */ { UD_Imov, O_S, O_MwRv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0834 */ { UD_Imov, O_AL, O_Ob, O_NONE, O_NONE, P_none }, + /* 0835 */ { UD_Imov, O_rAX, O_Ov, O_NONE, O_NONE, P_aso|P_oso|P_rexw }, + /* 0836 */ { UD_Imov, O_Ob, O_AL, O_NONE, O_NONE, P_none }, + /* 0837 */ { UD_Imov, O_Ov, O_rAX, O_NONE, O_NONE, P_aso|P_oso|P_rexw }, + /* 0838 */ { UD_Imov, O_R0b, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 0839 */ { UD_Imov, O_R1b, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 0840 */ { UD_Imov, O_R2b, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 0841 */ { UD_Imov, O_R3b, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 0842 */ { UD_Imov, O_R4b, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 0843 */ { UD_Imov, O_R5b, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 0844 */ { UD_Imov, O_R6b, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 0845 */ { UD_Imov, O_R7b, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 0846 */ { UD_Imov, O_R0v, O_Iv, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 0847 */ { UD_Imov, O_R1v, O_Iv, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 0848 */ { UD_Imov, O_R2v, O_Iv, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 0849 */ { UD_Imov, O_R3v, O_Iv, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 0850 */ { UD_Imov, O_R4v, O_Iv, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 0851 */ { UD_Imov, O_R5v, O_Iv, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 0852 */ { UD_Imov, O_R6v, O_Iv, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 0853 */ { UD_Imov, O_R7v, O_Iv, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 0854 */ { UD_Imov, O_R, O_C, O_NONE, O_NONE, P_rexr|P_rexw|P_rexb }, + /* 0855 */ { UD_Imov, O_R, O_D, O_NONE, O_NONE, P_rexr|P_rexw|P_rexb }, + /* 0856 */ { UD_Imov, O_C, O_R, O_NONE, O_NONE, P_rexr|P_rexw|P_rexb }, + /* 0857 */ { UD_Imov, O_D, O_R, O_NONE, O_NONE, P_rexr|P_rexw|P_rexb }, + /* 0858 */ { UD_Imovapd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0859 */ { UD_Ivmovapd, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0860 */ { UD_Imovapd, O_W, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0861 */ { UD_Ivmovapd, O_Wx, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0862 */ { UD_Imovaps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0863 */ { UD_Ivmovaps, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0864 */ { UD_Imovaps, O_W, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0865 */ { UD_Ivmovaps, O_Wx, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0866 */ { UD_Imovd, O_P, O_Ey, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0867 */ { UD_Imovd, O_P, O_Ey, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0868 */ { UD_Imovd, O_V, O_Ey, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0869 */ { UD_Ivmovd, O_Vx, O_Ey, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0870 */ { UD_Imovd, O_V, O_Ey, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0871 */ { UD_Ivmovd, O_Vx, O_Ey, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0872 */ { UD_Imovd, O_Ey, O_P, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0873 */ { UD_Imovd, O_Ey, O_P, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0874 */ { UD_Imovd, O_Ey, O_V, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0875 */ { UD_Ivmovd, O_Ey, O_Vx, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0876 */ { UD_Imovd, O_Ey, O_V, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0877 */ { UD_Ivmovd, O_Ey, O_Vx, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0878 */ { UD_Imovhpd, O_V, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0879 */ { UD_Ivmovhpd, O_Vx, O_Hx, O_M, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0880 */ { UD_Imovhpd, O_M, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0881 */ { UD_Ivmovhpd, O_M, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0882 */ { UD_Imovhps, O_V, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0883 */ { UD_Ivmovhps, O_Vx, O_Hx, O_M, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0884 */ { UD_Imovhps, O_M, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0885 */ { UD_Ivmovhps, O_M, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0886 */ { UD_Imovlhps, O_V, O_U, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0887 */ { UD_Ivmovlhps, O_Vx, O_Hx, O_Ux, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0888 */ { UD_Imovlpd, O_V, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0889 */ { UD_Ivmovlpd, O_Vx, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0890 */ { UD_Imovlpd, O_M, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0891 */ { UD_Ivmovlpd, O_M, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0892 */ { UD_Imovlps, O_V, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0893 */ { UD_Ivmovlps, O_Vx, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0894 */ { UD_Imovlps, O_M, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0895 */ { UD_Ivmovlps, O_M, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0896 */ { UD_Imovhlps, O_V, O_U, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0897 */ { UD_Ivmovhlps, O_Vx, O_Ux, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0898 */ { UD_Imovmskpd, O_Gd, O_U, O_NONE, O_NONE, P_oso|P_rexr|P_rexb }, + /* 0899 */ { UD_Ivmovmskpd, O_Gd, O_Ux, O_NONE, O_NONE, P_oso|P_rexr|P_rexb|P_vexl }, + /* 0900 */ { UD_Imovmskps, O_Gd, O_U, O_NONE, O_NONE, P_oso|P_rexr|P_rexb }, + /* 0901 */ { UD_Ivmovmskps, O_Gd, O_Ux, O_NONE, O_NONE, P_oso|P_rexr|P_rexb }, + /* 0902 */ { UD_Imovntdq, O_M, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0903 */ { UD_Ivmovntdq, O_M, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0904 */ { UD_Imovnti, O_M, O_Gy, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0905 */ { UD_Imovntpd, O_M, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0906 */ { UD_Ivmovntpd, O_M, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0907 */ { UD_Imovntps, O_M, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0908 */ { UD_Ivmovntps, O_M, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0909 */ { UD_Imovntq, O_M, O_P, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0910 */ { UD_Imovq, O_P, O_Eq, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0911 */ { UD_Imovq, O_V, O_Eq, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0912 */ { UD_Ivmovq, O_Vx, O_Eq, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0913 */ { UD_Imovq, O_Eq, O_P, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0914 */ { UD_Imovq, O_Eq, O_V, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0915 */ { UD_Ivmovq, O_Eq, O_Vx, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0916 */ { UD_Imovq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0917 */ { UD_Ivmovq, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0918 */ { UD_Imovq, O_W, O_V, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0919 */ { UD_Ivmovq, O_Wx, O_Vx, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0920 */ { UD_Imovq, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0921 */ { UD_Imovq, O_Q, O_P, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0922 */ { UD_Imovsb, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg }, + /* 0923 */ { UD_Imovsw, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg|P_oso|P_rexw }, + /* 0924 */ { UD_Imovsd, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg|P_oso|P_rexw }, + /* 0925 */ { UD_Imovsd, O_V, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0926 */ { UD_Imovsd, O_W, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0927 */ { UD_Imovsq, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg|P_oso|P_rexw }, + /* 0928 */ { UD_Imovss, O_V, O_MdU, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0929 */ { UD_Imovss, O_W, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0930 */ { UD_Imovsx, O_Gv, O_Eb, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0931 */ { UD_Imovsx, O_Gy, O_Ew, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0932 */ { UD_Imovupd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0933 */ { UD_Ivmovupd, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0934 */ { UD_Imovupd, O_W, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0935 */ { UD_Ivmovupd, O_Wx, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0936 */ { UD_Imovups, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0937 */ { UD_Ivmovups, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0938 */ { UD_Imovups, O_W, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0939 */ { UD_Ivmovups, O_Wx, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0940 */ { UD_Imovzx, O_Gv, O_Eb, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0941 */ { UD_Imovzx, O_Gy, O_Ew, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0942 */ { UD_Imul, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0943 */ { UD_Imul, O_Ev, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0944 */ { UD_Imulpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0945 */ { UD_Ivmulpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0946 */ { UD_Imulps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0947 */ { UD_Ivmulps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0948 */ { UD_Imulsd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0949 */ { UD_Ivmulsd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0950 */ { UD_Imulss, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0951 */ { UD_Ivmulss, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0952 */ { UD_Imwait, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0953 */ { UD_Ineg, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0954 */ { UD_Ineg, O_Ev, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0955 */ { UD_Inop, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0956 */ { UD_Inop, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0957 */ { UD_Inop, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0958 */ { UD_Inop, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0959 */ { UD_Inop, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0960 */ { UD_Inop, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0961 */ { UD_Inop, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0962 */ { UD_Inot, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0963 */ { UD_Inot, O_Ev, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0964 */ { UD_Ior, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0965 */ { UD_Ior, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0966 */ { UD_Ior, O_Gb, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0967 */ { UD_Ior, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0968 */ { UD_Ior, O_AL, O_Ib, O_NONE, O_NONE, P_none }, + /* 0969 */ { UD_Ior, O_rAX, O_sIz, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0970 */ { UD_Ior, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0971 */ { UD_Ior, O_Ev, O_sIz, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0972 */ { UD_Ior, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0973 */ { UD_Ior, O_Ev, O_sIb, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0974 */ { UD_Iorpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0975 */ { UD_Ivorpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0976 */ { UD_Iorps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0977 */ { UD_Ivorps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0978 */ { UD_Iout, O_Ib, O_AL, O_NONE, O_NONE, P_none }, + /* 0979 */ { UD_Iout, O_Ib, O_eAX, O_NONE, O_NONE, P_oso }, + /* 0980 */ { UD_Iout, O_DX, O_AL, O_NONE, O_NONE, P_none }, + /* 0981 */ { UD_Iout, O_DX, O_eAX, O_NONE, O_NONE, P_oso }, + /* 0982 */ { UD_Ioutsb, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg }, + /* 0983 */ { UD_Ioutsw, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_oso|P_seg }, + /* 0984 */ { UD_Ioutsd, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_oso|P_seg }, + /* 0985 */ { UD_Ipacksswb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0986 */ { UD_Ivpacksswb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0987 */ { UD_Ipacksswb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0988 */ { UD_Ipackssdw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0989 */ { UD_Ivpackssdw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0990 */ { UD_Ipackssdw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0991 */ { UD_Ipackuswb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0992 */ { UD_Ivpackuswb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0993 */ { UD_Ipackuswb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0994 */ { UD_Ipaddb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0995 */ { UD_Ivpaddb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0996 */ { UD_Ipaddb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0997 */ { UD_Ipaddw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0998 */ { UD_Ipaddw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0999 */ { UD_Ivpaddw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1000 */ { UD_Ipaddd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1001 */ { UD_Ipaddd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1002 */ { UD_Ivpaddd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1003 */ { UD_Ipaddsb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1004 */ { UD_Ipaddsb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1005 */ { UD_Ivpaddsb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1006 */ { UD_Ipaddsw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1007 */ { UD_Ipaddsw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1008 */ { UD_Ivpaddsw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1009 */ { UD_Ipaddusb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1010 */ { UD_Ipaddusb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1011 */ { UD_Ivpaddusb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1012 */ { UD_Ipaddusw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1013 */ { UD_Ipaddusw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1014 */ { UD_Ivpaddusw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1015 */ { UD_Ipand, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1016 */ { UD_Ivpand, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1017 */ { UD_Ipand, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1018 */ { UD_Ipandn, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1019 */ { UD_Ivpandn, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1020 */ { UD_Ipandn, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1021 */ { UD_Ipavgb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1022 */ { UD_Ivpavgb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1023 */ { UD_Ipavgb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1024 */ { UD_Ipavgw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1025 */ { UD_Ivpavgw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1026 */ { UD_Ipavgw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1027 */ { UD_Ipcmpeqb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1028 */ { UD_Ipcmpeqb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1029 */ { UD_Ivpcmpeqb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1030 */ { UD_Ipcmpeqw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1031 */ { UD_Ipcmpeqw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1032 */ { UD_Ivpcmpeqw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1033 */ { UD_Ipcmpeqd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1034 */ { UD_Ipcmpeqd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1035 */ { UD_Ivpcmpeqd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1036 */ { UD_Ipcmpgtb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1037 */ { UD_Ivpcmpgtb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1038 */ { UD_Ipcmpgtb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1039 */ { UD_Ipcmpgtw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1040 */ { UD_Ivpcmpgtw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1041 */ { UD_Ipcmpgtw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1042 */ { UD_Ipcmpgtd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1043 */ { UD_Ivpcmpgtd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1044 */ { UD_Ipcmpgtd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1045 */ { UD_Ipextrb, O_MbRv, O_V, O_Ib, O_NONE, P_aso|P_rexx|P_rexr|P_rexb|P_def64 }, + /* 1046 */ { UD_Ivpextrb, O_MbRv, O_Vx, O_Ib, O_NONE, P_aso|P_rexx|P_rexr|P_rexb|P_def64 }, + /* 1047 */ { UD_Ipextrd, O_Ed, O_V, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexw|P_rexb }, + /* 1048 */ { UD_Ivpextrd, O_Ed, O_Vx, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexw|P_rexb }, + /* 1049 */ { UD_Ipextrd, O_Ed, O_V, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexw|P_rexb }, + /* 1050 */ { UD_Ivpextrd, O_Ed, O_Vx, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexw|P_rexb }, + /* 1051 */ { UD_Ipextrq, O_Eq, O_V, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexb|P_def64 }, + /* 1052 */ { UD_Ivpextrq, O_Eq, O_Vx, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexb|P_def64 }, + /* 1053 */ { UD_Ipextrw, O_Gd, O_U, O_Ib, O_NONE, P_aso|P_rexw|P_rexr|P_rexb }, + /* 1054 */ { UD_Ivpextrw, O_Gd, O_Ux, O_Ib, O_NONE, P_aso|P_rexw|P_rexr|P_rexb }, + /* 1055 */ { UD_Ipextrw, O_Gd, O_N, O_Ib, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1056 */ { UD_Ipextrw, O_MwRd, O_V, O_Ib, O_NONE, P_aso|P_rexw|P_rexx|P_rexr|P_rexb }, + /* 1057 */ { UD_Ivpextrw, O_MwRd, O_Vx, O_Ib, O_NONE, P_aso|P_rexw|P_rexx|P_rexr|P_rexb }, + /* 1058 */ { UD_Ipinsrb, O_V, O_MbRd, O_Ib, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1059 */ { UD_Ipinsrw, O_P, O_MwRy, O_Ib, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb|P_def64 }, + /* 1060 */ { UD_Ipinsrw, O_V, O_MwRy, O_Ib, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb|P_def64 }, + /* 1061 */ { UD_Ivpinsrw, O_Vx, O_MwRy, O_Ib, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb|P_def64 }, + /* 1062 */ { UD_Ipinsrd, O_V, O_Ed, O_Ib, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1063 */ { UD_Ipinsrd, O_V, O_Ed, O_Ib, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1064 */ { UD_Ipinsrq, O_V, O_Eq, O_Ib, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1065 */ { UD_Ivpinsrb, O_V, O_H, O_MbRd, O_Ib, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1066 */ { UD_Ivpinsrd, O_V, O_H, O_Ed, O_Ib, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1067 */ { UD_Ivpinsrd, O_V, O_H, O_Ed, O_Ib, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1068 */ { UD_Ivpinsrq, O_V, O_H, O_Eq, O_Ib, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1069 */ { UD_Ipmaddwd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1070 */ { UD_Ipmaddwd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1071 */ { UD_Ivpmaddwd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1072 */ { UD_Ipmaxsw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1073 */ { UD_Ivpmaxsw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1074 */ { UD_Ipmaxsw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1075 */ { UD_Ipmaxub, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1076 */ { UD_Ipmaxub, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1077 */ { UD_Ivpmaxub, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1078 */ { UD_Ipminsw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1079 */ { UD_Ivpminsw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1080 */ { UD_Ipminsw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1081 */ { UD_Ipminub, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1082 */ { UD_Ivpminub, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1083 */ { UD_Ipminub, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1084 */ { UD_Ipmovmskb, O_Gd, O_U, O_NONE, O_NONE, P_oso|P_rexr|P_rexw|P_rexb }, + /* 1085 */ { UD_Ivpmovmskb, O_Gd, O_Ux, O_NONE, O_NONE, P_oso|P_rexr|P_rexw|P_rexb }, + /* 1086 */ { UD_Ipmovmskb, O_Gd, O_N, O_NONE, O_NONE, P_oso|P_rexr|P_rexw|P_rexb }, + /* 1087 */ { UD_Ipmulhuw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1088 */ { UD_Ipmulhuw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1089 */ { UD_Ivpmulhuw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1090 */ { UD_Ipmulhw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1091 */ { UD_Ivpmulhw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1092 */ { UD_Ipmulhw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1093 */ { UD_Ipmullw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1094 */ { UD_Ipmullw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1095 */ { UD_Ivpmullw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1096 */ { UD_Ipop, O_ES, O_NONE, O_NONE, O_NONE, P_inv64 }, + /* 1097 */ { UD_Ipop, O_SS, O_NONE, O_NONE, O_NONE, P_inv64 }, + /* 1098 */ { UD_Ipop, O_DS, O_NONE, O_NONE, O_NONE, P_inv64 }, + /* 1099 */ { UD_Ipop, O_GS, O_NONE, O_NONE, O_NONE, P_none }, + /* 1100 */ { UD_Ipop, O_FS, O_NONE, O_NONE, O_NONE, P_none }, + /* 1101 */ { UD_Ipop, O_R0v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1102 */ { UD_Ipop, O_R1v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1103 */ { UD_Ipop, O_R2v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1104 */ { UD_Ipop, O_R3v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1105 */ { UD_Ipop, O_R4v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1106 */ { UD_Ipop, O_R5v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1107 */ { UD_Ipop, O_R6v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1108 */ { UD_Ipop, O_R7v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1109 */ { UD_Ipop, O_Ev, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb|P_def64 }, + /* 1110 */ { UD_Ipopa, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_inv64 }, + /* 1111 */ { UD_Ipopad, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_inv64 }, + /* 1112 */ { UD_Ipopfw, O_NONE, O_NONE, O_NONE, O_NONE, P_oso }, + /* 1113 */ { UD_Ipopfd, O_NONE, O_NONE, O_NONE, O_NONE, P_oso }, + /* 1114 */ { UD_Ipopfq, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 1115 */ { UD_Ipopfq, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 1116 */ { UD_Ipor, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1117 */ { UD_Ivpor, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1118 */ { UD_Ipor, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1119 */ { UD_Iprefetch, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1120 */ { UD_Iprefetch, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1121 */ { UD_Iprefetch, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1122 */ { UD_Iprefetch, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1123 */ { UD_Iprefetch, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1124 */ { UD_Iprefetch, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1125 */ { UD_Iprefetch, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1126 */ { UD_Iprefetch, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1127 */ { UD_Iprefetchnta, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1128 */ { UD_Iprefetcht0, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1129 */ { UD_Iprefetcht1, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1130 */ { UD_Iprefetcht2, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1131 */ { UD_Ipsadbw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1132 */ { UD_Ivpsadbw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1133 */ { UD_Ipsadbw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1134 */ { UD_Ipshufw, O_P, O_Q, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1135 */ { UD_Ipsllw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1136 */ { UD_Ipsllw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1137 */ { UD_Ipsllw, O_U, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 1138 */ { UD_Ipsllw, O_N, O_Ib, O_NONE, O_NONE, P_none }, + /* 1139 */ { UD_Ipslld, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1140 */ { UD_Ipslld, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1141 */ { UD_Ipslld, O_U, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 1142 */ { UD_Ipslld, O_N, O_Ib, O_NONE, O_NONE, P_none }, + /* 1143 */ { UD_Ipsllq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1144 */ { UD_Ipsllq, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1145 */ { UD_Ipsllq, O_U, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 1146 */ { UD_Ipsllq, O_N, O_Ib, O_NONE, O_NONE, P_none }, + /* 1147 */ { UD_Ipsraw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1148 */ { UD_Ipsraw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1149 */ { UD_Ivpsraw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1150 */ { UD_Ipsraw, O_U, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 1151 */ { UD_Ivpsraw, O_Hx, O_Ux, O_Ib, O_NONE, P_rexb }, + /* 1152 */ { UD_Ipsraw, O_N, O_Ib, O_NONE, O_NONE, P_none }, + /* 1153 */ { UD_Ipsrad, O_N, O_Ib, O_NONE, O_NONE, P_none }, + /* 1154 */ { UD_Ipsrad, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1155 */ { UD_Ivpsrad, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1156 */ { UD_Ipsrad, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1157 */ { UD_Ipsrad, O_U, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 1158 */ { UD_Ivpsrad, O_Hx, O_Ux, O_Ib, O_NONE, P_rexb }, + /* 1159 */ { UD_Ipsrlw, O_N, O_Ib, O_NONE, O_NONE, P_none }, + /* 1160 */ { UD_Ipsrlw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1161 */ { UD_Ipsrlw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1162 */ { UD_Ivpsrlw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1163 */ { UD_Ipsrlw, O_U, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 1164 */ { UD_Ivpsrlw, O_Hx, O_Ux, O_Ib, O_NONE, P_rexb }, + /* 1165 */ { UD_Ipsrld, O_N, O_Ib, O_NONE, O_NONE, P_none }, + /* 1166 */ { UD_Ipsrld, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1167 */ { UD_Ipsrld, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1168 */ { UD_Ivpsrld, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1169 */ { UD_Ipsrld, O_U, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 1170 */ { UD_Ivpsrld, O_Hx, O_Ux, O_Ib, O_NONE, P_rexb }, + /* 1171 */ { UD_Ipsrlq, O_N, O_Ib, O_NONE, O_NONE, P_none }, + /* 1172 */ { UD_Ipsrlq, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1173 */ { UD_Ipsrlq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1174 */ { UD_Ivpsrlq, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1175 */ { UD_Ipsrlq, O_U, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 1176 */ { UD_Ivpsrlq, O_Hx, O_Ux, O_Ib, O_NONE, P_rexb }, + /* 1177 */ { UD_Ipsubb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1178 */ { UD_Ivpsubb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1179 */ { UD_Ipsubb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1180 */ { UD_Ipsubw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1181 */ { UD_Ivpsubw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1182 */ { UD_Ipsubw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1183 */ { UD_Ipsubd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1184 */ { UD_Ipsubd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1185 */ { UD_Ivpsubd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1186 */ { UD_Ipsubsb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1187 */ { UD_Ipsubsb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1188 */ { UD_Ivpsubsb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1189 */ { UD_Ipsubsw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1190 */ { UD_Ipsubsw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1191 */ { UD_Ivpsubsw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1192 */ { UD_Ipsubusb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1193 */ { UD_Ipsubusb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1194 */ { UD_Ivpsubusb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1195 */ { UD_Ipsubusw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1196 */ { UD_Ipsubusw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1197 */ { UD_Ivpsubusw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1198 */ { UD_Ipunpckhbw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1199 */ { UD_Ivpunpckhbw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1200 */ { UD_Ipunpckhbw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1201 */ { UD_Ipunpckhwd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1202 */ { UD_Ivpunpckhwd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1203 */ { UD_Ipunpckhwd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1204 */ { UD_Ipunpckhdq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1205 */ { UD_Ivpunpckhdq, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1206 */ { UD_Ipunpckhdq, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1207 */ { UD_Ipunpcklbw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1208 */ { UD_Ivpunpcklbw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1209 */ { UD_Ipunpcklbw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1210 */ { UD_Ipunpcklwd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1211 */ { UD_Ivpunpcklwd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1212 */ { UD_Ipunpcklwd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1213 */ { UD_Ipunpckldq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1214 */ { UD_Ivpunpckldq, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1215 */ { UD_Ipunpckldq, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1216 */ { UD_Ipi2fw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1217 */ { UD_Ipi2fd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1218 */ { UD_Ipf2iw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1219 */ { UD_Ipf2id, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1220 */ { UD_Ipfnacc, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1221 */ { UD_Ipfpnacc, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1222 */ { UD_Ipfcmpge, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1223 */ { UD_Ipfmin, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1224 */ { UD_Ipfrcp, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1225 */ { UD_Ipfrsqrt, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1226 */ { UD_Ipfsub, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1227 */ { UD_Ipfadd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1228 */ { UD_Ipfcmpgt, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1229 */ { UD_Ipfmax, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1230 */ { UD_Ipfrcpit1, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1231 */ { UD_Ipfrsqit1, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1232 */ { UD_Ipfsubr, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1233 */ { UD_Ipfacc, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1234 */ { UD_Ipfcmpeq, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1235 */ { UD_Ipfmul, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1236 */ { UD_Ipfrcpit2, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1237 */ { UD_Ipmulhrw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1238 */ { UD_Ipswapd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1239 */ { UD_Ipavgusb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1240 */ { UD_Ipush, O_ES, O_NONE, O_NONE, O_NONE, P_inv64 }, + /* 1241 */ { UD_Ipush, O_CS, O_NONE, O_NONE, O_NONE, P_inv64 }, + /* 1242 */ { UD_Ipush, O_SS, O_NONE, O_NONE, O_NONE, P_inv64 }, + /* 1243 */ { UD_Ipush, O_DS, O_NONE, O_NONE, O_NONE, P_inv64 }, + /* 1244 */ { UD_Ipush, O_GS, O_NONE, O_NONE, O_NONE, P_none }, + /* 1245 */ { UD_Ipush, O_FS, O_NONE, O_NONE, O_NONE, P_none }, + /* 1246 */ { UD_Ipush, O_R0v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1247 */ { UD_Ipush, O_R1v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1248 */ { UD_Ipush, O_R2v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1249 */ { UD_Ipush, O_R3v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1250 */ { UD_Ipush, O_R4v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1251 */ { UD_Ipush, O_R5v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1252 */ { UD_Ipush, O_R6v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1253 */ { UD_Ipush, O_R7v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1254 */ { UD_Ipush, O_sIz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 1255 */ { UD_Ipush, O_Ev, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb|P_def64 }, + /* 1256 */ { UD_Ipush, O_sIb, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 1257 */ { UD_Ipusha, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_inv64 }, + /* 1258 */ { UD_Ipushad, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_inv64 }, + /* 1259 */ { UD_Ipushfw, O_NONE, O_NONE, O_NONE, O_NONE, P_oso }, + /* 1260 */ { UD_Ipushfw, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_rexw|P_def64 }, + /* 1261 */ { UD_Ipushfd, O_NONE, O_NONE, O_NONE, O_NONE, P_oso }, + /* 1262 */ { UD_Ipushfq, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_rexw|P_def64 }, + /* 1263 */ { UD_Ipushfq, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_rexw|P_def64 }, + /* 1264 */ { UD_Ipxor, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1265 */ { UD_Ivpxor, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1266 */ { UD_Ipxor, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1267 */ { UD_Ircl, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1268 */ { UD_Ircl, O_Ev, O_Ib, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1269 */ { UD_Ircl, O_Eb, O_I1, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1270 */ { UD_Ircl, O_Eb, O_CL, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1271 */ { UD_Ircl, O_Ev, O_CL, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1272 */ { UD_Ircl, O_Ev, O_I1, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1273 */ { UD_Ircr, O_Eb, O_I1, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1274 */ { UD_Ircr, O_Ev, O_Ib, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1275 */ { UD_Ircr, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1276 */ { UD_Ircr, O_Ev, O_I1, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1277 */ { UD_Ircr, O_Eb, O_CL, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1278 */ { UD_Ircr, O_Ev, O_CL, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1279 */ { UD_Irol, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1280 */ { UD_Irol, O_Eb, O_I1, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1281 */ { UD_Irol, O_Ev, O_I1, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1282 */ { UD_Irol, O_Eb, O_CL, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1283 */ { UD_Irol, O_Ev, O_CL, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1284 */ { UD_Irol, O_Ev, O_Ib, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1285 */ { UD_Iror, O_Eb, O_I1, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1286 */ { UD_Iror, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1287 */ { UD_Iror, O_Ev, O_Ib, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1288 */ { UD_Iror, O_Ev, O_I1, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1289 */ { UD_Iror, O_Eb, O_CL, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1290 */ { UD_Iror, O_Ev, O_CL, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1291 */ { UD_Ircpps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1292 */ { UD_Ivrcpps, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1293 */ { UD_Ircpss, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1294 */ { UD_Ivrcpss, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1295 */ { UD_Irdmsr, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1296 */ { UD_Irdpmc, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1297 */ { UD_Irdtsc, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1298 */ { UD_Irdtscp, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1299 */ { UD_Irepne, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1300 */ { UD_Irep, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1301 */ { UD_Iret, O_Iw, O_NONE, O_NONE, O_NONE, P_none }, + /* 1302 */ { UD_Iret, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1303 */ { UD_Iretf, O_Iw, O_NONE, O_NONE, O_NONE, P_none }, + /* 1304 */ { UD_Iretf, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1305 */ { UD_Irsm, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1306 */ { UD_Irsqrtps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1307 */ { UD_Ivrsqrtps, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1308 */ { UD_Irsqrtss, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1309 */ { UD_Ivrsqrtss, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1310 */ { UD_Isahf, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1311 */ { UD_Isalc, O_NONE, O_NONE, O_NONE, O_NONE, P_inv64 }, + /* 1312 */ { UD_Isar, O_Ev, O_I1, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1313 */ { UD_Isar, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1314 */ { UD_Isar, O_Eb, O_I1, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1315 */ { UD_Isar, O_Ev, O_Ib, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1316 */ { UD_Isar, O_Eb, O_CL, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1317 */ { UD_Isar, O_Ev, O_CL, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1318 */ { UD_Ishl, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1319 */ { UD_Ishl, O_Ev, O_Ib, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1320 */ { UD_Ishl, O_Eb, O_I1, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1321 */ { UD_Ishl, O_Eb, O_CL, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1322 */ { UD_Ishl, O_Ev, O_CL, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1323 */ { UD_Ishl, O_Ev, O_Ib, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1324 */ { UD_Ishl, O_Eb, O_CL, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1325 */ { UD_Ishl, O_Ev, O_I1, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1326 */ { UD_Ishl, O_Eb, O_I1, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1327 */ { UD_Ishl, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1328 */ { UD_Ishl, O_Ev, O_CL, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1329 */ { UD_Ishl, O_Ev, O_I1, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1330 */ { UD_Ishr, O_Ev, O_Ib, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1331 */ { UD_Ishr, O_Eb, O_CL, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1332 */ { UD_Ishr, O_Ev, O_I1, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1333 */ { UD_Ishr, O_Eb, O_I1, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1334 */ { UD_Ishr, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1335 */ { UD_Ishr, O_Ev, O_CL, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1336 */ { UD_Isbb, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1337 */ { UD_Isbb, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1338 */ { UD_Isbb, O_Gb, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1339 */ { UD_Isbb, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1340 */ { UD_Isbb, O_AL, O_Ib, O_NONE, O_NONE, P_none }, + /* 1341 */ { UD_Isbb, O_rAX, O_sIz, O_NONE, O_NONE, P_oso|P_rexw }, + /* 1342 */ { UD_Isbb, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1343 */ { UD_Isbb, O_Ev, O_sIz, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1344 */ { UD_Isbb, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_inv64 }, + /* 1345 */ { UD_Isbb, O_Ev, O_sIb, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1346 */ { UD_Iscasb, O_NONE, O_NONE, O_NONE, O_NONE, P_strz }, + /* 1347 */ { UD_Iscasw, O_NONE, O_NONE, O_NONE, O_NONE, P_strz|P_oso|P_rexw }, + /* 1348 */ { UD_Iscasd, O_NONE, O_NONE, O_NONE, O_NONE, P_strz|P_oso|P_rexw }, + /* 1349 */ { UD_Iscasq, O_NONE, O_NONE, O_NONE, O_NONE, P_strz|P_oso|P_rexw }, + /* 1350 */ { UD_Iseto, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1351 */ { UD_Isetno, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1352 */ { UD_Isetb, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1353 */ { UD_Isetae, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1354 */ { UD_Isetz, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1355 */ { UD_Isetnz, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1356 */ { UD_Isetbe, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1357 */ { UD_Iseta, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1358 */ { UD_Isets, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1359 */ { UD_Isetns, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1360 */ { UD_Isetp, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1361 */ { UD_Isetnp, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1362 */ { UD_Isetl, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1363 */ { UD_Isetge, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1364 */ { UD_Isetle, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1365 */ { UD_Isetg, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1366 */ { UD_Isfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1367 */ { UD_Isfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1368 */ { UD_Isfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1369 */ { UD_Isfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1370 */ { UD_Isfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1371 */ { UD_Isfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1372 */ { UD_Isfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1373 */ { UD_Isfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1374 */ { UD_Isgdt, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1375 */ { UD_Ishld, O_Ev, O_Gv, O_Ib, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1376 */ { UD_Ishld, O_Ev, O_Gv, O_CL, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1377 */ { UD_Ishrd, O_Ev, O_Gv, O_Ib, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1378 */ { UD_Ishrd, O_Ev, O_Gv, O_CL, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1379 */ { UD_Ishufpd, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1380 */ { UD_Ivshufpd, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1381 */ { UD_Ishufps, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1382 */ { UD_Ivshufps, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1383 */ { UD_Isidt, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1384 */ { UD_Isldt, O_MwRv, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1385 */ { UD_Ismsw, O_MwRv, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1386 */ { UD_Ismsw, O_MwRv, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1387 */ { UD_Isqrtps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1388 */ { UD_Ivsqrtps, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1389 */ { UD_Isqrtpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1390 */ { UD_Ivsqrtpd, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1391 */ { UD_Isqrtsd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1392 */ { UD_Ivsqrtsd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1393 */ { UD_Isqrtss, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1394 */ { UD_Ivsqrtss, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1395 */ { UD_Istc, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1396 */ { UD_Istd, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1397 */ { UD_Istgi, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1398 */ { UD_Isti, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1399 */ { UD_Iskinit, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1400 */ { UD_Istmxcsr, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1401 */ { UD_Ivstmxcsr, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1402 */ { UD_Istosb, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg }, + /* 1403 */ { UD_Istosw, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg|P_oso|P_rexw }, + /* 1404 */ { UD_Istosd, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg|P_oso|P_rexw }, + /* 1405 */ { UD_Istosq, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg|P_oso|P_rexw }, + /* 1406 */ { UD_Istr, O_MwRv, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1407 */ { UD_Isub, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1408 */ { UD_Isub, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1409 */ { UD_Isub, O_Gb, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1410 */ { UD_Isub, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1411 */ { UD_Isub, O_AL, O_Ib, O_NONE, O_NONE, P_none }, + /* 1412 */ { UD_Isub, O_rAX, O_sIz, O_NONE, O_NONE, P_oso|P_rexw }, + /* 1413 */ { UD_Isub, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1414 */ { UD_Isub, O_Ev, O_sIz, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1415 */ { UD_Isub, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_inv64 }, + /* 1416 */ { UD_Isub, O_Ev, O_sIb, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1417 */ { UD_Isubpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1418 */ { UD_Ivsubpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1419 */ { UD_Isubps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1420 */ { UD_Ivsubps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1421 */ { UD_Isubsd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1422 */ { UD_Ivsubsd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1423 */ { UD_Isubss, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1424 */ { UD_Ivsubss, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1425 */ { UD_Iswapgs, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1426 */ { UD_Isyscall, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1427 */ { UD_Isysenter, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1428 */ { UD_Isysenter, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1429 */ { UD_Isysexit, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1430 */ { UD_Isysexit, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1431 */ { UD_Isysret, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1432 */ { UD_Itest, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1433 */ { UD_Itest, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1434 */ { UD_Itest, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1435 */ { UD_Itest, O_AL, O_Ib, O_NONE, O_NONE, P_none }, + /* 1436 */ { UD_Itest, O_rAX, O_sIz, O_NONE, O_NONE, P_oso|P_rexw }, + /* 1437 */ { UD_Itest, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1438 */ { UD_Itest, O_Ev, O_sIz, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1439 */ { UD_Itest, O_Ev, O_Iz, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1440 */ { UD_Iucomisd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1441 */ { UD_Ivucomisd, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1442 */ { UD_Iucomiss, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1443 */ { UD_Ivucomiss, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1444 */ { UD_Iud2, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1445 */ { UD_Iunpckhpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1446 */ { UD_Ivunpckhpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1447 */ { UD_Iunpckhps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1448 */ { UD_Ivunpckhps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1449 */ { UD_Iunpcklps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1450 */ { UD_Ivunpcklps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1451 */ { UD_Iunpcklpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1452 */ { UD_Ivunpcklpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1453 */ { UD_Iverr, O_Ew, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1454 */ { UD_Iverw, O_Ew, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1455 */ { UD_Ivmcall, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1456 */ { UD_Irdrand, O_R, O_NONE, O_NONE, O_NONE, P_oso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1457 */ { UD_Ivmclear, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1458 */ { UD_Ivmxon, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1459 */ { UD_Ivmptrld, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1460 */ { UD_Ivmptrst, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1461 */ { UD_Ivmlaunch, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1462 */ { UD_Ivmresume, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1463 */ { UD_Ivmxoff, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1464 */ { UD_Ivmread, O_Ey, O_Gy, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_def64 }, + /* 1465 */ { UD_Ivmwrite, O_Gy, O_Ey, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_def64 }, + /* 1466 */ { UD_Ivmrun, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1467 */ { UD_Ivmmcall, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1468 */ { UD_Ivmload, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1469 */ { UD_Ivmsave, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1470 */ { UD_Iwait, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1471 */ { UD_Iwbinvd, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1472 */ { UD_Iwrmsr, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1473 */ { UD_Ixadd, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_oso|P_rexr|P_rexx|P_rexb }, + /* 1474 */ { UD_Ixadd, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1475 */ { UD_Ixchg, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1476 */ { UD_Ixchg, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1477 */ { UD_Ixchg, O_R0v, O_rAX, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1478 */ { UD_Ixchg, O_R1v, O_rAX, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1479 */ { UD_Ixchg, O_R2v, O_rAX, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1480 */ { UD_Ixchg, O_R3v, O_rAX, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1481 */ { UD_Ixchg, O_R4v, O_rAX, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1482 */ { UD_Ixchg, O_R5v, O_rAX, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1483 */ { UD_Ixchg, O_R6v, O_rAX, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1484 */ { UD_Ixchg, O_R7v, O_rAX, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1485 */ { UD_Ixgetbv, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1486 */ { UD_Ixlatb, O_NONE, O_NONE, O_NONE, O_NONE, P_rexw|P_seg }, + /* 1487 */ { UD_Ixor, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1488 */ { UD_Ixor, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1489 */ { UD_Ixor, O_Gb, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1490 */ { UD_Ixor, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1491 */ { UD_Ixor, O_AL, O_Ib, O_NONE, O_NONE, P_none }, + /* 1492 */ { UD_Ixor, O_rAX, O_sIz, O_NONE, O_NONE, P_oso|P_rexw }, + /* 1493 */ { UD_Ixor, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1494 */ { UD_Ixor, O_Ev, O_sIz, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1495 */ { UD_Ixor, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_inv64 }, + /* 1496 */ { UD_Ixor, O_Ev, O_sIb, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1497 */ { UD_Ixorpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1498 */ { UD_Ivxorpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1499 */ { UD_Ixorps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1500 */ { UD_Ivxorps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1501 */ { UD_Ixcryptecb, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1502 */ { UD_Ixcryptcbc, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1503 */ { UD_Ixcryptctr, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1504 */ { UD_Ixcryptcfb, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1505 */ { UD_Ixcryptofb, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1506 */ { UD_Ixrstor, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1507 */ { UD_Ixsave, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1508 */ { UD_Ixsetbv, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1509 */ { UD_Ixsha1, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1510 */ { UD_Ixsha256, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1511 */ { UD_Ixstore, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1512 */ { UD_Ipclmulqdq, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1513 */ { UD_Ivpclmulqdq, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1514 */ { UD_Igetsec, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1515 */ { UD_Imovdqa, O_W, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1516 */ { UD_Ivmovdqa, O_Wx, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1517 */ { UD_Imovdqa, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1518 */ { UD_Ivmovdqa, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1519 */ { UD_Imaskmovdqu, O_V, O_U, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1520 */ { UD_Ivmaskmovdqu, O_Vx, O_Ux, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1521 */ { UD_Imovdq2q, O_P, O_U, O_NONE, O_NONE, P_aso|P_rexb }, + /* 1522 */ { UD_Imovdqu, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1523 */ { UD_Ivmovdqu, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1524 */ { UD_Imovdqu, O_W, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1525 */ { UD_Ivmovdqu, O_Wx, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1526 */ { UD_Imovq2dq, O_V, O_N, O_NONE, O_NONE, P_aso|P_rexr }, + /* 1527 */ { UD_Ipaddq, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1528 */ { UD_Ipaddq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1529 */ { UD_Ivpaddq, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1530 */ { UD_Ipsubq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1531 */ { UD_Ivpsubq, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1532 */ { UD_Ipsubq, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1533 */ { UD_Ipmuludq, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1534 */ { UD_Ipmuludq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1535 */ { UD_Ipshufhw, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1536 */ { UD_Ivpshufhw, O_Vx, O_Wx, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1537 */ { UD_Ipshuflw, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1538 */ { UD_Ivpshuflw, O_Vx, O_Wx, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1539 */ { UD_Ipshufd, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1540 */ { UD_Ivpshufd, O_Vx, O_Wx, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1541 */ { UD_Ipslldq, O_U, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 1542 */ { UD_Ivpslldq, O_Hx, O_Ux, O_Ib, O_NONE, P_rexb }, + /* 1543 */ { UD_Ipsrldq, O_U, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 1544 */ { UD_Ivpsrldq, O_Hx, O_Ux, O_Ib, O_NONE, P_rexb }, + /* 1545 */ { UD_Ipunpckhqdq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1546 */ { UD_Ivpunpckhqdq, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1547 */ { UD_Ipunpcklqdq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1548 */ { UD_Ivpunpcklqdq, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1549 */ { UD_Ihaddpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1550 */ { UD_Ivhaddpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1551 */ { UD_Ihaddps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1552 */ { UD_Ivhaddps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1553 */ { UD_Ihsubpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1554 */ { UD_Ivhsubpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1555 */ { UD_Ihsubps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1556 */ { UD_Ivhsubps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1557 */ { UD_Iinsertps, O_V, O_Md, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1558 */ { UD_Ivinsertps, O_Vx, O_Hx, O_Md, O_Ib, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1559 */ { UD_Ilddqu, O_V, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1560 */ { UD_Ivlddqu, O_Vx, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1561 */ { UD_Imovddup, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1562 */ { UD_Ivmovddup, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1563 */ { UD_Imovddup, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1564 */ { UD_Ivmovddup, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1565 */ { UD_Imovshdup, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1566 */ { UD_Ivmovshdup, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1567 */ { UD_Imovshdup, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1568 */ { UD_Ivmovshdup, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1569 */ { UD_Imovsldup, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1570 */ { UD_Ivmovsldup, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1571 */ { UD_Imovsldup, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1572 */ { UD_Ivmovsldup, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1573 */ { UD_Ipabsb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1574 */ { UD_Ipabsb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1575 */ { UD_Ivpabsb, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1576 */ { UD_Ipabsw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1577 */ { UD_Ipabsw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1578 */ { UD_Ivpabsw, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1579 */ { UD_Ipabsd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1580 */ { UD_Ipabsd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1581 */ { UD_Ivpabsd, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1582 */ { UD_Ipshufb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1583 */ { UD_Ipshufb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1584 */ { UD_Ivpshufb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1585 */ { UD_Iphaddw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1586 */ { UD_Iphaddw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1587 */ { UD_Ivphaddw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1588 */ { UD_Iphaddd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1589 */ { UD_Iphaddd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1590 */ { UD_Ivphaddd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1591 */ { UD_Iphaddsw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1592 */ { UD_Iphaddsw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1593 */ { UD_Ivphaddsw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1594 */ { UD_Ipmaddubsw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1595 */ { UD_Ipmaddubsw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1596 */ { UD_Ivpmaddubsw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1597 */ { UD_Iphsubw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1598 */ { UD_Iphsubw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1599 */ { UD_Ivphsubw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1600 */ { UD_Iphsubd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1601 */ { UD_Iphsubd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1602 */ { UD_Ivphsubd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1603 */ { UD_Iphsubsw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1604 */ { UD_Iphsubsw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1605 */ { UD_Ivphsubsw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1606 */ { UD_Ipsignb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1607 */ { UD_Ipsignb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1608 */ { UD_Ivpsignb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1609 */ { UD_Ipsignd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1610 */ { UD_Ipsignd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1611 */ { UD_Ivpsignd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1612 */ { UD_Ipsignw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1613 */ { UD_Ipsignw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1614 */ { UD_Ivpsignw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1615 */ { UD_Ipmulhrsw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1616 */ { UD_Ipmulhrsw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1617 */ { UD_Ivpmulhrsw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1618 */ { UD_Ipalignr, O_P, O_Q, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1619 */ { UD_Ipalignr, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1620 */ { UD_Ivpalignr, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1621 */ { UD_Ipblendvb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1622 */ { UD_Ipmuldq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1623 */ { UD_Ivpmuldq, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1624 */ { UD_Ipminsb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1625 */ { UD_Ivpminsb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1626 */ { UD_Ipminsd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1627 */ { UD_Ivpminsd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1628 */ { UD_Ipminuw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1629 */ { UD_Ivpminuw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1630 */ { UD_Ipminud, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1631 */ { UD_Ivpminud, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1632 */ { UD_Ipmaxsb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1633 */ { UD_Ivpmaxsb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1634 */ { UD_Ipmaxsd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1635 */ { UD_Ivpmaxsd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1636 */ { UD_Ipmaxud, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1637 */ { UD_Ivpmaxud, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1638 */ { UD_Ipmaxuw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1639 */ { UD_Ivpmaxuw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1640 */ { UD_Ipmulld, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1641 */ { UD_Ivpmulld, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1642 */ { UD_Iphminposuw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1643 */ { UD_Ivphminposuw, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1644 */ { UD_Iroundps, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1645 */ { UD_Ivroundps, O_Vx, O_Wx, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1646 */ { UD_Iroundpd, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1647 */ { UD_Ivroundpd, O_Vx, O_Wx, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1648 */ { UD_Iroundss, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1649 */ { UD_Ivroundss, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1650 */ { UD_Iroundsd, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1651 */ { UD_Ivroundsd, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1652 */ { UD_Iblendpd, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1653 */ { UD_Ivblendpd, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1654 */ { UD_Iblendps, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1655 */ { UD_Ivblendps, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1656 */ { UD_Iblendvpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1657 */ { UD_Iblendvps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1658 */ { UD_Ibound, O_Gv, O_M, O_NONE, O_NONE, P_aso|P_oso }, + /* 1659 */ { UD_Ibsf, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1660 */ { UD_Ibsr, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1661 */ { UD_Ibswap, O_R0y, O_NONE, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1662 */ { UD_Ibswap, O_R1y, O_NONE, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1663 */ { UD_Ibswap, O_R2y, O_NONE, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1664 */ { UD_Ibswap, O_R3y, O_NONE, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1665 */ { UD_Ibswap, O_R4y, O_NONE, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1666 */ { UD_Ibswap, O_R5y, O_NONE, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1667 */ { UD_Ibswap, O_R6y, O_NONE, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1668 */ { UD_Ibswap, O_R7y, O_NONE, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1669 */ { UD_Ibt, O_Ev, O_Ib, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1670 */ { UD_Ibt, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1671 */ { UD_Ibtc, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1672 */ { UD_Ibtc, O_Ev, O_Ib, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1673 */ { UD_Ibtr, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1674 */ { UD_Ibtr, O_Ev, O_Ib, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1675 */ { UD_Ibts, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1676 */ { UD_Ibts, O_Ev, O_Ib, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1677 */ { UD_Ipblendw, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1678 */ { UD_Ivpblendw, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1679 */ { UD_Impsadbw, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1680 */ { UD_Ivmpsadbw, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1681 */ { UD_Imovntdqa, O_V, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1682 */ { UD_Ivmovntdqa, O_Vx, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb|P_vexl }, + /* 1683 */ { UD_Ipackusdw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1684 */ { UD_Ivpackusdw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb|P_vexl }, + /* 1685 */ { UD_Ipmovsxbw, O_V, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1686 */ { UD_Ivpmovsxbw, O_Vx, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1687 */ { UD_Ipmovsxbd, O_V, O_MdU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1688 */ { UD_Ivpmovsxbd, O_Vx, O_MdU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1689 */ { UD_Ipmovsxbq, O_V, O_MwU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1690 */ { UD_Ivpmovsxbq, O_Vx, O_MwU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1691 */ { UD_Ipmovsxwd, O_V, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1692 */ { UD_Ivpmovsxwd, O_Vx, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1693 */ { UD_Ipmovsxwq, O_V, O_MdU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1694 */ { UD_Ivpmovsxwq, O_Vx, O_MdU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1695 */ { UD_Ipmovsxdq, O_V, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1696 */ { UD_Ipmovzxbw, O_V, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1697 */ { UD_Ivpmovzxbw, O_Vx, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1698 */ { UD_Ipmovzxbd, O_V, O_MdU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1699 */ { UD_Ivpmovzxbd, O_Vx, O_MdU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1700 */ { UD_Ipmovzxbq, O_V, O_MwU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1701 */ { UD_Ivpmovzxbq, O_Vx, O_MwU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1702 */ { UD_Ipmovzxwd, O_V, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1703 */ { UD_Ivpmovzxwd, O_Vx, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1704 */ { UD_Ipmovzxwq, O_V, O_MdU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1705 */ { UD_Ivpmovzxwq, O_Vx, O_MdU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1706 */ { UD_Ipmovzxdq, O_V, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1707 */ { UD_Ivpmovzxdq, O_Vx, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1708 */ { UD_Ipcmpeqq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1709 */ { UD_Ivpcmpeqq, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1710 */ { UD_Ipopcnt, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1711 */ { UD_Iptest, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1712 */ { UD_Ivptest, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb|P_vexl }, + /* 1713 */ { UD_Ipcmpestri, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1714 */ { UD_Ivpcmpestri, O_Vx, O_Wx, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1715 */ { UD_Ipcmpestrm, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1716 */ { UD_Ivpcmpestrm, O_Vx, O_Wx, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1717 */ { UD_Ipcmpgtq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1718 */ { UD_Ivpcmpgtq, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1719 */ { UD_Ipcmpistri, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1720 */ { UD_Ivpcmpistri, O_Vx, O_Wx, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1721 */ { UD_Ipcmpistrm, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1722 */ { UD_Ivpcmpistrm, O_Vx, O_Wx, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1723 */ { UD_Imovbe, O_Gv, O_Mv, O_NONE, O_NONE, P_aso|P_oso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1724 */ { UD_Imovbe, O_Mv, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1725 */ { UD_Icrc32, O_Gy, O_Eb, O_NONE, O_NONE, P_aso|P_oso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1726 */ { UD_Icrc32, O_Gy, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1727 */ { UD_Ivbroadcastss, O_V, O_Md, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1728 */ { UD_Ivbroadcastsd, O_Vqq, O_Mq, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1729 */ { UD_Ivextractf128, O_Wdq, O_Vqq, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1730 */ { UD_Ivinsertf128, O_Vqq, O_Hqq, O_Wdq, O_Ib, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1731 */ { UD_Ivmaskmovps, O_V, O_H, O_M, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1732 */ { UD_Ivmaskmovps, O_M, O_H, O_V, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1733 */ { UD_Ivmaskmovpd, O_V, O_H, O_M, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1734 */ { UD_Ivmaskmovpd, O_M, O_H, O_V, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1735 */ { UD_Ivpermilpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1736 */ { UD_Ivpermilpd, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1737 */ { UD_Ivpermilps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1738 */ { UD_Ivpermilps, O_Vx, O_Wx, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1739 */ { UD_Ivperm2f128, O_Vqq, O_Hqq, O_Wqq, O_Ib, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1740 */ { UD_Ivtestps, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1741 */ { UD_Ivtestpd, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1742 */ { UD_Ivzeroupper, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1743 */ { UD_Ivzeroall, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1744 */ { UD_Ivblendvpd, O_Vx, O_Hx, O_Wx, O_Lx, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1745 */ { UD_Ivblendvps, O_Vx, O_Hx, O_Wx, O_Lx, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1746 */ { UD_Ivmovsd, O_V, O_H, O_U, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1747 */ { UD_Ivmovsd, O_V, O_Mq, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1748 */ { UD_Ivmovsd, O_U, O_H, O_V, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1749 */ { UD_Ivmovsd, O_Mq, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1750 */ { UD_Ivmovss, O_V, O_H, O_U, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1751 */ { UD_Ivmovss, O_V, O_Md, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1752 */ { UD_Ivmovss, O_U, O_H, O_V, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1753 */ { UD_Ivmovss, O_Md, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1754 */ { UD_Ivpblendvb, O_V, O_H, O_W, O_L, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1755 */ { UD_Ivpsllw, O_V, O_H, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1756 */ { UD_Ivpsllw, O_H, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1757 */ { UD_Ivpslld, O_V, O_H, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1758 */ { UD_Ivpslld, O_H, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1759 */ { UD_Ivpsllq, O_V, O_H, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1760 */ { UD_Ivpsllq, O_H, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, +}; + + +const char* ud_mnemonics_str[] = { + "aaa", + "aad", + "aam", + "aas", + "adc", + "add", + "addpd", + "addps", + "addsd", + "addss", + "addsubpd", + "addsubps", + "aesdec", + "aesdeclast", + "aesenc", + "aesenclast", + "aesimc", + "aeskeygenassist", + "and", + "andnpd", + "andnps", + "andpd", + "andps", + "arpl", + "blendpd", + "blendps", + "blendvpd", + "blendvps", + "bound", + "bsf", + "bsr", + "bswap", + "bt", + "btc", + "btr", + "bts", + "call", + "cbw", + "cdq", + "cdqe", + "clc", + "cld", + "clflush", + "clgi", + "cli", + "clts", + "cmc", + "cmova", + "cmovae", + "cmovb", + "cmovbe", + "cmovg", + "cmovge", + "cmovl", + "cmovle", + "cmovno", + "cmovnp", + "cmovns", + "cmovnz", + "cmovo", + "cmovp", + "cmovs", + "cmovz", + "cmp", + "cmppd", + "cmpps", + "cmpsb", + "cmpsd", + "cmpsq", + "cmpss", + "cmpsw", + "cmpxchg", + "cmpxchg16b", + "cmpxchg8b", + "comisd", + "comiss", + "cpuid", + "cqo", + "crc32", + "cvtdq2pd", + "cvtdq2ps", + "cvtpd2dq", + "cvtpd2pi", + "cvtpd2ps", + "cvtpi2pd", + "cvtpi2ps", + "cvtps2dq", + "cvtps2pd", + "cvtps2pi", + "cvtsd2si", + "cvtsd2ss", + "cvtsi2sd", + "cvtsi2ss", + "cvtss2sd", + "cvtss2si", + "cvttpd2dq", + "cvttpd2pi", + "cvttps2dq", + "cvttps2pi", + "cvttsd2si", + "cvttss2si", + "cwd", + "cwde", + "daa", + "das", + "dec", + "div", + "divpd", + "divps", + "divsd", + "divss", + "dppd", + "dpps", + "emms", + "enter", + "extractps", + "f2xm1", + "fabs", + "fadd", + "faddp", + "fbld", + "fbstp", + "fchs", + "fclex", + "fcmovb", + "fcmovbe", + "fcmove", + "fcmovnb", + "fcmovnbe", + "fcmovne", + "fcmovnu", + "fcmovu", + "fcom", + "fcom2", + "fcomi", + "fcomip", + "fcomp", + "fcomp3", + "fcomp5", + "fcompp", + "fcos", + "fdecstp", + "fdiv", + "fdivp", + "fdivr", + "fdivrp", + "femms", + "ffree", + "ffreep", + "fiadd", + "ficom", + "ficomp", + "fidiv", + "fidivr", + "fild", + "fimul", + "fincstp", + "fist", + "fistp", + "fisttp", + "fisub", + "fisubr", + "fld", + "fld1", + "fldcw", + "fldenv", + "fldl2e", + "fldl2t", + "fldlg2", + "fldln2", + "fldpi", + "fldz", + "fmul", + "fmulp", + "fndisi", + "fneni", + "fninit", + "fnop", + "fnsave", + "fnsetpm", + "fnstcw", + "fnstenv", + "fnstsw", + "fpatan", + "fprem", + "fprem1", + "fptan", + "frndint", + "frstor", + "frstpm", + "fscale", + "fsin", + "fsincos", + "fsqrt", + "fst", + "fstp", + "fstp1", + "fstp8", + "fstp9", + "fsub", + "fsubp", + "fsubr", + "fsubrp", + "ftst", + "fucom", + "fucomi", + "fucomip", + "fucomp", + "fucompp", + "fxam", + "fxch", + "fxch4", + "fxch7", + "fxrstor", + "fxsave", + "fxtract", + "fyl2x", + "fyl2xp1", + "getsec", + "haddpd", + "haddps", + "hlt", + "hsubpd", + "hsubps", + "idiv", + "imul", + "in", + "inc", + "insb", + "insd", + "insertps", + "insw", + "int", + "int1", + "int3", + "into", + "invd", + "invept", + "invlpg", + "invlpga", + "invvpid", + "iretd", + "iretq", + "iretw", + "ja", + "jae", + "jb", + "jbe", + "jcxz", + "jecxz", + "jg", + "jge", + "jl", + "jle", + "jmp", + "jno", + "jnp", + "jns", + "jnz", + "jo", + "jp", + "jrcxz", + "js", + "jz", + "lahf", + "lar", + "lddqu", + "ldmxcsr", + "lds", + "lea", + "leave", + "les", + "lfence", + "lfs", + "lgdt", + "lgs", + "lidt", + "lldt", + "lmsw", + "lock", + "lodsb", + "lodsd", + "lodsq", + "lodsw", + "loop", + "loope", + "loopne", + "lsl", + "lss", + "ltr", + "maskmovdqu", + "maskmovq", + "maxpd", + "maxps", + "maxsd", + "maxss", + "mfence", + "minpd", + "minps", + "minsd", + "minss", + "monitor", + "montmul", + "mov", + "movapd", + "movaps", + "movbe", + "movd", + "movddup", + "movdq2q", + "movdqa", + "movdqu", + "movhlps", + "movhpd", + "movhps", + "movlhps", + "movlpd", + "movlps", + "movmskpd", + "movmskps", + "movntdq", + "movntdqa", + "movnti", + "movntpd", + "movntps", + "movntq", + "movq", + "movq2dq", + "movsb", + "movsd", + "movshdup", + "movsldup", + "movsq", + "movss", + "movsw", + "movsx", + "movsxd", + "movupd", + "movups", + "movzx", + "mpsadbw", + "mul", + "mulpd", + "mulps", + "mulsd", + "mulss", + "mwait", + "neg", + "nop", + "not", + "or", + "orpd", + "orps", + "out", + "outsb", + "outsd", + "outsw", + "pabsb", + "pabsd", + "pabsw", + "packssdw", + "packsswb", + "packusdw", + "packuswb", + "paddb", + "paddd", + "paddq", + "paddsb", + "paddsw", + "paddusb", + "paddusw", + "paddw", + "palignr", + "pand", + "pandn", + "pavgb", + "pavgusb", + "pavgw", + "pblendvb", + "pblendw", + "pclmulqdq", + "pcmpeqb", + "pcmpeqd", + "pcmpeqq", + "pcmpeqw", + "pcmpestri", + "pcmpestrm", + "pcmpgtb", + "pcmpgtd", + "pcmpgtq", + "pcmpgtw", + "pcmpistri", + "pcmpistrm", + "pextrb", + "pextrd", + "pextrq", + "pextrw", + "pf2id", + "pf2iw", + "pfacc", + "pfadd", + "pfcmpeq", + "pfcmpge", + "pfcmpgt", + "pfmax", + "pfmin", + "pfmul", + "pfnacc", + "pfpnacc", + "pfrcp", + "pfrcpit1", + "pfrcpit2", + "pfrsqit1", + "pfrsqrt", + "pfsub", + "pfsubr", + "phaddd", + "phaddsw", + "phaddw", + "phminposuw", + "phsubd", + "phsubsw", + "phsubw", + "pi2fd", + "pi2fw", + "pinsrb", + "pinsrd", + "pinsrq", + "pinsrw", + "pmaddubsw", + "pmaddwd", + "pmaxsb", + "pmaxsd", + "pmaxsw", + "pmaxub", + "pmaxud", + "pmaxuw", + "pminsb", + "pminsd", + "pminsw", + "pminub", + "pminud", + "pminuw", + "pmovmskb", + "pmovsxbd", + "pmovsxbq", + "pmovsxbw", + "pmovsxdq", + "pmovsxwd", + "pmovsxwq", + "pmovzxbd", + "pmovzxbq", + "pmovzxbw", + "pmovzxdq", + "pmovzxwd", + "pmovzxwq", + "pmuldq", + "pmulhrsw", + "pmulhrw", + "pmulhuw", + "pmulhw", + "pmulld", + "pmullw", + "pmuludq", + "pop", + "popa", + "popad", + "popcnt", + "popfd", + "popfq", + "popfw", + "por", + "prefetch", + "prefetchnta", + "prefetcht0", + "prefetcht1", + "prefetcht2", + "psadbw", + "pshufb", + "pshufd", + "pshufhw", + "pshuflw", + "pshufw", + "psignb", + "psignd", + "psignw", + "pslld", + "pslldq", + "psllq", + "psllw", + "psrad", + "psraw", + "psrld", + "psrldq", + "psrlq", + "psrlw", + "psubb", + "psubd", + "psubq", + "psubsb", + "psubsw", + "psubusb", + "psubusw", + "psubw", + "pswapd", + "ptest", + "punpckhbw", + "punpckhdq", + "punpckhqdq", + "punpckhwd", + "punpcklbw", + "punpckldq", + "punpcklqdq", + "punpcklwd", + "push", + "pusha", + "pushad", + "pushfd", + "pushfq", + "pushfw", + "pxor", + "rcl", + "rcpps", + "rcpss", + "rcr", + "rdmsr", + "rdpmc", + "rdrand", + "rdtsc", + "rdtscp", + "rep", + "repne", + "ret", + "retf", + "rol", + "ror", + "roundpd", + "roundps", + "roundsd", + "roundss", + "rsm", + "rsqrtps", + "rsqrtss", + "sahf", + "salc", + "sar", + "sbb", + "scasb", + "scasd", + "scasq", + "scasw", + "seta", + "setae", + "setb", + "setbe", + "setg", + "setge", + "setl", + "setle", + "setno", + "setnp", + "setns", + "setnz", + "seto", + "setp", + "sets", + "setz", + "sfence", + "sgdt", + "shl", + "shld", + "shr", + "shrd", + "shufpd", + "shufps", + "sidt", + "skinit", + "sldt", + "smsw", + "sqrtpd", + "sqrtps", + "sqrtsd", + "sqrtss", + "stc", + "std", + "stgi", + "sti", + "stmxcsr", + "stosb", + "stosd", + "stosq", + "stosw", + "str", + "sub", + "subpd", + "subps", + "subsd", + "subss", + "swapgs", + "syscall", + "sysenter", + "sysexit", + "sysret", + "test", + "ucomisd", + "ucomiss", + "ud2", + "unpckhpd", + "unpckhps", + "unpcklpd", + "unpcklps", + "vaddpd", + "vaddps", + "vaddsd", + "vaddss", + "vaddsubpd", + "vaddsubps", + "vaesdec", + "vaesdeclast", + "vaesenc", + "vaesenclast", + "vaesimc", + "vaeskeygenassist", + "vandnpd", + "vandnps", + "vandpd", + "vandps", + "vblendpd", + "vblendps", + "vblendvpd", + "vblendvps", + "vbroadcastsd", + "vbroadcastss", + "vcmppd", + "vcmpps", + "vcmpsd", + "vcmpss", + "vcomisd", + "vcomiss", + "vcvtdq2pd", + "vcvtdq2ps", + "vcvtpd2dq", + "vcvtpd2ps", + "vcvtps2dq", + "vcvtps2pd", + "vcvtsd2si", + "vcvtsd2ss", + "vcvtsi2sd", + "vcvtsi2ss", + "vcvtss2sd", + "vcvtss2si", + "vcvttpd2dq", + "vcvttps2dq", + "vcvttsd2si", + "vcvttss2si", + "vdivpd", + "vdivps", + "vdivsd", + "vdivss", + "vdppd", + "vdpps", + "verr", + "verw", + "vextractf128", + "vextractps", + "vhaddpd", + "vhaddps", + "vhsubpd", + "vhsubps", + "vinsertf128", + "vinsertps", + "vlddqu", + "vmaskmovdqu", + "vmaskmovpd", + "vmaskmovps", + "vmaxpd", + "vmaxps", + "vmaxsd", + "vmaxss", + "vmcall", + "vmclear", + "vminpd", + "vminps", + "vminsd", + "vminss", + "vmlaunch", + "vmload", + "vmmcall", + "vmovapd", + "vmovaps", + "vmovd", + "vmovddup", + "vmovdqa", + "vmovdqu", + "vmovhlps", + "vmovhpd", + "vmovhps", + "vmovlhps", + "vmovlpd", + "vmovlps", + "vmovmskpd", + "vmovmskps", + "vmovntdq", + "vmovntdqa", + "vmovntpd", + "vmovntps", + "vmovq", + "vmovsd", + "vmovshdup", + "vmovsldup", + "vmovss", + "vmovupd", + "vmovups", + "vmpsadbw", + "vmptrld", + "vmptrst", + "vmread", + "vmresume", + "vmrun", + "vmsave", + "vmulpd", + "vmulps", + "vmulsd", + "vmulss", + "vmwrite", + "vmxoff", + "vmxon", + "vorpd", + "vorps", + "vpabsb", + "vpabsd", + "vpabsw", + "vpackssdw", + "vpacksswb", + "vpackusdw", + "vpackuswb", + "vpaddb", + "vpaddd", + "vpaddq", + "vpaddsb", + "vpaddsw", + "vpaddusb", + "vpaddusw", + "vpaddw", + "vpalignr", + "vpand", + "vpandn", + "vpavgb", + "vpavgw", + "vpblendvb", + "vpblendw", + "vpclmulqdq", + "vpcmpeqb", + "vpcmpeqd", + "vpcmpeqq", + "vpcmpeqw", + "vpcmpestri", + "vpcmpestrm", + "vpcmpgtb", + "vpcmpgtd", + "vpcmpgtq", + "vpcmpgtw", + "vpcmpistri", + "vpcmpistrm", + "vperm2f128", + "vpermilpd", + "vpermilps", + "vpextrb", + "vpextrd", + "vpextrq", + "vpextrw", + "vphaddd", + "vphaddsw", + "vphaddw", + "vphminposuw", + "vphsubd", + "vphsubsw", + "vphsubw", + "vpinsrb", + "vpinsrd", + "vpinsrq", + "vpinsrw", + "vpmaddubsw", + "vpmaddwd", + "vpmaxsb", + "vpmaxsd", + "vpmaxsw", + "vpmaxub", + "vpmaxud", + "vpmaxuw", + "vpminsb", + "vpminsd", + "vpminsw", + "vpminub", + "vpminud", + "vpminuw", + "vpmovmskb", + "vpmovsxbd", + "vpmovsxbq", + "vpmovsxbw", + "vpmovsxwd", + "vpmovsxwq", + "vpmovzxbd", + "vpmovzxbq", + "vpmovzxbw", + "vpmovzxdq", + "vpmovzxwd", + "vpmovzxwq", + "vpmuldq", + "vpmulhrsw", + "vpmulhuw", + "vpmulhw", + "vpmulld", + "vpmullw", + "vpor", + "vpsadbw", + "vpshufb", + "vpshufd", + "vpshufhw", + "vpshuflw", + "vpsignb", + "vpsignd", + "vpsignw", + "vpslld", + "vpslldq", + "vpsllq", + "vpsllw", + "vpsrad", + "vpsraw", + "vpsrld", + "vpsrldq", + "vpsrlq", + "vpsrlw", + "vpsubb", + "vpsubd", + "vpsubq", + "vpsubsb", + "vpsubsw", + "vpsubusb", + "vpsubusw", + "vpsubw", + "vptest", + "vpunpckhbw", + "vpunpckhdq", + "vpunpckhqdq", + "vpunpckhwd", + "vpunpcklbw", + "vpunpckldq", + "vpunpcklqdq", + "vpunpcklwd", + "vpxor", + "vrcpps", + "vrcpss", + "vroundpd", + "vroundps", + "vroundsd", + "vroundss", + "vrsqrtps", + "vrsqrtss", + "vshufpd", + "vshufps", + "vsqrtpd", + "vsqrtps", + "vsqrtsd", + "vsqrtss", + "vstmxcsr", + "vsubpd", + "vsubps", + "vsubsd", + "vsubss", + "vtestpd", + "vtestps", + "vucomisd", + "vucomiss", + "vunpckhpd", + "vunpckhps", + "vunpcklpd", + "vunpcklps", + "vxorpd", + "vxorps", + "vzeroall", + "vzeroupper", + "wait", + "wbinvd", + "wrmsr", + "xadd", + "xchg", + "xcryptcbc", + "xcryptcfb", + "xcryptctr", + "xcryptecb", + "xcryptofb", + "xgetbv", + "xlatb", + "xor", + "xorpd", + "xorps", + "xrstor", + "xsave", + "xsetbv", + "xsha1", + "xsha256", + "xstore", + "invalid", + "3dnow", + "none", + "db", + "pause" +}; diff --git a/deps/udis86/libudis86/itab.h b/deps/udis86/libudis86/itab.h new file mode 100644 index 0000000..3d54c43 --- /dev/null +++ b/deps/udis86/libudis86/itab.h @@ -0,0 +1,939 @@ +#ifndef UD_ITAB_H +#define UD_ITAB_H + +/* itab.h -- generated by udis86:scripts/ud_itab.py, do no edit */ + +/* ud_table_type -- lookup table types (see decode.c) */ +enum ud_table_type { + UD_TAB__OPC_VEX, + UD_TAB__OPC_TABLE, + UD_TAB__OPC_X87, + UD_TAB__OPC_MOD, + UD_TAB__OPC_RM, + UD_TAB__OPC_OSIZE, + UD_TAB__OPC_MODE, + UD_TAB__OPC_VEX_L, + UD_TAB__OPC_3DNOW, + UD_TAB__OPC_REG, + UD_TAB__OPC_ASIZE, + UD_TAB__OPC_VEX_W, + UD_TAB__OPC_SSE, + UD_TAB__OPC_VENDOR +}; + +/* ud_mnemonic -- mnemonic constants */ +enum ud_mnemonic_code { + UD_Iaaa, + UD_Iaad, + UD_Iaam, + UD_Iaas, + UD_Iadc, + UD_Iadd, + UD_Iaddpd, + UD_Iaddps, + UD_Iaddsd, + UD_Iaddss, + UD_Iaddsubpd, + UD_Iaddsubps, + UD_Iaesdec, + UD_Iaesdeclast, + UD_Iaesenc, + UD_Iaesenclast, + UD_Iaesimc, + UD_Iaeskeygenassist, + UD_Iand, + UD_Iandnpd, + UD_Iandnps, + UD_Iandpd, + UD_Iandps, + UD_Iarpl, + UD_Iblendpd, + UD_Iblendps, + UD_Iblendvpd, + UD_Iblendvps, + UD_Ibound, + UD_Ibsf, + UD_Ibsr, + UD_Ibswap, + UD_Ibt, + UD_Ibtc, + UD_Ibtr, + UD_Ibts, + UD_Icall, + UD_Icbw, + UD_Icdq, + UD_Icdqe, + UD_Iclc, + UD_Icld, + UD_Iclflush, + UD_Iclgi, + UD_Icli, + UD_Iclts, + UD_Icmc, + UD_Icmova, + UD_Icmovae, + UD_Icmovb, + UD_Icmovbe, + UD_Icmovg, + UD_Icmovge, + UD_Icmovl, + UD_Icmovle, + UD_Icmovno, + UD_Icmovnp, + UD_Icmovns, + UD_Icmovnz, + UD_Icmovo, + UD_Icmovp, + UD_Icmovs, + UD_Icmovz, + UD_Icmp, + UD_Icmppd, + UD_Icmpps, + UD_Icmpsb, + UD_Icmpsd, + UD_Icmpsq, + UD_Icmpss, + UD_Icmpsw, + UD_Icmpxchg, + UD_Icmpxchg16b, + UD_Icmpxchg8b, + UD_Icomisd, + UD_Icomiss, + UD_Icpuid, + UD_Icqo, + UD_Icrc32, + UD_Icvtdq2pd, + UD_Icvtdq2ps, + UD_Icvtpd2dq, + UD_Icvtpd2pi, + UD_Icvtpd2ps, + UD_Icvtpi2pd, + UD_Icvtpi2ps, + UD_Icvtps2dq, + UD_Icvtps2pd, + UD_Icvtps2pi, + UD_Icvtsd2si, + UD_Icvtsd2ss, + UD_Icvtsi2sd, + UD_Icvtsi2ss, + UD_Icvtss2sd, + UD_Icvtss2si, + UD_Icvttpd2dq, + UD_Icvttpd2pi, + UD_Icvttps2dq, + UD_Icvttps2pi, + UD_Icvttsd2si, + UD_Icvttss2si, + UD_Icwd, + UD_Icwde, + UD_Idaa, + UD_Idas, + UD_Idec, + UD_Idiv, + UD_Idivpd, + UD_Idivps, + UD_Idivsd, + UD_Idivss, + UD_Idppd, + UD_Idpps, + UD_Iemms, + UD_Ienter, + UD_Iextractps, + UD_If2xm1, + UD_Ifabs, + UD_Ifadd, + UD_Ifaddp, + UD_Ifbld, + UD_Ifbstp, + UD_Ifchs, + UD_Ifclex, + UD_Ifcmovb, + UD_Ifcmovbe, + UD_Ifcmove, + UD_Ifcmovnb, + UD_Ifcmovnbe, + UD_Ifcmovne, + UD_Ifcmovnu, + UD_Ifcmovu, + UD_Ifcom, + UD_Ifcom2, + UD_Ifcomi, + UD_Ifcomip, + UD_Ifcomp, + UD_Ifcomp3, + UD_Ifcomp5, + UD_Ifcompp, + UD_Ifcos, + UD_Ifdecstp, + UD_Ifdiv, + UD_Ifdivp, + UD_Ifdivr, + UD_Ifdivrp, + UD_Ifemms, + UD_Iffree, + UD_Iffreep, + UD_Ifiadd, + UD_Ificom, + UD_Ificomp, + UD_Ifidiv, + UD_Ifidivr, + UD_Ifild, + UD_Ifimul, + UD_Ifincstp, + UD_Ifist, + UD_Ifistp, + UD_Ifisttp, + UD_Ifisub, + UD_Ifisubr, + UD_Ifld, + UD_Ifld1, + UD_Ifldcw, + UD_Ifldenv, + UD_Ifldl2e, + UD_Ifldl2t, + UD_Ifldlg2, + UD_Ifldln2, + UD_Ifldpi, + UD_Ifldz, + UD_Ifmul, + UD_Ifmulp, + UD_Ifndisi, + UD_Ifneni, + UD_Ifninit, + UD_Ifnop, + UD_Ifnsave, + UD_Ifnsetpm, + UD_Ifnstcw, + UD_Ifnstenv, + UD_Ifnstsw, + UD_Ifpatan, + UD_Ifprem, + UD_Ifprem1, + UD_Ifptan, + UD_Ifrndint, + UD_Ifrstor, + UD_Ifrstpm, + UD_Ifscale, + UD_Ifsin, + UD_Ifsincos, + UD_Ifsqrt, + UD_Ifst, + UD_Ifstp, + UD_Ifstp1, + UD_Ifstp8, + UD_Ifstp9, + UD_Ifsub, + UD_Ifsubp, + UD_Ifsubr, + UD_Ifsubrp, + UD_Iftst, + UD_Ifucom, + UD_Ifucomi, + UD_Ifucomip, + UD_Ifucomp, + UD_Ifucompp, + UD_Ifxam, + UD_Ifxch, + UD_Ifxch4, + UD_Ifxch7, + UD_Ifxrstor, + UD_Ifxsave, + UD_Ifxtract, + UD_Ifyl2x, + UD_Ifyl2xp1, + UD_Igetsec, + UD_Ihaddpd, + UD_Ihaddps, + UD_Ihlt, + UD_Ihsubpd, + UD_Ihsubps, + UD_Iidiv, + UD_Iimul, + UD_Iin, + UD_Iinc, + UD_Iinsb, + UD_Iinsd, + UD_Iinsertps, + UD_Iinsw, + UD_Iint, + UD_Iint1, + UD_Iint3, + UD_Iinto, + UD_Iinvd, + UD_Iinvept, + UD_Iinvlpg, + UD_Iinvlpga, + UD_Iinvvpid, + UD_Iiretd, + UD_Iiretq, + UD_Iiretw, + UD_Ija, + UD_Ijae, + UD_Ijb, + UD_Ijbe, + UD_Ijcxz, + UD_Ijecxz, + UD_Ijg, + UD_Ijge, + UD_Ijl, + UD_Ijle, + UD_Ijmp, + UD_Ijno, + UD_Ijnp, + UD_Ijns, + UD_Ijnz, + UD_Ijo, + UD_Ijp, + UD_Ijrcxz, + UD_Ijs, + UD_Ijz, + UD_Ilahf, + UD_Ilar, + UD_Ilddqu, + UD_Ildmxcsr, + UD_Ilds, + UD_Ilea, + UD_Ileave, + UD_Iles, + UD_Ilfence, + UD_Ilfs, + UD_Ilgdt, + UD_Ilgs, + UD_Ilidt, + UD_Illdt, + UD_Ilmsw, + UD_Ilock, + UD_Ilodsb, + UD_Ilodsd, + UD_Ilodsq, + UD_Ilodsw, + UD_Iloop, + UD_Iloope, + UD_Iloopne, + UD_Ilsl, + UD_Ilss, + UD_Iltr, + UD_Imaskmovdqu, + UD_Imaskmovq, + UD_Imaxpd, + UD_Imaxps, + UD_Imaxsd, + UD_Imaxss, + UD_Imfence, + UD_Iminpd, + UD_Iminps, + UD_Iminsd, + UD_Iminss, + UD_Imonitor, + UD_Imontmul, + UD_Imov, + UD_Imovapd, + UD_Imovaps, + UD_Imovbe, + UD_Imovd, + UD_Imovddup, + UD_Imovdq2q, + UD_Imovdqa, + UD_Imovdqu, + UD_Imovhlps, + UD_Imovhpd, + UD_Imovhps, + UD_Imovlhps, + UD_Imovlpd, + UD_Imovlps, + UD_Imovmskpd, + UD_Imovmskps, + UD_Imovntdq, + UD_Imovntdqa, + UD_Imovnti, + UD_Imovntpd, + UD_Imovntps, + UD_Imovntq, + UD_Imovq, + UD_Imovq2dq, + UD_Imovsb, + UD_Imovsd, + UD_Imovshdup, + UD_Imovsldup, + UD_Imovsq, + UD_Imovss, + UD_Imovsw, + UD_Imovsx, + UD_Imovsxd, + UD_Imovupd, + UD_Imovups, + UD_Imovzx, + UD_Impsadbw, + UD_Imul, + UD_Imulpd, + UD_Imulps, + UD_Imulsd, + UD_Imulss, + UD_Imwait, + UD_Ineg, + UD_Inop, + UD_Inot, + UD_Ior, + UD_Iorpd, + UD_Iorps, + UD_Iout, + UD_Ioutsb, + UD_Ioutsd, + UD_Ioutsw, + UD_Ipabsb, + UD_Ipabsd, + UD_Ipabsw, + UD_Ipackssdw, + UD_Ipacksswb, + UD_Ipackusdw, + UD_Ipackuswb, + UD_Ipaddb, + UD_Ipaddd, + UD_Ipaddq, + UD_Ipaddsb, + UD_Ipaddsw, + UD_Ipaddusb, + UD_Ipaddusw, + UD_Ipaddw, + UD_Ipalignr, + UD_Ipand, + UD_Ipandn, + UD_Ipavgb, + UD_Ipavgusb, + UD_Ipavgw, + UD_Ipblendvb, + UD_Ipblendw, + UD_Ipclmulqdq, + UD_Ipcmpeqb, + UD_Ipcmpeqd, + UD_Ipcmpeqq, + UD_Ipcmpeqw, + UD_Ipcmpestri, + UD_Ipcmpestrm, + UD_Ipcmpgtb, + UD_Ipcmpgtd, + UD_Ipcmpgtq, + UD_Ipcmpgtw, + UD_Ipcmpistri, + UD_Ipcmpistrm, + UD_Ipextrb, + UD_Ipextrd, + UD_Ipextrq, + UD_Ipextrw, + UD_Ipf2id, + UD_Ipf2iw, + UD_Ipfacc, + UD_Ipfadd, + UD_Ipfcmpeq, + UD_Ipfcmpge, + UD_Ipfcmpgt, + UD_Ipfmax, + UD_Ipfmin, + UD_Ipfmul, + UD_Ipfnacc, + UD_Ipfpnacc, + UD_Ipfrcp, + UD_Ipfrcpit1, + UD_Ipfrcpit2, + UD_Ipfrsqit1, + UD_Ipfrsqrt, + UD_Ipfsub, + UD_Ipfsubr, + UD_Iphaddd, + UD_Iphaddsw, + UD_Iphaddw, + UD_Iphminposuw, + UD_Iphsubd, + UD_Iphsubsw, + UD_Iphsubw, + UD_Ipi2fd, + UD_Ipi2fw, + UD_Ipinsrb, + UD_Ipinsrd, + UD_Ipinsrq, + UD_Ipinsrw, + UD_Ipmaddubsw, + UD_Ipmaddwd, + UD_Ipmaxsb, + UD_Ipmaxsd, + UD_Ipmaxsw, + UD_Ipmaxub, + UD_Ipmaxud, + UD_Ipmaxuw, + UD_Ipminsb, + UD_Ipminsd, + UD_Ipminsw, + UD_Ipminub, + UD_Ipminud, + UD_Ipminuw, + UD_Ipmovmskb, + UD_Ipmovsxbd, + UD_Ipmovsxbq, + UD_Ipmovsxbw, + UD_Ipmovsxdq, + UD_Ipmovsxwd, + UD_Ipmovsxwq, + UD_Ipmovzxbd, + UD_Ipmovzxbq, + UD_Ipmovzxbw, + UD_Ipmovzxdq, + UD_Ipmovzxwd, + UD_Ipmovzxwq, + UD_Ipmuldq, + UD_Ipmulhrsw, + UD_Ipmulhrw, + UD_Ipmulhuw, + UD_Ipmulhw, + UD_Ipmulld, + UD_Ipmullw, + UD_Ipmuludq, + UD_Ipop, + UD_Ipopa, + UD_Ipopad, + UD_Ipopcnt, + UD_Ipopfd, + UD_Ipopfq, + UD_Ipopfw, + UD_Ipor, + UD_Iprefetch, + UD_Iprefetchnta, + UD_Iprefetcht0, + UD_Iprefetcht1, + UD_Iprefetcht2, + UD_Ipsadbw, + UD_Ipshufb, + UD_Ipshufd, + UD_Ipshufhw, + UD_Ipshuflw, + UD_Ipshufw, + UD_Ipsignb, + UD_Ipsignd, + UD_Ipsignw, + UD_Ipslld, + UD_Ipslldq, + UD_Ipsllq, + UD_Ipsllw, + UD_Ipsrad, + UD_Ipsraw, + UD_Ipsrld, + UD_Ipsrldq, + UD_Ipsrlq, + UD_Ipsrlw, + UD_Ipsubb, + UD_Ipsubd, + UD_Ipsubq, + UD_Ipsubsb, + UD_Ipsubsw, + UD_Ipsubusb, + UD_Ipsubusw, + UD_Ipsubw, + UD_Ipswapd, + UD_Iptest, + UD_Ipunpckhbw, + UD_Ipunpckhdq, + UD_Ipunpckhqdq, + UD_Ipunpckhwd, + UD_Ipunpcklbw, + UD_Ipunpckldq, + UD_Ipunpcklqdq, + UD_Ipunpcklwd, + UD_Ipush, + UD_Ipusha, + UD_Ipushad, + UD_Ipushfd, + UD_Ipushfq, + UD_Ipushfw, + UD_Ipxor, + UD_Ircl, + UD_Ircpps, + UD_Ircpss, + UD_Ircr, + UD_Irdmsr, + UD_Irdpmc, + UD_Irdrand, + UD_Irdtsc, + UD_Irdtscp, + UD_Irep, + UD_Irepne, + UD_Iret, + UD_Iretf, + UD_Irol, + UD_Iror, + UD_Iroundpd, + UD_Iroundps, + UD_Iroundsd, + UD_Iroundss, + UD_Irsm, + UD_Irsqrtps, + UD_Irsqrtss, + UD_Isahf, + UD_Isalc, + UD_Isar, + UD_Isbb, + UD_Iscasb, + UD_Iscasd, + UD_Iscasq, + UD_Iscasw, + UD_Iseta, + UD_Isetae, + UD_Isetb, + UD_Isetbe, + UD_Isetg, + UD_Isetge, + UD_Isetl, + UD_Isetle, + UD_Isetno, + UD_Isetnp, + UD_Isetns, + UD_Isetnz, + UD_Iseto, + UD_Isetp, + UD_Isets, + UD_Isetz, + UD_Isfence, + UD_Isgdt, + UD_Ishl, + UD_Ishld, + UD_Ishr, + UD_Ishrd, + UD_Ishufpd, + UD_Ishufps, + UD_Isidt, + UD_Iskinit, + UD_Isldt, + UD_Ismsw, + UD_Isqrtpd, + UD_Isqrtps, + UD_Isqrtsd, + UD_Isqrtss, + UD_Istc, + UD_Istd, + UD_Istgi, + UD_Isti, + UD_Istmxcsr, + UD_Istosb, + UD_Istosd, + UD_Istosq, + UD_Istosw, + UD_Istr, + UD_Isub, + UD_Isubpd, + UD_Isubps, + UD_Isubsd, + UD_Isubss, + UD_Iswapgs, + UD_Isyscall, + UD_Isysenter, + UD_Isysexit, + UD_Isysret, + UD_Itest, + UD_Iucomisd, + UD_Iucomiss, + UD_Iud2, + UD_Iunpckhpd, + UD_Iunpckhps, + UD_Iunpcklpd, + UD_Iunpcklps, + UD_Ivaddpd, + UD_Ivaddps, + UD_Ivaddsd, + UD_Ivaddss, + UD_Ivaddsubpd, + UD_Ivaddsubps, + UD_Ivaesdec, + UD_Ivaesdeclast, + UD_Ivaesenc, + UD_Ivaesenclast, + UD_Ivaesimc, + UD_Ivaeskeygenassist, + UD_Ivandnpd, + UD_Ivandnps, + UD_Ivandpd, + UD_Ivandps, + UD_Ivblendpd, + UD_Ivblendps, + UD_Ivblendvpd, + UD_Ivblendvps, + UD_Ivbroadcastsd, + UD_Ivbroadcastss, + UD_Ivcmppd, + UD_Ivcmpps, + UD_Ivcmpsd, + UD_Ivcmpss, + UD_Ivcomisd, + UD_Ivcomiss, + UD_Ivcvtdq2pd, + UD_Ivcvtdq2ps, + UD_Ivcvtpd2dq, + UD_Ivcvtpd2ps, + UD_Ivcvtps2dq, + UD_Ivcvtps2pd, + UD_Ivcvtsd2si, + UD_Ivcvtsd2ss, + UD_Ivcvtsi2sd, + UD_Ivcvtsi2ss, + UD_Ivcvtss2sd, + UD_Ivcvtss2si, + UD_Ivcvttpd2dq, + UD_Ivcvttps2dq, + UD_Ivcvttsd2si, + UD_Ivcvttss2si, + UD_Ivdivpd, + UD_Ivdivps, + UD_Ivdivsd, + UD_Ivdivss, + UD_Ivdppd, + UD_Ivdpps, + UD_Iverr, + UD_Iverw, + UD_Ivextractf128, + UD_Ivextractps, + UD_Ivhaddpd, + UD_Ivhaddps, + UD_Ivhsubpd, + UD_Ivhsubps, + UD_Ivinsertf128, + UD_Ivinsertps, + UD_Ivlddqu, + UD_Ivmaskmovdqu, + UD_Ivmaskmovpd, + UD_Ivmaskmovps, + UD_Ivmaxpd, + UD_Ivmaxps, + UD_Ivmaxsd, + UD_Ivmaxss, + UD_Ivmcall, + UD_Ivmclear, + UD_Ivminpd, + UD_Ivminps, + UD_Ivminsd, + UD_Ivminss, + UD_Ivmlaunch, + UD_Ivmload, + UD_Ivmmcall, + UD_Ivmovapd, + UD_Ivmovaps, + UD_Ivmovd, + UD_Ivmovddup, + UD_Ivmovdqa, + UD_Ivmovdqu, + UD_Ivmovhlps, + UD_Ivmovhpd, + UD_Ivmovhps, + UD_Ivmovlhps, + UD_Ivmovlpd, + UD_Ivmovlps, + UD_Ivmovmskpd, + UD_Ivmovmskps, + UD_Ivmovntdq, + UD_Ivmovntdqa, + UD_Ivmovntpd, + UD_Ivmovntps, + UD_Ivmovq, + UD_Ivmovsd, + UD_Ivmovshdup, + UD_Ivmovsldup, + UD_Ivmovss, + UD_Ivmovupd, + UD_Ivmovups, + UD_Ivmpsadbw, + UD_Ivmptrld, + UD_Ivmptrst, + UD_Ivmread, + UD_Ivmresume, + UD_Ivmrun, + UD_Ivmsave, + UD_Ivmulpd, + UD_Ivmulps, + UD_Ivmulsd, + UD_Ivmulss, + UD_Ivmwrite, + UD_Ivmxoff, + UD_Ivmxon, + UD_Ivorpd, + UD_Ivorps, + UD_Ivpabsb, + UD_Ivpabsd, + UD_Ivpabsw, + UD_Ivpackssdw, + UD_Ivpacksswb, + UD_Ivpackusdw, + UD_Ivpackuswb, + UD_Ivpaddb, + UD_Ivpaddd, + UD_Ivpaddq, + UD_Ivpaddsb, + UD_Ivpaddsw, + UD_Ivpaddusb, + UD_Ivpaddusw, + UD_Ivpaddw, + UD_Ivpalignr, + UD_Ivpand, + UD_Ivpandn, + UD_Ivpavgb, + UD_Ivpavgw, + UD_Ivpblendvb, + UD_Ivpblendw, + UD_Ivpclmulqdq, + UD_Ivpcmpeqb, + UD_Ivpcmpeqd, + UD_Ivpcmpeqq, + UD_Ivpcmpeqw, + UD_Ivpcmpestri, + UD_Ivpcmpestrm, + UD_Ivpcmpgtb, + UD_Ivpcmpgtd, + UD_Ivpcmpgtq, + UD_Ivpcmpgtw, + UD_Ivpcmpistri, + UD_Ivpcmpistrm, + UD_Ivperm2f128, + UD_Ivpermilpd, + UD_Ivpermilps, + UD_Ivpextrb, + UD_Ivpextrd, + UD_Ivpextrq, + UD_Ivpextrw, + UD_Ivphaddd, + UD_Ivphaddsw, + UD_Ivphaddw, + UD_Ivphminposuw, + UD_Ivphsubd, + UD_Ivphsubsw, + UD_Ivphsubw, + UD_Ivpinsrb, + UD_Ivpinsrd, + UD_Ivpinsrq, + UD_Ivpinsrw, + UD_Ivpmaddubsw, + UD_Ivpmaddwd, + UD_Ivpmaxsb, + UD_Ivpmaxsd, + UD_Ivpmaxsw, + UD_Ivpmaxub, + UD_Ivpmaxud, + UD_Ivpmaxuw, + UD_Ivpminsb, + UD_Ivpminsd, + UD_Ivpminsw, + UD_Ivpminub, + UD_Ivpminud, + UD_Ivpminuw, + UD_Ivpmovmskb, + UD_Ivpmovsxbd, + UD_Ivpmovsxbq, + UD_Ivpmovsxbw, + UD_Ivpmovsxwd, + UD_Ivpmovsxwq, + UD_Ivpmovzxbd, + UD_Ivpmovzxbq, + UD_Ivpmovzxbw, + UD_Ivpmovzxdq, + UD_Ivpmovzxwd, + UD_Ivpmovzxwq, + UD_Ivpmuldq, + UD_Ivpmulhrsw, + UD_Ivpmulhuw, + UD_Ivpmulhw, + UD_Ivpmulld, + UD_Ivpmullw, + UD_Ivpor, + UD_Ivpsadbw, + UD_Ivpshufb, + UD_Ivpshufd, + UD_Ivpshufhw, + UD_Ivpshuflw, + UD_Ivpsignb, + UD_Ivpsignd, + UD_Ivpsignw, + UD_Ivpslld, + UD_Ivpslldq, + UD_Ivpsllq, + UD_Ivpsllw, + UD_Ivpsrad, + UD_Ivpsraw, + UD_Ivpsrld, + UD_Ivpsrldq, + UD_Ivpsrlq, + UD_Ivpsrlw, + UD_Ivpsubb, + UD_Ivpsubd, + UD_Ivpsubq, + UD_Ivpsubsb, + UD_Ivpsubsw, + UD_Ivpsubusb, + UD_Ivpsubusw, + UD_Ivpsubw, + UD_Ivptest, + UD_Ivpunpckhbw, + UD_Ivpunpckhdq, + UD_Ivpunpckhqdq, + UD_Ivpunpckhwd, + UD_Ivpunpcklbw, + UD_Ivpunpckldq, + UD_Ivpunpcklqdq, + UD_Ivpunpcklwd, + UD_Ivpxor, + UD_Ivrcpps, + UD_Ivrcpss, + UD_Ivroundpd, + UD_Ivroundps, + UD_Ivroundsd, + UD_Ivroundss, + UD_Ivrsqrtps, + UD_Ivrsqrtss, + UD_Ivshufpd, + UD_Ivshufps, + UD_Ivsqrtpd, + UD_Ivsqrtps, + UD_Ivsqrtsd, + UD_Ivsqrtss, + UD_Ivstmxcsr, + UD_Ivsubpd, + UD_Ivsubps, + UD_Ivsubsd, + UD_Ivsubss, + UD_Ivtestpd, + UD_Ivtestps, + UD_Ivucomisd, + UD_Ivucomiss, + UD_Ivunpckhpd, + UD_Ivunpckhps, + UD_Ivunpcklpd, + UD_Ivunpcklps, + UD_Ivxorpd, + UD_Ivxorps, + UD_Ivzeroall, + UD_Ivzeroupper, + UD_Iwait, + UD_Iwbinvd, + UD_Iwrmsr, + UD_Ixadd, + UD_Ixchg, + UD_Ixcryptcbc, + UD_Ixcryptcfb, + UD_Ixcryptctr, + UD_Ixcryptecb, + UD_Ixcryptofb, + UD_Ixgetbv, + UD_Ixlatb, + UD_Ixor, + UD_Ixorpd, + UD_Ixorps, + UD_Ixrstor, + UD_Ixsave, + UD_Ixsetbv, + UD_Ixsha1, + UD_Ixsha256, + UD_Ixstore, + UD_Iinvalid, + UD_I3dnow, + UD_Inone, + UD_Idb, + UD_Ipause, + UD_MAX_MNEMONIC_CODE +}; + +extern const char * ud_mnemonics_str[]; + +#endif /* UD_ITAB_H */ diff --git a/deps/udis86/libudis86/syn-att.c b/deps/udis86/libudis86/syn-att.c new file mode 100644 index 0000000..d1ba89b --- /dev/null +++ b/deps/udis86/libudis86/syn-att.c @@ -0,0 +1,228 @@ +/* udis86 - libudis86/syn-att.c + * + * Copyright (c) 2002-2009 Vivek Thampi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "types.h" +#include "extern.h" +#include "decode.h" +#include "itab.h" +#include "syn.h" +#include "udint.h" + +/* ----------------------------------------------------------------------------- + * opr_cast() - Prints an operand cast. + * ----------------------------------------------------------------------------- + */ +static void +opr_cast(struct ud* u, struct ud_operand* op) +{ + switch(op->size) { + case 16 : case 32 : + ud_asmprintf(u, "*"); break; + default: break; + } +} + +/* ----------------------------------------------------------------------------- + * gen_operand() - Generates assembly output for each operand. + * ----------------------------------------------------------------------------- + */ +static void +gen_operand(struct ud* u, struct ud_operand* op) +{ + switch(op->type) { + case UD_OP_CONST: + ud_asmprintf(u, "$0x%x", op->lval.udword); + break; + + case UD_OP_REG: + ud_asmprintf(u, "%%%s", ud_reg_tab[op->base - UD_R_AL]); + break; + + case UD_OP_MEM: + if (u->br_far) { + opr_cast(u, op); + } + if (u->pfx_seg) { + ud_asmprintf(u, "%%%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]); + } + if (op->offset != 0) { + ud_syn_print_mem_disp(u, op, 0); + } + if (op->base) { + ud_asmprintf(u, "(%%%s", ud_reg_tab[op->base - UD_R_AL]); + } + if (op->index) { + if (op->base) { + ud_asmprintf(u, ","); + } else { + ud_asmprintf(u, "("); + } + ud_asmprintf(u, "%%%s", ud_reg_tab[op->index - UD_R_AL]); + } + if (op->scale) { + ud_asmprintf(u, ",%d", op->scale); + } + if (op->base || op->index) { + ud_asmprintf(u, ")"); + } + break; + + case UD_OP_IMM: + ud_asmprintf(u, "$"); + ud_syn_print_imm(u, op); + break; + + case UD_OP_JIMM: + ud_syn_print_addr(u, ud_syn_rel_target(u, op)); + break; + + case UD_OP_PTR: + switch (op->size) { + case 32: + ud_asmprintf(u, "$0x%x, $0x%x", op->lval.ptr.seg, + op->lval.ptr.off & 0xFFFF); + break; + case 48: + ud_asmprintf(u, "$0x%x, $0x%x", op->lval.ptr.seg, + op->lval.ptr.off); + break; + } + break; + + default: return; + } +} + +/* ============================================================================= + * translates to AT&T syntax + * ============================================================================= + */ +extern void +ud_translate_att(struct ud *u) +{ + int size = 0; + int star = 0; + + /* check if P_OSO prefix is used */ + if (! P_OSO(u->itab_entry->prefix) && u->pfx_opr) { + switch (u->dis_mode) { + case 16: + ud_asmprintf(u, "o32 "); + break; + case 32: + case 64: + ud_asmprintf(u, "o16 "); + break; + } + } + + /* check if P_ASO prefix was used */ + if (! P_ASO(u->itab_entry->prefix) && u->pfx_adr) { + switch (u->dis_mode) { + case 16: + ud_asmprintf(u, "a32 "); + break; + case 32: + ud_asmprintf(u, "a16 "); + break; + case 64: + ud_asmprintf(u, "a32 "); + break; + } + } + + if (u->pfx_lock) + ud_asmprintf(u, "lock "); + if (u->pfx_rep) { + ud_asmprintf(u, "rep "); + } else if (u->pfx_repe) { + ud_asmprintf(u, "repe "); + } else if (u->pfx_repne) { + ud_asmprintf(u, "repne "); + } + + /* special instructions */ + switch (u->mnemonic) { + case UD_Iretf: + ud_asmprintf(u, "lret "); + break; + case UD_Idb: + ud_asmprintf(u, ".byte 0x%x", u->operand[0].lval.ubyte); + return; + case UD_Ijmp: + case UD_Icall: + if (u->br_far) ud_asmprintf(u, "l"); + if (u->operand[0].type == UD_OP_REG) { + star = 1; + } + ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic)); + break; + case UD_Ibound: + case UD_Ienter: + if (u->operand[0].type != UD_NONE) + gen_operand(u, &u->operand[0]); + if (u->operand[1].type != UD_NONE) { + ud_asmprintf(u, ","); + gen_operand(u, &u->operand[1]); + } + return; + default: + ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic)); + } + + if (size == 8) { + ud_asmprintf(u, "b"); + } else if (size == 16) { + ud_asmprintf(u, "w"); + } else if (size == 64) { + ud_asmprintf(u, "q"); + } + + if (star) { + ud_asmprintf(u, " *"); + } else { + ud_asmprintf(u, " "); + } + + if (u->operand[3].type != UD_NONE) { + gen_operand(u, &u->operand[3]); + ud_asmprintf(u, ", "); + } + if (u->operand[2].type != UD_NONE) { + gen_operand(u, &u->operand[2]); + ud_asmprintf(u, ", "); + } + if (u->operand[1].type != UD_NONE) { + gen_operand(u, &u->operand[1]); + ud_asmprintf(u, ", "); + } + if (u->operand[0].type != UD_NONE) { + gen_operand(u, &u->operand[0]); + } +} + +/* +vim: set ts=2 sw=2 expandtab +*/ diff --git a/deps/udis86/libudis86/syn-intel.c b/deps/udis86/libudis86/syn-intel.c new file mode 100644 index 0000000..0664fea --- /dev/null +++ b/deps/udis86/libudis86/syn-intel.c @@ -0,0 +1,224 @@ +/* udis86 - libudis86/syn-intel.c + * + * Copyright (c) 2002-2013 Vivek Thampi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "types.h" +#include "extern.h" +#include "decode.h" +#include "itab.h" +#include "syn.h" +#include "udint.h" + +/* ----------------------------------------------------------------------------- + * opr_cast() - Prints an operand cast. + * ----------------------------------------------------------------------------- + */ +static void +opr_cast(struct ud* u, struct ud_operand* op) +{ + if (u->br_far) { + ud_asmprintf(u, "far "); + } + switch(op->size) { + case 8: ud_asmprintf(u, "byte " ); break; + case 16: ud_asmprintf(u, "word " ); break; + case 32: ud_asmprintf(u, "dword "); break; + case 64: ud_asmprintf(u, "qword "); break; + case 80: ud_asmprintf(u, "tword "); break; + case 128: ud_asmprintf(u, "oword "); break; + case 256: ud_asmprintf(u, "yword "); break; + default: break; + } +} + +/* ----------------------------------------------------------------------------- + * gen_operand() - Generates assembly output for each operand. + * ----------------------------------------------------------------------------- + */ +static void gen_operand(struct ud* u, struct ud_operand* op, int syn_cast) +{ + switch(op->type) { + case UD_OP_REG: + ud_asmprintf(u, "%s", ud_reg_tab[op->base - UD_R_AL]); + break; + + case UD_OP_MEM: + if (syn_cast) { + opr_cast(u, op); + } + ud_asmprintf(u, "["); + if (u->pfx_seg) { + ud_asmprintf(u, "%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]); + } + if (op->base) { + ud_asmprintf(u, "%s", ud_reg_tab[op->base - UD_R_AL]); + } + if (op->index) { + ud_asmprintf(u, "%s%s", op->base != UD_NONE? "+" : "", + ud_reg_tab[op->index - UD_R_AL]); + if (op->scale) { + ud_asmprintf(u, "*%d", op->scale); + } + } + if (op->offset != 0) { + ud_syn_print_mem_disp(u, op, (op->base != UD_NONE || + op->index != UD_NONE) ? 1 : 0); + } + ud_asmprintf(u, "]"); + break; + + case UD_OP_IMM: + ud_syn_print_imm(u, op); + break; + + + case UD_OP_JIMM: + ud_syn_print_addr(u, ud_syn_rel_target(u, op)); + break; + + case UD_OP_PTR: + switch (op->size) { + case 32: + ud_asmprintf(u, "word 0x%x:0x%x", op->lval.ptr.seg, + op->lval.ptr.off & 0xFFFF); + break; + case 48: + ud_asmprintf(u, "dword 0x%x:0x%x", op->lval.ptr.seg, + op->lval.ptr.off); + break; + } + break; + + case UD_OP_CONST: + if (syn_cast) opr_cast(u, op); + ud_asmprintf(u, "%d", op->lval.udword); + break; + + default: return; + } +} + +/* ============================================================================= + * translates to intel syntax + * ============================================================================= + */ +extern void +ud_translate_intel(struct ud* u) +{ + /* check if P_OSO prefix is used */ + if (!P_OSO(u->itab_entry->prefix) && u->pfx_opr) { + switch (u->dis_mode) { + case 16: ud_asmprintf(u, "o32 "); break; + case 32: + case 64: ud_asmprintf(u, "o16 "); break; + } + } + + /* check if P_ASO prefix was used */ + if (!P_ASO(u->itab_entry->prefix) && u->pfx_adr) { + switch (u->dis_mode) { + case 16: ud_asmprintf(u, "a32 "); break; + case 32: ud_asmprintf(u, "a16 "); break; + case 64: ud_asmprintf(u, "a32 "); break; + } + } + + if (u->pfx_seg && + u->operand[0].type != UD_OP_MEM && + u->operand[1].type != UD_OP_MEM ) { + ud_asmprintf(u, "%s ", ud_reg_tab[u->pfx_seg - UD_R_AL]); + } + + if (u->pfx_lock) { + ud_asmprintf(u, "lock "); + } + if (u->pfx_rep) { + ud_asmprintf(u, "rep "); + } else if (u->pfx_repe) { + ud_asmprintf(u, "repe "); + } else if (u->pfx_repne) { + ud_asmprintf(u, "repne "); + } + + /* print the instruction mnemonic */ + ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic)); + + if (u->operand[0].type != UD_NONE) { + int cast = 0; + ud_asmprintf(u, " "); + if (u->operand[0].type == UD_OP_MEM) { + if (u->operand[1].type == UD_OP_IMM || + u->operand[1].type == UD_OP_CONST || + u->operand[1].type == UD_NONE || + (u->operand[0].size != u->operand[1].size)) { + cast = 1; + } else if (u->operand[1].type == UD_OP_REG && + u->operand[1].base == UD_R_CL) { + switch (u->mnemonic) { + case UD_Ircl: + case UD_Irol: + case UD_Iror: + case UD_Ircr: + case UD_Ishl: + case UD_Ishr: + case UD_Isar: + cast = 1; + break; + default: break; + } + } + } + gen_operand(u, &u->operand[0], cast); + } + + if (u->operand[1].type != UD_NONE) { + int cast = 0; + ud_asmprintf(u, ", "); + if (u->operand[1].type == UD_OP_MEM && + u->operand[0].size != u->operand[1].size && + !ud_opr_is_sreg(&u->operand[0])) { + cast = 1; + } + gen_operand(u, &u->operand[1], cast); + } + + if (u->operand[2].type != UD_NONE) { + int cast = 0; + ud_asmprintf(u, ", "); + if (u->operand[2].type == UD_OP_MEM && + u->operand[2].size != u->operand[1].size) { + cast = 1; + } + gen_operand(u, &u->operand[2], cast); + } + + if (u->operand[3].type != UD_NONE) { + ud_asmprintf(u, ", "); + gen_operand(u, &u->operand[3], 0); + } +} + +/* +vim: set ts=2 sw=2 expandtab +*/ diff --git a/deps/udis86/libudis86/syn.c b/deps/udis86/libudis86/syn.c new file mode 100644 index 0000000..1b9e1d4 --- /dev/null +++ b/deps/udis86/libudis86/syn.c @@ -0,0 +1,212 @@ +/* udis86 - libudis86/syn.c + * + * Copyright (c) 2002-2013 Vivek Thampi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "types.h" +#include "decode.h" +#include "syn.h" +#include "udint.h" + +/* + * Register Table - Order Matters (types.h)! + * + */ +const char* ud_reg_tab[] = +{ + "al", "cl", "dl", "bl", + "ah", "ch", "dh", "bh", + "spl", "bpl", "sil", "dil", + "r8b", "r9b", "r10b", "r11b", + "r12b", "r13b", "r14b", "r15b", + + "ax", "cx", "dx", "bx", + "sp", "bp", "si", "di", + "r8w", "r9w", "r10w", "r11w", + "r12w", "r13w", "r14w", "r15w", + + "eax", "ecx", "edx", "ebx", + "esp", "ebp", "esi", "edi", + "r8d", "r9d", "r10d", "r11d", + "r12d", "r13d", "r14d", "r15d", + + "rax", "rcx", "rdx", "rbx", + "rsp", "rbp", "rsi", "rdi", + "r8", "r9", "r10", "r11", + "r12", "r13", "r14", "r15", + + "es", "cs", "ss", "ds", + "fs", "gs", + + "cr0", "cr1", "cr2", "cr3", + "cr4", "cr5", "cr6", "cr7", + "cr8", "cr9", "cr10", "cr11", + "cr12", "cr13", "cr14", "cr15", + + "dr0", "dr1", "dr2", "dr3", + "dr4", "dr5", "dr6", "dr7", + "dr8", "dr9", "dr10", "dr11", + "dr12", "dr13", "dr14", "dr15", + + "mm0", "mm1", "mm2", "mm3", + "mm4", "mm5", "mm6", "mm7", + + "st0", "st1", "st2", "st3", + "st4", "st5", "st6", "st7", + + "xmm0", "xmm1", "xmm2", "xmm3", + "xmm4", "xmm5", "xmm6", "xmm7", + "xmm8", "xmm9", "xmm10", "xmm11", + "xmm12", "xmm13", "xmm14", "xmm15", + + "ymm0", "ymm1", "ymm2", "ymm3", + "ymm4", "ymm5", "ymm6", "ymm7", + "ymm8", "ymm9", "ymm10", "ymm11", + "ymm12", "ymm13", "ymm14", "ymm15", + + "rip" +}; + + +uint64_t +ud_syn_rel_target(struct ud *u, struct ud_operand *opr) +{ + const uint64_t trunc_mask = 0xffffffffffffffffull >> (64 - u->opr_mode); + switch (opr->size) { + case 8 : return (u->pc + opr->lval.sbyte) & trunc_mask; + case 16: return (u->pc + opr->lval.sword) & trunc_mask; + case 32: return (u->pc + opr->lval.sdword) & trunc_mask; + default: UD_ASSERT(!"invalid relative offset size."); + return 0ull; + } +} + + +/* + * asmprintf + * Printf style function for printing translated assembly + * output. Returns the number of characters written and + * moves the buffer pointer forward. On an overflow, + * returns a negative number and truncates the output. + */ +int +ud_asmprintf(struct ud *u, const char *fmt, ...) +{ + int ret; + int avail; + va_list ap; + va_start(ap, fmt); + avail = u->asm_buf_size - u->asm_buf_fill - 1 /* nullchar */; + ret = vsnprintf((char*) u->asm_buf + u->asm_buf_fill, avail, fmt, ap); + if (ret < 0 || ret > avail) { + u->asm_buf_fill = u->asm_buf_size - 1; + } else { + u->asm_buf_fill += ret; + } + va_end(ap); + return ret; +} + + +void +ud_syn_print_addr(struct ud *u, uint64_t addr) +{ + const char *name = NULL; + if (u->sym_resolver) { + int64_t offset = 0; + name = u->sym_resolver(u, addr, &offset); + if (name) { + if (offset) { + ud_asmprintf(u, "%s%+" FMT64 "d", name, offset); + } else { + ud_asmprintf(u, "%s", name); + } + return; + } + } + ud_asmprintf(u, "0x%" FMT64 "x", addr); +} + + +void +ud_syn_print_imm(struct ud* u, const struct ud_operand *op) +{ + uint64_t v; + if (op->_oprcode == OP_sI && op->size != u->opr_mode) { + if (op->size == 8) { + v = (int64_t)op->lval.sbyte; + } else { + UD_ASSERT(op->size == 32); + v = (int64_t)op->lval.sdword; + } + if (u->opr_mode < 64) { + v = v & ((1ull << u->opr_mode) - 1ull); + } + } else { + switch (op->size) { + case 8 : v = op->lval.ubyte; break; + case 16: v = op->lval.uword; break; + case 32: v = op->lval.udword; break; + case 64: v = op->lval.uqword; break; + default: UD_ASSERT(!"invalid offset"); v = 0; /* keep cc happy */ + } + } + ud_asmprintf(u, "0x%" FMT64 "x", v); +} + + +void +ud_syn_print_mem_disp(struct ud* u, const struct ud_operand *op, int sign) +{ + UD_ASSERT(op->offset != 0); + if (op->base == UD_NONE && op->index == UD_NONE) { + uint64_t v; + UD_ASSERT(op->scale == UD_NONE && op->offset != 8); + /* unsigned mem-offset */ + switch (op->offset) { + case 16: v = op->lval.uword; break; + case 32: v = op->lval.udword; break; + case 64: v = op->lval.uqword; break; + default: UD_ASSERT(!"invalid offset"); v = 0; /* keep cc happy */ + } + ud_asmprintf(u, "0x%" FMT64 "x", v); + } else { + int64_t v; + UD_ASSERT(op->offset != 64); + switch (op->offset) { + case 8 : v = op->lval.sbyte; break; + case 16: v = op->lval.sword; break; + case 32: v = op->lval.sdword; break; + default: UD_ASSERT(!"invalid offset"); v = 0; /* keep cc happy */ + } + if (v < 0) { + ud_asmprintf(u, "-0x%" FMT64 "x", -v); + } else if (v > 0) { + ud_asmprintf(u, "%s0x%" FMT64 "x", sign? "+" : "", v); + } + } +} + +/* +vim: set ts=2 sw=2 expandtab +*/ diff --git a/deps/udis86/libudis86/syn.h b/deps/udis86/libudis86/syn.h new file mode 100644 index 0000000..d3b1e3f --- /dev/null +++ b/deps/udis86/libudis86/syn.h @@ -0,0 +1,53 @@ +/* udis86 - libudis86/syn.h + * + * Copyright (c) 2002-2009 + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef UD_SYN_H +#define UD_SYN_H + +#include "types.h" +#ifndef __UD_STANDALONE__ +# include +#endif /* __UD_STANDALONE__ */ + +extern const char* ud_reg_tab[]; + +uint64_t ud_syn_rel_target(struct ud*, struct ud_operand*); + +#ifdef __GNUC__ +int ud_asmprintf(struct ud *u, const char *fmt, ...) + __attribute__ ((format (printf, 2, 3))); +#else +int ud_asmprintf(struct ud *u, const char *fmt, ...); +#endif + +void ud_syn_print_addr(struct ud *u, uint64_t addr); +void ud_syn_print_imm(struct ud* u, const struct ud_operand *op); +void ud_syn_print_mem_disp(struct ud* u, const struct ud_operand *, int sign); + +#endif /* UD_SYN_H */ + +/* +vim: set ts=2 sw=2 expandtab +*/ diff --git a/deps/udis86/libudis86/types.h b/deps/udis86/libudis86/types.h new file mode 100644 index 0000000..69072ca --- /dev/null +++ b/deps/udis86/libudis86/types.h @@ -0,0 +1,260 @@ +/* udis86 - libudis86/types.h + * + * Copyright (c) 2002-2013 Vivek Thampi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef UD_TYPES_H +#define UD_TYPES_H + +#ifdef __KERNEL__ + /* + * -D__KERNEL__ is automatically passed on the command line when + * building something as part of the Linux kernel. Assume standalone + * mode. + */ +# include +# include +# ifndef __UD_STANDALONE__ +# define __UD_STANDALONE__ 1 +# endif +#endif /* __KERNEL__ */ + +#if !defined(__UD_STANDALONE__) +# include +# include +#endif + +/* gcc specific extensions */ +#ifdef __GNUC__ +# define UD_ATTR_PACKED __attribute__((packed)) +#else +# define UD_ATTR_PACKED +#endif /* UD_ATTR_PACKED */ + + +/* ----------------------------------------------------------------------------- + * All possible "types" of objects in udis86. Order is Important! + * ----------------------------------------------------------------------------- + */ +enum ud_type +{ + UD_NONE, + + /* 8 bit GPRs */ + UD_R_AL, UD_R_CL, UD_R_DL, UD_R_BL, + UD_R_AH, UD_R_CH, UD_R_DH, UD_R_BH, + UD_R_SPL, UD_R_BPL, UD_R_SIL, UD_R_DIL, + UD_R_R8B, UD_R_R9B, UD_R_R10B, UD_R_R11B, + UD_R_R12B, UD_R_R13B, UD_R_R14B, UD_R_R15B, + + /* 16 bit GPRs */ + UD_R_AX, UD_R_CX, UD_R_DX, UD_R_BX, + UD_R_SP, UD_R_BP, UD_R_SI, UD_R_DI, + UD_R_R8W, UD_R_R9W, UD_R_R10W, UD_R_R11W, + UD_R_R12W, UD_R_R13W, UD_R_R14W, UD_R_R15W, + + /* 32 bit GPRs */ + UD_R_EAX, UD_R_ECX, UD_R_EDX, UD_R_EBX, + UD_R_ESP, UD_R_EBP, UD_R_ESI, UD_R_EDI, + UD_R_R8D, UD_R_R9D, UD_R_R10D, UD_R_R11D, + UD_R_R12D, UD_R_R13D, UD_R_R14D, UD_R_R15D, + + /* 64 bit GPRs */ + UD_R_RAX, UD_R_RCX, UD_R_RDX, UD_R_RBX, + UD_R_RSP, UD_R_RBP, UD_R_RSI, UD_R_RDI, + UD_R_R8, UD_R_R9, UD_R_R10, UD_R_R11, + UD_R_R12, UD_R_R13, UD_R_R14, UD_R_R15, + + /* segment registers */ + UD_R_ES, UD_R_CS, UD_R_SS, UD_R_DS, + UD_R_FS, UD_R_GS, + + /* control registers*/ + UD_R_CR0, UD_R_CR1, UD_R_CR2, UD_R_CR3, + UD_R_CR4, UD_R_CR5, UD_R_CR6, UD_R_CR7, + UD_R_CR8, UD_R_CR9, UD_R_CR10, UD_R_CR11, + UD_R_CR12, UD_R_CR13, UD_R_CR14, UD_R_CR15, + + /* debug registers */ + UD_R_DR0, UD_R_DR1, UD_R_DR2, UD_R_DR3, + UD_R_DR4, UD_R_DR5, UD_R_DR6, UD_R_DR7, + UD_R_DR8, UD_R_DR9, UD_R_DR10, UD_R_DR11, + UD_R_DR12, UD_R_DR13, UD_R_DR14, UD_R_DR15, + + /* mmx registers */ + UD_R_MM0, UD_R_MM1, UD_R_MM2, UD_R_MM3, + UD_R_MM4, UD_R_MM5, UD_R_MM6, UD_R_MM7, + + /* x87 registers */ + UD_R_ST0, UD_R_ST1, UD_R_ST2, UD_R_ST3, + UD_R_ST4, UD_R_ST5, UD_R_ST6, UD_R_ST7, + + /* extended multimedia registers */ + UD_R_XMM0, UD_R_XMM1, UD_R_XMM2, UD_R_XMM3, + UD_R_XMM4, UD_R_XMM5, UD_R_XMM6, UD_R_XMM7, + UD_R_XMM8, UD_R_XMM9, UD_R_XMM10, UD_R_XMM11, + UD_R_XMM12, UD_R_XMM13, UD_R_XMM14, UD_R_XMM15, + + /* 256B multimedia registers */ + UD_R_YMM0, UD_R_YMM1, UD_R_YMM2, UD_R_YMM3, + UD_R_YMM4, UD_R_YMM5, UD_R_YMM6, UD_R_YMM7, + UD_R_YMM8, UD_R_YMM9, UD_R_YMM10, UD_R_YMM11, + UD_R_YMM12, UD_R_YMM13, UD_R_YMM14, UD_R_YMM15, + + UD_R_RIP, + + /* Operand Types */ + UD_OP_REG, UD_OP_MEM, UD_OP_PTR, UD_OP_IMM, + UD_OP_JIMM, UD_OP_CONST +}; + +#include "itab.h" + +union ud_lval { + int8_t sbyte; + uint8_t ubyte; + int16_t sword; + uint16_t uword; + int32_t sdword; + uint32_t udword; + int64_t sqword; + uint64_t uqword; + struct { + uint16_t seg; + uint32_t off; + } ptr; +}; + +/* ----------------------------------------------------------------------------- + * struct ud_operand - Disassembled instruction Operand. + * ----------------------------------------------------------------------------- + */ +struct ud_operand { + enum ud_type type; + uint16_t size; + enum ud_type base; + enum ud_type index; + uint8_t scale; + uint8_t offset; + union ud_lval lval; + /* + * internal use only + */ + uint64_t _legacy; /* this will be removed in 1.8 */ + uint8_t _oprcode; +}; + +/* ----------------------------------------------------------------------------- + * struct ud - The udis86 object. + * ----------------------------------------------------------------------------- + */ +struct ud +{ + /* + * input buffering + */ + int (*inp_hook) (struct ud*); +#ifndef __UD_STANDALONE__ + FILE* inp_file; +#endif + const uint8_t* inp_buf; + size_t inp_buf_size; + size_t inp_buf_index; + uint8_t inp_curr; + size_t inp_ctr; + uint8_t inp_sess[64]; + int inp_end; + int inp_peek; + + void (*translator)(struct ud*); + uint64_t insn_offset; + char insn_hexcode[64]; + + /* + * Assembly output buffer + */ + char *asm_buf; + size_t asm_buf_size; + size_t asm_buf_fill; + char asm_buf_int[128]; + + /* + * Symbol resolver for use in the translation phase. + */ + const char* (*sym_resolver)(struct ud*, uint64_t addr, int64_t *offset); + + uint8_t dis_mode; + uint64_t pc; + uint8_t vendor; + enum ud_mnemonic_code mnemonic; + struct ud_operand operand[4]; + uint8_t error; + uint8_t _rex; + uint8_t pfx_rex; + uint8_t pfx_seg; + uint8_t pfx_opr; + uint8_t pfx_adr; + uint8_t pfx_lock; + uint8_t pfx_str; + uint8_t pfx_rep; + uint8_t pfx_repe; + uint8_t pfx_repne; + uint8_t opr_mode; + uint8_t adr_mode; + uint8_t br_far; + uint8_t br_near; + uint8_t have_modrm; + uint8_t modrm; + uint8_t modrm_offset; + uint8_t vex_op; + uint8_t vex_b1; + uint8_t vex_b2; + uint8_t primary_opcode; + void * user_opaque_data; + struct ud_itab_entry * itab_entry; + struct ud_lookup_table_list_entry *le; +}; + +/* ----------------------------------------------------------------------------- + * Type-definitions + * ----------------------------------------------------------------------------- + */ +typedef enum ud_type ud_type_t; +typedef enum ud_mnemonic_code ud_mnemonic_code_t; + +typedef struct ud ud_t; +typedef struct ud_operand ud_operand_t; + +#define UD_SYN_INTEL ud_translate_intel +#define UD_SYN_ATT ud_translate_att +#define UD_EOI (-1) +#define UD_INP_CACHE_SZ 32 +#define UD_VENDOR_AMD 0 +#define UD_VENDOR_INTEL 1 +#define UD_VENDOR_ANY 2 + +#endif + +/* +vim: set ts=2 sw=2 expandtab +*/ diff --git a/deps/udis86/libudis86/udint.h b/deps/udis86/libudis86/udint.h new file mode 100644 index 0000000..734f0ea --- /dev/null +++ b/deps/udis86/libudis86/udint.h @@ -0,0 +1,99 @@ +/* udis86 - libudis86/udint.h -- definitions for internal use only + * + * Copyright (c) 2002-2009 Vivek Thampi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _UDINT_H_ +#define _UDINT_H_ + +#include "types.h" + +#ifdef HAVE_CONFIG_H +# include +#endif /* HAVE_CONFIG_H */ + +#if defined(UD_DEBUG) && HAVE_ASSERT_H +# include +# define UD_ASSERT(_x) assert(_x) +#else +# define UD_ASSERT(_x) +#endif /* !HAVE_ASSERT_H */ + +#if defined(UD_DEBUG) + #define UDERR(u, msg) \ + do { \ + (u)->error = 1; \ + fprintf(stderr, "decode-error: %s:%d: %s", \ + __FILE__, __LINE__, (msg)); \ + } while (0) +#else + #define UDERR(u, m) \ + do { \ + (u)->error = 1; \ + } while (0) +#endif /* !LOGERR */ + +#define UD_RETURN_ON_ERROR(u) \ + do { \ + if ((u)->error != 0) { \ + return (u)->error; \ + } \ + } while (0) + +#define UD_RETURN_WITH_ERROR(u, m) \ + do { \ + UDERR(u, m); \ + return (u)->error; \ + } while (0) + +#ifndef __UD_STANDALONE__ +# define UD_NON_STANDALONE(x) x +#else +# define UD_NON_STANDALONE(x) +#endif + +/* printf formatting int64 specifier */ +#ifdef FMT64 +# undef FMT64 +#endif +#if defined(_MSC_VER) || defined(__BORLANDC__) +# define FMT64 "I64" +#else +# if defined(__APPLE__) +# define FMT64 "ll" +# elif defined(__amd64__) || defined(__x86_64__) +# define FMT64 "l" +# else +# define FMT64 "ll" +# endif /* !x64 */ +#endif + +/* define an inline macro */ +#if defined(_MSC_VER) || defined(__BORLANDC__) +# define UD_INLINE __inline /* MS Visual Studio requires __inline + instead of inline for C code */ +#else +# define UD_INLINE inline +#endif + +#endif /* _UDINT_H_ */ diff --git a/deps/udis86/libudis86/udis86.c b/deps/udis86/libudis86/udis86.c new file mode 100644 index 0000000..e039c4e --- /dev/null +++ b/deps/udis86/libudis86/udis86.c @@ -0,0 +1,458 @@ +/* udis86 - libudis86/udis86.c + * + * Copyright (c) 2002-2013 Vivek Thampi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "udint.h" +#include "extern.h" +#include "decode.h" + +#if !defined(__UD_STANDALONE__) +# if HAVE_STRING_H +# include +# endif +#endif /* !__UD_STANDALONE__ */ + +static void ud_inp_init(struct ud *u); + +/* ============================================================================= + * ud_init + * Initializes ud_t object. + * ============================================================================= + */ +extern void +ud_init(struct ud* u) +{ + memset((void*)u, 0, sizeof(struct ud)); + ud_set_mode(u, 16); + u->mnemonic = UD_Iinvalid; + ud_set_pc(u, 0); +#ifndef __UD_STANDALONE__ + ud_set_input_file(u, stdin); +#endif /* __UD_STANDALONE__ */ + + ud_set_asm_buffer(u, u->asm_buf_int, sizeof(u->asm_buf_int)); +} + + +/* ============================================================================= + * ud_disassemble + * Disassembles one instruction and returns the number of + * bytes disassembled. A zero means end of disassembly. + * ============================================================================= + */ +extern unsigned int +ud_disassemble(struct ud* u) +{ + int len; + if (u->inp_end) { + return 0; + } + if ((len = ud_decode(u)) > 0) { + if (u->translator != NULL) { + u->asm_buf[0] = '\0'; + u->translator(u); + } + } + return len; +} + + +/* ============================================================================= + * ud_set_mode() - Set Disassemly Mode. + * ============================================================================= + */ +extern void +ud_set_mode(struct ud* u, uint8_t m) +{ + switch(m) { + case 16: + case 32: + case 64: u->dis_mode = m ; return; + default: u->dis_mode = 16; return; + } +} + +/* ============================================================================= + * ud_set_vendor() - Set vendor. + * ============================================================================= + */ +extern void +ud_set_vendor(struct ud* u, unsigned v) +{ + switch(v) { + case UD_VENDOR_INTEL: + u->vendor = v; + break; + case UD_VENDOR_ANY: + u->vendor = v; + break; + default: + u->vendor = UD_VENDOR_AMD; + } +} + +/* ============================================================================= + * ud_set_pc() - Sets code origin. + * ============================================================================= + */ +extern void +ud_set_pc(struct ud* u, uint64_t o) +{ + u->pc = o; +} + +/* ============================================================================= + * ud_set_syntax() - Sets the output syntax. + * ============================================================================= + */ +extern void +ud_set_syntax(struct ud* u, void (*t)(struct ud*)) +{ + u->translator = t; +} + +/* ============================================================================= + * ud_insn() - returns the disassembled instruction + * ============================================================================= + */ +const char* +ud_insn_asm(const struct ud* u) +{ + return u->asm_buf; +} + +/* ============================================================================= + * ud_insn_offset() - Returns the offset. + * ============================================================================= + */ +uint64_t +ud_insn_off(const struct ud* u) +{ + return u->insn_offset; +} + + +/* ============================================================================= + * ud_insn_hex() - Returns hex form of disassembled instruction. + * ============================================================================= + */ +const char* +ud_insn_hex(struct ud* u) +{ + u->insn_hexcode[0] = 0; + if (!u->error) { + unsigned int i; + const unsigned char *src_ptr = ud_insn_ptr(u); + char* src_hex; + src_hex = (char*) u->insn_hexcode; + /* for each byte used to decode instruction */ + for (i = 0; i < ud_insn_len(u) && i < sizeof(u->insn_hexcode) / 2; + ++i, ++src_ptr) { + sprintf(src_hex, "%02x", *src_ptr & 0xFF); + src_hex += 2; + } + } + return u->insn_hexcode; +} + + +/* ============================================================================= + * ud_insn_ptr + * Returns a pointer to buffer containing the bytes that were + * disassembled. + * ============================================================================= + */ +extern const uint8_t* +ud_insn_ptr(const struct ud* u) +{ + return (u->inp_buf == NULL) ? + u->inp_sess : u->inp_buf + (u->inp_buf_index - u->inp_ctr); +} + + +/* ============================================================================= + * ud_insn_len + * Returns the count of bytes disassembled. + * ============================================================================= + */ +extern unsigned int +ud_insn_len(const struct ud* u) +{ + return u->inp_ctr; +} + + +/* ============================================================================= + * ud_insn_get_opr + * Return the operand struct representing the nth operand of + * the currently disassembled instruction. Returns NULL if + * there's no such operand. + * ============================================================================= + */ +const struct ud_operand* +ud_insn_opr(const struct ud *u, unsigned int n) +{ + if (n > 3 || u->operand[n].type == UD_NONE) { + return NULL; + } else { + return &u->operand[n]; + } +} + + +/* ============================================================================= + * ud_opr_is_sreg + * Returns non-zero if the given operand is of a segment register type. + * ============================================================================= + */ +int +ud_opr_is_sreg(const struct ud_operand *opr) +{ + return opr->type == UD_OP_REG && + opr->base >= UD_R_ES && + opr->base <= UD_R_GS; +} + + +/* ============================================================================= + * ud_opr_is_sreg + * Returns non-zero if the given operand is of a general purpose + * register type. + * ============================================================================= + */ +int +ud_opr_is_gpr(const struct ud_operand *opr) +{ + return opr->type == UD_OP_REG && + opr->base >= UD_R_AL && + opr->base <= UD_R_R15; +} + + +/* ============================================================================= + * ud_set_user_opaque_data + * ud_get_user_opaque_data + * Get/set user opaqute data pointer + * ============================================================================= + */ +void +ud_set_user_opaque_data(struct ud * u, void* opaque) +{ + u->user_opaque_data = opaque; +} + +void* +ud_get_user_opaque_data(const struct ud *u) +{ + return u->user_opaque_data; +} + + +/* ============================================================================= + * ud_set_asm_buffer + * Allow the user to set an assembler output buffer. If `buf` is NULL, + * we switch back to the internal buffer. + * ============================================================================= + */ +void +ud_set_asm_buffer(struct ud *u, char *buf, size_t size) +{ + if (buf == NULL) { + ud_set_asm_buffer(u, u->asm_buf_int, sizeof(u->asm_buf_int)); + } else { + u->asm_buf = buf; + u->asm_buf_size = size; + } +} + + +/* ============================================================================= + * ud_set_sym_resolver + * Set symbol resolver for relative targets used in the translation + * phase. + * + * The resolver is a function that takes a uint64_t address and returns a + * symbolic name for the that address. The function also takes a second + * argument pointing to an integer that the client can optionally set to a + * non-zero value for offsetted targets. (symbol+offset) The function may + * also return NULL, in which case the translator only prints the target + * address. + * + * The function pointer maybe NULL which resets symbol resolution. + * ============================================================================= + */ +void +ud_set_sym_resolver(struct ud *u, const char* (*resolver)(struct ud*, + uint64_t addr, + int64_t *offset)) +{ + u->sym_resolver = resolver; +} + + +/* ============================================================================= + * ud_insn_mnemonic + * Return the current instruction mnemonic. + * ============================================================================= + */ +enum ud_mnemonic_code +ud_insn_mnemonic(const struct ud *u) +{ + return u->mnemonic; +} + + +/* ============================================================================= + * ud_lookup_mnemonic + * Looks up mnemonic code in the mnemonic string table. + * Returns NULL if the mnemonic code is invalid. + * ============================================================================= + */ +const char* +ud_lookup_mnemonic(enum ud_mnemonic_code c) +{ + if (c < UD_MAX_MNEMONIC_CODE) { + return ud_mnemonics_str[c]; + } else { + return NULL; + } +} + + +/* + * ud_inp_init + * Initializes the input system. + */ +static void +ud_inp_init(struct ud *u) +{ + u->inp_hook = NULL; + u->inp_buf = NULL; + u->inp_buf_size = 0; + u->inp_buf_index = 0; + u->inp_curr = 0; + u->inp_ctr = 0; + u->inp_end = 0; + u->inp_peek = UD_EOI; + UD_NON_STANDALONE(u->inp_file = NULL); +} + + +/* ============================================================================= + * ud_inp_set_hook + * Sets input hook. + * ============================================================================= + */ +void +ud_set_input_hook(register struct ud* u, int (*hook)(struct ud*)) +{ + ud_inp_init(u); + u->inp_hook = hook; +} + +/* ============================================================================= + * ud_inp_set_buffer + * Set buffer as input. + * ============================================================================= + */ +void +ud_set_input_buffer(register struct ud* u, const uint8_t* buf, size_t len) +{ + ud_inp_init(u); + u->inp_buf = buf; + u->inp_buf_size = len; + u->inp_buf_index = 0; +} + + +#ifndef __UD_STANDALONE__ +/* ============================================================================= + * ud_input_set_file + * Set FILE as input. + * ============================================================================= + */ +static int +inp_file_hook(struct ud* u) +{ + return fgetc(u->inp_file); +} + +void +ud_set_input_file(register struct ud* u, FILE* f) +{ + ud_inp_init(u); + u->inp_hook = inp_file_hook; + u->inp_file = f; +} +#endif /* __UD_STANDALONE__ */ + + +/* ============================================================================= + * ud_input_skip + * Skip n input bytes. + * ============================================================================ + */ +void +ud_input_skip(struct ud* u, size_t n) +{ + if (u->inp_end) { + return; + } + if (u->inp_buf == NULL) { + while (n--) { + int c = u->inp_hook(u); + if (c == UD_EOI) { + goto eoi; + } + } + return; + } else { + if (n > u->inp_buf_size || + u->inp_buf_index > u->inp_buf_size - n) { + u->inp_buf_index = u->inp_buf_size; + goto eoi; + } + u->inp_buf_index += n; + return; + } +eoi: + u->inp_end = 1; + UDERR(u, "cannot skip, eoi received\b"); + return; +} + + +/* ============================================================================= + * ud_input_end + * Returns non-zero on end-of-input. + * ============================================================================= + */ +int +ud_input_end(const struct ud *u) +{ + return u->inp_end; +} + +/* vim:set ts=2 sw=2 expandtab */ diff --git a/deps/udis86/udis86.h b/deps/udis86/udis86.h new file mode 100644 index 0000000..bdd3857 --- /dev/null +++ b/deps/udis86/udis86.h @@ -0,0 +1,33 @@ +/* udis86 - udis86.h + * + * Copyright (c) 2002-2009 Vivek Thampi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef UDIS86_H +#define UDIS86_H + +#include "libudis86/types.h" +#include "libudis86/extern.h" +#include "libudis86/itab.h" + +#endif diff --git a/premake5.bat b/premake5.bat new file mode 100644 index 0000000..1d11692 --- /dev/null +++ b/premake5.bat @@ -0,0 +1,2 @@ +premake5 vs2017 +pause \ No newline at end of file diff --git a/premake5.exe b/premake5.exe new file mode 100644 index 0000000..ebe7ae7 Binary files /dev/null and b/premake5.exe differ diff --git a/premake5.lua b/premake5.lua new file mode 100644 index 0000000..3e0e349 --- /dev/null +++ b/premake5.lua @@ -0,0 +1,71 @@ +workspace "OpenParrot" + configurations { "Debug", "Release"} + platforms { "x64", "x86" } + + flags { "StaticRuntime", "No64BitChecks" } + + systemversion "10.0.16299.0" + + symbols "On" + + characterset "Unicode" + + flags { "NoIncrementalLink", "NoEditAndContinue", "NoMinimalRebuild" } + + includedirs { "deps/inc/", "deps/udis86/" } + + libdirs { "deps/lib/" } + + buildoptions { "/MP", "/std:c++17" } + + configuration "Debug*" + targetdir "build/bin/debug" + defines "NDEBUG" + objdir "build/obj/debug" + + configuration "Release*" + targetdir "build/bin/release" + defines "NDEBUG" + optimize "speed" + objdir "build/obj/release" + + filter "platforms:x86" + architecture "x32" + + filter "platforms:x64" + architecture "x64" + +project "MinHook" + targetname "MinHook" + language "C" + kind "StaticLib" + + files + { + "deps/src/buffer.c", "deps/src/hook.c", + "deps/src/trampoline.c", + } + + filter "platforms:x86" + files { "deps/src/hde/hde32.c" } + + filter "platforms:x64" + files { "deps/src/hde/hde64.c" } + +project "udis86" + targetname "udis86" + language "C" + kind "StaticLib" + + includedirs + { + "deps/udis86/" + } + + files + { + "deps/udis86/libudis86/*.c" + } + +include "OpenParrot" +include "OpenParrotLoader" \ No newline at end of file