RoboGuard v3.7 - Source
Isto são para programadores, caso você seja um novato, tente compila-lo e mandar pelo XAT que nós postamos no AG compilado.
Main.CPP
Code:
#define WIN32_LEAN_AND_MEAN #define WIN32_EXTRA_LEAN #include#include #include #include #include #include #include #include using namespace std; #include "Detour/CDetour.h" #define ONCE( var ) static bool var = false; if(! var ){ var = true; bool CompareByteArrays(BYTE* data1, BYTE* data2, int len){ // If both are null, they're equal if (data1==NULL && data2==NULL) return true; // If either but not both are null, they're not equal if (data1==NULL || data2==NULL) return false; for (int i=0; i < len; i++){ if (data1[i] != data2[i]) if(data2[i] != 0xEE) return false; } return true; } DWORD m_CodeBase = 0x00400000; DWORD m_CodeLength = 0x001C5000; DWORD SigSearch(BYTE* Signature, int SigLength) { BYTE* test = NULL; for(unsigned int i = 0; i < (m_CodeLength-SigLength); i++) { if(CompareByteArrays((BYTE*)((DWORD)m_CodeBase + i), Signature,SigLength)) { return (DWORD)m_CodeBase + i; } } return 0; } //ServerAnnounce BYTE ServerAnnounceSignature[] = {0X64,0XA1,0X00,0X00,0X00,0X00,0X6A,0XFF,0X68,0XEE,0XEE,0XEE,0XEE,0X50,0X8B,0X44,0X24,0XEE,0X64,0X89,0X25,0X00,0X00,0X00,0X00,0X53,0X56,0X57,0X50,0X68,0X92,0X01,0X00,0X00,}; DWORD ServerAnnounceSignatureOffset = SigSearch(ServerAnnounceSignature, 34); //OnAdminAnnounce BYTE OnAdminAnnounceSignature[] = {0X6A,0XFF,0X68,0XEE,0XEE,0XEE,0XEE,0X64,0XA1,0X00,0X00,0X00,0X00,0X50,0X64,0X89,0X25,0X00,0X00,0X00,0X00,0X81,0XEC,0X10,0X01,0X00,0X00,}; DWORD OnAdminAnnounceSignatureOffset = SigSearch(OnAdminAnnounceSignature, 27); //OnStageStart BYTE OnStageStartSignature[] = {0X55,0X8B,0XEC,0X83,0XE4,0XF8,0X6A,0XFF,0X68,0XEE,0XEE,0XEE,0XEE,0X50,0X64,0X89,0X25,0X00,0X00,0X00,0X00,0X81,0XEC,0X30,0X04,0X00,0X00,}; DWORD OnStageStartSignatureOffset = SigSearch(OnStageStartSignature, 27); //OnGameKill BYTE OnGameKillSignature[] = {0X64,0XA1,0X00,0X00,0X00,0X00,0X6A,0XFF,0X68,0XEE,0XEE,0XEE,0XEE,0X50,0X8B,0X44,0X24,0X14,0X64,0X89,0X25,0X00,0X00,0X00,0X00,0X83,0XEC,0X14,0X53,0X55,0X56,0X50,}; DWORD OnGameKillSignatureOffset = SigSearch(OnGameKillSignature, 32); //OnUserWhisper BYTE OnUserWhisperSignature[] = {0X6A,0XFF,0X68,0XEE,0XEE,0XEE,0XEE,0X50,0X64,0X89,0X25,0X00,0X00,0X00,0X00,0X83,0XEC,0X10,0X8B,0X44,0X24,0X24,0X56,}; DWORD OnUserWhisperSignatureOffset = SigSearch(OnUserWhisperSignature, 23); //OnChannelChat BYTE OnChannelChatSignature[] = {0XE9,0XEE,0XEE,0XEE,0XEE,0XCC,0XCC,0XCC,0XCC,0XCC,0XCC,0XCC,0XCC,0XCC,0XCC,0XCC,0X8B,0X44,0X24,0X08,0X56,0X57,0X8B,0XF1,0X50,}; DWORD OnChannelChatSignatureOffset = SigSearch(OnChannelChatSignature, 25); //OnStageChat BYTE OnStageChatSignature[] = {0X53,0X8B,0X5C,0X24,0X0C,0X55,0X8B,0X6C,0X24,0X0C,0X56,0X57,0X8B,0X7C,0X24,}; DWORD OnStageChatSignatureOffset = SigSearch(OnStageChatSignature, 15); //OnClanMessage BYTE OnClanMessageSignature[] = {0X6A,0XFF,0X68,0XEE,0XEE,0XEE,0XEE,0X64,0XA1,0X00,0X00,0X00,0X00,0X50,0X64,0X89,0X25,0X00,0X00,0X00,0X00,0X81,0XEC,0X14,0X03,0X00,0X00,}; DWORD OnClanMessageSignatureOffset = SigSearch(OnClanMessageSignature, 27); //OnStageCreate BYTE OnStageCreateSignature[] = {0X83,0XEC,0X10,0X53,0X8B,0X5C,0X24,0X18,0X56,0X57,0X53,0X8B,0XF1,0XE8,0XEE,0XEE,0XEE,0XEE,0X8B,0XF8,0X85,0XFF,}; DWORD OnStageCreateSignatureOffset = SigSearch(OnStageCreateSignature, 22); HMODULE g_hLocalModule = NULL; DWORD g_dwUnloadRetAddr = 0; __declspec(naked) void UnloadProc(){ __asm push g_hLocalModule __asm push g_dwUnloadRetAddr __asm jmp dword ptr [FreeLibrary] } struct MUID{ long firstID; long secondID; }MYUID; MUID* Char1ID = new MUID(); MUID* Char2ID = new MUID(); MUID* StageID = new MUID(); long n; long uidChar; long uidClanAdmin; long uidStage; char pszMessage[128]; //Announcement typedef void(__cdecl* ServerAnnounceFunc)(MUID* uidChar,char*); ServerAnnounceFunc ServerAnnounce = (ServerAnnounceFunc)ServerAnnounceSignatureOffset; //Mega PowerLevel Patch DWORD OnGameKill = OnGameKillSignatureOffset; CDetour OnGameKillDet; void __stdcall OnGameKillHook(MUID* uidChar,MUID* uidChar2){ Sleep(800); } //Admin Announce Buffer Patch DWORD OnAdminAnnounce = OnAdminAnnounceSignatureOffset; // 0x00416370; CDetour OnAdminAnnounceDet; void __stdcall OnAdminAnnounceHook(MUID* uidChar,char* pszMessage,unsigned long unknown){ if(strlen(pszMessage)>128) { pszMessage = "\0"; } if(unknown = 1){ unknown = 0; } } //Whisper Buffer Patch DWORD OnWhisper = OnUserWhisperSignatureOffset; CDetour OnWhisperDet; void __stdcall OnWhisperHook(MUID* uidChar,char* pszSenderName,char* pszTargetName,char* pszMessage){ if(strlen(pszMessage)>128) { pszMessage = "I have attempted to crash you. Please report me."; } } //Channel Buffer Patch DWORD OnChannelChat = OnChannelChatSignatureOffset; CDetour OnChannelChatDet; void __stdcall OnChannelChatHook(MUID* uidChar,MUID* uidChannel,char* pszMessage){ if(strlen(pszMessage)>128) { pszMessage = "I have attempted to crash the channel. Please report me."; } } //Stage Buffer Patch DWORD OnStageChat = OnStageChatSignatureOffset; CDetour OnStageChatDet; void __stdcall OnStageChatHook(MUID* uidChar,MUID* uidStage,char* pszMessage){ if(strlen(pszMessage)>128) { pszMessage = "I have attempted to crash the stage. Please report me."; } } //Clan Buffer Patch DWORD OnClanMsg = OnClanMessageSignatureOffset; CDetour OnClanMsgDet; void __stdcall OnClanMsgHook(MUID* uidChar, char* pszMessage){ if(strlen(pszMessage)>128){ pszMessage = "\0"; } } void Initialize(){ //Mega PowerLevel Patch OnGameKillDet.Detour((BYTE*)OnGameKill, (BYTE*)OnGameKillHook, true); OnGameKillDet.Apply(); //Admin Announce Patch OnAdminAnnounceDet.Detour((BYTE*)OnAdminAnnounce, (BYTE*)OnAdminAnnounceHook, true); OnAdminAnnounceDet.Apply(); //Whisper Buffer Patch OnWhisperDet.Detour((BYTE*)OnWhisper, (BYTE*)OnWhisperHook, true); OnWhisperDet.Apply(); //Channel Buffer Patch OnChannelChatDet.Detour((BYTE*)OnChannelChat, (BYTE*)OnChannelChatHook, true); OnChannelChatDet.Apply(); //Stage Buffer Patch OnStageChatDet.Detour((BYTE*)OnStageChat, (BYTE*)OnStageChatHook, true); OnStageChatDet.Apply(); MessageBox(0,"GZRoboGuard v3.7 Injected!","Coded by OneWhoSighs",MB_ICONINFORMATION); } /********************************************************************************/ //Remove the detours/patches when unloaded void Shutdown(){ //Mega PowerLevel Patch OnGameKillDet.Remove(); //Admin Announce Patch OnAdminAnnounceDet.Remove(); //Whisper Buffer Patch OnWhisperDet.Remove(); //Channel Buffer Patch OnChannelChatDet.Remove(); //Stage Buffer Patch OnStageChatDet.Remove(); } /********************************************************************************/ bool WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved){ if(dwReason == DLL_PROCESS_ATTACH){ ONCE(bHasLoaded) g_hLocalModule = hModule; Initialize(); } } else if(dwReason == DLL_PROCESS_DETACH){ ONCE(bHasShutdown) Shutdown(); } } return true; }
DETOUR FOLDER
Credits to LanceVorgin
Detour/CDetour.h
Code:
/***************************** * Universal Detour Class * * v2.0 * ****************************** * By LanceVorgin * ****************************** * UNI owns all * *****************************/ #pragma once #include "CByteArray.h" typedef void* (__cdecl* CDetourOrg_Func)( ... ); class CDetour { public: static int Applied(); static int Removed(); static void InitRand(); private: static int g_iApplied; static int g_iRemoved; static void* __cdecl NullOrgFunc( ... ); static CDetourOrg_Func NullOrg; public: CDetour(); ~CDetour(); bool Detour(BYTE* pAddr, BYTE* pFuncToCall, bool bAutoReturn = false, bool bNoRegs = false, bool bPolymorphic = false, int iArgsOverride = -1, int iBytesToOverwrite = -1); bool Detour(LPCSTR lpLibraryName, LPCSTR lpProcName, BYTE* pFuncToCall, bool bAutoReturn = false, bool bNoRegs = false, bool bPolymorphic = false, int iArgsOverride = -1, int iBytesToOverwrite = -1); bool Apply(); bool Remove(); bool IsReady(); bool IsApplied(); BYTE* GetAddr(); BYTE* GetFuncToCall(); void SetFuncToCall(BYTE* pFuncToCall); BYTE* GetRetAddress(); BYTE* GetGateRetAddress(); void SetGateRetAddress(BYTE* pGateRetAddress); BYTE* GetThisPtr(); void SetThisPtr(BYTE* pThisPtr); void NoSetThisPtr(bool bNoSetThisPtr); void Ret(bool bReturnToOriginal); CDetourOrg_Func Org; private: void Deconstruct(); void FreeBuffers(); bool Generate(); int GetDetourSize(); bool GenerateDetour(CByteArray& Buffer, BYTE* pBase, BYTE* pTarget, int iFinalSize = -1); bool WriteToAddr(BYTE* pBuffer, int iSize); bool m_bReady; bool m_bApplied; bool m_bAutoReturn; bool m_bNoRegs; bool m_bPolymorphic; int m_iArgsOverride; int m_iBytesToOverwrite; BYTE* m_pAddr; BYTE* m_pFuncToCall; BYTE m_ubDetourType; int m_iDetourSize; BYTE* m_pOrgAfterDetour; BYTE* m_pDetourBuf; BYTE* m_pOrgBuf; BYTE* m_pGateBuf; BYTE* m_pOrgGateBuf; bool m_bDontReplaceOrgClassInstance; BYTE* m_pGateStack; BYTE* m_pGateRealRet; bool m_bReturnToOriginal; BYTE* m_pAutoReturnEndStack; BYTE* m_pRetAddress; BYTE* m_pClassInstance; BYTE* m_pOrgReturnAddress; BYTE* m_pOrgStack; }; class CSimpleDetour { public: static int Applied(); static int Removed(); private: static int g_iApplied; static int g_iRemoved; public: CSimpleDetour(); ~CSimpleDetour(); bool Detour(BYTE* pAddr, BYTE* pFuncToCall, bool bExecuteOverwrittenOps = true, int iBytesToOverwrite = 0); bool Apply(); bool Remove(); bool IsReady(); bool IsApplied(); BYTE* GetAddr(); BYTE* GetFuncToCall(); void SetFuncToCall(BYTE* pFuncToCall); BYTE* GetRetAddress(); void Ret(bool bReturnToOriginal); private: void Deconstruct(); void FreeBuffers(); bool Generate(); bool WriteToAddr(BYTE* pBuffer, int iSize); bool m_bReady; bool m_bApplied; bool m_bExecuteOverwrittenOps; int m_iBytesToOverwrite; BYTE* m_pAddr; BYTE* m_pFuncToCall; int m_iDetourSize; BYTE* m_pOrgAfterDetour; BYTE* m_pDetourBuf; BYTE* m_pOrgBuf; BYTE* m_pGateBuf; BYTE* m_pRetAddress; };
Detour/CDetour.cpp
Code:
/***************************** * Universal Detour Class * * v2.0 * ****************************** * By LanceVorgin * ****************************** * UNI owns all * *****************************/ /* All credit for CDetourDis goes to Micro$oft GG CB for the ByteArray idea - asshole :P License: I, LanceVorgin, allow you to use these classes in any of your projects under the following conditions: * My name appears in your readme and credits along with the fact that my CDetour was used * You do not take credit for CDetour That's all. GPL, closed source, private, it's all good :) Detour Settings: bAutoReturn - If true, after hookfunc is called, the original function will be called with the original args - unless Ret(false) has been called bNoRegs - If true, detour does not modify any registers besides esp. Use for fastcalls / other funcs that take params in regs (evil msvc 2k5) (usually, detour will save ecx and reset it in Org for class funcs) bPolymorphic - If false the detour is a jmp. If true the detour is randomiezed and impliments a random number. These are alot bigger than 5 bytes iArgsOverride - Usually, the hookfunc is defined as identical to the function hooked in both args and calling convention. With this set, the stack will be modified after the hookfunc is called as if an stdcall with x args has been called. Useful if you have a stdcall func with like 10 args that you don't give a shit about (you'd otherwise have to have 10 junk args on your hookfunc) iBytesToOverwrite - Overrides the automatic reassembler. Todo: * Add setproxy * Add Polymorph Dimension: replace push 8D 64 24 FC lea esp,[esp-4] C7 04 24 78 56 34 12 mov dword ptr [esp], 12345678h 83 EC 04 sub esp,4 C7 04 24 78 56 34 12 mov dword ptr [esp], 12345678h */ #define WIN32_LEAN_AND_MEAN #define WIN32_EXTRA_LEAN #include#include #include "CDetourDis.h" #include "CDetour.h" void* CDetour::NullOrgFunc( ... ){ return NULL; } CDetourOrg_Func CDetour::NullOrg = (CDetourOrg_Func)CDetour::NullOrgFunc; int CDetour::g_iApplied = 0; int CDetour::g_iRemoved = 0; int CDetour::Applied(){ return g_iApplied; } int CDetour::Removed(){ return g_iRemoved; } void CDetour::InitRand(){ srand(GetTickCount()); } CDetour::CDetour(){ m_pDetourBuf = NULL; m_pOrgBuf = NULL; m_pGateBuf = NULL; m_pOrgGateBuf = NULL; m_bApplied = false; Deconstruct(); }; CDetour::~CDetour(){ Deconstruct(); }; void CDetour::Deconstruct(){ m_bReady = false; if(m_bApplied) Remove(); FreeBuffers(); Org = NullOrgFunc; m_bAutoReturn = false; m_bNoRegs = false; m_bPolymorphic = false; m_iArgsOverride = -1; m_iBytesToOverwrite = -1; m_pAddr = NULL; m_pFuncToCall = NULL; m_ubDetourType = 0; m_iDetourSize = 0; m_pOrgAfterDetour = NULL; m_bDontReplaceOrgClassInstance = false; m_bReturnToOriginal = false; m_pGateStack = NULL; m_pGateRealRet = NULL; m_pAutoReturnEndStack = NULL; m_pRetAddress = NULL; m_pClassInstance = NULL; m_pOrgReturnAddress = NULL; m_pOrgStack = NULL; } void CDetour::FreeBuffers(){ m_bReady = false; if(m_pDetourBuf) delete[] m_pDetourBuf; if(m_pOrgBuf) delete[] m_pOrgBuf; if(m_pGateBuf) delete[] m_pGateBuf; if(m_pOrgGateBuf) delete[] m_pOrgGateBuf; m_pDetourBuf = NULL; m_pOrgBuf = NULL; m_pGateBuf = NULL; m_pOrgGateBuf = NULL; } bool CDetour::Detour(BYTE* pAddr, BYTE* pFuncToCall, bool bAutoReturn, bool bNoRegs, bool bPolymorphic, int iArgsOverride, int iBytesToOverwrite){ Deconstruct(); if(!pAddr || !pFuncToCall) return false; m_pAddr = pAddr; m_pFuncToCall = pFuncToCall; m_bAutoReturn = bAutoReturn; m_bNoRegs = bNoRegs; m_bPolymorphic = bPolymorphic; m_iArgsOverride = iArgsOverride; m_iBytesToOverwrite = iBytesToOverwrite; return Generate(); } bool CDetour::Detour(LPCSTR lpLibraryName, LPCSTR lpProcName, BYTE* pFuncToCall, bool bAutoReturn, bool bNoRegs, bool bPolymorphic, int iArgsOverride, int iBytesToOverwrite){ HMODULE hModule = LoadLibrary(lpLibraryName); if(!hModule) return false; BYTE* pTargetAddress = (BYTE*)GetProcAddress(hModule, lpProcName); if(!pTargetAddress) return false; return Detour(pTargetAddress, pFuncToCall, bAutoReturn, bNoRegs, bPolymorphic, iArgsOverride, iBytesToOverwrite); } bool CDetour::WriteToAddr(BYTE* pBuffer, int iSize){ if(!m_bReady) return false; DWORD dwOldProt, dwDummy; if(!VirtualProtect(m_pAddr, iSize, PAGE_EXECUTE_READWRITE, &dwOldProt)) return false; if(!memcpy(m_pAddr, pBuffer, iSize)) return false; FlushInstructionCache(GetCurrentProcess(), m_pAddr, iSize); VirtualProtect(m_pAddr, iSize, dwOldProt, &dwDummy); return true; } bool CDetour::Apply(){ if(!m_bReady || m_bApplied) return false;; if(!WriteToAddr(m_pDetourBuf, m_iDetourSize)) return false; m_bApplied = true; g_iApplied++; return true; } bool CDetour::Remove(){ if(!m_bApplied) return false; if(!WriteToAddr(m_pOrgBuf, m_iDetourSize)) return false; m_bApplied = false; g_iRemoved++; return true; } bool CDetour::IsReady(){ return m_bReady; } bool CDetour::IsApplied(){ return m_bApplied; } BYTE* CDetour::GetAddr(){ return m_pAddr; } BYTE* CDetour::GetFuncToCall(){ return m_pFuncToCall; } void CDetour::SetFuncToCall(BYTE* pFuncToCall){ m_pFuncToCall = pFuncToCall; } BYTE* CDetour::GetRetAddress(){ return m_pRetAddress; } BYTE* CDetour::GetGateRetAddress(){ return m_pGateRealRet; } void CDetour::SetGateRetAddress(BYTE* pGateRetAddress){ m_pGateRealRet = pGateRetAddress; } BYTE* CDetour::GetThisPtr(){ return m_pClassInstance; } void CDetour::SetThisPtr(BYTE* pThisPtr){ m_pClassInstance = pThisPtr; } void CDetour::NoSetThisPtr(bool bNoSetThisPtr){ m_bDontReplaceOrgClassInstance = bNoSetThisPtr; } void CDetour::Ret(bool bReturnToOriginal){ m_bReturnToOriginal = bReturnToOriginal; } int CDetour::GetDetourSize(){ CByteArray Buffer; if(!GenerateDetour(Buffer, 0, 0)) return -1; return Buffer.Size(); } #define RAND_DETOUR_TYPES 9 bool CDetour::GenerateDetour(CByteArray& Buffer, BYTE* pBase, BYTE* pTarget, int iFinalSize){ Buffer.Clear(); if(m_ubDetourType > RAND_DETOUR_TYPES) return false; DWORD dwTmpRnd = ((m_ubDetourType != 0) ? (rand() | (rand() << 16)) : 0); switch(m_ubDetourType){ case 0: Buffer += (BYTE)0xE9; //jmp Buffer += (DWORD)(pTarget - pBase - 5); break; case 1: case 2: case 3: Buffer += (BYTE)0x68; //push Buffer += (DWORD)dwTmpRnd; Buffer += (BYTE)0x81; //xor dword ptr [esp] Buffer += (BYTE)0x34; Buffer += (BYTE)0x24; Buffer += (DWORD)((DWORD)pTarget ^ dwTmpRnd); break; case 4: case 5: case 6: Buffer += (BYTE)0x68; //push Buffer += (DWORD)(((DWORD)pTarget << ((BYTE)dwTmpRnd & 31)) | ((DWORD)pTarget >> (32 - ((BYTE)dwTmpRnd & 31)))); Buffer += (BYTE)0xC1; //ror dword ptr [esp], Buffer += (BYTE)0x0C; Buffer += (BYTE)0x24; Buffer += (BYTE)dwTmpRnd; break; case 7: case 8: case 9: Buffer += (BYTE)0x68; //push Buffer += (DWORD)(pTarget - dwTmpRnd); Buffer += (BYTE)0x81; //add dword ptr [esp], Buffer += (BYTE)0x04; Buffer += (BYTE)0x24; Buffer += (DWORD)dwTmpRnd; break; } switch(m_ubDetourType){ case 1: case 4: case 7: Buffer += (BYTE)0xC3; //ret break; case 2: case 5: case 8: Buffer += (BYTE)0xC2; //retn Buffer += (WORD)0; break; case 3: case 6: case 9: Buffer += (BYTE)0x83; //add esp, 4 Buffer += (BYTE)0xC4; Buffer += (BYTE)0x04; Buffer += (BYTE)0xFF; //jmp dword ptr [esp-4] Buffer += (BYTE)0x64; Buffer += (BYTE)0x24; Buffer += (BYTE)0xFC; break; } if(iFinalSize != -1){ if(iFinalSize < (int)Buffer.Size()) return false; while((int)Buffer.Size() < iFinalSize) Buffer += (BYTE)OP_NOP; } return true; } bool CDetour::Generate(){ FreeBuffers(); CByteArray Buffer; //----------------- if(m_bPolymorphic) m_ubDetourType = (BYTE)(rand() % RAND_DETOUR_TYPES) + 1; else m_ubDetourType = 0; int iRawDetourSize = GetDetourSize(); if(iRawDetourSize == -1) return false; if(m_iBytesToOverwrite > 0) if(m_iBytesToOverwrite < iRawDetourSize){ if(!m_bPolymorphic) return false; for(m_ubDetourType = 1; m_ubDetourType <= RAND_DETOUR_TYPES; m_ubDetourType++){ iRawDetourSize = GetDetourSize(); if(iRawDetourSize <= m_iBytesToOverwrite) break; } if(m_ubDetourType > RAND_DETOUR_TYPES) return false; } //----------------- //DWORD dwOldProt, dwDummy; //if(!VirtualProtect((void*)m_dwAddr, iRawDetourSize, PAGE_EXECUTE_READWRITE, &dwOldProt)) // return false; //----------------- Buffer.Clear(); if(!m_bNoRegs){ Buffer += (BYTE)0x89; //mov dword ptr, ecx Buffer += (BYTE)0x0D; Buffer += (DWORD)&m_pClassInstance; } Buffer += (BYTE)0x8F; //pop dword ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_pRetAddress; Buffer += (BYTE)0x83; //sub esp, 4 Buffer += (BYTE)0xEC; Buffer += (BYTE)0x04; int iCallOrgEndOffsetIndex = -1; int iCallOrgEndOffset = -1; if(m_bAutoReturn){ //Buffer += (BYTE)0xCC; Buffer += (BYTE)0xC6; //mov byte ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_bReturnToOriginal; Buffer += (BYTE)1; Buffer += (BYTE)0x8F; //pop dword ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_pGateRealRet; Buffer += (BYTE)0x89; //mov dword ptr, esp Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pGateStack; Buffer += (BYTE)0xFF; //call dword ptr Buffer += (BYTE)0x15; Buffer += (DWORD)&m_pFuncToCall; Buffer += (BYTE)0x80; //cmp byte ptr Buffer += (BYTE)0x3D; Buffer += (DWORD)&m_bReturnToOriginal; Buffer += (BYTE)0; Buffer += (BYTE)0x74; //je iCallOrgEndOffsetIndex = Buffer + (BYTE)0; if(m_iArgsOverride <= 0){ Buffer += (BYTE)0x89; //mov dword ptr, esp Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pAutoReturnEndStack; } Buffer += (BYTE)0x8B; //mov esp, dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pGateStack; Buffer += (BYTE)0xFF; //call dword ptr Buffer += (BYTE)0x15; Buffer += (DWORD)&m_pOrgGateBuf; if(m_iArgsOverride > 0){ iCallOrgEndOffset = Buffer.Peek() - iCallOrgEndOffsetIndex - 1; Buffer += (BYTE)0x8B; //mov esp, dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pGateStack; Buffer += (BYTE)0xFF; //push dword ptr Buffer += (BYTE)0x35; Buffer += (DWORD)&m_pGateRealRet; Buffer += (BYTE)0xC2; //retn Buffer += (WORD)(m_iArgsOverride * 4); }else{ Buffer += (BYTE)0x8B; //mov esp, dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pAutoReturnEndStack; iCallOrgEndOffset = Buffer.Peek() - iCallOrgEndOffsetIndex - 1; Buffer += (BYTE)0xFF; //jmp dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pGateRealRet; } }else if(m_iArgsOverride > 0){ Buffer += (BYTE)0x8F; //pop dword ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_pGateRealRet; Buffer += (BYTE)0x89; //mov dword ptr, esp Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pGateStack; Buffer += (BYTE)0xFF; //call dword ptr Buffer += (BYTE)0x15; Buffer += (DWORD)&m_pFuncToCall; Buffer += (BYTE)0x8B; //mov esp, dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pGateStack; Buffer += (BYTE)0xFF; //push dword ptr Buffer += (BYTE)0x35; Buffer += (DWORD)&m_pGateRealRet; Buffer += (BYTE)0xC2; //retn Buffer += (WORD)(m_iArgsOverride * 4); }else{ Buffer += (BYTE)0xFF; //jmp dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pFuncToCall; } m_pGateBuf = Buffer.Copy(); if(m_bAutoReturn) *(BYTE*)&m_pGateBuf[iCallOrgEndOffsetIndex] = (BYTE)iCallOrgEndOffset; //----------------- Buffer.Clear(); Buffer += (BYTE)0x8F; //pop dword ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_pOrgReturnAddress; Buffer += (BYTE)0x89; //mov dword ptr, esp Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pOrgStack; Buffer += (BYTE)0x83; //add esp, 4 Buffer += (BYTE)0xEC; Buffer += (BYTE)0x04; Buffer += (BYTE)0xC7; //mov dword ptr [esp], Buffer += (BYTE)0x04; Buffer += (BYTE)0x24; int iOrgReturnAddressIndex = Buffer + (DWORD)0; if(!m_bNoRegs){ Buffer += (BYTE)0x80; //cmp byte ptr Buffer += (BYTE)0x3D; Buffer += (DWORD)&m_bDontReplaceOrgClassInstance; Buffer += (BYTE)0x00; Buffer += (BYTE)0x0F; //cmove ecx, dword ptr Buffer += (BYTE)0x44; Buffer += (BYTE)0x0D; Buffer += (DWORD)&m_pClassInstance; Buffer += (BYTE)0xC6; //mov byte ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_bDontReplaceOrgClassInstance; Buffer += (BYTE)0x00; //Buffer += (BYTE)0x8B; //mov ecx, dword ptr //Buffer += (BYTE)0x0D; //Buffer += (DWORD)&m_pClassInstance; } //----- int iOverwrittenOpsIndex = Buffer.Peek(); int iOverwrittenOps = 0; int iOverwrittenBytes = 0; CDetourDis Dis(NULL, NULL); BYTE* pbSrc = m_pAddr; BYTE* pbLastOp = pbSrc; if(m_iBytesToOverwrite > 0){ iOverwrittenBytes = m_iBytesToOverwrite; pbSrc += iOverwrittenBytes; Buffer.Grow(iOverwrittenBytes); }else{ while(iOverwrittenBytes < iRawDetourSize){ pbLastOp = pbSrc; if(*pbSrc == OP_BRK) break; BYTE* pbNew = Dis.CopyInstruction(NULL, pbSrc); iOverwrittenOps++; int iDelta = (int)(pbNew - pbSrc); if((pbNew == NULL) || (iDelta == 0)){ //VirtualProtect((void*)m_pAddr, m_iDetourSize, pOldProt, &dwDummy); return false; } iOverwrittenBytes += iDelta; pbSrc += iDelta; Buffer.Grow(iDelta); pbSrc = pbNew; } } m_iDetourSize = iOverwrittenBytes; m_pOrgAfterDetour = pbSrc; //----- if(!(*pbLastOp == OP_BRK || *pbLastOp == OP_NOP)){ //align [end of function] Buffer += (BYTE)0xFF; //jmp dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pOrgAfterDetour; } int iOrgReturnAddressOffset = Buffer.Peek(); Buffer += (BYTE)0x8B; //mov esp, dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pOrgStack; Buffer += (BYTE)0xFF; //jmp dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pOrgReturnAddress; m_pOrgGateBuf = Buffer.Copy(); //----- *(DWORD*)&m_pOrgGateBuf[iOrgReturnAddressIndex] = (DWORD)&m_pOrgGateBuf[iOrgReturnAddressOffset]; BYTE* pbDst = &m_pOrgGateBuf[iOverwrittenOpsIndex]; pbSrc = (BYTE*)m_pAddr; if(m_iBytesToOverwrite > 0){ memcpy(pbDst, pbSrc, iOverwrittenBytes); }else{ for(int iCurOp = 0; iCurOp < iOverwrittenOps; iCurOp++){ BYTE* pbNew = Dis.CopyInstruction(pbDst, pbSrc); pbDst += (pbNew - pbSrc); pbSrc = pbNew; } } //----------------- if(!GenerateDetour(Buffer, m_pAddr, m_pGateBuf, m_iDetourSize)) return false; m_pDetourBuf = Buffer.Copy(); Buffer.Clear(); //----------------- Org = (CDetourOrg_Func)m_pOrgGateBuf; //----------------- m_pOrgBuf = new BYTE[m_iDetourSize]; memcpy(m_pOrgBuf, m_pAddr, m_iDetourSize); //VirtualProtect((void*)m_pAddr, m_iDetourSize, dwOldProt, &dwDummy); m_bReady = true; return true; } int CSimpleDetour::g_iApplied = 0; int CSimpleDetour::g_iRemoved = 0; int CSimpleDetour::Applied(){ return g_iApplied; } int CSimpleDetour::Removed(){ return g_iRemoved; } CSimpleDetour::CSimpleDetour(){ m_pDetourBuf = NULL; m_pOrgBuf = NULL; m_pGateBuf = NULL; Deconstruct(); }; CSimpleDetour::~CSimpleDetour(){ Deconstruct(); }; void CSimpleDetour::Deconstruct(){ m_bReady = false; if(m_bApplied) Remove(); FreeBuffers(); m_iBytesToOverwrite = 0; m_pAddr = NULL; m_pFuncToCall = NULL; m_iDetourSize = 0; m_pRetAddress = 0; } void CSimpleDetour::FreeBuffers(){ m_bReady = false; if(m_pDetourBuf) delete[] m_pDetourBuf; if(m_pOrgBuf) delete[] m_pOrgBuf; if(m_pGateBuf) delete[] m_pGateBuf; m_pDetourBuf = NULL; m_pOrgBuf = NULL; m_pGateBuf = NULL; } bool CSimpleDetour::Detour(BYTE* pAddr, BYTE* pFuncToCall, bool bExecuteOverwrittenOps, int iBytesToOverwrite){ Deconstruct(); if(!pAddr || !pFuncToCall) return false; m_pAddr = pAddr; m_pFuncToCall = pFuncToCall; m_bExecuteOverwrittenOps = bExecuteOverwrittenOps; m_iBytesToOverwrite = iBytesToOverwrite; return Generate(); } bool CSimpleDetour::WriteToAddr(BYTE* pBuffer, int iSize){ if(!m_bReady) return false;; DWORD dwOldProt, dwDummy; if(!VirtualProtect(m_pAddr, iSize, PAGE_EXECUTE_READWRITE, &dwOldProt)) return false; if(!memcpy(m_pAddr, pBuffer, iSize)) return false; FlushInstructionCache(GetCurrentProcess(), m_pAddr, iSize); VirtualProtect(m_pAddr, iSize, dwOldProt, &dwDummy); return true; } bool CSimpleDetour::Apply(){ if(!m_bReady || m_bApplied) return false;; if(!WriteToAddr(m_pDetourBuf, m_iDetourSize)) return false; m_bApplied = true; g_iApplied++; return true; } bool CSimpleDetour::Remove(){ if(!m_bApplied) return false; if(!WriteToAddr(m_pOrgBuf, m_iDetourSize)) return false; m_bApplied = false; g_iRemoved++; return true; } bool CSimpleDetour::IsReady(){ return m_bReady; } bool CSimpleDetour::IsApplied(){ return m_bApplied; } BYTE* CSimpleDetour::GetAddr(){ return m_pAddr; } BYTE* CSimpleDetour::GetFuncToCall(){ return m_pFuncToCall; } void CSimpleDetour::SetFuncToCall(BYTE* pFuncToCall){ m_pFuncToCall = pFuncToCall; } BYTE* CSimpleDetour::GetRetAddress(){ return m_pRetAddress; } bool CSimpleDetour::Generate(){ FreeBuffers(); CByteArray Buffer; //----------------- Buffer.Clear(); Buffer += (BYTE)0xE8; //call int iDetourOffsetIndex = Buffer + (DWORD)0; BYTE* pRawDetourBuf = Buffer.Copy(); int iRawDetourSize = Buffer.Peek(); if(m_iBytesToOverwrite > 0) if(m_iBytesToOverwrite < iRawDetourSize) return false; //----------------- //DWORD dwOldProt, dwDummy; //if(!VirtualProtect(m_pAddr, iRawDetourSize, PAGE_EXECUTE_READWRITE, &dwOldProt)) // return false; //----------------- Buffer.Clear(); Buffer += (BYTE)0x8F; //pop dword ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_pRetAddress; Buffer += (BYTE)0xFF; //call dword ptr Buffer += (BYTE)0x15; Buffer += (DWORD)&m_pFuncToCall; //----------------- int iOverwrittenOpsIndex = Buffer.Peek(); int iOverwrittenOps = 0; int iOverwrittenBytes = 0; CDetourDis Dis(NULL, NULL); BYTE* pbSrc = m_pAddr; BYTE* pbLastOp = pbSrc; if(m_iBytesToOverwrite > 0){ iOverwrittenBytes = m_iBytesToOverwrite; pbSrc += iOverwrittenBytes; Buffer.Grow(iOverwrittenBytes); }else{ while(iOverwrittenBytes < iRawDetourSize){ pbLastOp = pbSrc; if(*pbSrc == OP_BRK) break; BYTE* pbNew = Dis.CopyInstruction(NULL, pbSrc); iOverwrittenOps++; int iDelta = (int)(pbNew - pbSrc); if((pbNew == NULL) || (iDelta == 0)){ //VirtualProtect(m_pAddr, m_iDetourSize, dwOldProt, &dwDummy); return false; } iOverwrittenBytes += iDelta; pbSrc += iDelta; Buffer.Grow(iDelta); pbSrc = pbNew; } } m_iDetourSize = iOverwrittenBytes; //----- Buffer += (BYTE)0xFF; //jmp dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pRetAddress; m_pGateBuf = Buffer.Copy(); //----------------- BYTE* pbDst = &m_pGateBuf[iOverwrittenOpsIndex]; pbSrc = m_pAddr; if(m_iBytesToOverwrite > 0){ memcpy(pbDst, pbSrc, iOverwrittenBytes); }else{ for(int iCurOp = 0; iCurOp < iOverwrittenOps; iCurOp++){ BYTE* pbNew = Dis.CopyInstruction(pbDst, pbSrc); pbDst += (pbNew - pbSrc); pbSrc = pbNew; } } //----------------- *(int*)&pRawDetourBuf[iDetourOffsetIndex] = m_pGateBuf - m_pAddr - 5; m_pDetourBuf = new BYTE[m_iDetourSize]; memset(m_pDetourBuf, OP_NOP, m_iDetourSize); memcpy(m_pDetourBuf, pRawDetourBuf, iRawDetourSize); delete[] pRawDetourBuf; pRawDetourBuf = NULL; //----------------- m_pOrgBuf = new BYTE[m_iDetourSize]; memcpy(m_pOrgBuf, m_pAddr, m_iDetourSize); //VirtualProtect((void*)m_dwAddr, m_iDetourSize, dwOldProt, &dwDummy); m_bReady = true; return true; }
Detour/CByteArray.h
Code:
/***************************** * Universal Detour Class * * v2.0 * ****************************** * By LanceVorgin * ****************************** * UNI owns all * *****************************/ /* All credit for CDetourDis goes to Micro$oft GG CB for the ByteArray idea - asshole :P License: I, LanceVorgin, allow you to use these classes in any of your projects under the following conditions: * My name appears in your readme and credits along with the fact that my CDetour was used * You do not take credit for CDetour That's all. GPL, closed source, private, it's all good :) Detour Settings: bAutoReturn - If true, after hookfunc is called, the original function will be called with the original args - unless Ret(false) has been called bNoRegs - If true, detour does not modify any registers besides esp. Use for fastcalls / other funcs that take params in regs (evil msvc 2k5) (usually, detour will save ecx and reset it in Org for class funcs) bPolymorphic - If false the detour is a jmp. If true the detour is randomiezed and impliments a random number. These are alot bigger than 5 bytes iArgsOverride - Usually, the hookfunc is defined as identical to the function hooked in both args and calling convention. With this set, the stack will be modified after the hookfunc is called as if an stdcall with x args has been called. Useful if you have a stdcall func with like 10 args that you don't give a shit about (you'd otherwise have to have 10 junk args on your hookfunc) iBytesToOverwrite - Overrides the automatic reassembler. Todo: * Add setproxy * Add Polymorph Dimension: replace push 8D 64 24 FC lea esp,[esp-4] C7 04 24 78 56 34 12 mov dword ptr [esp], 12345678h 83 EC 04 sub esp,4 C7 04 24 78 56 34 12 mov dword ptr [esp], 12345678h */ #define WIN32_LEAN_AND_MEAN #define WIN32_EXTRA_LEAN #include#include #include "CDetourDis.h" #include "CDetour.h" void* CDetour::NullOrgFunc( ... ){ return NULL; } CDetourOrg_Func CDetour::NullOrg = (CDetourOrg_Func)CDetour::NullOrgFunc; int CDetour::g_iApplied = 0; int CDetour::g_iRemoved = 0; int CDetour::Applied(){ return g_iApplied; } int CDetour::Removed(){ return g_iRemoved; } void CDetour::InitRand(){ srand(GetTickCount()); } CDetour::CDetour(){ m_pDetourBuf = NULL; m_pOrgBuf = NULL; m_pGateBuf = NULL; m_pOrgGateBuf = NULL; m_bApplied = false; Deconstruct(); }; CDetour::~CDetour(){ Deconstruct(); }; void CDetour::Deconstruct(){ m_bReady = false; if(m_bApplied) Remove(); FreeBuffers(); Org = NullOrgFunc; m_bAutoReturn = false; m_bNoRegs = false; m_bPolymorphic = false; m_iArgsOverride = -1; m_iBytesToOverwrite = -1; m_pAddr = NULL; m_pFuncToCall = NULL; m_ubDetourType = 0; m_iDetourSize = 0; m_pOrgAfterDetour = NULL; m_bDontReplaceOrgClassInstance = false; m_bReturnToOriginal = false; m_pGateStack = NULL; m_pGateRealRet = NULL; m_pAutoReturnEndStack = NULL; m_pRetAddress = NULL; m_pClassInstance = NULL; m_pOrgReturnAddress = NULL; m_pOrgStack = NULL; } void CDetour::FreeBuffers(){ m_bReady = false; if(m_pDetourBuf) delete[] m_pDetourBuf; if(m_pOrgBuf) delete[] m_pOrgBuf; if(m_pGateBuf) delete[] m_pGateBuf; if(m_pOrgGateBuf) delete[] m_pOrgGateBuf; m_pDetourBuf = NULL; m_pOrgBuf = NULL; m_pGateBuf = NULL; m_pOrgGateBuf = NULL; } bool CDetour::Detour(BYTE* pAddr, BYTE* pFuncToCall, bool bAutoReturn, bool bNoRegs, bool bPolymorphic, int iArgsOverride, int iBytesToOverwrite){ Deconstruct(); if(!pAddr || !pFuncToCall) return false; m_pAddr = pAddr; m_pFuncToCall = pFuncToCall; m_bAutoReturn = bAutoReturn; m_bNoRegs = bNoRegs; m_bPolymorphic = bPolymorphic; m_iArgsOverride = iArgsOverride; m_iBytesToOverwrite = iBytesToOverwrite; return Generate(); } bool CDetour::Detour(LPCSTR lpLibraryName, LPCSTR lpProcName, BYTE* pFuncToCall, bool bAutoReturn, bool bNoRegs, bool bPolymorphic, int iArgsOverride, int iBytesToOverwrite){ HMODULE hModule = LoadLibrary(lpLibraryName); if(!hModule) return false; BYTE* pTargetAddress = (BYTE*)GetProcAddress(hModule, lpProcName); if(!pTargetAddress) return false; return Detour(pTargetAddress, pFuncToCall, bAutoReturn, bNoRegs, bPolymorphic, iArgsOverride, iBytesToOverwrite); } bool CDetour::WriteToAddr(BYTE* pBuffer, int iSize){ if(!m_bReady) return false; DWORD dwOldProt, dwDummy; if(!VirtualProtect(m_pAddr, iSize, PAGE_EXECUTE_READWRITE, &dwOldProt)) return false; if(!memcpy(m_pAddr, pBuffer, iSize)) return false; FlushInstructionCache(GetCurrentProcess(), m_pAddr, iSize); VirtualProtect(m_pAddr, iSize, dwOldProt, &dwDummy); return true; } bool CDetour::Apply(){ if(!m_bReady || m_bApplied) return false;; if(!WriteToAddr(m_pDetourBuf, m_iDetourSize)) return false; m_bApplied = true; g_iApplied++; return true; } bool CDetour::Remove(){ if(!m_bApplied) return false; if(!WriteToAddr(m_pOrgBuf, m_iDetourSize)) return false; m_bApplied = false; g_iRemoved++; return true; } bool CDetour::IsReady(){ return m_bReady; } bool CDetour::IsApplied(){ return m_bApplied; } BYTE* CDetour::GetAddr(){ return m_pAddr; } BYTE* CDetour::GetFuncToCall(){ return m_pFuncToCall; } void CDetour::SetFuncToCall(BYTE* pFuncToCall){ m_pFuncToCall = pFuncToCall; } BYTE* CDetour::GetRetAddress(){ return m_pRetAddress; } BYTE* CDetour::GetGateRetAddress(){ return m_pGateRealRet; } void CDetour::SetGateRetAddress(BYTE* pGateRetAddress){ m_pGateRealRet = pGateRetAddress; } BYTE* CDetour::GetThisPtr(){ return m_pClassInstance; } void CDetour::SetThisPtr(BYTE* pThisPtr){ m_pClassInstance = pThisPtr; } void CDetour::NoSetThisPtr(bool bNoSetThisPtr){ m_bDontReplaceOrgClassInstance = bNoSetThisPtr; } void CDetour::Ret(bool bReturnToOriginal){ m_bReturnToOriginal = bReturnToOriginal; } int CDetour::GetDetourSize(){ CByteArray Buffer; if(!GenerateDetour(Buffer, 0, 0)) return -1; return Buffer.Size(); } #define RAND_DETOUR_TYPES 9 bool CDetour::GenerateDetour(CByteArray& Buffer, BYTE* pBase, BYTE* pTarget, int iFinalSize){ Buffer.Clear(); if(m_ubDetourType > RAND_DETOUR_TYPES) return false; DWORD dwTmpRnd = ((m_ubDetourType != 0) ? (rand() | (rand() << 16)) : 0); switch(m_ubDetourType){ case 0: Buffer += (BYTE)0xE9; //jmp Buffer += (DWORD)(pTarget - pBase - 5); break; case 1: case 2: case 3: Buffer += (BYTE)0x68; //push Buffer += (DWORD)dwTmpRnd; Buffer += (BYTE)0x81; //xor dword ptr [esp] Buffer += (BYTE)0x34; Buffer += (BYTE)0x24; Buffer += (DWORD)((DWORD)pTarget ^ dwTmpRnd); break; case 4: case 5: case 6: Buffer += (BYTE)0x68; //push Buffer += (DWORD)(((DWORD)pTarget << ((BYTE)dwTmpRnd & 31)) | ((DWORD)pTarget >> (32 - ((BYTE)dwTmpRnd & 31)))); Buffer += (BYTE)0xC1; //ror dword ptr [esp], Buffer += (BYTE)0x0C; Buffer += (BYTE)0x24; Buffer += (BYTE)dwTmpRnd; break; case 7: case 8: case 9: Buffer += (BYTE)0x68; //push Buffer += (DWORD)(pTarget - dwTmpRnd); Buffer += (BYTE)0x81; //add dword ptr [esp], Buffer += (BYTE)0x04; Buffer += (BYTE)0x24; Buffer += (DWORD)dwTmpRnd; break; } switch(m_ubDetourType){ case 1: case 4: case 7: Buffer += (BYTE)0xC3; //ret break; case 2: case 5: case 8: Buffer += (BYTE)0xC2; //retn Buffer += (WORD)0; break; case 3: case 6: case 9: Buffer += (BYTE)0x83; //add esp, 4 Buffer += (BYTE)0xC4; Buffer += (BYTE)0x04; Buffer += (BYTE)0xFF; //jmp dword ptr [esp-4] Buffer += (BYTE)0x64; Buffer += (BYTE)0x24; Buffer += (BYTE)0xFC; break; } if(iFinalSize != -1){ if(iFinalSize < (int)Buffer.Size()) return false; while((int)Buffer.Size() < iFinalSize) Buffer += (BYTE)OP_NOP; } return true; } bool CDetour::Generate(){ FreeBuffers(); CByteArray Buffer; //----------------- if(m_bPolymorphic) m_ubDetourType = (BYTE)(rand() % RAND_DETOUR_TYPES) + 1; else m_ubDetourType = 0; int iRawDetourSize = GetDetourSize(); if(iRawDetourSize == -1) return false; if(m_iBytesToOverwrite > 0) if(m_iBytesToOverwrite < iRawDetourSize){ if(!m_bPolymorphic) return false; for(m_ubDetourType = 1; m_ubDetourType <= RAND_DETOUR_TYPES; m_ubDetourType++){ iRawDetourSize = GetDetourSize(); if(iRawDetourSize <= m_iBytesToOverwrite) break; } if(m_ubDetourType > RAND_DETOUR_TYPES) return false; } //----------------- //DWORD dwOldProt, dwDummy; //if(!VirtualProtect((void*)m_dwAddr, iRawDetourSize, PAGE_EXECUTE_READWRITE, &dwOldProt)) // return false; //----------------- Buffer.Clear(); if(!m_bNoRegs){ Buffer += (BYTE)0x89; //mov dword ptr, ecx Buffer += (BYTE)0x0D; Buffer += (DWORD)&m_pClassInstance; } Buffer += (BYTE)0x8F; //pop dword ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_pRetAddress; Buffer += (BYTE)0x83; //sub esp, 4 Buffer += (BYTE)0xEC; Buffer += (BYTE)0x04; int iCallOrgEndOffsetIndex = -1; int iCallOrgEndOffset = -1; if(m_bAutoReturn){ //Buffer += (BYTE)0xCC; Buffer += (BYTE)0xC6; //mov byte ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_bReturnToOriginal; Buffer += (BYTE)1; Buffer += (BYTE)0x8F; //pop dword ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_pGateRealRet; Buffer += (BYTE)0x89; //mov dword ptr, esp Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pGateStack; Buffer += (BYTE)0xFF; //call dword ptr Buffer += (BYTE)0x15; Buffer += (DWORD)&m_pFuncToCall; Buffer += (BYTE)0x80; //cmp byte ptr Buffer += (BYTE)0x3D; Buffer += (DWORD)&m_bReturnToOriginal; Buffer += (BYTE)0; Buffer += (BYTE)0x74; //je iCallOrgEndOffsetIndex = Buffer + (BYTE)0; if(m_iArgsOverride <= 0){ Buffer += (BYTE)0x89; //mov dword ptr, esp Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pAutoReturnEndStack; } Buffer += (BYTE)0x8B; //mov esp, dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pGateStack; Buffer += (BYTE)0xFF; //call dword ptr Buffer += (BYTE)0x15; Buffer += (DWORD)&m_pOrgGateBuf; if(m_iArgsOverride > 0){ iCallOrgEndOffset = Buffer.Peek() - iCallOrgEndOffsetIndex - 1; Buffer += (BYTE)0x8B; //mov esp, dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pGateStack; Buffer += (BYTE)0xFF; //push dword ptr Buffer += (BYTE)0x35; Buffer += (DWORD)&m_pGateRealRet; Buffer += (BYTE)0xC2; //retn Buffer += (WORD)(m_iArgsOverride * 4); }else{ Buffer += (BYTE)0x8B; //mov esp, dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pAutoReturnEndStack; iCallOrgEndOffset = Buffer.Peek() - iCallOrgEndOffsetIndex - 1; Buffer += (BYTE)0xFF; //jmp dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pGateRealRet; } }else if(m_iArgsOverride > 0){ Buffer += (BYTE)0x8F; //pop dword ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_pGateRealRet; Buffer += (BYTE)0x89; //mov dword ptr, esp Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pGateStack; Buffer += (BYTE)0xFF; //call dword ptr Buffer += (BYTE)0x15; Buffer += (DWORD)&m_pFuncToCall; Buffer += (BYTE)0x8B; //mov esp, dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pGateStack; Buffer += (BYTE)0xFF; //push dword ptr Buffer += (BYTE)0x35; Buffer += (DWORD)&m_pGateRealRet; Buffer += (BYTE)0xC2; //retn Buffer += (WORD)(m_iArgsOverride * 4); }else{ Buffer += (BYTE)0xFF; //jmp dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pFuncToCall; } m_pGateBuf = Buffer.Copy(); if(m_bAutoReturn) *(BYTE*)&m_pGateBuf[iCallOrgEndOffsetIndex] = (BYTE)iCallOrgEndOffset; //----------------- Buffer.Clear(); Buffer += (BYTE)0x8F; //pop dword ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_pOrgReturnAddress; Buffer += (BYTE)0x89; //mov dword ptr, esp Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pOrgStack; Buffer += (BYTE)0x83; //add esp, 4 Buffer += (BYTE)0xEC; Buffer += (BYTE)0x04; Buffer += (BYTE)0xC7; //mov dword ptr [esp], Buffer += (BYTE)0x04; Buffer += (BYTE)0x24; int iOrgReturnAddressIndex = Buffer + (DWORD)0; if(!m_bNoRegs){ Buffer += (BYTE)0x80; //cmp byte ptr Buffer += (BYTE)0x3D; Buffer += (DWORD)&m_bDontReplaceOrgClassInstance; Buffer += (BYTE)0x00; Buffer += (BYTE)0x0F; //cmove ecx, dword ptr Buffer += (BYTE)0x44; Buffer += (BYTE)0x0D; Buffer += (DWORD)&m_pClassInstance; Buffer += (BYTE)0xC6; //mov byte ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_bDontReplaceOrgClassInstance; Buffer += (BYTE)0x00; //Buffer += (BYTE)0x8B; //mov ecx, dword ptr //Buffer += (BYTE)0x0D; //Buffer += (DWORD)&m_pClassInstance; } //----- int iOverwrittenOpsIndex = Buffer.Peek(); int iOverwrittenOps = 0; int iOverwrittenBytes = 0; CDetourDis Dis(NULL, NULL); BYTE* pbSrc = m_pAddr; BYTE* pbLastOp = pbSrc; if(m_iBytesToOverwrite > 0){ iOverwrittenBytes = m_iBytesToOverwrite; pbSrc += iOverwrittenBytes; Buffer.Grow(iOverwrittenBytes); }else{ while(iOverwrittenBytes < iRawDetourSize){ pbLastOp = pbSrc; if(*pbSrc == OP_BRK) break; BYTE* pbNew = Dis.CopyInstruction(NULL, pbSrc); iOverwrittenOps++; int iDelta = (int)(pbNew - pbSrc); if((pbNew == NULL) || (iDelta == 0)){ //VirtualProtect((void*)m_pAddr, m_iDetourSize, pOldProt, &dwDummy); return false; } iOverwrittenBytes += iDelta; pbSrc += iDelta; Buffer.Grow(iDelta); pbSrc = pbNew; } } m_iDetourSize = iOverwrittenBytes; m_pOrgAfterDetour = pbSrc; //----- if(!(*pbLastOp == OP_BRK || *pbLastOp == OP_NOP)){ //align [end of function] Buffer += (BYTE)0xFF; //jmp dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pOrgAfterDetour; } int iOrgReturnAddressOffset = Buffer.Peek(); Buffer += (BYTE)0x8B; //mov esp, dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pOrgStack; Buffer += (BYTE)0xFF; //jmp dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pOrgReturnAddress; m_pOrgGateBuf = Buffer.Copy(); //----- *(DWORD*)&m_pOrgGateBuf[iOrgReturnAddressIndex] = (DWORD)&m_pOrgGateBuf[iOrgReturnAddressOffset]; BYTE* pbDst = &m_pOrgGateBuf[iOverwrittenOpsIndex]; pbSrc = (BYTE*)m_pAddr; if(m_iBytesToOverwrite > 0){ memcpy(pbDst, pbSrc, iOverwrittenBytes); }else{ for(int iCurOp = 0; iCurOp < iOverwrittenOps; iCurOp++){ BYTE* pbNew = Dis.CopyInstruction(pbDst, pbSrc); pbDst += (pbNew - pbSrc); pbSrc = pbNew; } } //----------------- if(!GenerateDetour(Buffer, m_pAddr, m_pGateBuf, m_iDetourSize)) return false; m_pDetourBuf = Buffer.Copy(); Buffer.Clear(); //----------------- Org = (CDetourOrg_Func)m_pOrgGateBuf; //----------------- m_pOrgBuf = new BYTE[m_iDetourSize]; memcpy(m_pOrgBuf, m_pAddr, m_iDetourSize); //VirtualProtect((void*)m_pAddr, m_iDetourSize, dwOldProt, &dwDummy); m_bReady = true; return true; } int CSimpleDetour::g_iApplied = 0; int CSimpleDetour::g_iRemoved = 0; int CSimpleDetour::Applied(){ return g_iApplied; } int CSimpleDetour::Removed(){ return g_iRemoved; } CSimpleDetour::CSimpleDetour(){ m_pDetourBuf = NULL; m_pOrgBuf = NULL; m_pGateBuf = NULL; Deconstruct(); }; CSimpleDetour::~CSimpleDetour(){ Deconstruct(); }; void CSimpleDetour::Deconstruct(){ m_bReady = false; if(m_bApplied) Remove(); FreeBuffers(); m_iBytesToOverwrite = 0; m_pAddr = NULL; m_pFuncToCall = NULL; m_iDetourSize = 0; m_pRetAddress = 0; } void CSimpleDetour::FreeBuffers(){ m_bReady = false; if(m_pDetourBuf) delete[] m_pDetourBuf; if(m_pOrgBuf) delete[] m_pOrgBuf; if(m_pGateBuf) delete[] m_pGateBuf; m_pDetourBuf = NULL; m_pOrgBuf = NULL; m_pGateBuf = NULL; } bool CSimpleDetour::Detour(BYTE* pAddr, BYTE* pFuncToCall, bool bExecuteOverwrittenOps, int iBytesToOverwrite){ Deconstruct(); if(!pAddr || !pFuncToCall) return false; m_pAddr = pAddr; m_pFuncToCall = pFuncToCall; m_bExecuteOverwrittenOps = bExecuteOverwrittenOps; m_iBytesToOverwrite = iBytesToOverwrite; return Generate(); } bool CSimpleDetour::WriteToAddr(BYTE* pBuffer, int iSize){ if(!m_bReady) return false;; DWORD dwOldProt, dwDummy; if(!VirtualProtect(m_pAddr, iSize, PAGE_EXECUTE_READWRITE, &dwOldProt)) return false; if(!memcpy(m_pAddr, pBuffer, iSize)) return false; FlushInstructionCache(GetCurrentProcess(), m_pAddr, iSize); VirtualProtect(m_pAddr, iSize, dwOldProt, &dwDummy); return true; } bool CSimpleDetour::Apply(){ if(!m_bReady || m_bApplied) return false;; if(!WriteToAddr(m_pDetourBuf, m_iDetourSize)) return false; m_bApplied = true; g_iApplied++; return true; } bool CSimpleDetour::Remove(){ if(!m_bApplied) return false; if(!WriteToAddr(m_pOrgBuf, m_iDetourSize)) return false; m_bApplied = false; g_iRemoved++; return true; } bool CSimpleDetour::IsReady(){ return m_bReady; } bool CSimpleDetour::IsApplied(){ return m_bApplied; } BYTE* CSimpleDetour::GetAddr(){ return m_pAddr; } BYTE* CSimpleDetour::GetFuncToCall(){ return m_pFuncToCall; } void CSimpleDetour::SetFuncToCall(BYTE* pFuncToCall){ m_pFuncToCall = pFuncToCall; } BYTE* CSimpleDetour::GetRetAddress(){ return m_pRetAddress; } bool CSimpleDetour::Generate(){ FreeBuffers(); CByteArray Buffer; //----------------- Buffer.Clear(); Buffer += (BYTE)0xE8; //call int iDetourOffsetIndex = Buffer + (DWORD)0; BYTE* pRawDetourBuf = Buffer.Copy(); int iRawDetourSize = Buffer.Peek(); if(m_iBytesToOverwrite > 0) if(m_iBytesToOverwrite < iRawDetourSize) return false; //----------------- //DWORD dwOldProt, dwDummy; //if(!VirtualProtect(m_pAddr, iRawDetourSize, PAGE_EXECUTE_READWRITE, &dwOldProt)) // return false; //----------------- Buffer.Clear(); Buffer += (BYTE)0x8F; //pop dword ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_pRetAddress; Buffer += (BYTE)0xFF; //call dword ptr Buffer += (BYTE)0x15; Buffer += (DWORD)&m_pFuncToCall; //----------------- int iOverwrittenOpsIndex = Buffer.Peek(); int iOverwrittenOps = 0; int iOverwrittenBytes = 0; CDetourDis Dis(NULL, NULL); BYTE* pbSrc = m_pAddr; BYTE* pbLastOp = pbSrc; if(m_iBytesToOverwrite > 0){ iOverwrittenBytes = m_iBytesToOverwrite; pbSrc += iOverwrittenBytes; Buffer.Grow(iOverwrittenBytes); }else{ while(iOverwrittenBytes < iRawDetourSize){ pbLastOp = pbSrc; if(*pbSrc == OP_BRK) break; BYTE* pbNew = Dis.CopyInstruction(NULL, pbSrc); iOverwrittenOps++; int iDelta = (int)(pbNew - pbSrc); if((pbNew == NULL) || (iDelta == 0)){ //VirtualProtect(m_pAddr, m_iDetourSize, dwOldProt, &dwDummy); return false; } iOverwrittenBytes += iDelta; pbSrc += iDelta; Buffer.Grow(iDelta); pbSrc = pbNew; } } m_iDetourSize = iOverwrittenBytes; //----- Buffer += (BYTE)0xFF; //jmp dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pRetAddress; m_pGateBuf = Buffer.Copy(); //----------------- BYTE* pbDst = &m_pGateBuf[iOverwrittenOpsIndex]; pbSrc = m_pAddr; if(m_iBytesToOverwrite > 0){ memcpy(pbDst, pbSrc, iOverwrittenBytes); }else{ for(int iCurOp = 0; iCurOp < iOverwrittenOps; iCurOp++){ BYTE* pbNew = Dis.CopyInstruction(pbDst, pbSrc); pbDst += (pbNew - pbSrc); pbSrc = pbNew; } } //----------------- *(int*)&pRawDetourBuf[iDetourOffsetIndex] = m_pGateBuf - m_pAddr - 5; m_pDetourBuf = new BYTE[m_iDetourSize]; memset(m_pDetourBuf, OP_NOP, m_iDetourSize); memcpy(m_pDetourBuf, pRawDetourBuf, iRawDetourSize); delete[] pRawDetourBuf; pRawDetourBuf = NULL; //----------------- m_pOrgBuf = new BYTE[m_iDetourSize]; memcpy(m_pOrgBuf, m_pAddr, m_iDetourSize); //VirtualProtect((void*)m_dwAddr, m_iDetourSize, dwOldProt, &dwDummy); m_bReady = true; return true; }
Detour/CDetourDis.cpp
Code:
////////////////////////////////////////////////////////////////////////////// // // Module: detours.lib // File: disasm.cpp // // Detours for binary functions. Version 1.5 (Build 46) // Includes support for all x86 chips prior to the Pentium III. // // Copyright 1999-2001, Microsoft Corporation // #define WIN32_LEAN_AND_MEAN #define WIN32_EXTRA_LEAN #include//#include //#include "detours.h" //#include "disasm.h" #include "CDetourDis.h" #undef ASSERT #define ASSERT(x) ////////////////////////////////////////////////////////////////////////////// // // Function: // DetourCopyInstruction(PBYTE pbDst, PBYTE pbSrc, PBYTE* ppbTarget) // Purpose: // Copy a single instruction from pbSrc to pbDst. // Arguments: // pbDst: // Destination address for the instruction. May be NULL in which // case DetourCopyInstruction is used to measure an instruction. // If not NULL then the source instruction is copied to the // destination instruction and any relative arguments are adjusted. // pbSrc: // Source address of the instruction. // ppbTarget: // Out parameter for any target instruction address pointed to by // the instruction. For example, a branch or a jump insruction has // a target, but a load or store instruction doesn't. A target is // another instruction that may be executed as a result of this // instruction. ppbTarget may be NULL. // plExtra: // Out parameter for the number of extra bytes needed by the // instruction to reach the target. For example, lExtra = 3 if the // instruction had an 8-bit relative offset, but needs a 32-bit // relative offset. // Returns: // Returns the address of the next instruction (following in the source) // instruction. By subtracting pbSrc from the return value, the caller // can determinte the size of the instruction copied. // Comments: // By following the pbTarget, the caller can follow alternate // instruction streams. However, it is not always possible to determine // the target based on static analysis. For example, the destination of // a jump relative to a register cannot be determined from just the // instruction stream. The output value, pbTarget, can have any of the // following outputs: // DETOUR_INSTRUCTION_TARGET_NONE: // The instruction has no targets. // DETOUR_INSTRUCTION_TARGET_DYNAMIC: // The instruction has a non-deterministic (dynamic) target. // (i.e. the jump is to an address held in a register.) // Address: The instruction has the specified target. // // When copying instructions, DetourCopyInstruction insures that any // targets remain constant. It does so by adjusting any IP relative // offsets. // PBYTE WINAPI DetourCopyInstructionEx(PBYTE pbDst, PBYTE pbSrc, PBYTE* ppbTarget, LONG* plExtra){ CDetourDis oDetourDisasm(ppbTarget, plExtra); return oDetourDisasm.CopyInstruction(pbDst, pbSrc); } PBYTE WINAPI DetourCopyInstruction(PBYTE pbDst, PBYTE pbSrc, PBYTE* ppbTarget){ CDetourDis oDetourDisasm(ppbTarget, NULL); return oDetourDisasm.CopyInstruction(pbDst, pbSrc); } /////////////////////////////////////////////////////////// Disassembler Code. CDetourDis::CDetourDis(PBYTE* ppbTarget, LONG* plExtra){ Set32BitOperand(); Set32BitAddress(); m_ppbTarget = ppbTarget ? ppbTarget : &m_pbScratchTarget; m_plExtra = plExtra ? plExtra : &m_lScratchExtra; *m_ppbTarget = DETOUR_INSTRUCTION_TARGET_NONE; *m_plExtra = 0; m_pbDstOverride = 0; m_bAdjustZero = FALSE; } VOID CDetourDis::Set16BitOperand(){ m_b16BitOperand = TRUE; } VOID CDetourDis::Set32BitOperand(){ m_b16BitOperand = FALSE; } VOID CDetourDis::Set16BitAddress(){ m_b16BitAddress = TRUE; } VOID CDetourDis::Set32BitAddress(){ m_b16BitAddress = FALSE; } PBYTE CDetourDis::CopyInstruction(PBYTE pbDst, PBYTE pbSrc){ // Configure scratch areas if real areas are not available. if(NULL == pbDst) pbDst = m_rbScratchDst; if(NULL == pbSrc){ // We can't copy a non-existent instruction. SetLastError(ERROR_INVALID_DATA); return NULL; } // Figure out how big the instruction is, do the appropriate copy, // and figure out what the target of the instruction is if any. REFCOPYENTRY pEntry = &s_rceCopyTable[pbSrc[0]]; return (this->*pEntry->pfCopy)(pEntry, pbDst, pbSrc); } PBYTE CDetourDis::CopyInstructionEx(PBYTE pbDst, PBYTE pbSrc, PBYTE pbDstOverride){ m_pbDstOverride = pbDstOverride; PBYTE pbRet = CopyInstruction(pbDst, pbSrc); m_pbDstOverride = NULL; return pbRet; } PBYTE CDetourDis::CopyInstructionZero(PBYTE pbDst, PBYTE pbSrc){ m_bAdjustZero = TRUE; PBYTE pbRet = CopyInstructionEx(pbDst, pbSrc, NULL); m_bAdjustZero = FALSE; return pbRet; } BYTE CDetourDis::InstructionLen(PBYTE pbSrc){ PBYTE pbDst = m_rbScratchDst; if(NULL == pbSrc){ // We can't copy a non-existent instruction. SetLastError(ERROR_INVALID_DATA); return NULL; } // Figure out how big the instruction is, do the appropriate copy, // and figure out what the target of the instruction is if any. REFCOPYENTRY pEntry = &s_rceCopyTable[pbSrc[0]]; PBYTE pbEnd = (this->*pEntry->pfCopy)(pEntry, pbDst, pbSrc); if(!pbEnd) return 0; return (BYTE)(pbEnd - pbSrc); } PBYTE CDetourDis::CopyBytes(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc){ LONG nBytesFixed = (pEntry->nFlagBits & ADDRESS) ? (m_b16BitAddress ? pEntry->nFixedSize16 : pEntry->nFixedSize) : (m_b16BitOperand ? pEntry->nFixedSize16 : pEntry->nFixedSize); LONG nBytes = nBytesFixed; BYTE bAddrOfs = 0; if(pEntry->nModOffset > 0){ BYTE bModRm = pbSrc[pEntry->nModOffset]; BYTE bFlags = s_rbModRm[bModRm]; if((bFlags & NOENLARGE) && ((bFlags & NOTSIB) == 4)) bAddrOfs = (BYTE)pEntry->nModOffset + 1; if(bFlags & SIB){ BYTE bSib = pbSrc[pEntry->nModOffset + 1]; if((bSib & 0x07) == 0x05){ if((bModRm & 0xc0) == 0x00) nBytes += 4; else if((bModRm & 0xc0) == 0x40) nBytes += 1; else if ((bModRm & 0xc0) == 0x80) nBytes += 4; } } nBytes += bFlags & NOTSIB; } CopyMemory(pbDst, pbSrc, nBytes); if(m_bAdjustZero && bAddrOfs) *(DWORD*)&pbDst[bAddrOfs] = 0; if(pEntry->nRelOffset) *m_ppbTarget = AdjustTarget(pbDst, pbSrc, nBytesFixed, pEntry->nRelOffset); if(pEntry->nFlagBits & NOENLARGE) *m_plExtra = -*m_plExtra; if(pEntry->nFlagBits & DYNAMIC) *m_ppbTarget = DETOUR_INSTRUCTION_TARGET_DYNAMIC; return pbSrc + nBytes; } PBYTE CDetourDis::CopyBytesPrefix(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc){ CopyBytes(pEntry, pbDst, pbSrc); pEntry = &s_rceCopyTable[pbSrc[1]]; return (this->*pEntry->pfCopy)(pEntry, pbDst + 1, pbSrc + 1); } PBYTE CDetourDis::AdjustTarget(PBYTE pbDst, PBYTE pbSrc, LONG cbOp, LONG cbTargetOffset){ LONG cbTargetSize = cbOp - cbTargetOffset; PBYTE pbTarget = NULL; PVOID pvTargetAddr = &pbDst[cbTargetOffset]; LONG nOldOffset = 0; switch(cbTargetSize){ case 1: nOldOffset = (LONG)*(PCHAR&)pvTargetAddr; *m_plExtra = 3; break; case 2: nOldOffset = (LONG)*(PSHORT&)pvTargetAddr; *m_plExtra = 2; break; case 4: nOldOffset = (LONG)*(PLONG&)pvTargetAddr; *m_plExtra = 0; break; default: ASSERT(!"cbTargetSize is invalid."); break; } pbTarget = pbSrc + cbOp + nOldOffset; LONG nNewOffset = nOldOffset - (((m_pbDstOverride != NULL) ? m_pbDstOverride : pbDst) - pbSrc); switch (cbTargetSize) { case 1: *(PCHAR&)pvTargetAddr = (CHAR)nNewOffset; break; case 2: *(PSHORT&)pvTargetAddr = (SHORT)nNewOffset; break; case 4: *(PLONG&)pvTargetAddr = (LONG)nNewOffset; break; } ASSERT(pbDst + cbOp + nNewOffset == pbTarget); return pbTarget; } PBYTE CDetourDis::Invalid(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc){ (void)pbDst; (void)pEntry; ASSERT(!"Invalid Instruction"); return pbSrc + 1; } ////////////////////////////////////////////////////// Individual Bytes Codes. PBYTE CDetourDis::Copy0F(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc){ CopyBytes(pEntry, pbDst, pbSrc); pEntry = &s_rceCopyTable0F[pbSrc[1]]; return (this->*pEntry->pfCopy)(pEntry, pbDst + 1, pbSrc + 1); } PBYTE CDetourDis::Copy66(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc){ // Operand-size override prefix Set16BitOperand(); return CopyBytesPrefix(pEntry, pbDst, pbSrc); } PBYTE CDetourDis::Copy67(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc){ // Address size override prefix Set16BitAddress(); return CopyBytesPrefix(pEntry, pbDst, pbSrc); } PBYTE CDetourDis::CopyF6(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc){ (void)pEntry; // TEST BYTE /0 if(0x00 == (0x38 & pbSrc[1])){ // reg(bits 543) of ModR/M == 0 const COPYENTRY ce = { 0xf6, ENTRY_CopyBytes2Mod1 }; return (this->*ce.pfCopy)(&ce, pbDst, pbSrc); } // DIV /6 // IDIV /7 // IMUL /5 // MUL /4 // NEG /3 // NOT /2 const COPYENTRY ce = { 0xf6, ENTRY_CopyBytes2Mod }; return (this->*ce.pfCopy)(&ce, pbDst, pbSrc); } PBYTE CDetourDis::CopyF7(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc){ (void)pEntry; // TEST WORD /0 if(0x00 == (0x38 & pbSrc[1])){ // reg(bits 543) of ModR/M == 0 const COPYENTRY ce = {0xf7, ENTRY_CopyBytes2ModOperand}; return (this->*ce.pfCopy)(&ce, pbDst, pbSrc); } // DIV /6 // IDIV /7 // IMUL /5 // MUL /4 // NEG /3 // NOT /2 const COPYENTRY ce = { 0xf7, ENTRY_CopyBytes2Mod }; return (this->*ce.pfCopy)(&ce, pbDst, pbSrc); } PBYTE CDetourDis::CopyFF(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc){ // CALL /2 // CALL /3 // INC /0 // JMP /4 // JMP /5 // PUSH /6 (void)pEntry; if(0x15 == pbSrc[1] || 0x25 == pbSrc[1]){ // CALL [], JMP [] PBYTE* ppbTarget = *(PBYTE**)&pbSrc[2]; *m_ppbTarget = *ppbTarget; }else if(0x10 == (0x38 & pbSrc[1]) || // CALL /2 --> reg(bits 543) of ModR/M == 010 0x18 == (0x38 & pbSrc[1]) || // CALL /3 --> reg(bits 543) of ModR/M == 011 0x20 == (0x38 & pbSrc[1]) || // JMP /4 --> reg(bits 543) of ModR/M == 100 0x28 == (0x38 & pbSrc[1]) // JMP /5 --> reg(bits 543) of ModR/M == 101 ){ *m_ppbTarget = DETOUR_INSTRUCTION_TARGET_DYNAMIC; } const COPYENTRY ce = { 0xff, ENTRY_CopyBytes2Mod }; return (this->*ce.pfCopy)(&ce, pbDst, pbSrc); } ///////////////////////////////////////////////////////// Disassembler Tables. const BYTE CDetourDis::s_rbModRm[256] = { 0,0,0,0, SIB|1,4,0,0, 0,0,0,0, SIB|1,4,0,0, // 0x 0,0,0,0, SIB|1,4,0,0, 0,0,0,0, SIB|1,4,0,0, // 1x 0,0,0,0, SIB|1,4,0,0, 0,0,0,0, SIB|1,4,0,0, // 2x 0,0,0,0, SIB|1,4,0,0, 0,0,0,0, SIB|1,4,0,0, // 3x 1,1,1,1, 2,1,1,1, 1,1,1,1, 2,1,1,1, // 4x 1,1,1,1, 2,1,1,1, 1,1,1,1, 2,1,1,1, // 5x 1,1,1,1, 2,1,1,1, 1,1,1,1, 2,1,1,1, // 6x 1,1,1,1, 2,1,1,1, 1,1,1,1, 2,1,1,1, // 7x 4,4,4,4, 5,4,4,4, 4,4,4,4, 5,4,4,4, // 8x 4,4,4,4, 5,4,4,4, 4,4,4,4, 5,4,4,4, // 9x 4,4,4,4, 5,4,4,4, 4,4,4,4, 5,4,4,4, // Ax 4,4,4,4, 5,4,4,4, 4,4,4,4, 5,4,4,4, // Bx 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // Cx 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // Dx 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // Ex 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 // Fx }; const CDetourDis::COPYENTRY CDetourDis::s_rceCopyTable[257] = { { 0x00, ENTRY_CopyBytes2Mod }, // ADD /r { 0x01, ENTRY_CopyBytes2Mod }, // ADD /r { 0x02, ENTRY_CopyBytes2Mod }, // ADD /r { 0x03, ENTRY_CopyBytes2Mod }, // ADD /r { 0x04, ENTRY_CopyBytes2 }, // ADD ib { 0x05, ENTRY_CopyBytes3Or5 }, // ADD iw { 0x06, ENTRY_CopyBytes1 }, // PUSH { 0x07, ENTRY_CopyBytes1 }, // POP { 0x08, ENTRY_CopyBytes2Mod }, // OR /r { 0x09, ENTRY_CopyBytes2Mod }, // OR /r { 0x0A, ENTRY_CopyBytes2Mod }, // OR /r { 0x0B, ENTRY_CopyBytes2Mod }, // OR /r { 0x0C, ENTRY_CopyBytes2 }, // OR ib { 0x0D, ENTRY_CopyBytes3Or5 }, // OR iw { 0x0E, ENTRY_CopyBytes1 }, // PUSH { 0x0F, ENTRY_Copy0F }, // Extension Ops { 0x10, ENTRY_CopyBytes2Mod }, // ADC /r { 0x11, ENTRY_CopyBytes2Mod }, // ADC /r { 0x12, ENTRY_CopyBytes2Mod }, // ADC /r { 0x13, ENTRY_CopyBytes2Mod }, // ADC /r { 0x14, ENTRY_CopyBytes2 }, // ADC ib { 0x15, ENTRY_CopyBytes3Or5 }, // ADC id { 0x16, ENTRY_CopyBytes1 }, // PUSH { 0x17, ENTRY_CopyBytes1 }, // POP { 0x18, ENTRY_CopyBytes2Mod }, // SBB /r { 0x19, ENTRY_CopyBytes2Mod }, // SBB /r { 0x1A, ENTRY_CopyBytes2Mod }, // SBB /r { 0x1B, ENTRY_CopyBytes2Mod }, // SBB /r { 0x1C, ENTRY_CopyBytes2 }, // SBB ib { 0x1D, ENTRY_CopyBytes3Or5 }, // SBB id { 0x1E, ENTRY_CopyBytes1 }, // PUSH { 0x1F, ENTRY_CopyBytes1 }, // POP { 0x20, ENTRY_CopyBytes2Mod }, // AND /r { 0x21, ENTRY_CopyBytes2Mod }, // AND /r { 0x22, ENTRY_CopyBytes2Mod }, // AND /r { 0x23, ENTRY_CopyBytes2Mod }, // AND /r { 0x24, ENTRY_CopyBytes2 }, // AND ib { 0x25, ENTRY_CopyBytes3Or5 }, // AND id { 0x26, ENTRY_CopyBytesPrefix }, // ES prefix { 0x27, ENTRY_CopyBytes1 }, // DAA { 0x28, ENTRY_CopyBytes2Mod }, // SUB /r { 0x29, ENTRY_CopyBytes2Mod }, // SUB /r { 0x2A, ENTRY_CopyBytes2Mod }, // SUB /r { 0x2B, ENTRY_CopyBytes2Mod }, // SUB /r { 0x2C, ENTRY_CopyBytes2 }, // SUB ib { 0x2D, ENTRY_CopyBytes3Or5 }, // SUB id { 0x2E, ENTRY_CopyBytesPrefix }, // CS prefix { 0x2F, ENTRY_CopyBytes1 }, // DAS { 0x30, ENTRY_CopyBytes2Mod }, // XOR /r { 0x31, ENTRY_CopyBytes2Mod }, // XOR /r { 0x32, ENTRY_CopyBytes2Mod }, // XOR /r { 0x33, ENTRY_CopyBytes2Mod }, // XOR /r { 0x34, ENTRY_CopyBytes2 }, // XOR ib { 0x35, ENTRY_CopyBytes3Or5 }, // XOR id { 0x36, ENTRY_CopyBytesPrefix }, // SS prefix { 0x37, ENTRY_CopyBytes1 }, // AAA { 0x38, ENTRY_CopyBytes2Mod }, // CMP /r { 0x39, ENTRY_CopyBytes2Mod }, // CMP /r { 0x3A, ENTRY_CopyBytes2Mod }, // CMP /r { 0x3B, ENTRY_CopyBytes2Mod }, // CMP /r { 0x3C, ENTRY_CopyBytes2 }, // CMP ib { 0x3D, ENTRY_CopyBytes3Or5 }, // CMP id { 0x3E, ENTRY_CopyBytesPrefix }, // DS prefix { 0x3F, ENTRY_CopyBytes1 }, // AAS { 0x40, ENTRY_CopyBytes1 }, // INC { 0x41, ENTRY_CopyBytes1 }, // INC { 0x42, ENTRY_CopyBytes1 }, // INC { 0x43, ENTRY_CopyBytes1 }, // INC { 0x44, ENTRY_CopyBytes1 }, // INC { 0x45, ENTRY_CopyBytes1 }, // INC { 0x46, ENTRY_CopyBytes1 }, // INC { 0x47, ENTRY_CopyBytes1 }, // INC { 0x48, ENTRY_CopyBytes1 }, // DEC { 0x49, ENTRY_CopyBytes1 }, // DEC { 0x4A, ENTRY_CopyBytes1 }, // DEC { 0x4B, ENTRY_CopyBytes1 }, // DEC { 0x4C, ENTRY_CopyBytes1 }, // DEC { 0x4D, ENTRY_CopyBytes1 }, // DEC { 0x4E, ENTRY_CopyBytes1 }, // DEC { 0x4F, ENTRY_CopyBytes1 }, // DEC { 0x50, ENTRY_CopyBytes1 }, // PUSH { 0x51, ENTRY_CopyBytes1 }, // PUSH { 0x52, ENTRY_CopyBytes1 }, // PUSH { 0x53, ENTRY_CopyBytes1 }, // PUSH { 0x54, ENTRY_CopyBytes1 }, // PUSH { 0x55, ENTRY_CopyBytes1 }, // PUSH { 0x56, ENTRY_CopyBytes1 }, // PUSH { 0x57, ENTRY_CopyBytes1 }, // PUSH { 0x58, ENTRY_CopyBytes1 }, // POP { 0x59, ENTRY_CopyBytes1 }, // POP { 0x5A, ENTRY_CopyBytes1 }, // POP { 0x5B, ENTRY_CopyBytes1 }, // POP { 0x5C, ENTRY_CopyBytes1 }, // POP { 0x5D, ENTRY_CopyBytes1 }, // POP { 0x5E, ENTRY_CopyBytes1 }, // POP { 0x5F, ENTRY_CopyBytes1 }, // POP { 0x60, ENTRY_CopyBytes1 }, // PUSHAD { 0x61, ENTRY_CopyBytes1 }, // POPAD { 0x62, ENTRY_CopyBytes2Mod }, // BOUND /r { 0x63, ENTRY_CopyBytes2Mod }, // ARPL /r { 0x64, ENTRY_CopyBytesPrefix }, // FS prefix { 0x65, ENTRY_CopyBytesPrefix }, // GS prefix { 0x66, ENTRY_Copy66 }, // Operand Prefix { 0x67, ENTRY_Copy67 }, // Address Prefix { 0x68, ENTRY_CopyBytes3Or5 }, // PUSH { 0x69, ENTRY_CopyBytes2ModOperand }, // { 0x6A, ENTRY_CopyBytes2 }, // PUSH { 0x6B, ENTRY_CopyBytes2Mod1 }, // IMUL /r ib { 0x6C, ENTRY_CopyBytes1 }, // INS { 0x6D, ENTRY_CopyBytes1 }, // INS { 0x6E, ENTRY_CopyBytes1 }, // OUTS/OUTSB { 0x6F, ENTRY_CopyBytes1 }, // OUTS/OUTSW { 0x70, ENTRY_CopyBytes2Jump }, // JO { 0x71, ENTRY_CopyBytes2Jump }, // JNO { 0x72, ENTRY_CopyBytes2Jump }, // JB/JC/JNAE { 0x73, ENTRY_CopyBytes2Jump }, // JAE/JNB/JNC { 0x74, ENTRY_CopyBytes2Jump }, // JE/JZ { 0x75, ENTRY_CopyBytes2Jump }, // JNE/JNZ { 0x76, ENTRY_CopyBytes2Jump }, // JBE/JNA { 0x77, ENTRY_CopyBytes2Jump }, // JA/JNBE { 0x78, ENTRY_CopyBytes2Jump }, // JS { 0x79, ENTRY_CopyBytes2Jump }, // JNS { 0x7A, ENTRY_CopyBytes2Jump }, // JP/JPE { 0x7B, ENTRY_CopyBytes2Jump }, // JNP/JPO { 0x7C, ENTRY_CopyBytes2Jump }, // JL/JNGE { 0x7D, ENTRY_CopyBytes2Jump }, // JGE/JNL { 0x7E, ENTRY_CopyBytes2Jump }, // JLE/JNG { 0x7F, ENTRY_CopyBytes2Jump }, // JG/JNLE { 0x80, ENTRY_CopyBytes2Mod1 }, // ADC/2 ib, etc.s { 0x81, ENTRY_CopyBytes2ModOperand }, // { 0x82, ENTRY_CopyBytes2 }, // MOV al,x { 0x83, ENTRY_CopyBytes2Mod1 }, // ADC/2 ib, etc. { 0x84, ENTRY_CopyBytes2Mod }, // TEST /r { 0x85, ENTRY_CopyBytes2Mod }, // TEST /r { 0x86, ENTRY_CopyBytes2Mod }, // XCHG /r @todo { 0x87, ENTRY_CopyBytes2Mod }, // XCHG /r @todo { 0x88, ENTRY_CopyBytes2Mod }, // MOV /r { 0x89, ENTRY_CopyBytes2Mod }, // MOV /r { 0x8A, ENTRY_CopyBytes2Mod }, // MOV /r { 0x8B, ENTRY_CopyBytes2Mod }, // MOV /r { 0x8C, ENTRY_CopyBytes2Mod }, // MOV /r { 0x8D, ENTRY_CopyBytes2Mod }, // LEA /r { 0x8E, ENTRY_CopyBytes2Mod }, // MOV /r { 0x8F, ENTRY_CopyBytes2Mod }, // POP /0 { 0x90, ENTRY_CopyBytes1 }, // NOP { 0x91, ENTRY_CopyBytes1 }, // XCHG { 0x92, ENTRY_CopyBytes1 }, // XCHG { 0x93, ENTRY_CopyBytes1 }, // XCHG { 0x94, ENTRY_CopyBytes1 }, // XCHG { 0x95, ENTRY_CopyBytes1 }, // XCHG { 0x96, ENTRY_CopyBytes1 }, // XCHG { 0x97, ENTRY_CopyBytes1 }, // XCHG { 0x98, ENTRY_CopyBytes1 }, // CWDE { 0x99, ENTRY_CopyBytes1 }, // CDQ { 0x9A, ENTRY_CopyBytes5Or7Dynamic }, // CALL cp { 0x9B, ENTRY_CopyBytes1 }, // WAIT/FWAIT { 0x9C, ENTRY_CopyBytes1 }, // PUSHFD { 0x9D, ENTRY_CopyBytes1 }, // POPFD { 0x9E, ENTRY_CopyBytes1 }, // SAHF { 0x9F, ENTRY_CopyBytes1 }, // LAHF { 0xA0, ENTRY_CopyBytes3Or5Address }, // MOV { 0xA1, ENTRY_CopyBytes3Or5Address }, // MOV { 0xA2, ENTRY_CopyBytes3Or5Address }, // MOV { 0xA3, ENTRY_CopyBytes3Or5Address }, // MOV { 0xA4, ENTRY_CopyBytes1 }, // MOVS { 0xA5, ENTRY_CopyBytes1 }, // MOVS/MOVSD { 0xA6, ENTRY_CopyBytes1 }, // CMPS/CMPSB { 0xA7, ENTRY_CopyBytes1 }, // CMPS/CMPSW { 0xA8, ENTRY_CopyBytes2 }, // TEST { 0xA9, ENTRY_CopyBytes3Or5 }, // TEST { 0xAA, ENTRY_CopyBytes1 }, // STOS/STOSB { 0xAB, ENTRY_CopyBytes1 }, // STOS/STOSW { 0xAC, ENTRY_CopyBytes1 }, // LODS/LODSB { 0xAD, ENTRY_CopyBytes1 }, // LODS/LODSW { 0xAE, ENTRY_CopyBytes1 }, // SCAS/SCASB { 0xAF, ENTRY_CopyBytes1 }, // SCAS/SCASD { 0xB0, ENTRY_CopyBytes2 }, // MOV B0+rb { 0xB1, ENTRY_CopyBytes2 }, // MOV B0+rb { 0xB2, ENTRY_CopyBytes2 }, // MOV B0+rb { 0xB3, ENTRY_CopyBytes2 }, // MOV B0+rb { 0xB4, ENTRY_CopyBytes2 }, // MOV B0+rb { 0xB5, ENTRY_CopyBytes2 }, // MOV B0+rb { 0xB6, ENTRY_CopyBytes2 }, // MOV B0+rb { 0xB7, ENTRY_CopyBytes2 }, // MOV B0+rb { 0xB8, ENTRY_CopyBytes3Or5 }, // MOV B8+rb { 0xB9, ENTRY_CopyBytes3Or5 }, // MOV B8+rb { 0xBA, ENTRY_CopyBytes3Or5 }, // MOV B8+rb { 0xBB, ENTRY_CopyBytes3Or5 }, // MOV B8+rb { 0xBC, ENTRY_CopyBytes3Or5 }, // MOV B8+rb { 0xBD, ENTRY_CopyBytes3Or5 }, // MOV B8+rb { 0xBE, ENTRY_CopyBytes3Or5 }, // MOV B8+rb { 0xBF, ENTRY_CopyBytes3Or5 }, // MOV B8+rb { 0xC0, ENTRY_CopyBytes2Mod1 }, // RCL/2 ib, etc. { 0xC1, ENTRY_CopyBytes2Mod1 }, // RCL/2 ib, etc. { 0xC2, ENTRY_CopyBytes3 }, // RET { 0xC3, ENTRY_CopyBytes1 }, // RET { 0xC4, ENTRY_CopyBytes2Mod }, // LES { 0xC5, ENTRY_CopyBytes2Mod }, // LDS { 0xC6, ENTRY_CopyBytes2Mod1 }, // MOV { 0xC7, ENTRY_CopyBytes2ModOperand }, // MOV { 0xC8, ENTRY_CopyBytes4 }, // ENTER { 0xC9, ENTRY_CopyBytes1 }, // LEAVE { 0xCA, ENTRY_CopyBytes3Dynamic }, // RET { 0xCB, ENTRY_CopyBytes1Dynamic }, // RET { 0xCC, ENTRY_CopyBytes1Dynamic }, // INT 3 { 0xCD, ENTRY_CopyBytes2Dynamic }, // INT ib { 0xCE, ENTRY_CopyBytes1Dynamic }, // INTO { 0xCF, ENTRY_CopyBytes1Dynamic }, // IRET { 0xD0, ENTRY_CopyBytes2Mod }, // RCL/2, etc. { 0xD1, ENTRY_CopyBytes2Mod }, // RCL/2, etc. { 0xD2, ENTRY_CopyBytes2Mod }, // RCL/2, etc. { 0xD3, ENTRY_CopyBytes2Mod }, // RCL/2, etc. { 0xD4, ENTRY_CopyBytes2 }, // AAM { 0xD5, ENTRY_CopyBytes2 }, // AAD { 0xD6, ENTRY_Invalid }, // { 0xD7, ENTRY_CopyBytes1 }, // XLAT/XLATB { 0xD8, ENTRY_CopyBytes2Mod }, // FADD, etc. { 0xD9, ENTRY_CopyBytes2Mod }, // F2XM1, etc. { 0xDA, ENTRY_CopyBytes2Mod }, // FLADD, etc. { 0xDB, ENTRY_CopyBytes2Mod }, // FCLEX, etc. { 0xDC, ENTRY_CopyBytes2Mod }, // FADD/0, etc. { 0xDD, ENTRY_CopyBytes2Mod }, // FFREE, etc. { 0xDE, ENTRY_CopyBytes2Mod }, // FADDP, etc. { 0xDF, ENTRY_CopyBytes2Mod }, // FBLD/4, etc. { 0xE0, ENTRY_CopyBytes2CantJump }, // LOOPNE cb { 0xE1, ENTRY_CopyBytes2CantJump }, // LOOPE cb { 0xE2, ENTRY_CopyBytes2CantJump }, // LOOP cb { 0xE3, ENTRY_CopyBytes2Jump }, // JCXZ/JECXZ { 0xE4, ENTRY_CopyBytes2 }, // IN ib { 0xE5, ENTRY_CopyBytes2 }, // IN id { 0xE6, ENTRY_CopyBytes2 }, // OUT ib { 0xE7, ENTRY_CopyBytes2 }, // OUT ib { 0xE8, ENTRY_CopyBytes3Or5Target }, // CALL cd { 0xE9, ENTRY_CopyBytes3Or5Target }, // JMP cd { 0xEA, ENTRY_CopyBytes5Or7Dynamic }, // JMP cp { 0xEB, ENTRY_CopyBytes2Jump }, // JMP cb { 0xEC, ENTRY_CopyBytes1 }, // IN ib { 0xED, ENTRY_CopyBytes1 }, // IN id { 0xEE, ENTRY_CopyBytes1 }, // OUT { 0xEF, ENTRY_CopyBytes1 }, // OUT { 0xF0, ENTRY_CopyBytesPrefix }, // LOCK prefix { 0xF1, ENTRY_Invalid }, // { 0xF2, ENTRY_CopyBytesPrefix }, // REPNE prefix { 0xF3, ENTRY_CopyBytesPrefix }, // REPE prefix { 0xF4, ENTRY_CopyBytes1 }, // HLT { 0xF5, ENTRY_CopyBytes1 }, // CMC { 0xF6, ENTRY_CopyF6 }, // TEST/0, DIV/6 { 0xF7, ENTRY_CopyF7 }, // TEST/0, DIV/6 { 0xF8, ENTRY_CopyBytes1 }, // CLC { 0xF9, ENTRY_CopyBytes1 }, // STC { 0xFA, ENTRY_CopyBytes1 }, // CLI { 0xFB, ENTRY_CopyBytes1 }, // STI { 0xFC, ENTRY_CopyBytes1 }, // CLD { 0xFD, ENTRY_CopyBytes1 }, // STD { 0xFE, ENTRY_CopyBytes2Mod }, // DEC/1,INC/0 { 0xFF, ENTRY_CopyFF }, // CALL/2 { 0, ENTRY_End }, }; const CDetourDis::COPYENTRY CDetourDis::s_rceCopyTable0F[257] = { { 0x00, ENTRY_CopyBytes2Mod }, // LLDT/2, etc. { 0x01, ENTRY_CopyBytes2Mod }, // INVLPG/7, etc. { 0x02, ENTRY_CopyBytes2Mod }, // LAR/r { 0x03, ENTRY_CopyBytes2Mod }, // LSL/r { 0x04, ENTRY_Invalid }, // _04 { 0x05, ENTRY_Invalid }, // _05 { 0x06, ENTRY_CopyBytes2 }, // CLTS { 0x07, ENTRY_Invalid }, // _07 { 0x08, ENTRY_CopyBytes2 }, // INVD { 0x09, ENTRY_CopyBytes2 }, // WBINVD { 0x0A, ENTRY_Invalid }, // _0A { 0x0B, ENTRY_CopyBytes2 }, // UD2 { 0x0C, ENTRY_Invalid }, // _0C { 0x0D, ENTRY_Invalid }, // _0D { 0x0E, ENTRY_Invalid }, // _0E { 0x0F, ENTRY_Invalid }, // _0F { 0x10, ENTRY_Invalid }, // _10 { 0x11, ENTRY_Invalid }, // _11 { 0x12, ENTRY_Invalid }, // _12 { 0x13, ENTRY_Invalid }, // _13 { 0x14, ENTRY_Invalid }, // _14 { 0x15, ENTRY_Invalid }, // _15 { 0x16, ENTRY_Invalid }, // _16 { 0x17, ENTRY_Invalid }, // _17 { 0x18, ENTRY_Invalid }, // _18 { 0x19, ENTRY_Invalid }, // _19 { 0x1A, ENTRY_Invalid }, // _1A { 0x1B, ENTRY_Invalid }, // _1B { 0x1C, ENTRY_Invalid }, // _1C { 0x1D, ENTRY_Invalid }, // _1D { 0x1E, ENTRY_Invalid }, // _1E { 0x1F, ENTRY_Invalid }, // _1F { 0x20, ENTRY_CopyBytes2Mod }, // MOV/r { 0x21, ENTRY_CopyBytes2Mod }, // MOV/r { 0x22, ENTRY_CopyBytes2Mod }, // MOV/r { 0x23, ENTRY_CopyBytes2Mod }, // MOV/r { 0x24, ENTRY_Invalid }, // _24 { 0x25, ENTRY_Invalid }, // _25 { 0x26, ENTRY_Invalid }, // _26 { 0x27, ENTRY_Invalid }, // _27 { 0x28, ENTRY_Invalid }, // _28 { 0x29, ENTRY_Invalid }, // _29 { 0x2A, ENTRY_Invalid }, // _2A { 0x2B, ENTRY_Invalid }, // _2B { 0x2C, ENTRY_Invalid }, // _2C { 0x2D, ENTRY_Invalid }, // _2D { 0x2E, ENTRY_Invalid }, // _2E { 0x2F, ENTRY_Invalid }, // _2F { 0x30, ENTRY_CopyBytes2 }, // WRMSR { 0x31, ENTRY_CopyBytes2 }, // RDTSC { 0x32, ENTRY_CopyBytes2 }, // RDMSR { 0x33, ENTRY_CopyBytes2 }, // RDPMC { 0x34, ENTRY_CopyBytes2 }, // SYSENTER { 0x35, ENTRY_CopyBytes2 }, // SYSEXIT { 0x36, ENTRY_Invalid }, // _36 { 0x37, ENTRY_Invalid }, // _37 { 0x38, ENTRY_Invalid }, // _38 { 0x39, ENTRY_Invalid }, // _39 { 0x3A, ENTRY_Invalid }, // _3A { 0x3B, ENTRY_Invalid }, // _3B { 0x3C, ENTRY_Invalid }, // _3C { 0x3D, ENTRY_Invalid }, // _3D { 0x3E, ENTRY_Invalid }, // _3E { 0x3F, ENTRY_Invalid }, // _3F { 0x40, ENTRY_CopyBytes2Mod }, // CMOVO (0F 40) { 0x41, ENTRY_CopyBytes2Mod }, // CMOVNO (0F 41) { 0x42, ENTRY_CopyBytes2Mod }, // CMOVB & CMOVNE (0F 42) { 0x43, ENTRY_CopyBytes2Mod }, // CMOVAE & CMOVNB (0F 43) { 0x44, ENTRY_CopyBytes2Mod }, // CMOVE & CMOVZ (0F 44) { 0x45, ENTRY_CopyBytes2Mod }, // CMOVNE & CMOVNZ (0F 45) { 0x46, ENTRY_CopyBytes2Mod }, // CMOVBE & CMOVNA (0F 46) { 0x47, ENTRY_CopyBytes2Mod }, // CMOVA & CMOVNBE (0F 47) { 0x48, ENTRY_CopyBytes2Mod }, // CMOVS (0F 48) { 0x49, ENTRY_CopyBytes2Mod }, // CMOVNS (0F 49) { 0x4A, ENTRY_CopyBytes2Mod }, // CMOVP & CMOVPE (0F 4A) { 0x4B, ENTRY_CopyBytes2Mod }, // CMOVNP & CMOVPO (0F 4B) { 0x4C, ENTRY_CopyBytes2Mod }, // CMOVL & CMOVNGE (0F 4C) { 0x4D, ENTRY_CopyBytes2Mod }, // CMOVGE & CMOVNL (0F 4D) { 0x4E, ENTRY_CopyBytes2Mod }, // CMOVLE & CMOVNG (0F 4E) { 0x4F, ENTRY_CopyBytes2Mod }, // CMOVG & CMOVNLE (0F 4F) { 0x50, ENTRY_Invalid }, // _50 { 0x51, ENTRY_Invalid }, // _51 { 0x52, ENTRY_Invalid }, // _52 { 0x53, ENTRY_Invalid }, // _53 { 0x54, ENTRY_Invalid }, // _54 { 0x55, ENTRY_Invalid }, // _55 { 0x56, ENTRY_Invalid }, // _56 { 0x57, ENTRY_Invalid }, // _57 { 0x58, ENTRY_Invalid }, // _58 { 0x59, ENTRY_Invalid }, // _59 { 0x5A, ENTRY_Invalid }, // _5A { 0x5B, ENTRY_Invalid }, // _5B { 0x5C, ENTRY_Invalid }, // _5C { 0x5D, ENTRY_Invalid }, // _5D { 0x5E, ENTRY_Invalid }, // _5E { 0x5F, ENTRY_Invalid }, // _5F { 0x60, ENTRY_CopyBytes2Mod }, // PUNPCKLBW/r { 0x61, ENTRY_Invalid }, // _61 { 0x62, ENTRY_CopyBytes2Mod }, // PUNPCKLWD/r { 0x63, ENTRY_CopyBytes2Mod }, // PACKSSWB/r { 0x64, ENTRY_CopyBytes2Mod }, // PCMPGTB/r { 0x65, ENTRY_CopyBytes2Mod }, // PCMPGTW/r { 0x66, ENTRY_CopyBytes2Mod }, // PCMPGTD/r { 0x67, ENTRY_CopyBytes2Mod }, // PACKUSWB/r { 0x68, ENTRY_CopyBytes2Mod }, // PUNPCKHBW/r { 0x69, ENTRY_CopyBytes2Mod }, // PUNPCKHWD/r { 0x6A, ENTRY_CopyBytes2Mod }, // PUNPCKHDQ/r { 0x6B, ENTRY_CopyBytes2Mod }, // PACKSSDW/r { 0x6C, ENTRY_Invalid }, // _6C { 0x6D, ENTRY_Invalid }, // _6D { 0x6E, ENTRY_CopyBytes2Mod }, // MOVD/r { 0x6F, ENTRY_CopyBytes2Mod }, // MOV/r { 0x70, ENTRY_Invalid }, // _70 { 0x71, ENTRY_CopyBytes2Mod1 }, // PSLLW/6 ib,PSRAW/4 ib,PSRLW/2 ib { 0x72, ENTRY_CopyBytes2Mod1 }, // PSLLD/6 ib,PSRAD/4 ib,PSRLD/2 ib { 0x73, ENTRY_CopyBytes2Mod1 }, // PSLLQ/6 ib,PSRLQ/2 ib { 0x74, ENTRY_CopyBytes2Mod }, // PCMPEQB/r { 0x75, ENTRY_CopyBytes2Mod }, // PCMPEQW/r { 0x76, ENTRY_CopyBytes2Mod }, // PCMPEQD/r { 0x77, ENTRY_CopyBytes2 }, // EMMS { 0x78, ENTRY_Invalid }, // _78 { 0x79, ENTRY_Invalid }, // _79 { 0x7A, ENTRY_Invalid }, // _7A { 0x7B, ENTRY_Invalid }, // _7B { 0x7C, ENTRY_Invalid }, // _7C { 0x7D, ENTRY_Invalid }, // _7D { 0x7E, ENTRY_CopyBytes2Mod }, // MOVD/r { 0x7F, ENTRY_CopyBytes2Mod }, // MOV/r { 0x80, ENTRY_CopyBytes3Or5Target }, // JO { 0x81, ENTRY_CopyBytes3Or5Target }, // JNO { 0x82, ENTRY_CopyBytes3Or5Target }, // JB,JC,JNAE { 0x83, ENTRY_CopyBytes3Or5Target }, // JAE,JNB,JNC { 0x84, ENTRY_CopyBytes3Or5Target }, // JE,JZ,JZ { 0x85, ENTRY_CopyBytes3Or5Target }, // JNE,JNZ { 0x86, ENTRY_CopyBytes3Or5Target }, // JBE,JNA { 0x87, ENTRY_CopyBytes3Or5Target }, // JA,JNBE { 0x88, ENTRY_CopyBytes3Or5Target }, // JS { 0x89, ENTRY_CopyBytes3Or5Target }, // JNS { 0x8A, ENTRY_CopyBytes3Or5Target }, // JP,JPE { 0x8B, ENTRY_CopyBytes3Or5Target }, // JNP,JPO { 0x8C, ENTRY_CopyBytes3Or5Target }, // JL,NGE { 0x8D, ENTRY_CopyBytes3Or5Target }, // JGE,JNL { 0x8E, ENTRY_CopyBytes3Or5Target }, // JLE,JNG { 0x8F, ENTRY_CopyBytes3Or5Target }, // JG,JNLE { 0x90, ENTRY_CopyBytes2Mod }, // CMOVO (0F 40) { 0x91, ENTRY_CopyBytes2Mod }, // CMOVNO (0F 41) { 0x92, ENTRY_CopyBytes2Mod }, // CMOVB & CMOVC & CMOVNAE (0F 42) { 0x93, ENTRY_CopyBytes2Mod }, // CMOVAE & CMOVNB & CMOVNC (0F 43) { 0x94, ENTRY_CopyBytes2Mod }, // CMOVE & CMOVZ (0F 44) { 0x95, ENTRY_CopyBytes2Mod }, // CMOVNE & CMOVNZ (0F 45) { 0x96, ENTRY_CopyBytes2Mod }, // CMOVBE & CMOVNA (0F 46) { 0x97, ENTRY_CopyBytes2Mod }, // CMOVA & CMOVNBE (0F 47) { 0x98, ENTRY_CopyBytes2Mod }, // CMOVS (0F 48) { 0x99, ENTRY_CopyBytes2Mod }, // CMOVNS (0F 49) { 0x9A, ENTRY_CopyBytes2Mod }, // CMOVP & CMOVPE (0F 4A) { 0x9B, ENTRY_CopyBytes2Mod }, // CMOVNP & CMOVPO (0F 4B) { 0x9C, ENTRY_CopyBytes2Mod }, // CMOVL & CMOVNGE (0F 4C) { 0x9D, ENTRY_CopyBytes2Mod }, // CMOVGE & CMOVNL (0F 4D) { 0x9E, ENTRY_CopyBytes2Mod }, // CMOVLE & CMOVNG (0F 4E) { 0x9F, ENTRY_CopyBytes2Mod }, // CMOVG & CMOVNLE (0F 4F) { 0xA0, ENTRY_CopyBytes2 }, // PUSH { 0xA1, ENTRY_CopyBytes2 }, // POP { 0xA2, ENTRY_CopyBytes2 }, // CPUID { 0xA3, ENTRY_CopyBytes2Mod }, // BT (0F A3) { 0xA4, ENTRY_CopyBytes2Mod1 }, // SHLD { 0xA5, ENTRY_CopyBytes2Mod }, // SHLD { 0xA6, ENTRY_Invalid }, // _A6 { 0xA7, ENTRY_Invalid }, // _A7 { 0xA8, ENTRY_CopyBytes2 }, // PUSH { 0xA9, ENTRY_CopyBytes2 }, // POP { 0xAA, ENTRY_CopyBytes2 }, // RSM { 0xAB, ENTRY_CopyBytes2Mod }, // BTS (0F AB) { 0xAC, ENTRY_CopyBytes2Mod1 }, // SHRD { 0xAD, ENTRY_CopyBytes2Mod }, // SHRD { 0xAE, ENTRY_CopyBytes2Mod }, // FXRSTOR/1,FXSAVE/0 { 0xAF, ENTRY_CopyBytes2Mod }, // IMUL (0F AF) { 0xB0, ENTRY_CopyBytes2Mod }, // CMPXCHG (0F B0) { 0xB1, ENTRY_CopyBytes2Mod }, // CMPXCHG (0F B1) { 0xB2, ENTRY_CopyBytes2Mod }, // LSS/r { 0xB3, ENTRY_CopyBytes2Mod }, // BTR (0F B3) { 0xB4, ENTRY_CopyBytes2Mod }, // LFS/r { 0xB5, ENTRY_CopyBytes2Mod }, // LGS/r { 0xB6, ENTRY_CopyBytes2Mod }, // MOVZX/r { 0xB7, ENTRY_CopyBytes2Mod }, // MOVZX/r { 0xB8, ENTRY_Invalid }, // _B8 { 0xB9, ENTRY_Invalid }, // _B9 { 0xBA, ENTRY_CopyBytes2Mod1 }, // BT & BTC & BTR & BTS (0F BA) { 0xBB, ENTRY_CopyBytes2Mod }, // BTC (0F BB) { 0xBC, ENTRY_CopyBytes2Mod }, // BSF (0F BC) { 0xBD, ENTRY_CopyBytes2Mod }, // BSR (0F BD) { 0xBE, ENTRY_CopyBytes2Mod }, // MOVSX/r { 0xBF, ENTRY_CopyBytes2Mod }, // MOVSX/r { 0xC0, ENTRY_CopyBytes2Mod }, // XADD/r { 0xC1, ENTRY_CopyBytes2Mod }, // XADD/r { 0xC2, ENTRY_Invalid }, // _C2 { 0xC3, ENTRY_Invalid }, // _C3 { 0xC4, ENTRY_Invalid }, // _C4 { 0xC5, ENTRY_Invalid }, // _C5 { 0xC6, ENTRY_Invalid }, // _C6 { 0xC7, ENTRY_CopyBytes2Mod }, // CMPXCHG8B (0F C7) { 0xC8, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd { 0xC9, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd { 0xCA, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd { 0xCB, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd { 0xCC, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd { 0xCD, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd { 0xCE, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd { 0xCF, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd { 0xD0, ENTRY_Invalid }, // _D0 { 0xD1, ENTRY_CopyBytes2Mod }, // PSRLW/r { 0xD2, ENTRY_CopyBytes2Mod }, // PSRLD/r { 0xD3, ENTRY_CopyBytes2Mod }, // PSRLQ/r { 0xD4, ENTRY_Invalid }, // _D4 { 0xD5, ENTRY_CopyBytes2Mod }, // PMULLW/r { 0xD6, ENTRY_Invalid }, // _D6 { 0xD7, ENTRY_Invalid }, // _D7 { 0xD8, ENTRY_CopyBytes2Mod }, // PSUBUSB/r { 0xD9, ENTRY_CopyBytes2Mod }, // PSUBUSW/r { 0xDA, ENTRY_Invalid }, // _DA { 0xDB, ENTRY_CopyBytes2Mod }, // PAND/r { 0xDC, ENTRY_CopyBytes2Mod }, // PADDUSB/r { 0xDD, ENTRY_CopyBytes2Mod }, // PADDUSW/r { 0xDE, ENTRY_Invalid }, // _DE { 0xDF, ENTRY_CopyBytes2Mod }, // PANDN/r { 0xE0, ENTRY_Invalid }, // _E0 { 0xE1, ENTRY_CopyBytes2Mod }, // PSRAW/r { 0xE2, ENTRY_CopyBytes2Mod }, // PSRAD/r { 0xE3, ENTRY_Invalid }, // _E3 { 0xE4, ENTRY_Invalid }, // _E4 { 0xE5, ENTRY_CopyBytes2Mod }, // PMULHW/r { 0xE6, ENTRY_Invalid }, // _E6 { 0xE7, ENTRY_Invalid }, // _E7 { 0xE8, ENTRY_CopyBytes2Mod }, // PSUBB/r { 0xE9, ENTRY_CopyBytes2Mod }, // PSUBW/r { 0xEA, ENTRY_Invalid }, // _EA { 0xEB, ENTRY_CopyBytes2Mod }, // POR/r { 0xEC, ENTRY_CopyBytes2Mod }, // PADDSB/r { 0xED, ENTRY_CopyBytes2Mod }, // PADDSW/r { 0xEE, ENTRY_Invalid }, // _EE { 0xEF, ENTRY_CopyBytes2Mod }, // PXOR/r { 0xF0, ENTRY_Invalid }, // _F0 { 0xF1, ENTRY_CopyBytes2Mod }, // PSLLW/r { 0xF2, ENTRY_CopyBytes2Mod }, // PSLLD/r { 0xF3, ENTRY_CopyBytes2Mod }, // PSLLQ/r { 0xF4, ENTRY_Invalid }, // _F4 { 0xF5, ENTRY_CopyBytes2Mod }, // PMADDWD/r { 0xF6, ENTRY_Invalid }, // _F6 { 0xF7, ENTRY_Invalid }, // _F7 { 0xF8, ENTRY_CopyBytes2Mod }, // PSUBB/r { 0xF9, ENTRY_CopyBytes2Mod }, // PSUBW/r { 0xFA, ENTRY_CopyBytes2Mod }, // PSUBD/r { 0xFB, ENTRY_Invalid }, // _FB { 0xFC, ENTRY_CopyBytes2Mod }, // PADDB/r { 0xFD, ENTRY_CopyBytes2Mod }, // PADDW/r { 0xFE, ENTRY_CopyBytes2Mod }, // PADDD/r { 0xFF, ENTRY_Invalid }, // _FF { 0, ENTRY_End }, }; BOOL CDetourDis::SanityCheckSystem(){ for(ULONG n = 0; n < 256; n++){ REFCOPYENTRY pEntry = &s_rceCopyTable[n]; if(n != pEntry->nOpcode){ ASSERT(n == pEntry->nOpcode); return FALSE; } } if(s_rceCopyTable[256].pfCopy != NULL){ ASSERT(!"Missing end marker."); return FALSE; } for(n = 0; n < 256; n++){ REFCOPYENTRY pEntry = &s_rceCopyTable0F[n]; if(n != pEntry->nOpcode){ ASSERT(n == pEntry->nOpcode); return FALSE; } } if(s_rceCopyTable0F[256].pfCopy != NULL){ ASSERT(!"Missing end marker."); return FALSE; } return TRUE; }
Detour/CDetourDis.h
Code:
////////////////////////////////////////////////////////////////////////////// // // Module: detours.lib // File: disasm.h // // Detours for binary functions. Version 1.5 (Build 46) // Includes support for all x86 chips prior to the Pentium III. // // Copyright 1999-2001, Microsoft Corporation // #pragma once #ifndef _DISASM_H_ #define _DISASM_H_ class CDetourDis { public: CDetourDis(PBYTE* ppbTarget, LONG* plExtra); PBYTE CopyInstruction(PBYTE pbDst, PBYTE pbSrc); PBYTE CopyInstructionEx(PBYTE pbDst, PBYTE pbSrc, PBYTE pbDstOverride); PBYTE CopyInstructionZero(PBYTE pbDst, PBYTE pbSrc); BYTE InstructionLen(PBYTE pbSrc); static BOOL SanityCheckSystem(); public: struct COPYENTRY; typedef const COPYENTRY* REFCOPYENTRY; typedef PBYTE (CDetourDis::* COPYFUNC)(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc); enum { DYNAMIC = 0x1u, ADDRESS = 0x2u, NOENLARGE = 0x4u, SIB = 0x10u, NOTSIB = 0x0fu, }; struct COPYENTRY { ULONG nOpcode : 8; // Opcode ULONG nFixedSize : 3; // Fixed size of opcode ULONG nFixedSize16 : 3; // Fixed size when 16 bit operand ULONG nModOffset : 3; // Offset to mod/rm byte (0=none) LONG nRelOffset : 3; // Offset to relative target. ULONG nFlagBits : 4; // Flags for DYNAMIC, etc. COPYFUNC pfCopy; // Function pointer. }; protected: #define ENTRY_CopyBytes1 1, 1, 0, 0, 0, CopyBytes #define ENTRY_CopyBytes1Dynamic 1, 1, 0, 0, DYNAMIC, CopyBytes #define ENTRY_CopyBytes2 2, 2, 0, 0, 0, CopyBytes #define ENTRY_CopyBytes2Jump 2, 2, 0, 1, 0, CopyBytes #define ENTRY_CopyBytes2CantJump 2, 2, 0, 1, NOENLARGE, CopyBytes #define ENTRY_CopyBytes2Dynamic 2, 2, 0, 0, DYNAMIC, CopyBytes #define ENTRY_CopyBytes3 3, 3, 0, 0, 0, CopyBytes #define ENTRY_CopyBytes3Dynamic 3, 3, 0, 0, DYNAMIC, CopyBytes #define ENTRY_CopyBytes3Or5 5, 3, 0, 0, 0, CopyBytes #define ENTRY_CopyBytes3Or5Target 5, 3, 0, 1, 0, CopyBytes #define ENTRY_CopyBytes5Or7Dynamic 7, 5, 0, 0, DYNAMIC, CopyBytes #define ENTRY_CopyBytes3Or5Address 5, 3, 0, 0, ADDRESS, CopyBytes #define ENTRY_CopyBytes4 4, 4, 0, 0, 0, CopyBytes #define ENTRY_CopyBytes5 5, 5, 0, 0, 0, CopyBytes #define ENTRY_CopyBytes7 7, 7, 0, 0, 0, CopyBytes #define ENTRY_CopyBytes2Mod 2, 2, 1, 0, 0, CopyBytes #define ENTRY_CopyBytes2Mod1 3, 3, 1, 0, 0, CopyBytes #define ENTRY_CopyBytes2ModOperand 6, 4, 1, 0, 0, CopyBytes #define ENTRY_CopyBytes3Mod 3, 3, 2, 0, 0, CopyBytes #define ENTRY_CopyBytesPrefix 1, 1, 0, 0, 0, CopyBytesPrefix #define ENTRY_Copy0F 1, 1, 0, 0, 0, Copy0F #define ENTRY_Copy66 1, 1, 0, 0, 0, Copy66 #define ENTRY_Copy67 1, 1, 0, 0, 0, Copy67 #define ENTRY_CopyF6 0, 0, 0, 0, 0, CopyF6 #define ENTRY_CopyF7 0, 0, 0, 0, 0, CopyF7 #define ENTRY_CopyFF 0, 0, 0, 0, 0, CopyFF #define ENTRY_Invalid 1, 1, 0, 0, 0, Invalid #define ENTRY_End 0, 0, 0, 0, 0, NULL PBYTE CopyBytes(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc); PBYTE CopyBytesPrefix(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc); PBYTE Invalid(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc); PBYTE AdjustTarget(PBYTE pbDst, PBYTE pbSrc, LONG cbOp, LONG cbTargetOffset); VOID Set16BitOperand(); VOID Set32BitOperand(); VOID Set16BitAddress(); VOID Set32BitAddress(); protected: PBYTE Copy0F(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc); PBYTE Copy66(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc); PBYTE Copy67(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc); PBYTE CopyF6(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc); PBYTE CopyF7(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc); PBYTE CopyFF(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc); protected: static const COPYENTRY s_rceCopyTable[257]; static const COPYENTRY s_rceCopyTable0F[257]; static const BYTE s_rbModRm[256]; protected: BOOL m_b16BitOperand; BOOL m_b16BitAddress; PBYTE* m_ppbTarget; LONG* m_plExtra; LONG m_lScratchExtra; PBYTE m_pbScratchTarget; BYTE m_rbScratchDst[64]; BYTE* m_pbDstOverride; BOOL m_bAdjustZero; }; ////////////////////////////////////////////////////////////////////////////// enum { OP_PRE_ES = 0x26, OP_PRE_CS = 0x2e, OP_PRE_SS = 0x36, OP_PRE_DS = 0x3e, OP_PRE_FS = 0x64, OP_PRE_GS = 0x65, OP_JMP_SEG = 0x25, OP_JA = 0x77, OP_NOP = 0x90, OP_CALL = 0xe8, OP_JMP = 0xe9, OP_PREFIX = 0xff, OP_MOV_EAX = 0xa1, OP_SET_EAX = 0xb8, OP_JMP_EAX = 0xe0, OP_RET_POP = 0xc2, OP_RET = 0xc3, OP_BRK = 0xcc, SIZE_OF_JMP = 5, SIZE_OF_NOP = 1, SIZE_OF_BRK = 1, SIZE_OF_TRP_OPS = SIZE_OF_JMP /* + SIZE_OF_BRK */, }; ////////////////////////////////////////////////////////////////////////////// inline PBYTE DetourGenMovEax(PBYTE pbCode, UINT32 nValue){ *pbCode++ = 0xB8; *((UINT32*&)pbCode)++ = nValue; return pbCode; } inline PBYTE DetourGenMovEbx(PBYTE pbCode, UINT32 nValue){ *pbCode++ = 0xBB; *((UINT32*&)pbCode)++ = nValue; return pbCode; } inline PBYTE DetourGenMovEcx(PBYTE pbCode, UINT32 nValue){ *pbCode++ = 0xB9; *((UINT32*&)pbCode)++ = nValue; return pbCode; } inline PBYTE DetourGenMovEdx(PBYTE pbCode, UINT32 nValue){ *pbCode++ = 0xBA; *((UINT32*&)pbCode)++ = nValue; return pbCode; } inline PBYTE DetourGenMovEsi(PBYTE pbCode, UINT32 nValue){ *pbCode++ = 0xBE; *((UINT32*&)pbCode)++ = nValue; return pbCode; } inline PBYTE DetourGenMovEdi(PBYTE pbCode, UINT32 nValue){ *pbCode++ = 0xBF; *((UINT32*&)pbCode)++ = nValue; return pbCode; } inline PBYTE DetourGenMovEbp(PBYTE pbCode, UINT32 nValue){ *pbCode++ = 0xBD; *((UINT32*&)pbCode)++ = nValue; return pbCode; } inline PBYTE DetourGenMovEsp(PBYTE pbCode, UINT32 nValue){ *pbCode++ = 0xBC; *((UINT32*&)pbCode)++ = nValue; return pbCode; } inline PBYTE DetourGenPush(PBYTE pbCode, UINT32 nValue){ *pbCode++ = 0x68; *((UINT32*&)pbCode)++ = nValue; return pbCode; } inline PBYTE DetourGenPushad(PBYTE pbCode){ *pbCode++ = 0x60; return pbCode; } inline PBYTE DetourGenPopad(PBYTE pbCode){ *pbCode++ = 0x61; return pbCode; } inline PBYTE DetourGenJmp(PBYTE pbCode, PBYTE pbJmpDst, PBYTE pbJmpSrc = 0){ if(pbJmpSrc == 0) pbJmpSrc = pbCode; *pbCode++ = 0xE9; *((INT32*&)pbCode)++ = pbJmpDst - (pbJmpSrc + 5); return pbCode; } inline PBYTE DetourGenCall(PBYTE pbCode, PBYTE pbJmpDst, PBYTE pbJmpSrc = 0){ if(pbJmpSrc == 0) pbJmpSrc = pbCode; *pbCode++ = 0xE8; *((INT32*&)pbCode)++ = pbJmpDst - (pbJmpSrc + 5); return pbCode; } inline PBYTE DetourGenBreak(PBYTE pbCode){ *pbCode++ = 0xcc; return pbCode; } inline PBYTE DetourGenRet(PBYTE pbCode){ *pbCode++ = 0xc3; return pbCode; } inline PBYTE DetourGenNop(PBYTE pbCode){ *pbCode++ = 0x90; return pbCode; } #define DETOUR_INSTRUCTION_TARGET_NONE ((PBYTE)0) #define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PBYTE)~0ul) #endif //_DISASM_H_
--------------------------------------------------------------------------------------------------------------
Todas as funções e endereços
Usado para codificação em MatchServer
Exemplo:
sourcefiles.txt
Code:
*** SOURCE FILES Compiland = .\Release\MatchServer.res Compiland = .\Release\MBMatchAuth.obj c:\teamworks\stable\matchserver\mbmatchauth.h c:\teamworks\stable\matchserver\mbmatchauth.cpp Compiland = .\Release\MMatchServer_Schedule.obj c:\teamworks\stable\matchserver\mmatchserver_schedule.cpp c:\teamworks\stable\cscommon\include\mmatchobject.h Compiland = .\Release\MBMatchServerConfigReloader.obj c:\teamworks\stable\matchserver\mbmatchserverconfigreloader.cpp c:\program files\microsoft visual studio .net 2003\vc7\include\xtree c:\teamworks\stable\cscommon\include\mmatchantihack.h c:\teamworks\stable\matchserver\mbmatchserverconfigreloader.h c:\program files\microsoft visual studio .net 2003\vc7\include\stdexcept c:\teamworks\stable\cscommon\include\mmatchevent.h c:\program files\microsoft visual studio .net 2003\vc7\include\vector Compiland = .\Release\MBMatchServer_ServerKeeper.obj c:\teamworks\stable\cscommon\include\muid.h c:\teamworks\stable\cscommon\include\mcommandparameter.h c:\teamworks\stable\cscommon\include\mmatchobject.h c:\program files\microsoft visual studio .net 2003\vc7\include\vector c:\teamworks\stable\cml\include\mempool.h c:\teamworks\stable\matchserver\mbmatchserver_serverkeeper.cpp c:\program files\microsoft visual studio .net 2003\vc7\include\xstring c:\program files\microsoft visual studio .net 2003\vc7\include\xmemory c:\program files\microsoft visual studio .net 2003\vc7\include\xutility c:\program files\microsoft visual studio .net 2003\vc7\include\memory Compiland = .\Release\MBMatchServer_OnCommand.obj c:\teamworks\stable\matchserver\mbmatchserver_oncommand.cpp c:\teamworks\stable\cscommon\include\mmatchobject.h
Créditos:
Blasper