📄 image.cpp
字号:
//
if (SetFilePointer(hFile, 0, NULL, FILE_BEGIN) == ~0u) {
return FALSE;
}
if (!CopyFileData(hFile, 0, m_NtHeader.OptionalHeader.SizeOfHeaders)) {
return FALSE;
}
m_nNextFileAddr = m_NtHeader.OptionalHeader.SizeOfHeaders;
m_nNextVirtAddr = 0;
if (!AlignFileData(hFile)) {
return FALSE;
}
/////////////////////////////////////////////////////////// Copy Sections.
//
for (DWORD n = 0; 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;
}
}
/////////////////////////////////////////////////////////////// Old WriteSection
BOOLEAN bNeedDetourSection;
DWORD cbDone;
DWORD nTables = 0;
DWORD nThunks = 0;
DWORD nChars = 0;
bNeedDetourSection = CheckImportsNeeded(&nTables, &nThunks, &nChars);
if (bNeedDetourSection || !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;
strcpy((PCHAR)m_SectionHeaders[nSection].Name, ".detour");
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;
//////////////////////////////////////////////////////////////////////////
//
DWORD rvaImportTable = 0;
DWORD rvaLookupTable = 0;
DWORD rvaBoundTable = 0;
DWORD rvaNameTable = 0;
DWORD nImportTableSize = nTables * sizeof(IMAGE_IMPORT_DESCRIPTOR);
if (!SizeOutputBuffer(QuadAlign(sizeof(dh))
+ 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 vaData = 0;
PBYTE pbData = NULL;
if ((pbHead = AllocateOutput(sizeof(dh), &vaHead)) == 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(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_bByway) {
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 (DWORD 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, NULL)) {
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) {
PIMAGE_DEBUG_DIRECTORY pDir = (PIMAGE_DEBUG_DIRECTORY)RvaToVa(debugAddr);
if (pDir == NULL) {
return FALSE;
}
DWORD nEntries = debugSize / sizeof(*pDir);
for (DWORD n = 0; n < nEntries; n++) {
pDir[n].PointerToRawData += nExtraAdjust;
}
DWORD nFileOffset = RvaToFileOffset(debugAddr);
if (SetFilePointer(hFile, nFileOffset, NULL, FILE_BEGIN) == ~0u) {
return FALSE;
}
if (!WriteFile(hFile, pDir, debugSize, &cbDone, NULL)) {
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, NULL)) {
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, NULL)) {
return FALSE;
}
return TRUE;
}
}; // namespace Detour
//////////////////////////////////////////////////////////////////////////////
//
static BOOL CALLBACK ResetBywayCallback(PVOID pContext,
PCHAR pszFile,
PCHAR *ppszOutFile)
{
*ppszOutFile = NULL;
return TRUE;
}
static BOOL CALLBACK ResetFileCallback(PVOID pContext,
PCHAR pszOrigFile,
PCHAR pszFile,
PCHAR *ppszOutFile)
{
*ppszOutFile = pszOrigFile;
return TRUE;
}
static BOOL CALLBACK ResetSymbolCallback(PVOID pContext,
DWORD nOrdinal,
PCHAR pszOrigSymbol,
PCHAR pszSymbol,
PCHAR *ppszOutSymbol)
{
*ppszOutSymbol = pszOrigSymbol;
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////
//
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);
}
PBYTE 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);
}
PBYTE 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);
}
PBYTE WINAPI DetourBinarySetPayload(PDETOUR_BINARY pdi,
REFGUID rguid,
PBYTE pbData,
DWORD cbData)
{
Detour::CImage *pImage = Detour::CImage::IsValid(pdi);
if (pImage == NULL) {
return FALSE;
}
return pImage->DataSet(rguid, pbData, 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 DetourBinaryPurgePayload(PDETOUR_BINARY pdi)
{
Detour::CImage *pImage = Detour::CImage::IsValid(pdi);
if (pImage == NULL) {
return FALSE;
}
return pImage->DataPurge();
}
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_FINAL_CALLBACK pfFinalCallback)
{
Detour::CImage *pImage = Detour::CImage::IsValid(pdi);
if (pImage == NULL) {
return FALSE;
}
return pImage->EditImports(pContext,
pfBywayCallback,
pfFileCallback,
pfSymbolCallback,
pfFinalCallback);
}
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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -