📄 binutils.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.
//
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <assert.h>
#include "binutils.h"
struct RECORD_DATA{
DWORD start_address;
DWORD length;
DWORD chksum;
DWORD file_ptr;
};
#define MAX_BUFFER 1024
static RECORD_DATA records[MAX_BUFFER];
static DWORD record_count = 0;
static ROMHDR *pTOC;
static HANDLE hfile;
static DWORD rom_offset;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
bool read_image(void *pDestBuffer, DWORD dwAddress, DWORD dwLength, bool use_rom_offset){
assert(hfile != INVALID_HANDLE_VALUE);
DWORD dwDiff;
DWORD dwRead;
if(use_rom_offset)
dwAddress += rom_offset;
for (DWORD i = 0; i < record_count; i++){
// is the data contained within the bounds of this record?
if(records[i].start_address <= dwAddress &&
records[i].start_address + records[i].length >= (dwAddress + dwLength)){
// Offset into the record.
dwDiff = dwAddress - records[i].start_address;
SetFilePointer(hfile, records[i].file_ptr + dwDiff, NULL, FILE_BEGIN);
if(!ReadFile(hfile, pDestBuffer, dwLength, &dwRead, NULL)){
_tprintf(_T("ReadFile failed: %d"), GetLastError());
return false;
}
return true;
}
}
_ftprintf(stderr, _T("failed to read data of size %d at %08x\n"), dwLength, dwAddress);
return false;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
DWORD get_rom_offset(DWORD image_start, DWORD image_length, ROMHDR *ptoc){
bool ret = true;
DWORD temp_offset;
ROMHDR romhdr;
for(DWORD i = 0; i < record_count; i++){
// skip records of the wrong size
if (records[i].length != sizeof(ROMHDR))
continue;
// If this _IS_ the TOC record, compute the ROM Offset.
temp_offset = (DWORD) records[i].start_address - (DWORD)ptoc;
_tprintf(_T("Checking record #%d for potential TOC (ROMOFFSET = 0x%08X)\n"), i, temp_offset);
// Read out the record to verify. (unadjusted)
if(read_image((PBYTE)&romhdr, records[i].start_address, sizeof(ROMHDR), false))
if((romhdr.physfirst == image_start - temp_offset) &&
(romhdr.physlast == image_start - temp_offset + image_length) &&
(DWORD)(HIWORD(romhdr.dllfirst) << 16) <= romhdr.dlllast &&
(DWORD)(LOWORD(romhdr.dllfirst) << 16) <= romhdr.dlllast){
rom_offset = temp_offset;
goto EXIT;
}
}
// reverse of normal logic, we only get here if we DIDN'T find it
ret = false;
EXIT:
_tprintf(_T("ROM offset = 0x%08X\n"), rom_offset);
return ret;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
bool init(const TCHAR *file_name){
bool ret = false;
hfile = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hfile == INVALID_HANDLE_VALUE){
_tprintf(_T("failed opening %s: %d\n"), file_name, GetLastError());
return false;
}
char bin_header[] = {'B', '0', '0', '0', 'F', 'F', '\x0a'};
char buffer[sizeof(bin_header)];
DWORD image_start;
DWORD image_length;
DWORD image_jump;
DWORD cb;
// read headers
if(!ReadFile(hfile, buffer, sizeof(bin_header), &cb, NULL)){
_tprintf(_T("failed reading bin header: %d\n"), GetLastError());
goto EXIT;
}
if(memcmp(buffer, bin_header, sizeof(bin_header)) != 0){
_tprintf(_T("invalid bin header\n"));
goto EXIT;
}
if(!ReadFile(hfile, &image_start, sizeof(image_start), &cb, NULL)){
_tprintf(_T("failed reading image start: %d\n"), GetLastError());
goto EXIT;
}
if(!ReadFile(hfile, &image_length, sizeof(image_length), &cb, NULL)){
_tprintf(_T("failed reading image length: %d\n"), GetLastError());
goto EXIT;
}
// read records
for(; record_count < MAX_BUFFER; record_count++ ){
if(!ReadFile(hfile, &records[record_count], 3*sizeof(DWORD), &cb, NULL))
break;
records[record_count].file_ptr = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
// _tprintf(_T("record [%3d] : start = 0x%08X, length = 0x%08X, chksum = 0x%08X\n"), record_count, records[record_count].start_address, records[record_count].length, records[record_count].chksum);
if(records[record_count].start_address == 0 && records[record_count].chksum== 0){
image_jump = records[record_count].length;
_tprintf(_T("start address = 0x%08X\n"), image_jump);
break;
}
SetFilePointer(hfile, records[record_count].length, NULL, FILE_CURRENT);
}
// find toc
if(!read_image((PBYTE)buffer, image_start + 0x40, 8, false)) {
_tprintf(_T("Couldn't find pTOC @ image start (0x%08X) + 0x40\n"), image_start);
goto EXIT;
}
pTOC = *(ROMHDR**)(buffer + 4);
_tprintf(_T("found pTOC = 0x%08p\n"), pTOC);
if(!get_rom_offset(image_start, image_length, pTOC)){
_tprintf(_T("Failed to find the rom offset\n"));
goto EXIT;
}
ret = true;
EXIT:
if(!ret && hfile != INVALID_HANDLE_VALUE)
CloseHandle(hfile);
return ret;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
bool process_image(const TCHAR *file_name, SIGNING_CALLBACK call_back){
bool ret = false;
if(!init(file_name)){
_ftprintf(stderr, _T("init failed\n"));
goto EXIT;
}
ret = process_image(pTOC, rom_offset, call_back);
EXIT:
if(hfile != INVALID_HANDLE_VALUE)
CloseHandle(hfile);
return ret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -