576 lines
27 KiB
C++
576 lines
27 KiB
C++
// ******************************************************************
|
|
// *
|
|
// * .,-::::: .,:: .::::::::. .,:: .:
|
|
// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;;
|
|
// * [[[ '[[,,[[' [[[__[[\. '[[,,[['
|
|
// * $$$ Y$$$P $$""""Y$$ Y$$$P
|
|
// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo,
|
|
// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm,
|
|
// *
|
|
// * Cxbx->Win32->Cxbx->EmuExe.cpp
|
|
// *
|
|
// * This file is part of the Cxbx project.
|
|
// *
|
|
// * Cxbx and Cxbe are free software; you can redistribute them
|
|
// * and/or modify them under the terms of the GNU General Public
|
|
// * License as published by the Free Software Foundation; either
|
|
// * version 2 of the license, or (at your option) any later version.
|
|
// *
|
|
// * This program is distributed in the hope that it will be useful,
|
|
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// * GNU General Public License for more details.
|
|
// *
|
|
// * You should have recieved a copy of the GNU General Public License
|
|
// * along with this program; see the file COPYING.
|
|
// * If not, write to the Free Software Foundation, Inc.,
|
|
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
|
|
// *
|
|
// * (c) 2002-2003 Aaron Robinson <caustik@caustik.com>
|
|
// *
|
|
// * All rights reserved
|
|
// *
|
|
// ******************************************************************
|
|
#include "Cxbx.h"
|
|
|
|
#include "EmuExe.h"
|
|
#include "Prolog.h"
|
|
#include "CxbxKrnl.h"
|
|
|
|
#undef FIELD_OFFSET // prevent macro redefinition warnings
|
|
#include <windows.h>
|
|
|
|
#include <memory.h>
|
|
|
|
// ******************************************************************
|
|
// * constructor
|
|
// ******************************************************************
|
|
EmuExe::EmuExe(Xbe *x_Xbe, uint32 x_debug_console, char *x_debug_filename) : Exe()
|
|
{
|
|
ConstructorInit();
|
|
|
|
// ******************************************************************
|
|
// * generate pe header
|
|
// ******************************************************************
|
|
{
|
|
m_Header.m_magic = *(uint32 *)"PE\0\0"; // magic number : "PE\0\0"
|
|
m_Header.m_machine = IMAGE_FILE_MACHINE_I386; // machine type : i386
|
|
m_Header.m_sections = (uint16)(x_Xbe->m_Header.dwSections + 2); // xbe sections + .cxbximp + .cxbxplg
|
|
m_Header.m_timedate = x_Xbe->m_Header.dwTimeDate; // time/date stamp
|
|
m_Header.m_symbol_table_addr = 0; // unused
|
|
m_Header.m_symbols = 0; // unused
|
|
m_Header.m_sizeof_optional_header = sizeof(OptionalHeader); // size of optional header
|
|
m_Header.m_characteristics = 0x010F; // should be fine..
|
|
}
|
|
|
|
// ******************************************************************
|
|
// * generate optional header
|
|
// ******************************************************************
|
|
{
|
|
m_OptionalHeader.m_magic = 0x010B; // magic number : 0x010B
|
|
|
|
// ******************************************************************
|
|
// * abitrary linker version : 6.0
|
|
// ******************************************************************
|
|
m_OptionalHeader.m_linker_version_major = 0x06;
|
|
m_OptionalHeader.m_linker_version_minor = 0x00;
|
|
|
|
// ******************************************************************
|
|
// * size of headers
|
|
// ******************************************************************
|
|
m_OptionalHeader.m_sizeof_headers = sizeof(bzDOSStub) + sizeof(m_Header);
|
|
m_OptionalHeader.m_sizeof_headers += sizeof(m_OptionalHeader) + sizeof(*m_SectionHeader)*m_Header.m_sections;
|
|
m_OptionalHeader.m_sizeof_headers = RoundUp(m_OptionalHeader.m_sizeof_headers, PE_FILE_ALIGN);
|
|
|
|
m_OptionalHeader.m_image_base = x_Xbe->m_Header.dwBaseAddr;
|
|
|
|
m_OptionalHeader.m_section_alignment = PE_SEGM_ALIGN;
|
|
m_OptionalHeader.m_file_alignment = PE_FILE_ALIGN;
|
|
|
|
// ******************************************************************
|
|
// * OS version : 4.0
|
|
// ******************************************************************
|
|
m_OptionalHeader.m_os_version_major = 0x0004;
|
|
m_OptionalHeader.m_os_version_minor = 0x0000;
|
|
|
|
// ******************************************************************
|
|
// * image version : 0.0
|
|
// ******************************************************************
|
|
m_OptionalHeader.m_image_version_major = 0x0000;
|
|
m_OptionalHeader.m_image_version_minor = 0x0000;
|
|
|
|
// ******************************************************************
|
|
// * subsystem version : 4.0
|
|
// ******************************************************************
|
|
m_OptionalHeader.m_subsystem_version_major = 0x0004;
|
|
m_OptionalHeader.m_subsystem_version_minor = 0x0000;
|
|
|
|
m_OptionalHeader.m_win32_version = 0x00000000;
|
|
m_OptionalHeader.m_checksum = 0x00000000;
|
|
m_OptionalHeader.m_subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
|
|
|
|
// ******************************************************************
|
|
// * no special dll characteristics are necessary
|
|
// ******************************************************************
|
|
m_OptionalHeader.m_dll_characteristics = 0x0000;
|
|
|
|
// ******************************************************************
|
|
// * TODO: for each of these, check for bad values and correct them
|
|
// ******************************************************************
|
|
m_OptionalHeader.m_sizeof_stack_reserve = 0x00100000;
|
|
m_OptionalHeader.m_sizeof_stack_commit = 0x00001000;
|
|
m_OptionalHeader.m_sizeof_heap_reserve = x_Xbe->m_Header.dwPeHeapReserve;
|
|
m_OptionalHeader.m_sizeof_heap_commit = x_Xbe->m_Header.dwPeHeapCommit;
|
|
|
|
// ******************************************************************
|
|
// * this member is obsolete, so we'll just set it to zero
|
|
// ******************************************************************
|
|
m_OptionalHeader.m_loader_flags = 0x00000000;
|
|
|
|
// ******************************************************************
|
|
// * we'll set this to the typical 0x10 (16)
|
|
// ******************************************************************
|
|
m_OptionalHeader.m_data_directories = 0x10;
|
|
|
|
// ******************************************************************
|
|
// * clear all data directories (we'll setup some later)
|
|
// ******************************************************************
|
|
for(uint32 d=0;d<m_OptionalHeader.m_data_directories;d++)
|
|
{
|
|
m_OptionalHeader.m_image_data_directory[d].m_virtual_addr = 0;
|
|
m_OptionalHeader.m_image_data_directory[d].m_size = 0;
|
|
}
|
|
}
|
|
|
|
// ******************************************************************
|
|
// * generate section headers
|
|
// ******************************************************************
|
|
{
|
|
m_SectionHeader = new SectionHeader[m_Header.m_sections];
|
|
|
|
// ******************************************************************
|
|
// * start appending section headers at this point
|
|
// ******************************************************************
|
|
uint32 dwSectionCursor = RoundUp(m_OptionalHeader.m_sizeof_headers, 0x1000);
|
|
|
|
// ******************************************************************
|
|
// * generate xbe section headers
|
|
// ******************************************************************
|
|
{
|
|
for(uint32 v=0;v<x_Xbe->m_Header.dwSections;v++)
|
|
{
|
|
// ******************************************************************
|
|
// * generate xbe section name
|
|
// ******************************************************************
|
|
{
|
|
memset(m_SectionHeader[v].m_name, 0, 8);
|
|
|
|
for(int c=0;c<8;c++)
|
|
{
|
|
m_SectionHeader[v].m_name[c] = x_Xbe->m_szSectionName[v][c];
|
|
|
|
if(m_SectionHeader[v].m_name[c] == '\0')
|
|
break;
|
|
}
|
|
}
|
|
|
|
// ******************************************************************
|
|
// * generate xbe section virtual size / addr
|
|
// ******************************************************************
|
|
{
|
|
uint32 VirtSize = x_Xbe->m_SectionHeader[v].dwVirtualSize;
|
|
uint32 VirtAddr = x_Xbe->m_SectionHeader[v].dwVirtualAddr - x_Xbe->m_Header.dwBaseAddr;
|
|
|
|
m_SectionHeader[v].m_virtual_size = VirtSize;
|
|
m_SectionHeader[v].m_virtual_addr = VirtAddr;
|
|
}
|
|
|
|
// ******************************************************************
|
|
// * generate xbe section raw size / addr
|
|
// ******************************************************************
|
|
{
|
|
// TODO: get this working such that m_sizeof_raw can be the actual raw size, not virtual size
|
|
uint32 RawSize = RoundUp(x_Xbe->m_SectionHeader[v].dwVirtualSize, PE_FILE_ALIGN);
|
|
uint32 RawAddr = dwSectionCursor;
|
|
|
|
m_SectionHeader[v].m_sizeof_raw = RawSize;
|
|
m_SectionHeader[v].m_raw_addr = RawAddr;
|
|
|
|
dwSectionCursor += RawSize;
|
|
}
|
|
|
|
// ******************************************************************
|
|
// * relocation / line numbers will not exist
|
|
// ******************************************************************
|
|
{
|
|
m_SectionHeader[v].m_relocations_addr = 0;
|
|
m_SectionHeader[v].m_linenumbers_addr = 0;
|
|
|
|
m_SectionHeader[v].m_relocations = 0;
|
|
m_SectionHeader[v].m_linenumbers = 0;
|
|
}
|
|
|
|
// ******************************************************************
|
|
// * generate flags for this xbe section
|
|
// ******************************************************************
|
|
{
|
|
uint32 flags = IMAGE_SCN_MEM_READ;
|
|
|
|
if(x_Xbe->m_SectionHeader[v].dwFlags.bExecutable)
|
|
{
|
|
flags |= IMAGE_SCN_MEM_EXECUTE;
|
|
flags |= IMAGE_SCN_CNT_CODE;
|
|
}
|
|
else
|
|
{
|
|
flags |= IMAGE_SCN_CNT_INITIALIZED_DATA;
|
|
}
|
|
|
|
if(x_Xbe->m_SectionHeader[v].dwFlags.bWritable)
|
|
flags |= IMAGE_SCN_MEM_WRITE;
|
|
|
|
m_SectionHeader[v].m_characteristics = flags;
|
|
}
|
|
}
|
|
}
|
|
|
|
// ******************************************************************
|
|
// * generate .cxbximp section header
|
|
// ******************************************************************
|
|
{
|
|
uint32 i = m_Header.m_sections - 2;
|
|
|
|
memcpy(m_SectionHeader[i].m_name, ".cxbximp", 8);
|
|
|
|
// ******************************************************************
|
|
// * generate .cxbximp section virtual size / addr
|
|
// ******************************************************************
|
|
{
|
|
uint32 virt_size = RoundUp(0x55, PE_SEGM_ALIGN);
|
|
uint32 virt_addr = RoundUp(m_SectionHeader[i-1].m_virtual_addr + m_SectionHeader[i-1].m_virtual_size, PE_SEGM_ALIGN);
|
|
|
|
m_SectionHeader[i].m_virtual_size = virt_size;
|
|
m_SectionHeader[i].m_virtual_addr = virt_addr;
|
|
}
|
|
|
|
// ******************************************************************
|
|
// * generate .cxbximp section raw size / addr
|
|
// ******************************************************************
|
|
{
|
|
uint32 raw_size = RoundUp(m_SectionHeader[i].m_virtual_size, PE_FILE_ALIGN);
|
|
|
|
m_SectionHeader[i].m_sizeof_raw = raw_size;
|
|
m_SectionHeader[i].m_raw_addr = dwSectionCursor;
|
|
|
|
dwSectionCursor += raw_size;
|
|
}
|
|
|
|
// ******************************************************************
|
|
// * relocation / line numbers will not exist
|
|
// ******************************************************************
|
|
{
|
|
m_SectionHeader[i].m_relocations_addr = 0;
|
|
m_SectionHeader[i].m_linenumbers_addr = 0;
|
|
|
|
m_SectionHeader[i].m_relocations = 0;
|
|
m_SectionHeader[i].m_linenumbers = 0;
|
|
}
|
|
|
|
// ******************************************************************
|
|
// * make this section readable initialized data
|
|
// ******************************************************************
|
|
m_SectionHeader[i].m_characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA;
|
|
|
|
// ******************************************************************
|
|
// * update import table directory entry
|
|
// ******************************************************************
|
|
m_OptionalHeader.m_image_data_directory[1].m_virtual_addr = m_SectionHeader[i].m_virtual_addr + 0x08;
|
|
m_OptionalHeader.m_image_data_directory[1].m_size = 0x28;
|
|
|
|
// ******************************************************************
|
|
// * update import address table directory entry
|
|
// ******************************************************************
|
|
m_OptionalHeader.m_image_data_directory[12].m_virtual_addr = m_SectionHeader[i].m_virtual_addr;
|
|
m_OptionalHeader.m_image_data_directory[12].m_size = 0x08;
|
|
}
|
|
|
|
// ******************************************************************
|
|
// * generate .cxbxplg section header
|
|
// ******************************************************************
|
|
{
|
|
uint32 i = m_Header.m_sections - 1;
|
|
|
|
memcpy(m_SectionHeader[i].m_name, ".cxbxplg", 8);
|
|
|
|
// ******************************************************************
|
|
// * generate .cxbxplg section virtual size / addr
|
|
// ******************************************************************
|
|
{
|
|
uint32 virt_size = RoundUp(0x1000 + x_Xbe->m_Header.dwSizeofHeaders, 0x1000);
|
|
uint32 virt_addr = RoundUp(m_SectionHeader[i-1].m_virtual_addr + m_SectionHeader[i-1].m_virtual_size, PE_SEGM_ALIGN);
|
|
|
|
m_SectionHeader[i].m_virtual_size = virt_size;
|
|
m_SectionHeader[i].m_virtual_addr = virt_addr;
|
|
|
|
// our entry point should be the first bytes in this section
|
|
m_OptionalHeader.m_entry = virt_addr;
|
|
}
|
|
|
|
// ******************************************************************
|
|
// * generate .cxbxplg section raw size / addr
|
|
// ******************************************************************
|
|
{
|
|
uint32 raw_size = RoundUp(m_SectionHeader[i].m_virtual_size, PE_FILE_ALIGN);
|
|
|
|
m_SectionHeader[i].m_sizeof_raw = raw_size;
|
|
m_SectionHeader[i].m_raw_addr = dwSectionCursor;
|
|
|
|
dwSectionCursor += raw_size;
|
|
}
|
|
|
|
// ******************************************************************
|
|
// * relocation / line numbers will not exist
|
|
// ******************************************************************
|
|
{
|
|
m_SectionHeader[i].m_relocations_addr = 0;
|
|
m_SectionHeader[i].m_linenumbers_addr = 0;
|
|
|
|
m_SectionHeader[i].m_relocations = 0;
|
|
m_SectionHeader[i].m_linenumbers = 0;
|
|
}
|
|
|
|
// ******************************************************************
|
|
// * make this section readable and executable
|
|
// ******************************************************************
|
|
m_SectionHeader[i].m_characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_CODE;
|
|
}
|
|
}
|
|
|
|
// ******************************************************************
|
|
// * generate sections
|
|
// ******************************************************************
|
|
{
|
|
m_bzSection = new uint08*[m_Header.m_sections];
|
|
|
|
// ******************************************************************
|
|
// * generate xbe sections
|
|
// ******************************************************************
|
|
{
|
|
uint32 kt = x_Xbe->m_Header.dwKernelImageThunkAddr;
|
|
|
|
// ******************************************************************
|
|
// * decode kernel thunk address
|
|
// ******************************************************************
|
|
{
|
|
if((kt ^ XOR_KT_DEBUG) > 0x01000000)
|
|
kt ^= XOR_KT_RETAIL;
|
|
else
|
|
kt ^= XOR_KT_DEBUG;
|
|
}
|
|
|
|
// ******************************************************************
|
|
// * generate xbe sections
|
|
// ******************************************************************
|
|
for(uint32 v=0;v<x_Xbe->m_Header.dwSections;v++)
|
|
{
|
|
uint32 SectionSize = m_SectionHeader[v].m_sizeof_raw;
|
|
|
|
m_bzSection[v] = new uint08[SectionSize];
|
|
|
|
memset(m_bzSection[v], 0, SectionSize);
|
|
|
|
memcpy(m_bzSection[v], x_Xbe->m_bzSection[v], x_Xbe->m_SectionHeader[v].dwSizeofRaw);
|
|
}
|
|
|
|
}
|
|
|
|
// ******************************************************************
|
|
// * generate .cxbximp section
|
|
// ******************************************************************
|
|
{
|
|
// ******************************************************************
|
|
// * TODO: fix up this entire chunk of code, it is a total hack
|
|
// ******************************************************************
|
|
uint32 i = m_Header.m_sections - 2;
|
|
|
|
uint32 dwVirtAddr = m_SectionHeader[i].m_virtual_addr;
|
|
|
|
uint32 dwRawSize = m_SectionHeader[i].m_sizeof_raw;
|
|
|
|
m_bzSection[i] = new uint08[dwRawSize];
|
|
|
|
memset(m_bzSection[i], 0, dwRawSize);
|
|
|
|
*(uint32*)&m_bzSection[i][0x00] = dwVirtAddr + 0x38;
|
|
*(uint32*)&m_bzSection[i][0x04] = 0;
|
|
*(uint32*)&m_bzSection[i][0x08] = dwVirtAddr + 0x30;
|
|
*(uint32*)&m_bzSection[i][0x0C] = 0;
|
|
|
|
*(uint32*)&m_bzSection[i][0x10] = 0;
|
|
*(uint32*)&m_bzSection[i][0x14] = dwVirtAddr + 0x48;
|
|
*(uint32*)&m_bzSection[i][0x18] = dwVirtAddr + 0x00;
|
|
*(uint32*)&m_bzSection[i][0x1C] = 0;
|
|
|
|
*(uint32*)&m_bzSection[i][0x20] = 0;
|
|
*(uint32*)&m_bzSection[i][0x24] = 0;
|
|
*(uint32*)&m_bzSection[i][0x28] = 0;
|
|
*(uint32*)&m_bzSection[i][0x2C] = 0;
|
|
|
|
*(uint32*)&m_bzSection[i][0x30] = dwVirtAddr + 0x38;
|
|
*(uint32*)&m_bzSection[i][0x34] = 0;
|
|
*(uint16*)&m_bzSection[i][0x38] = 0x0001;
|
|
|
|
memcpy(&m_bzSection[i][0x3A], "_EmuXDummy@0\0\0cxbx.dll\0\0\0\0\0\0", 28);
|
|
}
|
|
|
|
// ******************************************************************
|
|
// * generate .cxbxplg section
|
|
// ******************************************************************
|
|
{
|
|
uint32 ep = x_Xbe->m_Header.dwEntryAddr;
|
|
uint32 i = m_Header.m_sections - 1;
|
|
|
|
// ******************************************************************
|
|
// * decode entry point
|
|
// ******************************************************************
|
|
if( (ep ^ XOR_EP_RETAIL) > 0x01000000)
|
|
ep ^= XOR_EP_DEBUG;
|
|
else
|
|
ep ^= XOR_EP_RETAIL;
|
|
|
|
m_bzSection[i] = new uint08[m_SectionHeader[i].m_sizeof_raw];
|
|
|
|
// ******************************************************************
|
|
// * append prolog section
|
|
// ******************************************************************
|
|
memcpy(m_bzSection[i], Prolog, 0x1000);
|
|
|
|
// ******************************************************************
|
|
// * append xbe header
|
|
// ******************************************************************
|
|
memcpy(m_bzSection[i] + 0x100, &x_Xbe->m_Header, sizeof(Xbe::Header));
|
|
|
|
// ******************************************************************
|
|
// * append xbe extra header bytes
|
|
// ******************************************************************
|
|
memcpy(m_bzSection[i] + 0x100 + sizeof(Xbe::Header), x_Xbe->m_HeaderEx, x_Xbe->m_Header.dwSizeofHeaders - sizeof(Xbe::Header));
|
|
|
|
// ******************************************************************
|
|
// * append x_debug_filename
|
|
// ******************************************************************
|
|
memcpy(m_bzSection[i] + 0x100 + x_Xbe->m_Header.dwSizeofHeaders, x_debug_filename, 260);
|
|
|
|
// ******************************************************************
|
|
// * patch prolog function parameters
|
|
// ******************************************************************
|
|
*(uint32 *)((uint32)m_bzSection[i] + 1) = (uint32)EmuXInit;
|
|
*(uint32 *)((uint32)m_bzSection[i] + 6) = (uint32)ep;
|
|
*(uint32 *)((uint32)m_bzSection[i] + 11) = (uint32)x_Xbe->m_Header.dwSizeofHeaders;
|
|
*(uint32 *)((uint32)m_bzSection[i] + 16) = m_SectionHeader[i].m_virtual_addr + m_OptionalHeader.m_image_base + 0x100;
|
|
*(uint32 *)((uint32)m_bzSection[i] + 21) = m_SectionHeader[i].m_virtual_addr + m_OptionalHeader.m_image_base + 0x100 + x_Xbe->m_Header.dwSizeofHeaders;
|
|
*(uint32 *)((uint32)m_bzSection[i] + 26) = x_debug_console;
|
|
}
|
|
}
|
|
|
|
// ******************************************************************
|
|
// * patch kernel thunk table
|
|
// ******************************************************************
|
|
{
|
|
uint32 kt = x_Xbe->m_Header.dwKernelImageThunkAddr;
|
|
|
|
// ******************************************************************
|
|
// * decode kernel thunk address
|
|
// ******************************************************************
|
|
{
|
|
if( (kt ^ XOR_KT_DEBUG) > 0x01000000)
|
|
kt ^= XOR_KT_RETAIL;
|
|
else
|
|
kt ^= XOR_KT_DEBUG;
|
|
}
|
|
|
|
// ******************************************************************
|
|
// * locate section containing kernel thunk table
|
|
// ******************************************************************
|
|
for(uint32 v=0;v<x_Xbe->m_Header.dwSections;v++)
|
|
{
|
|
uint32 imag_base = m_OptionalHeader.m_image_base;
|
|
|
|
uint32 virt_addr = m_SectionHeader[v].m_virtual_addr;
|
|
uint32 virt_size = m_SectionHeader[v].m_virtual_size;
|
|
|
|
// ******************************************************************
|
|
// * modify kernel thunk table, if found
|
|
// ******************************************************************
|
|
if(kt >= virt_addr + imag_base && kt < virt_addr + virt_size + imag_base)
|
|
{
|
|
uint32 *kt_tbl = (uint32*)&m_bzSection[v][kt - virt_addr - imag_base];
|
|
|
|
while(*kt_tbl != 0)
|
|
*kt_tbl++ = KernelThunkTable[*kt_tbl & 0x7FFFFFFF];
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// ******************************************************************
|
|
// * update imcomplete header fields
|
|
// ******************************************************************
|
|
{
|
|
// ******************************************************************
|
|
// * calculate size of code / data / image
|
|
// ******************************************************************
|
|
{
|
|
uint32 sizeof_code = 0;
|
|
uint32 sizeof_data = 0;
|
|
uint32 sizeof_undata = 0;
|
|
uint32 sizeof_image = 0;
|
|
|
|
for(uint32 v=0;v<m_Header.m_sections;v++)
|
|
{
|
|
uint32 characteristics = m_SectionHeader[v].m_characteristics;
|
|
|
|
if( (characteristics & IMAGE_SCN_MEM_EXECUTE) || (characteristics & IMAGE_SCN_CNT_CODE) )
|
|
sizeof_code += m_SectionHeader[v].m_sizeof_raw;
|
|
|
|
if( (characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) )
|
|
sizeof_data += m_SectionHeader[v].m_sizeof_raw;
|
|
}
|
|
|
|
// ******************************************************************
|
|
// * calculate size of image
|
|
// ******************************************************************
|
|
sizeof_image = sizeof_undata + sizeof_data + sizeof_code + m_OptionalHeader.m_sizeof_headers;
|
|
sizeof_image = RoundUp(sizeof_image, PE_SEGM_ALIGN);
|
|
|
|
// ******************************************************************
|
|
// * update optional header as necessary
|
|
// ******************************************************************
|
|
m_OptionalHeader.m_sizeof_code = sizeof_code;
|
|
m_OptionalHeader.m_sizeof_initialized_data = sizeof_data;
|
|
m_OptionalHeader.m_sizeof_uninitialized_data = sizeof_undata;
|
|
m_OptionalHeader.m_sizeof_image = sizeof_image;
|
|
}
|
|
|
|
// ******************************************************************
|
|
// * we'll set code base as the virtual address of the first section
|
|
// ******************************************************************
|
|
m_OptionalHeader.m_code_base = m_SectionHeader[0].m_virtual_addr;
|
|
|
|
// ******************************************************************
|
|
// * we'll set data base as the virtual address of the first section
|
|
// * that is not marked as containing code or being executable
|
|
// ******************************************************************
|
|
for(uint32 v=0;v<m_Header.m_sections;v++)
|
|
{
|
|
uint32 characteristics = m_SectionHeader[v].m_characteristics;
|
|
|
|
if( !(characteristics & IMAGE_SCN_MEM_EXECUTE) || !(characteristics & IMAGE_SCN_CNT_CODE) )
|
|
{
|
|
m_OptionalHeader.m_data_base = m_SectionHeader[v].m_virtual_addr;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|