Files
2022-08-19 11:16:05 +08:00

108 lines
3.4 KiB
C++

#pragma once
#define DETOUR_INSTRUCTION_TARGET_NONE ((PVOID)0)
#define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PVOID)(LONG_PTR)-1)
PVOID
NTAPI
DetourCopyInstruction(
_In_opt_ PVOID pDst,
_Inout_opt_ PVOID* ppDstPool,
_In_ PVOID pSrc,
_Out_opt_ PVOID* ppTarget,
_Out_opt_ LONG* pExtra
);
// nFlagBits flags
enum class FlagBits {
None = 0x0,
Dynamic = 0x1,
Address = 0x2,
NoEnlarge = 0x4,
Rax = 0x8,
};
DEFINE_ENUM_FLAG_OPERATORS(FlagBits);
// ModR/M flags
enum class ModRm : UCHAR{
Sib = 0x10,
Rip = 0x20,
NotSib = 0x0f,
};
DEFINE_ENUM_FLAG_OPERATORS(ModRm);
struct Disasm {
Disasm(PUCHAR* ppTarget, LONG* pExtra);
PUCHAR CopyInstruction(PUCHAR pDst, PUCHAR pSrc);
struct CopyEntry;
typedef const CopyEntry* RefCopyEntry;
typedef PUCHAR (Disasm::* CopyFunc)(RefCopyEntry pEntry, PUCHAR pDst, PUCHAR pSrc);
struct CopyEntry {
ULONG FixedSize : 4;
ULONG FixedSize16 : 4;
ULONG ModOffset : 4;
ULONG RelOffset : 4;
FlagBits FlagBits : 4;
CopyFunc pfCopy;
};
PUCHAR CopyBytes(RefCopyEntry pEntry, PUCHAR pDst, PUCHAR pSrc);
PUCHAR CopyBytesPrefix(RefCopyEntry pEntry, PUCHAR pDst, PUCHAR pSrc);
PUCHAR CopyBytesSegment(RefCopyEntry pEntry, PUCHAR pDst, PUCHAR pSrc);
PUCHAR CopyBytesRax(RefCopyEntry pEntry, PUCHAR pDst, PUCHAR pSrc);
PUCHAR CopyBytesJump(RefCopyEntry pEntry, PUCHAR pDst, PUCHAR pSrc);
PUCHAR Invalid(RefCopyEntry pEntry, PUCHAR pDst, PUCHAR pSrc);
PUCHAR AdjustTarget(PUCHAR pDst, PUCHAR pSrc, ULONG op, ULONG targetOffset,
ULONG targetSize);
protected:
PUCHAR Copy0F(RefCopyEntry pEntry, PUCHAR pDst, PUCHAR pSrc);
// x86 only sldt/0 str/1 lldt/2 ltr/3 err/4 verw/5 jmpe/6/dynamic invalid/7
PUCHAR Copy0F00(RefCopyEntry pEntry, PUCHAR pDst, PUCHAR pSrc);
// vmread, 66/extrq/ib/ib, F2/insertq/ib/ib
PUCHAR Copy0F78(RefCopyEntry pEntry, PUCHAR pDst, PUCHAR pSrc);
// jmpe or F3/popcnt
PUCHAR Copy0FB8(RefCopyEntry pEntry, PUCHAR pDst, PUCHAR pSrc);
PUCHAR Copy66(RefCopyEntry pEntry, PUCHAR pDst, PUCHAR pSrc);
PUCHAR Copy67(RefCopyEntry pEntry, PUCHAR pDst, PUCHAR pSrc);
PUCHAR CopyF2(RefCopyEntry pEntry, PUCHAR pDst, PUCHAR pSrc);
PUCHAR CopyF3(RefCopyEntry pEntry, PUCHAR pDst, PUCHAR pSrc);
PUCHAR CopyF6(RefCopyEntry pEntry, PUCHAR pDst, PUCHAR pSrc);
PUCHAR CopyF7(RefCopyEntry pEntry, PUCHAR pDst, PUCHAR pSrc);
PUCHAR CopyFF(RefCopyEntry pEntry, PUCHAR pDst, PUCHAR pSrc);
PUCHAR CopyVex2(RefCopyEntry pEntry, PUCHAR pDst, PUCHAR pSrc);
PUCHAR CopyVex3(RefCopyEntry pEntry, PUCHAR pDst, PUCHAR pSrc);
PUCHAR CopyVexCommon(UCHAR m, PUCHAR pDst, PUCHAR pSrc);
PUCHAR CopyVexEvexCommon(UCHAR m, PUCHAR pDst, PUCHAR pSrc, UCHAR p, UCHAR fp16 = 0);
PUCHAR CopyEvex(RefCopyEntry pEntry, PUCHAR pDst, PUCHAR pSrc);
PUCHAR CopyXop(RefCopyEntry pEntry, PUCHAR pDst, PUCHAR pSrc);
protected:
static const CopyEntry s_CopyTable[];
static const CopyEntry s_CopyTable0F[];
static const UCHAR s_ModRm[256];
static inline PUCHAR s_pModuleBeg{ nullptr };
static inline PUCHAR s_pModuleEnd{ (PUCHAR)~(ULONG_PTR)0 };
static inline bool s_fLimitReferencesToModule{ false };
protected:
bool m_OperandOverride{ false };
bool m_AddressOverride{ false };
bool m_RaxOverride{ false }; // AMD64 only
bool m_Vex{ false };
bool m_Evex{ false };
bool m_F2{ false };
bool m_F3{ false }; // x86 only
UCHAR m_SegmentOverride;
PUCHAR* m_ppTarget;
LONG* m_pExtra;
LONG m_ScratchExtra;
PUCHAR m_pScratchTarget;
UCHAR m_ScratchDst[64]; // matches or exceeds rbCode
};