| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257 |
- //////////////////////////////////////////////////////////////////////////////
- //
- // 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.
|