📄 viewbin.c
字号:
//
// 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.
//
//------------------------------------------------------------------------------
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
//------------------------------------------------------------------------------
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <pehdr.h>
#include <romldr.h>
#define BUFFER_SIZE 64*1024
BYTE pBuffer[BUFFER_SIZE];
BYTE pBufferSym[BUFFER_SIZE];
DWORD dwFreq;
DWORD dwHighTime = 0;
LPTSTR g_szFilename;
BOOL g_fPrintData;
BOOL g_fPrintRecords;
BOOL g_fGenerateSRE;
BOOL g_fGenerateROM;
BOOL g_fPrintTOC;
BOOL g_fPrintSYM;
BOOL g_fPrintOBJ;
BOOL g_fCheckFiles;
HANDLE hFile;
HANDLE hSRE;
HANDLE hRaw[8]; // should support a rom width of 8 in a 64 bit environment
DWORD g_dwImageStart;
DWORD g_dwImageLength;
DWORD g_dwNumRecords;
DWORD g_pTOC = 0;
DWORD g_dwROMOffset;
DWORD g_dwNumFiles;
DWORD g_dwNumModules;
DWORD g_dwNumCopySects;
DWORD g_dwProfileOffset;
DWORD g_dwProfileAdjust;
DWORD g_dwCopyOffset;
DWORD g_dwStartAddr;
DWORD g_iRomStartAddr;
DWORD g_iRomLength;
DWORD g_iRomWidth;
typedef struct _RECORD_DATA {
DWORD dwStartAddress;
DWORD dwLength;
DWORD dwChecksum;
DWORD dwFilePointer;
} RECORD_DATA, *PRECORD_DATA;
#define MAX_RECORDS 2048
RECORD_DATA g_Records[MAX_RECORDS];
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
printHelp(void)
{
/*
This #define is put here to make the programs cvrtbin and view bin look like two
different programs to the user to avoid any onfusion of syntax and meaning implied
in the names. Otherwise this could/should be one app due to the amount of code
reuse.
*/
#ifdef CVRTBIN
printf("Usage: cvrtbin [ options ] <filename>\r\n");
printf("Options:\r\n");
printf(" -s[re] Generates SRE file from BIN\r\n");
printf(" -r[om] Generates ROM file from BIN *\r\n\r\n");
printf(" * ROM conversion requires the following options to be set also...\r\n");
printf(" -a[ddress] Rom starting address\r\n");
printf(" -w[idth] Rom width 8, 16, or 32 bits\r\n");
printf(" -l[ength] Rom length as a hex value\r\n");
#else
printf("Usage: viewbin [ options ] <filename>\r\n");
printf("Options:\r\n");
printf(" -d[ata] Prints all data bytes (potentially huge output!)\r\n");
printf(" -t[oc] Prints Table of Contents\r\n");
printf(" -o[bj] Prints Table of Contents and Objects Information\r\n");
printf(" -r[ec] Prints Record Information\r\n");
printf(" -sym Prints Profiling Symbol Information\r\n");
#endif
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
TCHAR*
getNextWord(
TCHAR **ppCmdLine,
TCHAR *pStorage
)
{
TCHAR *pWord;
// First restore the saved char.
**ppCmdLine = *pStorage;
// Move over initial white space, and save the start of the word.
while (**ppCmdLine && (**ppCmdLine == TEXT(' ') || **ppCmdLine == TEXT('\t')))
(*ppCmdLine)++;
pWord = *ppCmdLine;
// Move over the word, store the char right after the word, and zero-terminate the word.
while (**ppCmdLine && **ppCmdLine != TEXT(' ') && **ppCmdLine != TEXT('\t'))
(*ppCmdLine)++;
*pStorage = **ppCmdLine;
**ppCmdLine = 0;
// Return start of word, or zero (in case the word is empty).
if (*pWord)
return pWord;
else
return 0;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL
parseCmdLine(
TCHAR *pCmdLine
)
{
TCHAR storage = *pCmdLine; // getNextWord needs to store a char
TCHAR *word;
BOOL address_found = FALSE;
//
// Eat the EXE name first.
//
word = getNextWord(&pCmdLine, &storage);
// Keep getting words from the command line.
while (word = getNextWord(&pCmdLine, &storage)) {
#ifdef CVRTBIN
if (!_tcscmp(TEXT("-sre"), word) || !_tcscmp(TEXT("-s"), word)) {
g_fGenerateSRE = TRUE;
}
else if (!_tcscmp(TEXT("-rom"), word) || !_tcscmp(TEXT("-r"), word)) {
g_fGenerateROM = TRUE;
}
else if (!_tcscmp(TEXT("-address"), word) || !_tcscmp(TEXT("-a"), word)) {
g_iRomStartAddr = strtoul(getNextWord(&pCmdLine, &storage), NULL, 16);
address_found = TRUE;
}
else if (!_tcscmp(TEXT("-length"), word) || !_tcscmp(TEXT("-l"), word)) {
g_iRomLength = strtoul(getNextWord(&pCmdLine, &storage), NULL, 16);
}
else if (!_tcscmp(TEXT("-width"), word) || !_tcscmp(TEXT("-w"), word)) {
g_iRomWidth = strtoul(getNextWord(&pCmdLine, &storage), NULL, 10);
}
#else
if (!_tcscmp(TEXT("-data"), word) || !_tcscmp(TEXT("-d"), word)) {
g_fPrintData = TRUE;
}
else if (!_tcscmp(TEXT("-toc"), word) || !_tcscmp(TEXT("-t"), word)) {
g_fPrintTOC = TRUE;
}
else if (!_tcscmp(TEXT("-obj"), word) || !_tcscmp(TEXT("-o"), word)) {
g_fPrintOBJ = TRUE;
}
else if (!_tcscmp(TEXT("-sym"), word)) {
g_fPrintSYM = TRUE;
}
else if (!_tcscmp(TEXT("-rec"), word) || !_tcscmp(TEXT("-r"), word)) {
g_fPrintRecords = TRUE;
}
else if (!_tcscmp(TEXT("-checkfiles"), word) || !_tcscmp(TEXT("-c"), word)) {
g_fCheckFiles = TRUE;
}
// else if (!_tcscmp(TEXT("-n"), word)) {
// if (word = getNextWord(&pCmdLine, &storage)) {
// g_nIterations = (int) _ttol(word);
// if (g_nIterations > MAX_ITERATIONS) {
// g_nIterations = MAX_ITERATIONS;
// }
//
// } else {
// RETAILMSG(1, (TEXT("Error -n (%s)\r\n"), word));
// return FALSE;
// }
// }
#endif
else if (word[0] == '-') {
printf("Unknown option... %s\n", word);
goto EXIT;
}
else {
g_szFilename = word;
}
}
if (g_szFilename == NULL) {
printf("Filename required\n");
goto EXIT;
}
if(g_fGenerateROM){
if(!g_iRomLength){
printf("ROM conversion specified but missing length option\n");
goto EXIT;
}
if(!address_found){
printf("ROM conversion specified but missing address option\n");
goto EXIT;
}
if(!g_iRomWidth){
printf("ROM conversion specified but missing width option\n");
goto EXIT;
}
}
return TRUE;
EXIT:
printHelp();
return FALSE;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL
CheckBinFile(
DWORD dwAddress,
DWORD dwLength
)
{
DWORD i;
//
// Adjust if needed
//
dwAddress += g_dwROMOffset;
for (i = 0; i < g_dwNumRecords; i++) {
if (g_Records[i].dwStartAddress <= dwAddress &&
g_Records[i].dwStartAddress + g_Records[i].dwLength >= (dwAddress + dwLength)) {
return TRUE;
}
}
return FALSE;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL
ReadBinFile(
PBYTE pDestBuffer,
DWORD dwAddress,
DWORD dwLength,
DWORD dwROMOffsetRead
)
{
DWORD dwRead;
BOOL fRet;
DWORD i;
DWORD dwDiff;
if (dwLength > BUFFER_SIZE) {
printf ("Trying to read %d bytes (too big)\n", dwLength);
return FALSE;
}
//
// Adjust if needed
//
dwAddress += dwROMOffsetRead;
for (i = 0; i < g_dwNumRecords; i++) {
if (g_Records[i].dwStartAddress <= dwAddress &&
g_Records[i].dwStartAddress + g_Records[i].dwLength >= (dwAddress + dwLength)) {
//
// Offset into the record.
//
dwDiff = dwAddress - g_Records[i].dwStartAddress;
SetFilePointer(hFile, g_Records[i].dwFilePointer + dwDiff, NULL, FILE_BEGIN);
if (dwLength) {
fRet = ReadFile(hFile, pDestBuffer, dwLength, &dwRead, NULL);
if (!fRet || dwRead != dwLength) {
return FALSE;
}
} else {
int count = 0;
do {
fRet = ReadFile(hFile, pDestBuffer, 1, &dwRead, NULL);
count++;
} while (*pDestBuffer++);
// no string here to read or string left record, then must have been the wrong record
if(!count || g_Records[i].dwStartAddress + g_Records[i].dwLength < (dwAddress + count)){
pDestBuffer -= count;
continue;
}
}
return TRUE;
}
}
return FALSE;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL
ComputeRomOffset()
{
DWORD i;
BOOL fFoundIt = FALSE;
BOOL fRet;
DWORD dwROMOffsetRead;
DWORD header[2] = {0};
ROMHDR *dwpTOC = 0;
static DWORD last_signature = 0;
for (i = last_signature; i < g_dwNumRecords; i++) {
//
// no pTOC and not an 8 byte record... skip
//
if(!dwpTOC){
if(g_Records[i].dwLength != 8)
continue;
//
// check for signature and pTOC
//
fRet = ReadBinFile((BYTE*)header, g_Records[i].dwStartAddress, 8, 0);
if(!fRet || header[0] != ROM_SIGNATURE)
continue;
//
// set pTOC and save current search and start record search over
//
dwpTOC = (ROMHDR*)header[1];
last_signature = i + 1;
i = 0;
}
//
// if it's not a TOC... skip
//
if(g_Records[i].dwLength == sizeof(ROMHDR)){
//
// If this _IS_ the TOC record, compute the ROM Offset.
//
dwROMOffsetRead = (DWORD) g_Records[i].dwStartAddress - (DWORD) dwpTOC;
printf("Checking record #%d for potential TOC (ROMOFFSET = 0x%08X)\n", i, dwROMOffsetRead);
//
// Read out the record to verify. (unadjusted)
//
fRet = ReadBinFile(pBuffer, g_Records[i].dwStartAddress, sizeof(ROMHDR), 0);
if (fRet) {
ROMHDR *pTOC = (ROMHDR*) pBuffer;
if(pTOC->physfirst > (DWORD)dwpTOC || pTOC->physlast < (DWORD)dwpTOC){
// printf ("NOTICE! Record %d looked like a TOC at 0x%08x except Phys first = 0x%08X, and Phys last = 0x%08X\r\n", i, dwpTOC, pTOC->physfirst, pTOC->physlast);
continue;
}
if ((pTOC->physfirst >= (g_dwImageStart - dwROMOffsetRead)) &&
(pTOC->physlast <= (g_dwImageStart - dwROMOffsetRead) + g_dwImageLength)) {
//
// Extra sanity check...
//
if ((DWORD)(HIWORD(pTOC->dllfirst) << 16) <= pTOC->dlllast &&
(DWORD)(LOWORD(pTOC->dllfirst) << 16) <= pTOC->dlllast) {
printf("Found pTOC = 0x%08x\n", (DWORD)dwpTOC);
fFoundIt = TRUE;
break;
} else {
printf ("NOTICE! Record %d looked like a TOC except DLL first = 0x%08X, and DLL last = 0x%08X\r\n", i, pTOC->dllfirst, pTOC->dlllast);
}
} else {
printf ("NOTICE! Record %d looked like a TOC except Phys first = 0x%08X, and Phys last = 0x%08X\r\n", i, pTOC->physfirst, pTOC->physlast);
}
}
}
//
// didn't find it so reset signature search
//
if(i == g_dwNumRecords - 1){
i = last_signature - 1;
dwpTOC = 0;
}
}
if (fFoundIt) {
g_dwROMOffset = dwROMOffsetRead;
g_pTOC = (DWORD)dwpTOC;
printf("ROMOFFSET = 0x%08X\n", g_dwROMOffset);
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -