📄 imgdata.h
字号:
//
// 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.h
#pragma once
#include "tt.h"
#define SignExtendShortToLong(x) ((LONG) ((SHORT) (x)))
class CImageData;
class CModuleData
{
public:
CModuleData(CImageData *pImg, TOCentry *pTocEntry, e32_rom *pE32, o32_rom *pO32List);
~CModuleData() {}
LPCSTR GetFilename();
TOCentry * GetTOCEntry() { return m_pTOCentry; }
e32_rom * GetE32() { return m_pE32; }
o32_rom * GetO32(int iIndex)
{
if(iIndex < 0 || iIndex >= m_pE32->e32_objcnt) {
return NULL;
}
return m_pO32List + iIndex;
}
CImageData * GetParentImage() { return m_pImg; }
private:
CImageData * m_pImg;
TOCentry * m_pTOCentry;
e32_rom * m_pE32;
o32_rom * m_pO32List;
};
//
// SectionDivisions class
//
class CSecDiv
{
public:
CSecDiv();
~CSecDiv();
HRESULT Add(LPBYTE pbDiv);
BOOL IsSecDiv(UCHAR* pbBuf);
LPBYTE GetSecDiv(int iIndex)
{
if(iIndex < 0 || iIndex >= m_cSections) {
return NULL;
}
return m_pSections[iIndex];
}
private:
DWORD m_cSections;
LPBYTE * m_pSections;
};
#define RELOC_REALLOC_SIZE 64
#define RELOC_CMD_MASK 0xC0
#define RELOC_CMD_SHIFT 6
#define GetRelocCmd(x) (((x) & RELOC_CMD_MASK) >> RELOC_CMD_SHIFT)
#define RELOC_SKIP_MASK 0x60
#define RELOC_SKIP_SHIFT 5
#define GetRelocSkip(x) (((x) & RELOC_SKIP_MASK) >> RELOC_SKIP_SHIFT)
#define RELOC_COUNT_MASK 0x1F
#define RELOC_COUNT_SHIFT 0
#define GetRelocCount(x) (((x) & RELOC_COUNT_MASK) >> RELOC_COUNT_SHIFT)
// The count field of a pattern command is 5 bits long, meaning it can encode
// 32 possible values (0-31). Since we know that the minimum length of a
// pattern is 2 (we wouldn't have created a pattern if it was just one entry)
// the count field encodes a value from 2-33. So the maximum length of a
// pattern is 33 cycles.
#define MAX_COUNT 31
#define MAX_SKIP 3
#define RELOC_CMDTYPE_OFFSET 0x0
#define RELOC_CMDTYPE_SINGLE 0x1
#define RELOC_CMDTYPE_PATTERN 0x2
#define RELOC_CMDTYPE_PATTERN2 0x3
#define INVALID_CMD 0xFFFFFFFF
#define RELOC_SINGLE_CONTINUATION_BIT 0x20
#define RELOC_OFFSET_64K_ALIGN_BIT 0x20
#define RELOC_OFFSET_CONTINUATION_BIT 0x10
#define RELOC_VARINT_CONTINUATION_BIT 0x80
//
// Section Data class
//
// Stores information about each section in this image.
//
class CSectionData
{
public:
CSectionData();
~CSectionData();
HRESULT SetSectionHeader(PROMIMAGE_SECTION prs) { m_pRomimageSection = prs; return NOERROR; };
HRESULT SetUncompressedSize(DWORD dwUncompressedSize) { m_dwUncompressedSize = dwUncompressedSize; return NOERROR; }
HRESULT SetCompressionCommands(COMPR_CMD *pcc, DWORD cCC)
{
if(m_pcc) {
LocalFree(m_pcc);
m_pcc = NULL;
}
// Special case the entire region uncompressed case
if(cCC == 1 && pcc->cBytesCompressed == pcc->cBytesUncompressed) {
m_cCompressionCommands = 0;
LocalFree(pcc);
} else {
m_pcc = pcc;
m_cCompressionCommands = cCC;
}
return NOERROR;
}
HRESULT SetDataPtr(LPBYTE pbData) { m_pbSectionData = pbData; return NOERROR; }
HRESULT SetUncompressedDataPtr(LPBYTE pbData) { m_pbUncompressedSectionData = pbData; return NOERROR; }
HRESULT BeginReloc(DWORD dwFixupOffset);
HRESULT AddReloc(DWORD dwFixupLoc);
ROMIMAGE_SECTION * GetSectionHeader() { return m_pRomimageSection; }
DWORD GetUncompressedSize() { return m_dwUncompressedSize; }
LPBYTE GetDataPtr() { return m_pbSectionData; }
LPBYTE GetUncompressedDataPtr() { return m_pbUncompressedSectionData; }
DWORD GetCountCompressionCommands() { return m_cCompressionCommands; }
COMPR_CMD * GetCompressionCommand(int iIndex)
{
if(iIndex < 0 || iIndex >= m_cCompressionCommands) {
return NULL;
}
return &m_pcc[iIndex];
}
HRESULT GetRelocCmdBuffer(LPBYTE *ppbRelocCmds, LPDWORD pdwLen)
{
HRESULT hr = NOERROR;
ASSERT(ppbRelocCmds);
ASSERT(pdwLen);
CHR(FlushPrevCmd());
*ppbRelocCmds = m_pbRelocCommands;
*pdwLen = m_cbRelocCommands;
Error:
return hr;
}
private:
HRESULT FlushPrevCmd();
HRESULT FlushPrevCmdVarInt(UINT32 u);
HRESULT AddRelocCmd(LPBYTE pb, DWORD cb)
{
HRESULT hr = NOERROR;
if (m_cbRelocCommands + cb > m_cbRelocBufferAlloced) {
CHR(SafeRealloc((LPVOID*)&m_pbRelocCommands, (m_cbRelocBufferAlloced + cb + RELOC_REALLOC_SIZE) * sizeof(BYTE)));
m_cbRelocBufferAlloced += cb + RELOC_REALLOC_SIZE;
}
ASSERT(m_cbRelocCommands + cb <= m_cbRelocBufferAlloced);
memcpy(m_pbRelocCommands + m_cbRelocCommands, pb, cb);
m_cbRelocCommands += cb;
Error:
return hr;
}
// Contains Address, length and checksum
// Note: The length contained in the section header
// is the actual length of data for this section. It
// is therefore the compressed size of the section if
// the section contains any compressed regions.
PROMIMAGE_SECTION m_pRomimageSection;
// Pointer into the image for the data for this section
LPBYTE m_pbSectionData;
// Pointer into the uncompressed copy of the image to the data for this
// section
LPBYTE m_pbUncompressedSectionData;
// Total uncompressed size of the section
DWORD m_dwUncompressedSize;
// Compression commands needed to regenerate the compressed
// version of this section
COMPR_CMD * m_pcc;
DWORD m_cCompressionCommands;
// Current offset for reloc fixups
DWORD m_dwCurrentRelocOffset;
LPBYTE m_pbRelocCommands;
DWORD m_cbRelocCommands;
DWORD m_cbRelocBufferAlloced;
DWORD m_dwPrevCmd;
DWORD m_dwPrevCmdData;
DWORD m_dwSecondtoLastCmdData;
};
__inline
CSectionData::CSectionData() : m_pRomimageSection(NULL), m_dwUncompressedSize(0),
m_pcc(NULL), m_cCompressionCommands(0),
m_dwCurrentRelocOffset(0), m_cbRelocCommands(0),
m_pbRelocCommands(NULL), m_cbRelocBufferAlloced(0),
m_dwPrevCmd(INVALID_CMD), m_dwPrevCmdData(0),
m_dwSecondtoLastCmdData(0)
/*---------------------------------------------------------------------------*\
*
\*---------------------------------------------------------------------------*/
{
} /* CSectionData::CSectionData()
*/
__inline
CSectionData::~CSectionData()
/*---------------------------------------------------------------------------*\
*
\*---------------------------------------------------------------------------*/
{
LocalFree(m_pcc);
LocalFree(m_pbRelocCommands);
} /* CSectionData::~CSectionData()
*/
// This class stores image about a BIN file
class CImageData
{
public:
CImageData();
~CImageData();
HRESULT Initialize(LPBYTE pbImage, DWORD dwLen);
TOCentry * GetModule(int iModuleIndex) { return &(((TOCentry *)m_pbModules)[iModuleIndex]); }
FILESentry* GetFile(int iFilesIndex) { return &(((FILESentry *)m_pbFiles)[iFilesIndex]); }
e32_rom * GetE32(int iModuleIndex) { return m_ppE32Entries[iModuleIndex]; }
o32_rom * GetO32List(int iModuleIndex) { return m_ppO32Entries[iModuleIndex]; }
LPBYTE GetDataPtr() { return m_pbImage; }
DWORD GetDataLen() { return m_dwImageLen; }
CModuleData * GetModuleData(int iModuleIndex)
{
if((iModuleIndex < 0) || (iModuleIndex >= m_cModules)) {
return NULL;
}
TOCentry *pEntry = GetModule(iModuleIndex);
e32_rom *pe32 = GetE32(iModuleIndex);
o32_rom *po32 = GetO32List(iModuleIndex);
if(pEntry && pe32 && po32) {
return new CModuleData(this, pEntry, pe32, po32);
} else {
return NULL;
}
}
int FindModuleByName(LPCSTR szModuleName)
{
if(szModuleName) {
for(int i = 0; i < m_cModules; i++) {
TOCentry *pEntry = GetModule(i);
if(pEntry) {
LPSTR szFilename = (LPSTR)FindAddress((UINT32)pEntry->lpszFileName);
if(!stricmp(szModuleName, szFilename)) {
return i;
}
}
}
}
return -1;
}
DWORD GetModuleCount() { return m_cModules; }
DWORD GetFileCount() { return m_cFiles; }
LPBYTE FindAddress(UINT32 ulAddr, BOOL fExact = FALSE);
DWORD FindVirtualAddress(LPBYTE pb);
HRESULT FindCompressedRegions();
HRESULT GenerateDecompressedImage(CSecDiv *pSecDiv);
HRESULT DumpImageData();
UINT32 TokenLen(Run *pRun);
DWORD GetSectionCount() { return m_cSections; }
CSectionData * GetSection(int iIndex)
{
if(iIndex < 0 || iIndex >= m_cSections) {
return NULL;
}
return &m_pSectionDataList[iIndex];
}
HRESULT FindDataPtr(DWORD dwVirtualAddr, DWORD dwLen, CSectionData **ppSection, LPBYTE *ppbData);
CTranslationTable * GetTranslationTable() { return &m_tt; }
LPBYTE GetUncompressedDataPtr() { return m_pbUncompressedImage; }
DWORD GetUncompressedImageLength() { return m_cbUncompressedImage; }
DWORD GetMaxBytesUncompressed() { return m_cbLargestUncompressedSection; }
DWORD GetCompressedRegionCount() { return m_cCompressedRegions; }
COMPR_RGN * GetCompressedRegion(int iIndex)
{
if(iIndex < 0 || iIndex >= m_cCompressedRegions) {
return NULL;
}
return &m_pCompressedRegions[iIndex];
}
ROMIMAGE_HEADER * GetHeader() { return m_pRomimageHeader; }
private:
PBYTE m_pbImage;
DWORD m_dwImageLen;
ROMIMAGE_HEADER * m_pRomimageHeader;
ROMIMAGE_SECTION * m_pFirstSection;
DWORD m_cSections;
DWORD m_dwRomOffset;
LPBYTE m_pTOC;
LPBYTE m_pbModules;
LPBYTE m_pbFiles;
e32_rom** m_ppE32Entries;
o32_rom** m_ppO32Entries;
CSectionData * m_pSectionDataList;
DWORD m_cbLargestUncompressedSection;
// Translation Table for translating addresses from compressed to uncompressed
CTranslationTable m_tt;
// List of compressed regions for this entire image
COMPR_RGN * m_pCompressedRegions;
DWORD m_cCompressedRegions;
// Uncompressed version of this image
LPBYTE m_pbUncompressedImage;
DWORD m_cbUncompressedImage;
DWORD m_cModules;
DWORD m_cFiles;
};
__inline PROMIMAGE_SECTION
SectionFromPtr(LPBYTE pbBeginningOfSection)
/*---------------------------------------------------------------------------*\
*
\*---------------------------------------------------------------------------*/
{
// Preserve a NULL if we get one...
if(pbBeginningOfSection == NULL) {
return NULL;
}
return (PROMIMAGE_SECTION)(pbBeginningOfSection - sizeof(ROMIMAGE_SECTION));
} /* SectionFromPtr()
*/
__inline LPBYTE
DataFromSection(PROMIMAGE_SECTION pSection)
/*---------------------------------------------------------------------------*\
*
\*---------------------------------------------------------------------------*/
{
return (LPBYTE)pSection + sizeof(ROMIMAGE_SECTION);
} /* DataFromSection()
*/
__inline DWORD
SectionSize(LPBYTE pbBeginningOfSection)
/*---------------------------------------------------------------------------*\
*
\*---------------------------------------------------------------------------*/
{
PROMIMAGE_SECTION pSection = SectionFromPtr(pbBeginningOfSection);
return pSection->Size;
} /* SectionSize()
*/
__inline LPBYTE
NextSection(LPBYTE pbBeginningOfSection)
/*---------------------------------------------------------------------------*\
*
\*---------------------------------------------------------------------------*/
{
return pbBeginningOfSection + SectionSize(pbBeginningOfSection) + sizeof(ROMIMAGE_SECTION);
} /* NextSection()
*/
__inline PROMIMAGE_SECTION
NextSection(PROMIMAGE_SECTION pSection)
/*---------------------------------------------------------------------------*\
*
\*---------------------------------------------------------------------------*/
{
return (PROMIMAGE_SECTION) (DataFromSection(pSection) + pSection->Size);
} /* NextSection()
*/
__inline LPCSTR
CModuleData::GetFilename()
/*---------------------------------------------------------------------------*\
*
\*---------------------------------------------------------------------------*/
{
return (LPCSTR)m_pImg->FindAddress((UINT32)m_pTOCentry->lpszFileName);
} /* CModuleData::GetFilename()
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -