public void writeOboeFile(BinaryOut outfile) { //write header outfile.putFixedString(OBOESIG, 4); outfile.putFour((uint)sections.Count); //write initial section tbl uint sectblsize = (uint)(sections.Count * SECTIONENTRYSIZE); uint sectbl = outfile.getPos(); outfile.skip(sectblsize); //write section data uint pos = outfile.getPos(); foreach (Section sec in sections) { sec.addr = pos; sec.writeOut(outfile); pos = outfile.getPos(); sec.size = pos - sec.addr; } //adjust section tbl outfile.seek(sectbl); foreach (Section sec in sections) { outfile.putFour(sec.sectype); outfile.putFour(sec.addr); outfile.putFour(sec.size); } }
public void writeSectionData(BinaryOut outfile) { uint pos = outfile.getPos(); outfile.putRange(data.ToArray()); //these get written directly after the section data CoffRelocation.write(outfile, relocTblPos); uint padding = fileSize - (outfile.getPos() - pos); outfile.putZeros(padding); }
//- writing out ------------------------------------------------------- public override void writeOut(BinaryOut outfile) { base.writeOut(outfile); //initize block header uint hdrpos = outfile.getPos(); outfile.skip(24); //write block data uint blockaddr = outfile.getPos(); uint blocksize = (uint)blockdata.Count; outfile.putRange(blockdata.ToArray()); //write import list uint importaddr = outfile.getPos(); uint importcount = (uint)imports.Count; foreach (ImportEntry imp in imports) { imp.writeToFile(outfile); } //write export list uint exportaddr = outfile.getPos(); uint exportcount = (uint)exports.Count; foreach (ExportEntry exp in exports) { exp.writeToFile(outfile); } uint endpos = outfile.getPos(); //go back and adjust block header outfile.seek(hdrpos); outfile.putFour(blockaddr); outfile.putFour(blocksize); outfile.putFour(importaddr); outfile.putFour(importcount); outfile.putFour(exportaddr); outfile.putFour(exportcount); outfile.seek(endpos); }
public void buildRelocSection() { relocList.Sort(); BinaryOut relData = new BinaryOut(); uint basepage = relocList[0].addr & 0xFFFFF000; uint blocksize = 8; relData.putFour(basepage); uint blockstart = relData.getPos(); relData.putFour(0); foreach (CoffRelocationEntry rel in relocList) { uint page = rel.addr & 0xFFFFF000; if (page != basepage) { if (blocksize % 4 != 0) { relData.putTwo(0); blocksize += 2; } uint blockend = relData.getPos(); relData.seek(blockstart); relData.putFour(blocksize); relData.seek(blockend); basepage = page; blocksize = 8; relData.putFour(basepage); blockstart = relData.getPos(); relData.putFour(0); } uint ofs = rel.addr % 0x1000; ofs += 0x3000; relData.putTwo(ofs); blocksize += 2; } if (blocksize % 4 != 0) { relData.putTwo(0); blocksize += 2; } relData.seek(blockstart); relData.putFour(blocksize); relocSec = new CoffSection(".reloc"); relocSec.data = new List <byte>(relData.getData()); uint datasize = (uint)relocSec.data.Count; relocSec.filePos = filepos; relocSec.fileSize = (datasize + (fileAlignment - 1)) & ~(fileAlignment - 1); filepos += relocSec.fileSize; relocSec.memPos = mempos; relocSec.memSize = datasize; mempos += (datasize + (memAlignment - 1)) & ~(memAlignment - 1); relocSec.settings.canRead = true; relocSec.settings.hasInitData = true; relocSec.settings.canDiscard = true; uint msize = (relocSec.memSize + fileAlignment - 1) & ~(fileAlignment - 1); sizeOfInitializedData += msize; sections.Add(relocSec); baseRelocationTable.rva = relocSec.memPos; baseRelocationTable.size = relocSec.memSize; }
//standard sections public void buildExportSection() { uint ordinalBase = 1; BinaryOut expData = new BinaryOut(); expData.putFour(0); expData.putFour((uint)getTimestamp()); expData.putTwo(1); expData.putTwo(0); expData.putFour(0); //filename addr expData.putFour(ordinalBase); expData.putFour((uint)exportList.Count); expData.putFour((uint)exportList.Count); expData.putFour(0x28 + mempos); uint expnametbl = 0x28 + 4 * (uint)exportList.Count; expData.putFour(expnametbl + mempos); uint ordtbl = expnametbl + 4 * (uint)exportList.Count; expData.putFour(ordtbl + mempos); //export addr tbl foreach (CoffExportEntry exp in exportList) { expData.putFour(exp.addr); } //export name tbl expData.skip(4 * (uint)exportList.Count); //ordinal number tbl foreach (CoffExportEntry exp in exportList) { expData.putTwo(exp.ord - ordinalBase); } uint faddr = expData.getPos() + mempos; expData.putString(filename); List <uint> nameaddrs = new List <uint>(); foreach (CoffExportEntry exp in exportList) { nameaddrs.Add(expData.getPos() + mempos); expData.putString(exp.name); } expData.seek(0xc); expData.putFour(faddr); expData.seek(expnametbl); foreach (uint nameaddr in nameaddrs) { expData.putFour(nameaddr); } exportSec = new CoffSection(".edata"); exportSec.data = new List <byte>(expData.getData()); uint datasize = (uint)exportSec.data.Count; exportSec.filePos = filepos; exportSec.fileSize = (datasize + (fileAlignment - 1)) & ~(fileAlignment - 1); filepos += exportSec.fileSize; exportSec.memPos = mempos; exportSec.memSize = datasize; mempos += (datasize + (memAlignment - 1)) & ~(memAlignment - 1); exportSec.settings.canRead = true; exportSec.settings.hasInitData = true; uint msize = (exportSec.memSize + fileAlignment - 1) & ~(fileAlignment - 1); sizeOfInitializedData += msize; sections.Add(exportSec); dExportTable.rva = exportSec.memPos; dExportTable.size = exportSec.memSize; }
//private void getResourceTable(SourceFile source) //{ // if (optHeader.dataDirectory[DataDirectory.IMAGE_DIRECTORY_ENTRY_RESOURCE].size > 0) // { // uint resOfs = optHeader.dataDirectory[DataDirectory.IMAGE_DIRECTORY_ENTRY_RESOURCE].rva; // uint resSize = optHeader.dataDirectory[DataDirectory.IMAGE_DIRECTORY_ENTRY_RESOURCE].size; // Section resSec = findSection(resOfs); // if (resSec != null) // { // SourceFile secData = new SourceFile(resSec.data); // resourceTable = new ResourceTable(); // resourceTable.imageBase = imageBase; // resourceTable.resourceRVA = resOfs; // resourceTable.data = secData.getRange(resOfs - resSec.memloc, resSize); // } // } //} //- writing out ---------------------------------------------------------------- public void writeFile(String _filename) { filename = _filename; mempos = 0x1000; filepos = 0; //build dos header if (dosHeader == null) { dosHeader = new MsDosHeader(); } uint winHdrPos = (((dosHeader.headerSize + 7) / 8) * 8); dosHeader.e_lfanew = winHdrPos; //win hdr fields characteristics.isExecutable = true; characteristics.is32BitMachine = true; if (isDLL) { characteristics.isDLL = true; imageBase = 0x10000000; //dll default image base } uint sectionCount = (uint)sections.Count; if (exportList.Count > 0) { sectionCount++; } if (relocList.Count > 0) { sectionCount++; } filepos = (winHdrPos + 0x18 + 0xe0 + (uint)(sectionCount * 0x28) + (fileAlignment - 1)) & ~(fileAlignment - 1); sizeOfHeaders = filepos; buildSectionTable(); //build standard sections //int importSecNum = -1; //if (importTable != null) //{ // importSecNum = sections.Count; // CoffSection importSection = importTable.createSection(); // sections.Add(importSection); //} if (exportList.Count > 0) { buildExportSection(); } //int resourceSecNum = -1; //if (resourceTable != null) //{ // resourceSecNum = sections.Count; // CoffSection resourceSection = resourceTable.createSection(); // sections.Add(resourceSection); //} if (relocList.Count > 0) { buildRelocSection(); } sizeOfImage = mempos; //total image size BinaryOut outfile = new BinaryOut(filename); dosHeader.writeOut(outfile); outfile.putZeros(winHdrPos - dosHeader.headerSize); writeCoffHeader(outfile); writeOptionalHeader(outfile); writeSectionTable(outfile); outfile.putZeros(sizeOfHeaders - outfile.getPos()); writeSectionData(outfile); outfile.writeOut(); }