📄 imgdata.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
// ImgData.cpp
#include "diffbin.h"
static char c_szBINHeader[] = "B000FF\n";
CImageData::CImageData() : m_pbImage(NULL),
m_dwImageLen(0),
m_pRomimageHeader(NULL),
m_pFirstSection(NULL),
m_cSections(0),
m_pTOC(NULL),
m_pbModules(NULL),
m_pbFiles(NULL),
m_ppE32Entries(NULL),
m_ppO32Entries(NULL),
m_pSectionDataList(NULL),
m_pCompressedRegions(NULL),
m_cCompressedRegions(0),
m_pbUncompressedImage(NULL),
m_cbUncompressedImage(0),
m_cbLargestUncompressedSection(0),
m_cModules(0),
m_cFiles(0)
/*---------------------------------------------------------------------------*\
*
\*---------------------------------------------------------------------------*/
{
} /* CImageData::CImageData()
*/
CImageData::~CImageData()
/*---------------------------------------------------------------------------*\
*
\*---------------------------------------------------------------------------*/
{
LocalFree(m_ppE32Entries);
LocalFree(m_ppO32Entries);
LocalFree(m_pCompressedRegions);
LocalFree(m_pbUncompressedImage);
delete [] m_pSectionDataList;
} /* CImageData::~CImageData()
*/
LPBYTE
CImageData::FindAddress(UINT32 ulAddr, BOOL fExact)
/*---------------------------------------------------------------------------*\
*
\*---------------------------------------------------------------------------*/
{
BOOL romoffset = false;
PROMIMAGE_SECTION pSection = NULL;
ulAddr += m_dwRomOffset;
AGAIN:
pSection = m_pFirstSection;
while (pSection->Address || (!pSection->Address && pSection->CheckSum))
{
if ((pSection->Address <= ulAddr) &&
(pSection->Address + pSection->Size > ulAddr) &&
(!fExact || (pSection->Address == ulAddr)))
{
return DataFromSection(pSection) + (ulAddr - pSection->Address);
}
pSection = NextSection(pSection);
}
if(!romoffset){
romoffset = true;
ulAddr -= m_dwRomOffset;
goto AGAIN;
}
return NULL;
} /* CImageData::FindAddress()
*/
DWORD
CImageData::FindVirtualAddress(LPBYTE pb)
/*---------------------------------------------------------------------------*\
*
\*---------------------------------------------------------------------------*/
{
int i = 0;
CSectionData *pSection;
while(pSection = GetSection(i++)) {
if(pb >= pSection->GetDataPtr() &&
pb <= pSection->GetDataPtr() + pSection->GetSectionHeader()->Size)
{
return pSection->GetSectionHeader()->Address + (pb - pSection->GetDataPtr());
}
}
return 0;
} /* CImageData::FindVirtualAddress()
*/
HRESULT
CImageData::Initialize(LPBYTE pbImage, DWORD dwLen)
/*---------------------------------------------------------------------------*\
*
\*---------------------------------------------------------------------------*/
{
HRESULT hr = NOERROR;
UINT32 i;
DWORD dwTOCSection = 0;
LPDWORD pdwROMSignature = NULL;
PROMIMAGE_SECTION pSection = NULL;
DWORD dwSectionCount;
// Set up internal pointers
m_pbImage = pbImage;
m_dwImageLen = dwLen;
m_pRomimageHeader = (ROMIMAGE_HEADER *)m_pbImage;
m_pFirstSection = (ROMIMAGE_SECTION *)(m_pbImage + sizeof(ROMIMAGE_HEADER));
//
// Verify the signature in the ROM header
//
CBR(memcmp(m_pRomimageHeader->Signature, c_szBINHeader, sizeof(c_szBINHeader)) == 0);
//
// Walk through the image and count the sections
//
pSection = m_pFirstSection;
while(pSection->Address || (!pSection->Address && pSection->CheckSum)) {
m_cSections++;
pSection = NextSection(pSection);
}
CPR(m_pSectionDataList = new CSectionData[m_cSections]);
dwSectionCount = 0;
pSection = m_pFirstSection;
while(pSection->Address || (!pSection->Address && pSection->CheckSum)) {
m_pSectionDataList[dwSectionCount].SetSectionHeader(pSection);
m_pSectionDataList[dwSectionCount++].SetDataPtr(DataFromSection(pSection));
pSection = NextSection(pSection);
}
ASSERT(dwSectionCount == m_cSections);
//
// Find the TOC
//
pdwROMSignature = (LPDWORD)FindAddress(m_pRomimageHeader->PhysicalStartAddress + ROM_SIGNATURE_OFFSET, TRUE);
CBR(pdwROMSignature);
CBR(pdwROMSignature[0] == ROM_SIGNATURE);
dwTOCSection = pdwROMSignature[1];
m_dwRomOffset = ((m_pRomimageHeader->PhysicalStartAddress + m_pRomimageHeader->PhysicalSize) & 0xFF000000) - (DWORD) ((DWORD)dwTOCSection & 0xFF000000);
//m_pTOC = FindAddress(dwTOCSection + dwRomOffset, TRUE);
m_pTOC = FindAddress(dwTOCSection, TRUE);
CBR(m_pTOC);
ASSERT(m_pTOC);
m_pbModules = NextSection(m_pTOC);
ASSERT(m_pbModules);
//
// Initialze member variables for Modules
//
m_cModules = ((ROMHDR*)m_pTOC)->nummods;
// m_cModules = SectionSize(m_pbModules) / sizeof(TOCentry);
CPR(m_ppE32Entries = (e32_rom**)LocalAlloc(LMEM_FIXED, m_cModules * sizeof(e32_rom*)));
CPR(m_ppO32Entries = (o32_rom**)LocalAlloc(LMEM_FIXED, m_cModules * sizeof(o32_rom*)));
m_pbFiles = m_pbModules + m_cModules * sizeof(TOCentry);
ASSERT(m_pbFiles);
//
// Initialize member variables for Files section
//
m_cFiles = ((ROMHDR*)m_pTOC)->numfiles;
// m_cFiles = SectionSize(m_pbFiles) / sizeof(FILESentry);
//
// Find E32 and O32 for each Module
//
for (i = 0; i < m_cModules; ++i) {
TOCentry *pEntry = GetModule(i);
ASSERT(pEntry);
m_ppE32Entries[i] = (e32_rom *)FindAddress(pEntry->ulE32Offset);
m_ppO32Entries[i] = (o32_rom *)FindAddress(pEntry->ulO32Offset);
}
CHR(DumpImageData());
Error:
return hr;
} /* CImageData::Initialize()
*/
char e32str[11][4] = { // e32 image header data directory types
"EXP", // export table
"IMP", // import table
"RES", // resource table
"EXC", // exception table
"SEC", // security table
"FIX", // base relocation table
"DEB", // debug data
"IMD", // copyright
"MSP" // global ptr
};
void DumpHeader(e32_rom* e32)
{
int loop;
RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT(" e32_objcnt : %8.8lx\n"),e32->e32_objcnt));
RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT(" e32_imageflags : %8.8lx\n"),e32->e32_imageflags));
RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT(" e32_entryrva : %8.8lx\n"),e32->e32_entryrva));
RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT(" e32_vbase : %8.8lx\n"),e32->e32_vbase));
RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT(" e32_subsysmajor: %8.8lx\n"),e32->e32_subsysmajor));
RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT(" e32_subsysminor: %8.8lx\n"),e32->e32_subsysminor));
RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT(" e32_stackmax : %8.8lx\n"),e32->e32_stackmax));
RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT(" e32_vsize : %8.8lx\n"),e32->e32_vsize));
RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT(" e32_subsys : %8.8lx\n"),e32->e32_subsys));
for (loop = 0; loop < 9; loop++)
RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT(" e32_unit:%3.3s : %8.8lx %8.8lx\n"),
e32str[loop],e32->e32_unit[loop].rva,e32->e32_unit[loop].size));
}
HRESULT
CImageData::DumpImageData()
/*---------------------------------------------------------------------------*\
*
\*---------------------------------------------------------------------------*/
{
DWORD nCount = 0;
int i;
// Dump out ROMIMAGE sections
RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT("ROMIMAGE Sections\n")));
RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT("Index Address Size Checksum\n")));
PROMIMAGE_SECTION pSection = m_pFirstSection;
LPBYTE pbBuf = (LPBYTE)pSection;
while (pSection->Address || (!pSection->Address && pSection->CheckSum)) {
pbBuf += sizeof(ROMIMAGE_SECTION);
RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT("0x%04d 0x%08x 0x%08x 0x%08x\n"), nCount++, pSection->Address, pSection->Size, pSection->CheckSum));
pbBuf += pSection->Size;
pSection = (PROMIMAGE_SECTION)pbBuf;
}
RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT("\npTOC=0x%08lx pModules=0x%08lx pFiles=0x%08lx\n"),
FindVirtualAddress(m_pTOC), FindVirtualAddress(m_pbModules), FindVirtualAddress(m_pbFiles)));
// Print out Modules TOC
RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT("\nModules TOC\n")));
RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT(" # Filename FileAttr FileSize LoadOffset\n")));
for (i = 0; i < m_cModules; ++i)
{
TOCentry *pEntry = GetModule(i);
LPSTR szFilename = (LPSTR)FindAddress((DWORD)pEntry->lpszFileName);
RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT("%3d %25s 0x%08x 0x%08x 0x%08x\n"),
i, szFilename, pEntry->dwFileAttributes, pEntry->nFileSize, pEntry->ulLoadOffset));
}
// Print out Files TOC
RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT("\nFiles TOC\n")));
RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT(" # Filename FileAttr RealSize CompSize LoadOffset Compressed?\n")));
for (i = 0; i < m_cFiles; i++)
{
FILESentry *pEntry = GetFile(i);
LPSTR szFilename = (LPSTR)FindAddress((DWORD)pEntry->lpszFileName);
RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT("%3d %25s 0x%08x 0x%08x 0x%08x 0x%08x %s\n"),
i, szFilename, pEntry->dwFileAttributes, pEntry->nRealFileSize,pEntry->nCompFileSize,pEntry->ulLoadOffset,
((pEntry->dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED) &&
(pEntry->nRealFileSize > pEntry->nCompFileSize)) ? "Yes" : "No"));
}
// Print out E32 and O32s for each module
for (i = 0; i < m_cModules; ++i) {
CModuleData *pMod = GetModuleData(i);
RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT("\nModule %d: e32=0x%08lx o32=0x%08lx\n"), i,
FindVirtualAddress((LPBYTE)pMod->GetE32()), FindVirtualAddress((LPBYTE)pMod->GetO32(0))));
DumpHeader(pMod->GetE32());
RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT(" o32_vsize o32_rva o32_psize o32_dataptr o32_realsize o32_flags\n")));
for(int j = 0; j < pMod->GetE32()->e32_objcnt; j++) {
o32_rom *o32 = pMod->GetO32(j);
RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT(" 0x%08lx 0x%08lx 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n"),
o32->o32_vsize, o32->o32_rva, o32->o32_psize, o32->o32_dataptr, o32->o32_realaddr,o32->o32_flags));
}
}
RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT("\n")));
return NOERROR;
} /* CImageData::DumpImageData()
*/
////////////////////////////////////////////////////////////
// SortCompressedRegions
// Sort the compressed regions by address
////////////////////////////////////////////////////////////
void SortCompressedRgns(COMPR_RGN* pcr, UINT32 cComprRgns)
{
UINT16 i, j, k;
for (i = 1; i < cComprRgns; ++i)
{
j = 0;
while (pcr[i].iAddress > pcr[j].iAddress)
++j;
if (i > j)
{
COMPR_RGN temp = pcr[i];
for (k = i; k > j; --k)
pcr[k] = pcr[k - 1];
pcr[j] = temp;
}
}
}
UINT32
CImageData::TokenLen(Run *pRun)
/*---------------------------------------------------------------------------*\
* Return the length of the token for "iType", "dwRunLength" and "iOffset,"
* including, for DATA tokens, the actual data
\*---------------------------------------------------------------------------*/
{
DWORD dwLen = 0;
switch(pRun->eType) {
case RUNTYPE_SECTIONHEADER:
dwLen += sizeof(ROMIMAGE_SECTION);
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -