| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186 |
- //////////////////////////////////////////////////////////////////////////////
- //
- // Image manipulation functions (image.cpp of detours.lib)
- //
- // Microsoft Research Detours Package, Version 2.1.
- //
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //
- // Used for for payloads, byways, and imports.
- //
- #include <windows.h>
- #if (_MSC_VER < 1310)
- #else
- #include <strsafe.h>
- #endif
- #if (_MSC_VER < 1299)
- #pragma warning(disable: 4710)
- #else
- #endif
- //#define DETOUR_DEBUG 1
- #define DETOURS_INTERNAL
- #include "detours.h"
- namespace Detour
- {
- //////////////////////////////////////////////////////////////////////////////
- //
- #ifndef _STRSAFE_H_INCLUDED_
- static inline HRESULT StringCchLengthA(const char* psz, size_t cchMax, size_t* pcch)
- {
- HRESULT hr = S_OK;
- size_t cchMaxPrev = cchMax;
- if (cchMax > 2147483647)
- {
- return ERROR_INVALID_PARAMETER;
- }
- while (cchMax && (*psz != '\0'))
- {
- psz++;
- cchMax--;
- }
- if (cchMax == 0)
- {
- // the string is longer than cchMax
- hr = ERROR_INVALID_PARAMETER;
- }
- if (SUCCEEDED(hr) && pcch)
- {
- *pcch = cchMaxPrev - cchMax;
- }
- return hr;
- }
- static inline HRESULT StringCchCopyA(char* pszDest, size_t cchDest, const char* pszSrc)
- {
- HRESULT hr = S_OK;
- if (cchDest == 0)
- {
- // can not null terminate a zero-byte dest buffer
- hr = ERROR_INVALID_PARAMETER;
- }
- else
- {
- while (cchDest && (*pszSrc != '\0'))
- {
- *pszDest++ = *pszSrc++;
- cchDest--;
- }
- if (cchDest == 0)
- {
- // we are going to truncate pszDest
- pszDest--;
- hr = ERROR_INVALID_PARAMETER;
- }
- *pszDest= '\0';
- }
- return hr;
- }
- static inline HRESULT StringCchCatA(char* pszDest, size_t cchDest, const char* pszSrc)
- {
- HRESULT hr;
- size_t cchDestCurrent;
- if (cchDest > 2147483647)
- {
- return ERROR_INVALID_PARAMETER;
- }
- hr = StringCchLengthA(pszDest, cchDest, &cchDestCurrent);
- if (SUCCEEDED(hr))
- {
- hr = StringCchCopyA(pszDest + cchDestCurrent,
- cchDest - cchDestCurrent,
- pszSrc);
- }
- return hr;
- }
- #endif
- ///////////////////////////////////////////////////////////////////////////////
- //
- class CImageData
- {
- friend class CImage;
- public:
- CImageData(PBYTE pbData, DWORD cbData);
- ~CImageData();
- PBYTE Enumerate(GUID *pGuid, DWORD *pcbData, DWORD *pnIterator);
- PBYTE Find(REFGUID rguid, DWORD *pcbData);
- PBYTE Set(REFGUID rguid, PBYTE pbData, DWORD cbData);
- BOOL Delete(REFGUID rguid);
- BOOL Purge();
- BOOL IsEmpty() { return m_cbData == 0; }
- BOOL IsValid();
- protected:
- BOOL SizeTo(DWORD cbData);
- protected:
- PBYTE m_pbData;
- DWORD m_cbData;
- DWORD m_cbAlloc;
- };
- class CImageImportFile
- {
- friend class CImage;
- friend class CImageImportName;
- public:
- CImageImportFile();
- ~CImageImportFile();
- public:
- CImageImportFile * m_pNextFile;
- BOOL m_fByway;
- CImageImportName * m_pImportNames;
- DWORD m_nImportNames;
- DWORD m_rvaOriginalFirstThunk;
- DWORD m_rvaFirstThunk;
- DWORD m_nForwarderChain;
- PCHAR m_pszOrig;
- PCHAR m_pszName;
- };
- class CImageImportName
- {
- friend class CImage;
- friend class CImageImportFile;
- public:
- CImageImportName();
- ~CImageImportName();
- public:
- WORD m_nHint;
- ULONG m_nOrig;
- ULONG m_nOrdinal;
- PCHAR m_pszOrig;
- PCHAR m_pszName;
- };
- class CImage
- {
- friend class CImageThunks;
- friend class CImageChars;
- friend class CImageImportFile;
- friend class CImageImportName;
- public:
- CImage();
- ~CImage();
- static CImage * IsValid(PDETOUR_BINARY pBinary);
- public: // File Functions
- BOOL Read(HANDLE hFile);
- BOOL Write(HANDLE hFile);
- BOOL Close();
- public: // Manipulation Functions
- PBYTE DataEnum(GUID *pGuid, DWORD *pcbData, DWORD *pnIterator);
- PBYTE DataFind(REFGUID rguid, DWORD *pcbData);
- PBYTE DataSet(REFGUID rguid, PBYTE pbData, DWORD cbData);
- BOOL DataDelete(REFGUID rguid);
- BOOL DataPurge();
- BOOL EditImports(PVOID pContext,
- PF_DETOUR_BINARY_BYWAY_CALLBACK pfBywayCallback,
- PF_DETOUR_BINARY_FILE_CALLBACK pfFileCallback,
- PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbolCallback,
- PF_DETOUR_BINARY_COMMIT_CALLBACK pfCommitCallback);
- protected:
- BOOL WriteFile(HANDLE hFile,
- LPCVOID lpBuffer,
- DWORD nNumberOfBytesToWrite,
- LPDWORD lpNumberOfBytesWritten);
- BOOL CopyFileData(HANDLE hFile, DWORD nOldPos, DWORD cbData);
- BOOL ZeroFileData(HANDLE hFile, DWORD cbData);
- BOOL AlignFileData(HANDLE hFile);
- BOOL SizeOutputBuffer(DWORD cbData);
- PBYTE AllocateOutput(DWORD cbData, DWORD *pnVirtAddr);
- PVOID RvaToVa(ULONG_PTR nRva);
- DWORD RvaToFileOffset(DWORD nRva);
- DWORD FileAlign(DWORD nAddr);
- DWORD SectionAlign(DWORD nAddr);
- BOOL CheckImportsNeeded(DWORD *pnTables,
- DWORD *pnThunks,
- DWORD *pnChars);
- CImageImportFile * NewByway(__in_z PCHAR pszName);
- private:
- DWORD m_dwValidSignature;
- CImageData * m_pImageData; // Read & Write
- HANDLE m_hMap; // Read & Write
- PBYTE m_pMap; // Read & Write
- DWORD m_nNextFileAddr; // Write
- DWORD m_nNextVirtAddr; // Write
- IMAGE_DOS_HEADER m_DosHeader; // Read & Write
- IMAGE_NT_HEADERS m_NtHeader; // Read & Write
- IMAGE_SECTION_HEADER m_SectionHeaders[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
- DWORD m_nPrePE;
- DWORD m_cbPrePE;
- DWORD m_cbPostPE;
- DWORD m_nPeOffset;
- DWORD m_nSectionsOffset;
- DWORD m_nExtraOffset;
- DWORD m_nFileSize;
- DWORD m_nOutputVirtAddr;
- DWORD m_nOutputVirtSize;
- DWORD m_nOutputFileAddr;
- PBYTE m_pbOutputBuffer;
- DWORD m_cbOutputBuffer;
- CImageImportFile * m_pImportFiles;
- DWORD m_nImportFiles;
- BOOL m_fHadDetourSection;
- private:
- enum {
- DETOUR_IMAGE_VALID_SIGNATURE = 0xfedcba01, // "Dtr\0"
- };
- };
- //////////////////////////////////////////////////////////////////////////////
- //
- static BYTE s_rbDosCode[0x10] = {
- 0x0E,0x1F,0xBA,0x0E,0x00,0xB4,0x09,0xCD,
- 0x21,0xB8,0x01,0x4C,0xCD,0x21,'*','*'
- };
- static inline DWORD Max(DWORD a, DWORD b)
- {
- return a > b ? a : b;
- }
- static inline DWORD Align(DWORD a, DWORD size)
- {
- size--;
- return (a + size) & ~size;
- }
- static inline DWORD QuadAlign(DWORD a)
- {
- return Align(a, 8);
- }
- static PCHAR DuplicateString(__in_z PCHAR pszIn)
- {
- if (pszIn) {
- UINT nIn = (UINT)strlen(pszIn);
- PCHAR pszOut = new CHAR [nIn + 1];
- if (pszOut == NULL) {
- SetLastError(ERROR_OUTOFMEMORY);
- }
- else {
- CopyMemory(pszOut, pszIn, nIn + 1);
- }
- return pszOut;
- }
- return NULL;
- }
- static PCHAR ReplaceString(__deref_out PCHAR *ppsz, __in_z PCHAR pszIn)
- {
- if (ppsz == NULL) {
- return NULL;
- }
- UINT nIn;
- if (*ppsz != NULL) {
- if (strcmp(*ppsz, pszIn) == 0) {
- return *ppsz;
- }
- nIn = (UINT)strlen(pszIn);
- if (strlen(*ppsz) == nIn) {
- CopyMemory(*ppsz, pszIn, nIn + 1);
- return *ppsz;
- }
- else {
- delete[] *ppsz;
- *ppsz = NULL;
- }
- }
- else {
- nIn = (UINT)strlen(pszIn);
- }
- *ppsz = new CHAR [nIn + 1];
- if (*ppsz == NULL) {
- SetLastError(ERROR_OUTOFMEMORY);
- }
- else {
- CopyMemory(*ppsz, pszIn, nIn + 1);
- }
- return *ppsz;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- CImageImportFile::CImageImportFile()
- {
- m_pNextFile = NULL;
- m_fByway = FALSE;
- m_pImportNames = NULL;
- m_nImportNames = 0;
- m_rvaOriginalFirstThunk = 0;
- m_rvaFirstThunk = 0;
- m_nForwarderChain = (UINT)0;
- m_pszName = NULL;
- m_pszOrig = NULL;
- }
- CImageImportFile::~CImageImportFile()
- {
- if (m_pNextFile) {
- delete m_pNextFile;
- m_pNextFile = NULL;
- }
- if (m_pImportNames) {
- delete[] m_pImportNames;
- m_pImportNames = NULL;
- m_nImportNames = 0;
- }
- if (m_pszName) {
- delete[] m_pszName;
- m_pszName = NULL;
- }
- if (m_pszOrig) {
- delete[] m_pszOrig;
- m_pszOrig = NULL;
- }
- }
- CImageImportName::CImageImportName()
- {
- m_nOrig = 0;
- m_nOrdinal = 0;
- m_nHint = 0;
- m_pszName = NULL;
- m_pszOrig = NULL;
- }
- CImageImportName::~CImageImportName()
- {
- if (m_pszName) {
- delete[] m_pszName;
- m_pszName = NULL;
- }
- if (m_pszOrig) {
- delete[] m_pszOrig;
- m_pszOrig = NULL;
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- CImageData::CImageData(PBYTE pbData, DWORD cbData)
- {
- m_pbData = pbData;
- m_cbData = cbData;
- m_cbAlloc = 0;
- }
- CImageData::~CImageData()
- {
- IsValid();
- if (m_cbAlloc == 0) {
- m_pbData = NULL;
- }
- if (m_pbData) {
- delete[] m_pbData;
- m_pbData = NULL;
- }
- m_cbData = 0;
- m_cbAlloc = 0;
- }
- BOOL CImageData::SizeTo(DWORD cbData)
- {
- IsValid();
- if (cbData <= m_cbAlloc) {
- return TRUE;
- }
- PBYTE pbNew = new BYTE [cbData];
- if (pbNew == NULL) {
- SetLastError(ERROR_OUTOFMEMORY);
- return FALSE;
- }
- if (m_pbData) {
- CopyMemory(pbNew, m_pbData, m_cbData);
- if (m_cbAlloc > 0) {
- delete[] m_pbData;
- }
- m_pbData = NULL;
- }
- m_pbData = pbNew;
- m_cbAlloc = cbData;
- IsValid();
- return TRUE;
- }
- BOOL CImageData::Purge()
- {
- m_cbData = 0;
- IsValid();
- return TRUE;
- }
- BOOL CImageData::IsValid()
- {
- if (m_pbData == NULL) {
- return TRUE;
- }
- PBYTE pbBeg = m_pbData;
- PBYTE pbEnd = m_pbData + m_cbData;
- for (PBYTE pbIter = pbBeg; pbIter < pbEnd;) {
- PDETOUR_SECTION_RECORD pRecord = (PDETOUR_SECTION_RECORD)pbIter;
- if (pRecord->cbBytes < sizeof(DETOUR_SECTION_RECORD)) {
- return FALSE;
- }
- if (pRecord->nReserved != 0) {
- return FALSE;
- }
- pbIter += pRecord->cbBytes;
- }
- return TRUE;
- }
- PBYTE CImageData::Enumerate(GUID *pGuid, DWORD *pcbData, DWORD *pnIterator)
- {
- IsValid();
- if (pnIterator == NULL ||
- m_cbData < *pnIterator + sizeof(DETOUR_SECTION_RECORD)) {
- if (pcbData) {
- *pcbData = 0;
- }
- if (pGuid) {
- ZeroMemory(pGuid, sizeof(*pGuid));
- }
- return NULL;
- }
- PDETOUR_SECTION_RECORD pRecord = (PDETOUR_SECTION_RECORD)(m_pbData + *pnIterator);
- if (pGuid) {
- *pGuid = pRecord->guid;
- }
- if (pcbData) {
- *pcbData = pRecord->cbBytes - sizeof(DETOUR_SECTION_RECORD);
- }
- *pnIterator = (LONG)(((PBYTE)pRecord - m_pbData) + pRecord->cbBytes);
- return (PBYTE)(pRecord + 1);
- }
- PBYTE CImageData::Find(REFGUID rguid, DWORD *pcbData)
- {
- IsValid();
- DWORD cbBytes = sizeof(DETOUR_SECTION_RECORD);
- for (DWORD nOffset = 0; nOffset < m_cbData; nOffset += cbBytes) {
- PDETOUR_SECTION_RECORD pRecord = (PDETOUR_SECTION_RECORD)(m_pbData + nOffset);
- cbBytes = pRecord->cbBytes;
- if (cbBytes > m_cbData) {
- break;
- }
- if (cbBytes < sizeof(DETOUR_SECTION_RECORD)) {
- continue;
- }
- if (pRecord->guid.Data1 == rguid.Data1 &&
- pRecord->guid.Data2 == rguid.Data2 &&
- pRecord->guid.Data3 == rguid.Data3 &&
- pRecord->guid.Data4[0] == rguid.Data4[0] &&
- pRecord->guid.Data4[1] == rguid.Data4[1] &&
- pRecord->guid.Data4[2] == rguid.Data4[2] &&
- pRecord->guid.Data4[3] == rguid.Data4[3] &&
- pRecord->guid.Data4[4] == rguid.Data4[4] &&
- pRecord->guid.Data4[5] == rguid.Data4[5] &&
- pRecord->guid.Data4[6] == rguid.Data4[6] &&
- pRecord->guid.Data4[7] == rguid.Data4[7]) {
- *pcbData = cbBytes - sizeof(DETOUR_SECTION_RECORD);
- return (PBYTE)(pRecord + 1);
- }
- }
- if (pcbData) {
- *pcbData = 0;
- }
- return NULL;
- }
- BOOL CImageData::Delete(REFGUID rguid)
- {
- IsValid();
- PBYTE pbFound = NULL;
- DWORD cbFound = 0;
- pbFound = Find(rguid, &cbFound);
- if (pbFound == NULL) {
- SetLastError(ERROR_MOD_NOT_FOUND);
- return FALSE;
- }
- pbFound -= sizeof(DETOUR_SECTION_RECORD);
- cbFound += sizeof(DETOUR_SECTION_RECORD);
- PBYTE pbRestData = pbFound + cbFound;
- DWORD cbRestData = m_cbData - (LONG)(pbRestData - m_pbData);
- if (cbRestData) {
- MoveMemory(pbFound, pbRestData, cbRestData);
- }
- m_cbData -= cbFound;
- IsValid();
- return TRUE;
- }
- PBYTE CImageData::Set(REFGUID rguid, PBYTE pbData, DWORD cbData)
- {
- IsValid();
- Delete(rguid);
- DWORD cbAlloc = QuadAlign(cbData);
- if (!SizeTo(m_cbData + cbAlloc + sizeof(DETOUR_SECTION_RECORD))) {
- return NULL;
- }
- PDETOUR_SECTION_RECORD pRecord = (PDETOUR_SECTION_RECORD)(m_pbData + m_cbData);
- pRecord->cbBytes = cbAlloc + sizeof(DETOUR_SECTION_RECORD);
- pRecord->nReserved = 0;
- pRecord->guid = rguid;
- PBYTE pbDest = (PBYTE)(pRecord + 1);
- if (pbData) {
- CopyMemory(pbDest, pbData, cbData);
- if (cbData < cbAlloc) {
- ZeroMemory(pbDest + cbData, cbAlloc - cbData);
- }
- }
- else {
- if (cbAlloc > 0) {
- ZeroMemory(pbDest, cbAlloc);
- }
- }
- m_cbData += cbAlloc + sizeof(DETOUR_SECTION_RECORD);
- IsValid();
- return pbDest;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- class CImageThunks
- {
- private:
- CImage * m_pImage;
- PIMAGE_THUNK_DATA m_pThunks;
- DWORD m_nThunks;
- DWORD m_nThunksMax;
- DWORD m_nThunkVirtAddr;
- public:
- CImageThunks(CImage *pImage, DWORD nThunksMax, DWORD *pnAddr)
- {
- m_pImage = pImage;
- m_nThunks = 0;
- m_nThunksMax = nThunksMax;
- m_pThunks = (PIMAGE_THUNK_DATA)
- m_pImage->AllocateOutput(sizeof(IMAGE_THUNK_DATA) * nThunksMax,
- &m_nThunkVirtAddr);
- *pnAddr = m_nThunkVirtAddr;
- }
- PIMAGE_THUNK_DATA Current(DWORD *pnVirtAddr)
- {
- if (m_nThunksMax > 1) {
- *pnVirtAddr = m_nThunkVirtAddr;
- return m_pThunks;
- }
- *pnVirtAddr = 0;
- return NULL;
- }
- PIMAGE_THUNK_DATA Allocate(ULONG_PTR nData, DWORD *pnVirtAddr)
- {
- if (m_nThunks < m_nThunksMax) {
- *pnVirtAddr = m_nThunkVirtAddr;
- m_nThunks++;
- m_nThunkVirtAddr += sizeof(IMAGE_THUNK_DATA);
- m_pThunks->u1.Ordinal = nData;
- return m_pThunks++;
- }
- *pnVirtAddr = 0;
- return NULL;
- }
- DWORD Size()
- {
- return m_nThunksMax * sizeof(IMAGE_THUNK_DATA);
- }
- };
- //////////////////////////////////////////////////////////////////////////////
- //
- class CImageChars
- {
- private:
- CImage * m_pImage;
- PCHAR m_pChars;
- DWORD m_nChars;
- DWORD m_nCharsMax;
- DWORD m_nCharVirtAddr;
- public:
- CImageChars(CImage *pImage, DWORD nCharsMax, DWORD *pnAddr)
- {
- m_pImage = pImage;
- m_nChars = 0;
- m_nCharsMax = nCharsMax;
- m_pChars = (PCHAR)m_pImage->AllocateOutput(nCharsMax, &m_nCharVirtAddr);
- *pnAddr = m_nCharVirtAddr;
- }
- PCHAR Allocate(__in_z PCHAR pszString, DWORD *pnVirtAddr)
- {
- DWORD nLen = (DWORD)strlen(pszString) + 1;
- nLen += (nLen & 1);
- if (m_nChars + nLen > m_nCharsMax) {
- *pnVirtAddr = 0;
- return NULL;
- }
- *pnVirtAddr = m_nCharVirtAddr;
- HRESULT hrRet = StringCchCopyA(m_pChars,m_nCharsMax, pszString);
- if (FAILED(hrRet)) {
- return NULL;
- }
- pszString = m_pChars;
- m_pChars += nLen;
- m_nChars += nLen;
- m_nCharVirtAddr += nLen;
- return pszString;
- }
- PCHAR Allocate(PCHAR pszString, DWORD nHint, DWORD *pnVirtAddr)
- {
- DWORD nLen = (DWORD)strlen(pszString) + 1 + sizeof(USHORT);
- nLen += (nLen & 1);
- if (m_nChars + nLen > m_nCharsMax) {
- *pnVirtAddr = 0;
- return NULL;
- }
- *pnVirtAddr = m_nCharVirtAddr;
- *(USHORT *)m_pChars = (USHORT)nHint;
- HRESULT hrRet = StringCchCopyA(m_pChars + sizeof(USHORT), m_nCharsMax, pszString);
- if (FAILED(hrRet)) {
- return NULL;
- }
- pszString = m_pChars + sizeof(USHORT);
- m_pChars += nLen;
- m_nChars += nLen;
- m_nCharVirtAddr += nLen;
- return pszString;
- }
- DWORD Size()
- {
- return m_nChars;
- }
- };
- //////////////////////////////////////////////////////////////////////////////
- //
- CImage * CImage::IsValid(PDETOUR_BINARY pBinary)
- {
- if (pBinary) {
- CImage *pImage = (CImage *)pBinary;
- if (pImage->m_dwValidSignature == DETOUR_IMAGE_VALID_SIGNATURE) {
- return pImage;
- }
- }
- SetLastError(ERROR_INVALID_HANDLE);
- return NULL;
- }
- CImage::CImage()
- {
- m_dwValidSignature = (DWORD)DETOUR_IMAGE_VALID_SIGNATURE;
- m_hMap = NULL;
- m_pMap = NULL;
- m_nPeOffset = 0;
- m_nSectionsOffset = 0;
- m_pbOutputBuffer = NULL;
- m_cbOutputBuffer = 0;
- m_pImageData = NULL;
- m_pImportFiles = NULL;
- m_nImportFiles = 0;
- m_fHadDetourSection = FALSE;
- }
- CImage::~CImage()
- {
- Close();
- m_dwValidSignature = 0;
- }
- BOOL CImage::Close()
- {
- if (m_pImportFiles) {
- delete m_pImportFiles;
- m_pImportFiles = NULL;
- m_nImportFiles = 0;
- }
- if (m_pImageData) {
- delete m_pImageData;
- m_pImageData = NULL;
- }
- if (m_pMap != NULL) {
- UnmapViewOfFile(m_pMap);
- m_pMap = NULL;
- }
- if (m_hMap) {
- CloseHandle(m_hMap);
- m_hMap = NULL;
- }
- if (m_pbOutputBuffer) {
- delete[] m_pbOutputBuffer;
- m_pbOutputBuffer = NULL;
- m_cbOutputBuffer = 0;
- }
- return TRUE;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- PBYTE CImage::DataEnum(GUID *pGuid, DWORD *pcbData, DWORD *pnIterator)
- {
- if (m_pImageData == NULL) {
- return NULL;
- }
- return m_pImageData->Enumerate(pGuid, pcbData, pnIterator);
- }
- PBYTE CImage::DataFind(REFGUID rguid, DWORD *pcbData)
- {
- if (m_pImageData == NULL) {
- return NULL;
- }
- return m_pImageData->Find(rguid, pcbData);
- }
- PBYTE CImage::DataSet(REFGUID rguid, PBYTE pbData, DWORD cbData)
- {
- if (m_pImageData == NULL) {
- return NULL;
- }
- return m_pImageData->Set(rguid, pbData, cbData);
- }
- BOOL CImage::DataDelete(REFGUID rguid)
- {
- if (m_pImageData == NULL) {
- return FALSE;
- }
- return m_pImageData->Delete(rguid);
- }
- BOOL CImage::DataPurge()
- {
- if (m_pImageData == NULL) {
- return TRUE;
- }
- return m_pImageData->Purge();
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- BOOL CImage::SizeOutputBuffer(DWORD cbData)
- {
- if (m_cbOutputBuffer < cbData) {
- if (cbData < 1024) {//65536
- cbData = 1024;
- }
- cbData = FileAlign(cbData);
- PBYTE pOutput = new BYTE [cbData];
- if (pOutput == NULL) {
- SetLastError(ERROR_OUTOFMEMORY);
- return FALSE;
- }
- if (m_pbOutputBuffer) {
- CopyMemory(pOutput, m_pbOutputBuffer, m_cbOutputBuffer);
- delete[] m_pbOutputBuffer;
- m_pbOutputBuffer = NULL;
- }
- ZeroMemory(pOutput + m_cbOutputBuffer, cbData - m_cbOutputBuffer),
- m_pbOutputBuffer = pOutput;
- m_cbOutputBuffer = cbData;
- }
- return TRUE;
- }
- PBYTE CImage::AllocateOutput(DWORD cbData, DWORD *pnVirtAddr)
- {
- cbData = QuadAlign(cbData);
- PBYTE pbData = m_pbOutputBuffer + m_nOutputVirtSize;
- *pnVirtAddr = m_nOutputVirtAddr + m_nOutputVirtSize;
- m_nOutputVirtSize += cbData;
- if (m_nOutputVirtSize > m_cbOutputBuffer) {
- SetLastError(ERROR_OUTOFMEMORY);
- return NULL;
- }
- ZeroMemory(pbData, cbData);
- return pbData;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- DWORD CImage::FileAlign(DWORD nAddr)
- {
- return Align(nAddr, m_NtHeader.OptionalHeader.FileAlignment);
- }
- DWORD CImage::SectionAlign(DWORD nAddr)
- {
- return Align(nAddr, m_NtHeader.OptionalHeader.SectionAlignment);
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- PVOID CImage::RvaToVa(ULONG_PTR nRva)
- {
- if (nRva == 0) {
- return NULL;
- }
- for (DWORD n = 0; n < m_NtHeader.FileHeader.NumberOfSections; n++) {
- DWORD vaStart = m_SectionHeaders[n].VirtualAddress;
- DWORD vaEnd = vaStart + m_SectionHeaders[n].SizeOfRawData;
- if (nRva >= vaStart && nRva < vaEnd) {
- return (PBYTE)m_pMap
- + m_SectionHeaders[n].PointerToRawData
- + nRva - m_SectionHeaders[n].VirtualAddress;
- }
- }
- return NULL;
- }
- DWORD CImage::RvaToFileOffset(DWORD nRva)
- {
- DWORD n;
- for (n = 0; n < m_NtHeader.FileHeader.NumberOfSections; n++) {
- DWORD vaStart = m_SectionHeaders[n].VirtualAddress;
- DWORD vaEnd = vaStart + m_SectionHeaders[n].SizeOfRawData;
- if (nRva >= vaStart && nRva < vaEnd) {
- return m_SectionHeaders[n].PointerToRawData
- + nRva - m_SectionHeaders[n].VirtualAddress;
- }
- }
- return 0;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- BOOL CImage::WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
- LPDWORD lpNumberOfBytesWritten)
- {
- return ::WriteFile(hFile,
- lpBuffer,
- nNumberOfBytesToWrite,
- lpNumberOfBytesWritten,
- NULL);
- }
- BOOL CImage::CopyFileData(HANDLE hFile, DWORD nOldPos, DWORD cbData)
- {
- DWORD cbDone = 0;
- return WriteFile(hFile, m_pMap + nOldPos, cbData, &cbDone);
- }
- BOOL CImage::ZeroFileData(HANDLE hFile, DWORD cbData)
- {
- if (!SizeOutputBuffer(4096)) {
- return FALSE;
- }
- ZeroMemory(m_pbOutputBuffer, 4096);
- for (DWORD cbLeft = cbData; cbLeft > 0;) {
- DWORD cbStep = cbLeft > sizeof(m_pbOutputBuffer)
- ? sizeof(m_pbOutputBuffer) : cbLeft;
- DWORD cbDone = 0;
- if (!WriteFile(hFile, m_pbOutputBuffer, cbStep, &cbDone)) {
- return FALSE;
- }
- if (cbDone == 0) {
- break;
- }
- cbLeft -= cbDone;
- }
- return TRUE;
- }
- BOOL CImage::AlignFileData(HANDLE hFile)
- {
- DWORD nLastFileAddr = m_nNextFileAddr;
- m_nNextFileAddr = FileAlign(m_nNextFileAddr);
- m_nNextVirtAddr = SectionAlign(m_nNextVirtAddr);
- if (hFile != INVALID_HANDLE_VALUE) {
- if (m_nNextFileAddr > nLastFileAddr) {
- if (SetFilePointer(hFile, nLastFileAddr, NULL, FILE_BEGIN) == ~0u) {
- return FALSE;
- }
- return ZeroFileData(hFile, m_nNextFileAddr - nLastFileAddr);
- }
- }
- return TRUE;
- }
- BOOL CImage::Read(HANDLE hFile)
- {
- DWORD n;
- PBYTE pbData = NULL;
- DWORD cbData = 0;
- if (hFile == INVALID_HANDLE_VALUE) {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- ///////////////////////////////////////////////////////// Create mapping.
- //
- m_nFileSize = GetFileSize(hFile, NULL);
- if (m_nFileSize == (DWORD)-1) {
- return FALSE;
- }
- m_hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
- if (m_hMap == NULL) {
- return FALSE;
- }
- m_pMap = (PBYTE)MapViewOfFile(m_hMap, FILE_MAP_READ, 0, 0, 0);
- if (m_pMap == NULL) {
- return FALSE;
- }
- ////////////////////////////////////////////////////// Process DOS Header.
- //
- PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)m_pMap;
- if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
- SetLastError(ERROR_BAD_EXE_FORMAT);
- return FALSE;
- }
- m_nPeOffset = pDosHeader->e_lfanew;
- m_nPrePE = 0;
- m_cbPrePE = QuadAlign(pDosHeader->e_lfanew);
- CopyMemory(&m_DosHeader, m_pMap + m_nPrePE, sizeof(m_DosHeader));
- /////////////////////////////////////////////////////// Process PE Header.
- //
- CopyMemory(&m_NtHeader, m_pMap + m_nPeOffset, sizeof(m_NtHeader));
- if (m_NtHeader.Signature != IMAGE_NT_SIGNATURE) {
- SetLastError(ERROR_INVALID_EXE_SIGNATURE);
- return FALSE;
- }
- if (m_NtHeader.FileHeader.SizeOfOptionalHeader == 0) {
- SetLastError(ERROR_EXE_MARKED_INVALID);
- return FALSE;
- }
- m_nSectionsOffset = m_nPeOffset
- + sizeof(m_NtHeader.Signature)
- + sizeof(m_NtHeader.FileHeader)
- + m_NtHeader.FileHeader.SizeOfOptionalHeader;
- ///////////////////////////////////////////////// Process Section Headers.
- //
- if (m_NtHeader.FileHeader.NumberOfSections > (sizeof(m_SectionHeaders) /
- sizeof(m_SectionHeaders[0]))) {
- SetLastError(ERROR_EXE_MARKED_INVALID);
- return FALSE;
- }
- CopyMemory(&m_SectionHeaders,
- m_pMap + m_nSectionsOffset,
- sizeof(m_SectionHeaders[0]) * m_NtHeader.FileHeader.NumberOfSections);
- /////////////////////////////////////////////////// Parse .detour Section.
- //
- DWORD rvaOriginalImageDirectory = 0;
- DWORD rvaDetourBeg = 0;
- DWORD rvaDetourEnd = 0;
- for (n = 0; n < m_NtHeader.FileHeader.NumberOfSections; n++) {
- if (strcmp((PCHAR)m_SectionHeaders[n].Name, ".detour") == 0) {
- DETOUR_SECTION_HEADER dh;
- CopyMemory(&dh,
- m_pMap + m_SectionHeaders[n].PointerToRawData,
- sizeof(dh));
- rvaOriginalImageDirectory = dh.nOriginalImportVirtualAddress;
- if (dh.cbPrePE != 0) {
- m_nPrePE = m_SectionHeaders[n].PointerToRawData + sizeof(dh);
- m_cbPrePE = dh.cbPrePE;
- }
- rvaDetourBeg = m_SectionHeaders[n].VirtualAddress;
- rvaDetourEnd = rvaDetourBeg + m_SectionHeaders[n].SizeOfRawData;
- }
- }
- //////////////////////////////////////////////////////// Get Import Table.
- //
- DWORD rvaImageDirectory = m_NtHeader.OptionalHeader
- .DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
- PIMAGE_IMPORT_DESCRIPTOR iidp
- = (PIMAGE_IMPORT_DESCRIPTOR)RvaToVa(rvaImageDirectory);
- PIMAGE_IMPORT_DESCRIPTOR oidp
- = (PIMAGE_IMPORT_DESCRIPTOR)RvaToVa(rvaOriginalImageDirectory);
- if (oidp == NULL) {
- oidp = iidp;
- }
- if (iidp == NULL || oidp == NULL) {
- SetLastError(ERROR_EXE_MARKED_INVALID);
- return FALSE;
- }
- DWORD nFiles = 0;
- for (; iidp[nFiles].OriginalFirstThunk != 0; nFiles++) {
- }
- CImageImportFile **ppLastFile = &m_pImportFiles;
- m_pImportFiles = NULL;
- for (n = 0; n < nFiles; n++, iidp++) {
- ULONG_PTR rvaName = iidp->Name;
- PCHAR pszName = (PCHAR)RvaToVa(rvaName);
- if (pszName == NULL) {
- SetLastError(ERROR_EXE_MARKED_INVALID);
- goto fail;
- }
- CImageImportFile *pImportFile = new CImageImportFile;
- if (pImportFile == NULL) {
- SetLastError(ERROR_OUTOFMEMORY);
- goto fail;
- }
- *ppLastFile = pImportFile;
- ppLastFile = &pImportFile->m_pNextFile;
- m_nImportFiles++;
- pImportFile->m_pszName = DuplicateString(pszName);
- if (pImportFile->m_pszName == NULL) {
- goto fail;
- }
- pImportFile->m_rvaOriginalFirstThunk = iidp->OriginalFirstThunk;
- pImportFile->m_rvaFirstThunk = iidp->FirstThunk;
- pImportFile->m_nForwarderChain = iidp->ForwarderChain;
- pImportFile->m_pImportNames = NULL;
- pImportFile->m_nImportNames = 0;
- pImportFile->m_fByway = FALSE;
- if ((ULONG)iidp->FirstThunk >= rvaDetourBeg &&
- (ULONG)iidp->FirstThunk < rvaDetourEnd) {
- pImportFile->m_pszOrig = NULL;
- pImportFile->m_fByway = TRUE;
- continue;
- }
- rvaName = oidp->Name;
- pszName = (PCHAR)RvaToVa(rvaName);
- if (pszName == NULL) {
- SetLastError(ERROR_EXE_MARKED_INVALID);
- goto fail;
- }
- pImportFile->m_pszOrig = DuplicateString(pszName);
- if (pImportFile->m_pszOrig == NULL) {
- goto fail;
- }
- DWORD rvaThunk = iidp->OriginalFirstThunk;
- PIMAGE_THUNK_DATA pAddrThunk = (PIMAGE_THUNK_DATA)RvaToVa(rvaThunk);
- rvaThunk = oidp->OriginalFirstThunk;
- PIMAGE_THUNK_DATA pLookThunk = (PIMAGE_THUNK_DATA)RvaToVa(rvaThunk);
- DWORD nNames = 0;
- if (pAddrThunk) {
- for (; pAddrThunk[nNames].u1.Ordinal; nNames++) {
- }
- }
- if (pAddrThunk && nNames) {
- pImportFile->m_nImportNames = nNames;
- pImportFile->m_pImportNames = new CImageImportName [nNames];
- if (pImportFile->m_pImportNames == NULL) {
- SetLastError(ERROR_OUTOFMEMORY);
- goto fail;
- }
- CImageImportName *pImportName = &pImportFile->m_pImportNames[0];
- for (DWORD f = 0; f < nNames; f++, pImportName++) {
- pImportName->m_nOrig = 0;
- pImportName->m_nOrdinal = 0;
- pImportName->m_nHint = 0;
- pImportName->m_pszName = NULL;
- pImportName->m_pszOrig = NULL;
- rvaName = pAddrThunk[f].u1.Ordinal;
- if (rvaName & IMAGE_ORDINAL_FLAG) {
- pImportName->m_nOrig = (ULONG)IMAGE_ORDINAL(rvaName);
- pImportName->m_nOrdinal = pImportName->m_nOrig;
- }
- else {
- PIMAGE_IMPORT_BY_NAME pName
- = (PIMAGE_IMPORT_BY_NAME)RvaToVa(rvaName);
- if (pName) {
- pImportName->m_nHint = pName->Hint;
- pImportName->m_pszName = DuplicateString((PCHAR)pName->Name);
- if (pImportName->m_pszName == NULL) {
- goto fail;
- }
- }
- rvaName = pLookThunk[f].u1.Ordinal;
- if (rvaName & IMAGE_ORDINAL_FLAG) {
- pImportName->m_nOrig = (ULONG)IMAGE_ORDINAL(rvaName);
- pImportName->m_nOrdinal = (ULONG)IMAGE_ORDINAL(rvaName);
- }
- else {
- pName = (PIMAGE_IMPORT_BY_NAME)RvaToVa(rvaName);
- if (pName) {
- pImportName->m_pszOrig
- = DuplicateString((PCHAR)pName->Name);
- if (pImportName->m_pszOrig == NULL) {
- goto fail;
- }
- }
- }
- }
- }
- }
- oidp++;
- }
- ////////////////////////////////////////////////////////// Parse Sections.
- //
- m_nExtraOffset = 0;
- for (n = 0; n < m_NtHeader.FileHeader.NumberOfSections; n++) {
- m_nExtraOffset = Max(m_SectionHeaders[n].PointerToRawData +
- m_SectionHeaders[n].SizeOfRawData,
- m_nExtraOffset);
- if (strcmp((PCHAR)m_SectionHeaders[n].Name, ".detour") == 0) {
- DETOUR_SECTION_HEADER dh;
- CopyMemory(&dh,
- m_pMap + m_SectionHeaders[n].PointerToRawData,
- sizeof(dh));
- if (dh.nDataOffset == 0) {
- dh.nDataOffset = dh.cbHeaderSize;
- }
- cbData = dh.cbDataSize - dh.nDataOffset;
- pbData = (m_pMap +
- m_SectionHeaders[n].PointerToRawData +
- dh.nDataOffset);
- m_nExtraOffset = Max(m_SectionHeaders[n].PointerToRawData +
- m_SectionHeaders[n].SizeOfRawData,
- m_nExtraOffset);
- m_NtHeader.FileHeader.NumberOfSections--;
- m_NtHeader.OptionalHeader
- .DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress
- = dh.nOriginalImportVirtualAddress;
- m_NtHeader.OptionalHeader
- .DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size
- = dh.nOriginalImportSize;
- m_NtHeader.OptionalHeader
- .DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress
- = dh.nOriginalBoundImportVirtualAddress;
- m_NtHeader.OptionalHeader
- .DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size
- = dh.nOriginalBoundImportSize;
- m_NtHeader.OptionalHeader
- .DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress
- = dh.nOriginalIatVirtualAddress;
- m_NtHeader.OptionalHeader
- .DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size
- = dh.nOriginalIatSize;
- m_NtHeader.OptionalHeader.CheckSum = 0;
- m_NtHeader.OptionalHeader.SizeOfImage
- = dh.nOriginalSizeOfImage;
- m_fHadDetourSection = TRUE;
- }
- }
- m_pImageData = new CImageData(pbData, cbData);
- if (m_pImageData == NULL) {
- SetLastError(ERROR_OUTOFMEMORY);
- }
- return TRUE;
- fail:
- return FALSE;
- }
- static inline BOOL strneq(__in_z PCHAR pszOne, __in_z PCHAR pszTwo)
- {
- if (pszOne == pszTwo) {
- return FALSE;
- }
- if (!pszOne || !pszTwo) {
- return TRUE;
- }
- return (strcmp(pszOne, pszTwo) != 0);
- }
- BOOL CImage::CheckImportsNeeded(DWORD *pnTables, DWORD *pnThunks, DWORD *pnChars)
- {
- DWORD nTables = 0;
- DWORD nThunks = 0;
- DWORD nChars = 0;
- BOOL fNeedDetourSection = FALSE;
- for (CImageImportFile *pImportFile = m_pImportFiles;
- pImportFile != NULL; pImportFile = pImportFile->m_pNextFile) {
- nChars += (int)strlen(pImportFile->m_pszName) + 1;
- nChars += nChars & 1;
- if (pImportFile->m_fByway) {
- fNeedDetourSection = TRUE;
- nThunks++;
- }
- else {
- if (!fNeedDetourSection &&
- strneq(pImportFile->m_pszName, pImportFile->m_pszOrig)) {
- fNeedDetourSection = TRUE;
- }
- for (DWORD n = 0; n < pImportFile->m_nImportNames; n++) {
- CImageImportName *pImportName = &pImportFile->m_pImportNames[n];
- if (!fNeedDetourSection &&
- strneq(pImportName->m_pszName, pImportName->m_pszOrig)) {
- fNeedDetourSection = TRUE;
- }
- if (pImportName->m_pszName) {
- nChars += sizeof(WORD); // Hint
- nChars += (int)strlen(pImportName->m_pszName) + 1;
- nChars += nChars & 1;
- }
- nThunks++;
- }
- }
- nThunks++;
- nTables++;
- }
- nTables++;
- *pnTables = nTables;
- *pnThunks = nThunks;
- *pnChars = nChars;
- return fNeedDetourSection;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- CImageImportFile * CImage::NewByway(__in_z PCHAR pszName)
- {
- CImageImportFile *pImportFile = new CImageImportFile;
- if (pImportFile == NULL) {
- SetLastError(ERROR_OUTOFMEMORY);
- goto fail;
- }
- pImportFile->m_pNextFile = NULL;
- pImportFile->m_fByway = TRUE;
- pImportFile->m_pszName = DuplicateString(pszName);
- if (pImportFile->m_pszName == NULL) {
- goto fail;
- }
- pImportFile->m_rvaOriginalFirstThunk = 0;
- pImportFile->m_rvaFirstThunk = 0;
- pImportFile->m_nForwarderChain = (UINT)0;
- pImportFile->m_pImportNames = NULL;
- pImportFile->m_nImportNames = 0;
- m_nImportFiles++;
- return pImportFile;
- fail:
- if (pImportFile) {
- delete pImportFile;
- pImportFile = NULL;
- }
- return NULL;
- }
- BOOL CImage::EditImports(PVOID pContext,
- PF_DETOUR_BINARY_BYWAY_CALLBACK pfBywayCallback,
- PF_DETOUR_BINARY_FILE_CALLBACK pfFileCallback,
- PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbolCallback,
- PF_DETOUR_BINARY_COMMIT_CALLBACK pfCommitCallback)
- {
- CImageImportFile *pImportFile = NULL;
- CImageImportFile **ppLastFile = &m_pImportFiles;
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- while ((pImportFile = *ppLastFile) != NULL) {
- if (pfBywayCallback) {
- PCHAR pszFile = NULL;
- if (!(*pfBywayCallback)(pContext, pszFile, &pszFile)) {
- goto fail;
- }
- if (pszFile) {
- // Insert a new Byway.
- CImageImportFile *pByway = NewByway(pszFile);
- if (pByway == NULL) {
- return FALSE;
- }
- pByway->m_pNextFile = pImportFile;
- *ppLastFile = pByway;
- ppLastFile = &pByway->m_pNextFile;
- continue; // Retry after Byway.
- }
- }
- if (pImportFile->m_fByway) {
- if (pfBywayCallback) {
- PCHAR pszFile = pImportFile->m_pszName;
- if (!(*pfBywayCallback)(pContext, pszFile, &pszFile)) {
- goto fail;
- }
- if (pszFile) { // Replace? Byway
- if (ReplaceString(&pImportFile->m_pszName, pszFile) == NULL) {
- goto fail;
- }
- }
- else { // Delete Byway
- *ppLastFile = pImportFile->m_pNextFile;
- pImportFile->m_pNextFile = NULL;
- delete pImportFile;
- pImportFile = *ppLastFile;
- m_nImportFiles--;
- continue; // Retry after delete.
- }
- }
- }
- else {
- if (pfFileCallback) {
- PCHAR pszFile = pImportFile->m_pszName;
- if (!(*pfFileCallback)(pContext, pImportFile->m_pszOrig,
- pszFile, &pszFile)) {
- goto fail;
- }
- if (pszFile != NULL) {
- if (ReplaceString(&pImportFile->m_pszName, pszFile) == NULL) {
- goto fail;
- }
- }
- }
- if (pfSymbolCallback) {
- for (DWORD n = 0; n < pImportFile->m_nImportNames; n++) {
- CImageImportName *pImportName = &pImportFile->m_pImportNames[n];
- PCHAR pszName = pImportName->m_pszName;
- ULONG nOrdinal = pImportName->m_nOrdinal;
- if (!(*pfSymbolCallback)(pContext,
- pImportName->m_nOrig,
- nOrdinal,
- &nOrdinal,
- pImportName->m_pszOrig,
- pszName,
- &pszName)) {
- goto fail;
- }
- if (pszName != NULL) {
- pImportName->m_nOrdinal = 0;
- if (ReplaceString(&pImportName->m_pszName, pszName) == NULL) {
- goto fail;
- }
- }
- else if (nOrdinal != 0) {
- pImportName->m_nOrdinal = nOrdinal;
- if (pImportName->m_pszName != NULL) {
- delete[] pImportName->m_pszName;
- pImportName->m_pszName = NULL;
- }
- }
- }
- }
- }
- ppLastFile = &pImportFile->m_pNextFile;
- pImportFile = pImportFile->m_pNextFile;
- }
- for (;;) {
- if (pfBywayCallback) {
- PCHAR pszFile = NULL;
- if (!(*pfBywayCallback)(pContext, NULL, &pszFile)) {
- goto fail;
- }
- if (pszFile) {
- // Insert a new Byway.
- CImageImportFile *pByway = NewByway(pszFile);
- if (pByway == NULL) {
- return FALSE;
- }
- pByway->m_pNextFile = pImportFile;
- *ppLastFile = pByway;
- ppLastFile = &pByway->m_pNextFile;
- continue; // Retry after Byway.
- }
- }
- break;
- }
- if (pfCommitCallback) {
- if (!(*pfCommitCallback)(pContext)) {
- goto fail;
- }
- }
- SetLastError(NO_ERROR);
- return TRUE;
- fail:
- return FALSE;
- }
- BOOL CImage::Write(HANDLE hFile)
- {
- DWORD cbDone;
- if (hFile == INVALID_HANDLE_VALUE) {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- m_nNextFileAddr = 0;
- m_nNextVirtAddr = 0;
- DWORD nTables = 0;
- DWORD nThunks = 0;
- DWORD nChars = 0;
- BOOL fNeedDetourSection = CheckImportsNeeded(&nTables, &nThunks, &nChars);
- //////////////////////////////////////////////////////////// Copy Headers.
- //
- if (SetFilePointer(hFile, 0, NULL, FILE_BEGIN) == ~0u) {
- return FALSE;
- }
- if (!CopyFileData(hFile, 0, m_NtHeader.OptionalHeader.SizeOfHeaders)) {
- return FALSE;
- }
- if (fNeedDetourSection || !m_pImageData->IsEmpty()) {
- // Replace the file's DOS header with our own.
- m_nPeOffset = sizeof(m_DosHeader) + sizeof(s_rbDosCode);
- m_nSectionsOffset = m_nPeOffset
- + sizeof(m_NtHeader.Signature)
- + sizeof(m_NtHeader.FileHeader)
- + m_NtHeader.FileHeader.SizeOfOptionalHeader;
- m_DosHeader.e_lfanew = m_nPeOffset;
- if (SetFilePointer(hFile, 0, NULL, FILE_BEGIN) == ~0u) {
- return FALSE;
- }
- if (!WriteFile(hFile, &m_DosHeader, sizeof(m_DosHeader), &cbDone)) {
- return FALSE;
- }
- if (!WriteFile(hFile, &s_rbDosCode, sizeof(s_rbDosCode), &cbDone)) {
- return FALSE;
- }
- }
- else {
- // Restore the file's original DOS header.
- if (m_nPrePE != 0) {
- m_nPeOffset = m_cbPrePE;
- m_nSectionsOffset = m_nPeOffset
- + sizeof(m_NtHeader.Signature)
- + sizeof(m_NtHeader.FileHeader)
- + m_NtHeader.FileHeader.SizeOfOptionalHeader;
- m_DosHeader.e_lfanew = m_nPeOffset;
- if (SetFilePointer(hFile, 0, NULL, FILE_BEGIN) == ~0u) {
- return FALSE;
- }
- if (!CopyFileData(hFile, m_nPrePE, m_cbPrePE)) {
- return FALSE;
- }
- }
- }
- m_nNextFileAddr = m_NtHeader.OptionalHeader.SizeOfHeaders;
- m_nNextVirtAddr = 0;
- if (!AlignFileData(hFile)) {
- return FALSE;
- }
- /////////////////////////////////////////////////////////// Copy Sections.
- //
- DWORD n = 0;
- for (; n < m_NtHeader.FileHeader.NumberOfSections; n++) {
- if (m_SectionHeaders[n].SizeOfRawData) {
- if (SetFilePointer(hFile,
- m_SectionHeaders[n].PointerToRawData,
- NULL, FILE_BEGIN) == ~0u) {
- return FALSE;
- }
- if (!CopyFileData(hFile,
- m_SectionHeaders[n].PointerToRawData,
- m_SectionHeaders[n].SizeOfRawData)) {
- return FALSE;
- }
- }
- m_nNextFileAddr = Max(m_SectionHeaders[n].PointerToRawData +
- m_SectionHeaders[n].SizeOfRawData,
- m_nNextFileAddr);
- m_nNextVirtAddr = Max(m_SectionHeaders[n].VirtualAddress +
- m_SectionHeaders[n].Misc.VirtualSize,
- m_nNextVirtAddr);
- m_nExtraOffset = Max(m_nNextFileAddr, m_nExtraOffset);
- if (!AlignFileData(hFile)) {
- return FALSE;
- }
- }
- if (fNeedDetourSection || !m_pImageData->IsEmpty()) {
- ////////////////////////////////////////////// Insert .detour Section.
- //
- DWORD nSection = m_NtHeader.FileHeader.NumberOfSections++;
- DETOUR_SECTION_HEADER dh;
- ZeroMemory(&dh, sizeof(dh));
- ZeroMemory(&m_SectionHeaders[nSection], sizeof(m_SectionHeaders[nSection]));
- dh.cbHeaderSize = sizeof(DETOUR_SECTION_HEADER);
- dh.nSignature = DETOUR_SECTION_HEADER_SIGNATURE;
- dh.nOriginalImportVirtualAddress = m_NtHeader.OptionalHeader
- .DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
- dh.nOriginalImportSize = m_NtHeader.OptionalHeader
- .DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
- dh.nOriginalBoundImportVirtualAddress
- = m_NtHeader.OptionalHeader
- .DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress;
- dh.nOriginalBoundImportSize = m_NtHeader.OptionalHeader
- .DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size;
- dh.nOriginalIatVirtualAddress = m_NtHeader.OptionalHeader
- .DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress;
- dh.nOriginalIatSize = m_NtHeader.OptionalHeader
- .DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size;
- dh.nOriginalSizeOfImage = m_NtHeader.OptionalHeader.SizeOfImage;
- DWORD clrAddr = m_NtHeader.OptionalHeader
- .DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress;
- DWORD clrSize = m_NtHeader.OptionalHeader
- .DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size;
- if (clrAddr && clrSize) {
- PDETOUR_CLR_HEADER pHdr = (PDETOUR_CLR_HEADER)RvaToVa(clrAddr);
- if (pHdr != NULL) {
- DETOUR_CLR_HEADER hdr;
- hdr = *pHdr;
- dh.nOriginalClrFlags = hdr.Flags;
- }
- }
- HRESULT hrRet = StringCchCopyA((PCHAR)m_SectionHeaders[nSection].Name, IMAGE_SIZEOF_SHORT_NAME , ".detour");
- if (FAILED(hrRet))
- return FALSE;
- m_SectionHeaders[nSection].Characteristics
- = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
- m_nOutputVirtAddr = m_nNextVirtAddr;
- m_nOutputVirtSize = 0;
- m_nOutputFileAddr = m_nNextFileAddr;
- dh.nDataOffset = 0; // pbData
- dh.cbDataSize = m_pImageData->m_cbData;
- dh.cbPrePE = m_cbPrePE;
- //////////////////////////////////////////////////////////////////////////
- //
- DWORD rvaImportTable = 0;
- DWORD rvaLookupTable = 0;
- DWORD rvaBoundTable = 0;
- DWORD rvaNameTable = 0;
- DWORD nImportTableSize = nTables * sizeof(IMAGE_IMPORT_DESCRIPTOR);
- if (!SizeOutputBuffer(QuadAlign(sizeof(dh))
- + m_cbPrePE
- + QuadAlign(m_pImageData->m_cbData)
- + QuadAlign(sizeof(IMAGE_THUNK_DATA) * nThunks)
- + QuadAlign(sizeof(IMAGE_THUNK_DATA) * nThunks)
- + QuadAlign(nChars)
- + QuadAlign(nImportTableSize))) {
- return FALSE;
- }
- DWORD vaHead = 0;
- PBYTE pbHead = NULL;
- DWORD vaPrePE = 0;
- PBYTE pbPrePE = NULL;
- DWORD vaData = 0;
- PBYTE pbData = NULL;
- if ((pbHead = AllocateOutput(sizeof(dh), &vaHead)) == NULL) {
- return FALSE;
- }
- if ((pbPrePE = AllocateOutput(m_cbPrePE, &vaPrePE)) == NULL) {
- return FALSE;
- }
- CImageThunks lookupTable(this, nThunks, &rvaLookupTable);
- CImageThunks boundTable(this, nThunks, &rvaBoundTable);
- CImageChars nameTable(this, nChars, &rvaNameTable);
- if ((pbData = AllocateOutput(m_pImageData->m_cbData, &vaData)) == NULL) {
- return FALSE;
- }
- dh.nDataOffset = vaData - vaHead;
- dh.cbDataSize = dh.nDataOffset + m_pImageData->m_cbData;
- CopyMemory(pbHead, &dh, sizeof(dh));
- CopyMemory(pbPrePE, m_pMap + m_nPrePE, m_cbPrePE);
- CopyMemory(pbData, m_pImageData->m_pbData, m_pImageData->m_cbData);
- PIMAGE_IMPORT_DESCRIPTOR piidDst = (PIMAGE_IMPORT_DESCRIPTOR)
- AllocateOutput(nImportTableSize, &rvaImportTable);
- if (piidDst == NULL) {
- return FALSE;
- }
- //////////////////////////////////////////////// Step Through Imports.
- //
- for (CImageImportFile *pImportFile = m_pImportFiles;
- pImportFile != NULL; pImportFile = pImportFile->m_pNextFile) {
- ZeroMemory(piidDst, sizeof(piidDst));
- nameTable.Allocate(pImportFile->m_pszName, (DWORD *)&piidDst->Name);
- piidDst->TimeDateStamp = 0;
- piidDst->ForwarderChain = pImportFile->m_nForwarderChain;
- if (pImportFile->m_fByway) {
- ULONG rvaIgnored;
- lookupTable.Allocate(IMAGE_ORDINAL_FLAG+1,
- (DWORD *)&piidDst->OriginalFirstThunk);
- boundTable.Allocate(IMAGE_ORDINAL_FLAG+1,
- (DWORD *)&piidDst->FirstThunk);
- lookupTable.Allocate(0, &rvaIgnored);
- boundTable.Allocate(0, &rvaIgnored);
- }
- else {
- ULONG rvaIgnored;
- piidDst->FirstThunk = (ULONG)pImportFile->m_rvaFirstThunk;
- lookupTable.Current((DWORD *)&piidDst->OriginalFirstThunk);
- for (n = 0; n < pImportFile->m_nImportNames; n++) {
- CImageImportName *pImportName = &pImportFile->m_pImportNames[n];
- if (pImportName->m_pszName) {
- ULONG nDstName = 0;
- nameTable.Allocate(pImportName->m_pszName,
- pImportName->m_nHint,
- &nDstName);
- lookupTable.Allocate(nDstName, &rvaIgnored);
- }
- else {
- lookupTable.Allocate(IMAGE_ORDINAL_FLAG + pImportName->m_nOrdinal,
- &rvaIgnored);
- }
- }
- lookupTable.Allocate(0, &rvaIgnored);
- }
- piidDst++;
- }
- ZeroMemory(piidDst, sizeof(piidDst));
- //////////////////////////////////////////////////////////////////////////
- //
- m_nNextVirtAddr += m_nOutputVirtSize;
- m_nNextFileAddr += FileAlign(m_nOutputVirtSize);
- if (!AlignFileData(hFile)) {
- return FALSE;
- }
- //////////////////////////////////////////////////////////////////////////
- //
- m_SectionHeaders[nSection].VirtualAddress = m_nOutputVirtAddr;
- m_SectionHeaders[nSection].Misc.VirtualSize = m_nOutputVirtSize;
- m_SectionHeaders[nSection].PointerToRawData = m_nOutputFileAddr;
- m_SectionHeaders[nSection].SizeOfRawData = FileAlign(m_nOutputVirtSize);
- m_NtHeader.OptionalHeader
- .DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress
- = rvaImportTable;
- m_NtHeader.OptionalHeader
- .DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size
- = nImportTableSize;
- m_NtHeader.OptionalHeader
- .DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;
- m_NtHeader.OptionalHeader
- .DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;
- //////////////////////////////////////////////////////////////////////////
- //
- if (SetFilePointer(hFile, m_SectionHeaders[nSection].PointerToRawData,
- NULL, FILE_BEGIN) == ~0u) {
- return FALSE;
- }
- if (!WriteFile(hFile, m_pbOutputBuffer, m_SectionHeaders[nSection].SizeOfRawData,
- &cbDone)) {
- return FALSE;
- }
- }
- ///////////////////////////////////////////////////// Adjust Extra Data.
- //
- LONG nExtraAdjust = m_nNextFileAddr - m_nExtraOffset;
- for (n = 0; n < m_NtHeader.FileHeader.NumberOfSections; n++) {
- if (m_SectionHeaders[n].PointerToRawData > m_nExtraOffset) {
- m_SectionHeaders[n].PointerToRawData += nExtraAdjust;
- }
- if (m_SectionHeaders[n].PointerToRelocations > m_nExtraOffset) {
- m_SectionHeaders[n].PointerToRelocations += nExtraAdjust;
- }
- if (m_SectionHeaders[n].PointerToLinenumbers > m_nExtraOffset) {
- m_SectionHeaders[n].PointerToLinenumbers += nExtraAdjust;
- }
- }
- if (m_NtHeader.FileHeader.PointerToSymbolTable > m_nExtraOffset) {
- m_NtHeader.FileHeader.PointerToSymbolTable += nExtraAdjust;
- }
- m_NtHeader.OptionalHeader.CheckSum = 0;
- m_NtHeader.OptionalHeader.SizeOfImage = m_nNextVirtAddr;
- ////////////////////////////////////////////////// Adjust Debug Directory.
- //
- DWORD debugAddr = m_NtHeader.OptionalHeader
- .DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
- DWORD debugSize = m_NtHeader.OptionalHeader
- .DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
- if (debugAddr && debugSize) {
- DWORD nFileOffset = RvaToFileOffset(debugAddr);
- if (SetFilePointer(hFile, nFileOffset, NULL, FILE_BEGIN) == ~0u) {
- return FALSE;
- }
- PIMAGE_DEBUG_DIRECTORY pDir = (PIMAGE_DEBUG_DIRECTORY)RvaToVa(debugAddr);
- if (pDir == NULL) {
- return FALSE;
- }
- DWORD nEntries = debugSize / sizeof(*pDir);
- for (n = 0; n < nEntries; n++) {
- IMAGE_DEBUG_DIRECTORY dir = pDir[n];
- if (dir.PointerToRawData > m_nExtraOffset) {
- dir.PointerToRawData += nExtraAdjust;
- }
- if (!WriteFile(hFile, &dir, sizeof(dir), &cbDone)) {
- return FALSE;
- }
- }
- }
- /////////////////////////////////////////////////////// Adjust CLR Header.
- //
- DWORD clrAddr = m_NtHeader.OptionalHeader
- .DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress;
- DWORD clrSize = m_NtHeader.OptionalHeader
- .DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size;
- if (clrAddr && clrSize && fNeedDetourSection) {
- DWORD nFileOffset = RvaToFileOffset(clrAddr);
- if (SetFilePointer(hFile, nFileOffset, NULL, FILE_BEGIN) == ~0u) {
- return FALSE;
- }
- PDETOUR_CLR_HEADER pHdr = (PDETOUR_CLR_HEADER)RvaToVa(clrAddr);
- if (pHdr == NULL) {
- return FALSE;
- }
- DETOUR_CLR_HEADER hdr;
- hdr = *pHdr;
- hdr.Flags &= 0xfffffffe; // Clear the IL_ONLY flag.
- if (!WriteFile(hFile, &hdr, sizeof(hdr), &cbDone)) {
- return FALSE;
- }
- }
- ///////////////////////////////////////////////// Copy Left-over Data.
- //
- if (m_nFileSize > m_nExtraOffset) {
- if (SetFilePointer(hFile, m_nNextFileAddr, NULL, FILE_BEGIN) == ~0u) {
- return FALSE;
- }
- if (!CopyFileData(hFile, m_nExtraOffset, m_nFileSize - m_nExtraOffset)) {
- return FALSE;
- }
- }
- //////////////////////////////////////////////////// Finalize Headers.
- //
- if (SetFilePointer(hFile, m_nPeOffset, NULL, FILE_BEGIN) == ~0u) {
- return FALSE;
- }
- if (!WriteFile(hFile, &m_NtHeader, sizeof(m_NtHeader), &cbDone)) {
- return FALSE;
- }
- if (SetFilePointer(hFile, m_nSectionsOffset, NULL, FILE_BEGIN) == ~0u) {
- return FALSE;
- }
- if (!WriteFile(hFile, &m_SectionHeaders,
- sizeof(m_SectionHeaders[0])
- * m_NtHeader.FileHeader.NumberOfSections,
- &cbDone)) {
- return FALSE;
- }
- m_cbPostPE = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
- if (m_cbPostPE == ~0u) {
- return FALSE;
- }
- m_cbPostPE = m_NtHeader.OptionalHeader.SizeOfHeaders - m_cbPostPE;
- return TRUE;
- }
- }; // namespace Detour
- //////////////////////////////////////////////////////////////////////////////
- //
- PDETOUR_BINARY WINAPI DetourBinaryOpen(HANDLE hFile)
- {
- Detour::CImage *pImage = new Detour::CImage;
- if (pImage == NULL) {
- SetLastError(ERROR_OUTOFMEMORY);
- return FALSE;
- }
- if (!pImage->Read(hFile)) {
- delete pImage;
- return FALSE;
- }
- return (PDETOUR_BINARY)pImage;
- }
- BOOL WINAPI DetourBinaryWrite(PDETOUR_BINARY pdi, HANDLE hFile)
- {
- Detour::CImage *pImage = Detour::CImage::IsValid(pdi);
- if (pImage == NULL) {
- return FALSE;
- }
- return pImage->Write(hFile);
- }
- PVOID WINAPI DetourBinaryEnumeratePayloads(PDETOUR_BINARY pdi,
- GUID *pGuid,
- DWORD *pcbData,
- DWORD *pnIterator)
- {
- Detour::CImage *pImage = Detour::CImage::IsValid(pdi);
- if (pImage == NULL) {
- return FALSE;
- }
- return pImage->DataEnum(pGuid, pcbData, pnIterator);
- }
- PVOID WINAPI DetourBinaryFindPayload(PDETOUR_BINARY pdi,
- REFGUID rguid,
- DWORD *pcbData)
- {
- Detour::CImage *pImage = Detour::CImage::IsValid(pdi);
- if (pImage == NULL) {
- return FALSE;
- }
- return pImage->DataFind(rguid, pcbData);
- }
- PVOID WINAPI DetourBinarySetPayload(PDETOUR_BINARY pdi,
- REFGUID rguid,
- PVOID pvData,
- DWORD cbData)
- {
- Detour::CImage *pImage = Detour::CImage::IsValid(pdi);
- if (pImage == NULL) {
- return FALSE;
- }
- return pImage->DataSet(rguid, (PBYTE)pvData, cbData);
- }
- BOOL WINAPI DetourBinaryDeletePayload(PDETOUR_BINARY pdi,
- REFGUID rguid)
- {
- Detour::CImage *pImage = Detour::CImage::IsValid(pdi);
- if (pImage == NULL) {
- return FALSE;
- }
- return pImage->DataDelete(rguid);
- }
- BOOL WINAPI DetourBinaryPurgePayloads(PDETOUR_BINARY pdi)
- {
- Detour::CImage *pImage = Detour::CImage::IsValid(pdi);
- if (pImage == NULL) {
- return FALSE;
- }
- return pImage->DataPurge();
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- static BOOL CALLBACK ResetBywayCallback(PVOID pContext,
- __in_z PCHAR pszFile,
- __deref PCHAR *ppszOutFile)
- {
- (void)pContext;
- (void)pszFile;
- *ppszOutFile = NULL;
- return TRUE;
- }
- static BOOL CALLBACK ResetFileCallback(PVOID pContext,
- __in_z PCHAR pszOrigFile,
- __in_z PCHAR pszFile,
- __deref PCHAR *ppszOutFile)
- {
- (void)pContext;
- (void)pszFile;
- *ppszOutFile = pszOrigFile;
- return TRUE;
- }
- static BOOL CALLBACK ResetSymbolCallback(PVOID pContext,
- ULONG nOrigOrdinal,
- ULONG nOrdinal,
- ULONG *pnOutOrdinal,
- __in_z PCHAR pszOrigSymbol,
- __in_z PCHAR pszSymbol,
- __deref PCHAR *ppszOutSymbol)
- {
- (void)pContext;
- (void)nOrdinal;
- (void)pszSymbol;
- *pnOutOrdinal = nOrigOrdinal;
- *ppszOutSymbol = pszOrigSymbol;
- return TRUE;
- }
- BOOL WINAPI DetourBinaryResetImports(PDETOUR_BINARY pdi)
- {
- Detour::CImage *pImage = Detour::CImage::IsValid(pdi);
- if (pImage == NULL) {
- return FALSE;
- }
- return pImage->EditImports(NULL,
- ResetBywayCallback,
- ResetFileCallback,
- ResetSymbolCallback,
- NULL);
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- BOOL WINAPI DetourBinaryEditImports(PDETOUR_BINARY pdi,
- PVOID pContext,
- PF_DETOUR_BINARY_BYWAY_CALLBACK pfBywayCallback,
- PF_DETOUR_BINARY_FILE_CALLBACK pfFileCallback,
- PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbolCallback,
- PF_DETOUR_BINARY_COMMIT_CALLBACK pfCommitCallback)
- {
- Detour::CImage *pImage = Detour::CImage::IsValid(pdi);
- if (pImage == NULL) {
- return FALSE;
- }
- return pImage->EditImports(pContext,
- pfBywayCallback,
- pfFileCallback,
- pfSymbolCallback,
- pfCommitCallback);
- }
- BOOL WINAPI DetourBinaryClose(PDETOUR_BINARY pdi)
- {
- Detour::CImage *pImage = Detour::CImage::IsValid(pdi);
- if (pImage == NULL) {
- return FALSE;
- }
- BOOL bSuccess = pImage->Close();
- delete pImage;
- pImage = NULL;
- return bSuccess;
- }
- //
- ///////////////////////////////////////////////////////////////// End of File.
|