static public DataDirectory readIn(BinaryIn source) { uint rva = source.getFour(); uint size = source.getFour(); return(new DataDirectory(rva, size)); }
//recursively descend through resource directory structure //resource directories are 3 levels deep by Microsoft convention: //level 1 : resource type //level 2 : resource name str/id num //level 3 : language (aka code page) private void parseResourceDirectory(BinaryIn source, int level) { //parse IMAGE_RESOURCE_DIRECTORY uint characteristics = source.getFour(); //unused uint timeDateStamp = source.getFour(); uint majorVersion = source.getTwo(); uint minorVersion = source.getTwo(); uint numberOfNamedEntries = source.getTwo(); uint numberOfIdEntries = source.getTwo(); int entryCount = (int)(numberOfNamedEntries + numberOfIdEntries); for (int i = 0; i < entryCount; i++) { uint idName = source.getFour(); //either numeric val or a ptr to name str uint data = source.getFour(); //either ptr to subdir or a leaf node resIdNameValues[level] = idName; //store id/name val at this level uint curPos = source.getPos(); //save cur pos in resource directory uint dataPos = (data & 0x7FFFFFFF); source.seek(dataPos); //goto leaf/subtree data if (data < 0x80000000) //high bit not set -> data points to leaf node { parseResourceData(source); } else { //high bit is set -> data points to subtree parseResourceDirectory(source, level + 1); //recurse next subtree } source.seek(curPos); //ret to pos in resource directory } }
static public MsDosHeader readMSDOSHeader(BinaryIn source) { MsDosHeader dosHeader = new MsDosHeader(); dosHeader.signature = source.getTwo(); if (dosHeader.signature != 0x5a4d) { throw new Win32FormatException("this is not a valid win32 executable file"); } dosHeader.lastsize = source.getTwo(); dosHeader.nblocks = source.getTwo(); dosHeader.nreloc = source.getTwo(); dosHeader.hdrsize = source.getTwo(); dosHeader.minalloc = source.getTwo(); dosHeader.maxalloc = source.getTwo(); dosHeader.ss = source.getTwo(); dosHeader.sp = source.getTwo(); dosHeader.checksum = source.getTwo(); dosHeader.ip = source.getTwo(); dosHeader.cs = source.getTwo(); dosHeader.relocpos = source.getTwo(); dosHeader.noverlay = source.getTwo(); dosHeader.reserved1 = source.getRange(8); dosHeader.oem_id = source.getTwo(); dosHeader.oem_info = source.getTwo(); dosHeader.reserved2 = source.getRange(20); dosHeader.e_lfanew = source.getFour(); return(dosHeader); }
public static ExportEntry loadFromFile(BinaryIn infile) { string name = infile.getAsciiZString(); uint addr = infile.getFour(); ExportEntry exp = new ExportEntry(name, addr); return(exp); }
//- reading in ---------------------------------------------------------------- public static CoffSection readSection(BinaryIn source) { string name = source.getAsciiString(8); CoffSection sec = new CoffSection(name); sec.memSize = source.getFour(); sec.memPos = source.getFour(); sec.fileSize = source.getFour(); sec.filePos = source.getFour(); sec.relocTblPos = source.getFour(); uint skip1 = source.getFour(); //line numbers are deprecated sec.relocTblCount = source.getTwo(); uint skip2 = source.getTwo(); uint flagval = source.getFour(); sec.settings = SectionSettings.decodeFlags(flagval); uint mark = source.getPos(); source.seek(sec.filePos); byte[] secdata = source.getRange(sec.fileSize); sec.data = new List <byte>(secdata); source.seek(mark); return(sec); }
internal static Section loadSection(BinaryIn infile, uint secaddr, uint secsize) { infile.seek(secaddr); String blockname = infile.getAsciiZString(); BSSBlock block = new BSSBlock(); block.bssSize = infile.getFour(); uint exportcount = infile.getFour(); //export list for (int i = 0; i < exportcount; i++) { ExportEntry exp = ExportEntry.loadFromFile(infile); block.exports.Add(exp); } return(block); }
public static ImportEntry loadFromFile(BinaryIn infile) { string name = infile.getAsciiZString(); uint addr = infile.getFour(); uint b = infile.getOne(); ImportEntry imp = new ImportEntry(name, addr, (IMPORTTYPE)b); return(imp); }
//- reading in -------------------------------------------------------- internal static OboeBlock loadSection(BinaryIn infile, uint secaddr, uint secsize, uint sectype) { infile.seek(secaddr); String blockname = infile.getAsciiZString(); OboeBlock block = new OboeBlock(blockname, sectype); uint blockaddr = infile.getFour(); uint blocksize = infile.getFour(); uint importaddr = infile.getFour(); uint importcount = infile.getFour(); uint exportaddr = infile.getFour(); uint exportcount = infile.getFour(); //block data infile.seek(blockaddr); block.blockdata = new List <byte>(infile.getRange(blocksize)); //import list infile.seek(importaddr); for (int i = 0; i < importcount; i++) { ImportEntry imp = ImportEntry.loadFromFile(infile); block.imports.Add(imp); } //export list infile.seek(exportaddr); for (int i = 0; i < exportcount; i++) { ExportEntry exp = ExportEntry.loadFromFile(infile); block.exports.Add(exp); } return(block); }
//- reading in ---------------------------------------------------------------- public void readFile(String _filename) { filename = _filename; BinaryIn source = new BinaryIn(filename); dosHeader = MsDosHeader.readMSDOSHeader(source); source.seek(dosHeader.e_lfanew); uint pesig = source.getFour(); if (pesig != 0x00004550) { throw new Win32ReadException("this is not a valid win32 executable file"); } machine = (MachineType)source.getTwo(); uint secCount = source.getTwo(); uint stamp = source.getFour(); timeStamp = setTimestamp(stamp); uint symbolTblAddr = source.getFour(); uint symbolTblCount = source.getFour(); //these fields should be zero uint optionalHdrSize = source.getTwo(); if (optionalHdrSize != 0xe0) { throw new Win32ReadException("this is not a valid win32 executable file"); } uint flags = source.getTwo(); characteristics = Characteristics.decodeFlags(flags); readOptionalHeader(source); loadSections(source, secCount); //getImportTable(source); //getExportTable(source); //getResourceTable(source); }
//- reading in from file ----------------------------------------------- public static Oboe loadFromFile(string inname) { BinaryIn infile = new BinaryIn(inname); Oboe oboe = new Oboe(); try { string sig = infile.getAsciiString(4); if (!sig.Equals(OBOESIG)) { throw new OboeFormatException("this is not a valid OBOE file"); } uint secCount = infile.getFour(); for (int i = 0; i < secCount; i++) { uint sectype = infile.getFour(); uint secaddr = infile.getFour(); uint secsize = infile.getFour(); uint hdrpos = infile.getPos(); //ignore any section types we don't recognize if (loaders.ContainsKey(sectype)) { infile.seek(secaddr); Section sec = loaders[sectype].readIn(infile, secsize); oboe.addSection(sec); infile.seek(hdrpos); } } } catch (BinaryReadException) { throw new OboeFormatException("this is not a valid OBOE file"); } return(oboe); }
public static ResImageGroupDataEntry parseData(BinaryIn src) { ResImageGroupDataEntry cgdata = new ResImageGroupDataEntry(); cgdata.bWidth = src.getOne(); cgdata.bHeight = src.getOne(); cgdata.bColorCount = src.getOne(); uint res = src.getOne(); cgdata.wPlanes = src.getTwo(); cgdata.wBitCount = src.getTwo(); cgdata.dwBytesInRes = src.getFour(); cgdata.nID = src.getTwo(); cgdata.image = null; return cgdata; }
public static void loadRelocations(BinaryIn source, CoffSection sec, Win32Obj objfile) { source.seek(sec.relocTblPos); for (int i = 0; i < sec.relocTblCount; i++) { uint addr = source.getFour(); int symidx = (int)source.getFour(); uint reloctype = source.getTwo(); CoffRelocation.Reloctype reltype = CoffRelocation.Reloctype.NONE; switch (reloctype) { case 06: reltype = CoffRelocation.Reloctype.ABSOLUTE; //IMAGE_REL_I386_DIR32 break; case 07: reltype = CoffRelocation.Reloctype.RVA; //IMAGE_REL_I386_DIR32NB break; case 11: reltype = CoffRelocation.Reloctype.SECREL32; //IMAGE_REL_I386_SECREL break; case 20: reltype = CoffRelocation.Reloctype.RELATIVE; //IMAGE_REL_I386_REL32 break; default: break; } CoffSymbol sym = objfile.symbols[symidx]; CoffRelocation reloc = new CoffRelocation(addr - sec.memPos, sym, reltype); sec.relocations.Add(reloc); } }
private void readOptionalHeader(BinaryIn source) { magicNum = source.getTwo(); majorLinkerVersion = source.getOne(); minorLinkerVersion = source.getOne(); sizeOfCode = source.getFour(); sizeOfInitializedData = source.getFour(); sizeOfUninitializedData = source.getFour(); addressOfEntryPoint = source.getFour(); baseOfCode = source.getFour(); baseOfData = source.getFour(); imageBase = source.getFour(); memAlignment = source.getFour(); fileAlignment = source.getFour(); majorOSVersion = source.getTwo(); minorOSVersion = source.getTwo(); majorImageVersion = source.getTwo(); minorImageVersion = source.getTwo(); majorSubsystemVersion = source.getTwo(); minorSubsystemVersion = source.getTwo(); win32VersionValue = source.getFour(); sizeOfImage = source.getFour(); sizeOfHeaders = source.getFour(); checksum = source.getFour(); subsystem = source.getTwo(); dLLCharacteristics = source.getTwo(); sizeOfStackReserve = source.getFour(); sizeOfStackCommit = source.getFour(); sizeOfHeapReserve = source.getFour(); sizeOfHeapCommit = source.getFour(); loaderFlags = source.getFour(); numberOfRvaAndSizes = source.getFour(); dExportTable = DataDirectory.readIn(source); dImportTable = DataDirectory.readIn(source); dResourceTable = DataDirectory.readIn(source); exceptionTable = DataDirectory.readIn(source); certificatesTable = DataDirectory.readIn(source); baseRelocationTable = DataDirectory.readIn(source); debugTable = DataDirectory.readIn(source); architecture = DataDirectory.readIn(source); globalPtr = DataDirectory.readIn(source); threadLocalStorageTable = DataDirectory.readIn(source); loadConfigurationTable = DataDirectory.readIn(source); boundImportTable = DataDirectory.readIn(source); importAddressTable = DataDirectory.readIn(source); delayImportDescriptor = DataDirectory.readIn(source); CLRRuntimeHeader = DataDirectory.readIn(source); reserved = DataDirectory.readIn(source); }
public static void loadSymbols(BinaryIn source, uint count, byte[] strtbl, Win32Obj objfile) { for (int i = 0; i < count;) { //get short name or pos in string tbl uint nameloc = source.getPos(); uint namezeros = source.getFour(); String name = ""; if (namezeros == 0) //if first 4 bytes = 0, 2nd 4 bytes = ofs into str tbl { int namepos = (int)source.getFour(); name = readString(strtbl, namepos); } else { source.seek(nameloc); name = source.getAsciiString(8); } //read rest of sym entry uint val = source.getFour(); uint secval = source.getTwo(); uint type = source.getTwo(); CoffStorageClass storage = (CoffStorageClass)source.getOne(); uint aux = source.getOne(); CoffSymbol sym = null; CoffSymbol.SYMBIND bind = CoffSymbol.SYMBIND.EXTERNAL; uint size = 0; uint addr = 0; CoffSection sec = null; switch (storage) { case CoffStorageClass.IMAGE_SYM_CLASS_EXTERNAL: if (secval == 0) { if (val == 0) { bind = CoffSymbol.SYMBIND.EXTERNAL; } else { bind = CoffSymbol.SYMBIND.COMMON; size = val; } } else { bind = CoffSymbol.SYMBIND.GLOBAL; sec = objfile.sections[(int)secval - 1]; if (val >= sec.memPos) { addr = val - sec.memPos; } } sym = new CoffSymbol(name); sym.bind = bind; sym.typ = CoffSymbol.SYMTYPE.FUNCTION; sym.section = sec; sym.ofs = addr; sym.size = size; break; case CoffStorageClass.IMAGE_SYM_CLASS_STATIC: case CoffStorageClass.IMAGE_SYM_CLASS_LABEL: if (secval != 0xffff) { sec = objfile.sections[(int)secval - 1]; if (val >= sec.memPos) { addr = val - sec.memPos; } sym = new CoffSymbol(name); sym.bind = CoffSymbol.SYMBIND.LOCAL; sym.typ = CoffSymbol.SYMTYPE.FUNCTION; sym.section = sec; sym.ofs = addr; sym.size = size; } break; case CoffStorageClass.IMAGE_SYM_CLASS_SECTION: sec = objfile.sections[(int)secval - 1]; sym = new CoffSymbol(name); sym.bind = CoffSymbol.SYMBIND.LOCAL; sym.typ = CoffSymbol.SYMTYPE.FUNCTION; sym.section = sec; sym.ofs = addr; sym.size = size; break; case CoffStorageClass.IMAGE_SYM_CLASS_FUNCTION: case CoffStorageClass.IMAGE_SYM_CLASS_FILE: break; default: break; } i++; objfile.symbols.Add(sym); if (sym != null) { objfile.symNames[sym.name] = sym; } //skip any aux sym entries for (int j = 0; j < aux; j++) { source.skip(CoffSymbol.SYMTBLENTRYSIZE); objfile.symbols.Add(null); i++; } } }
public static Win32Obj readFromFile(String filename) { Win32Obj objfile = new Win32Obj(filename); BinaryIn source = new BinaryIn(filename); //coff header objfile.machine = (MachineType)source.getTwo(); uint sectionCount = source.getTwo(); objfile.timeStamp = source.getFour(); uint symbolTblAddr = source.getFour(); uint symbolCount = source.getFour(); uint optionalHdrSize = source.getTwo(); objfile.characteristics = (int)source.getTwo(); //string tbl - follows symbol tbl uint strtblpos = symbolTblAddr + symbolCount * CoffSymbol.SYMTBLENTRYSIZE; source.seek(strtblpos); byte[] strtbl = null; uint len = source.getFour(); if (len > 4) { source.seek(strtblpos); strtbl = source.getRange(len); } //section tbl source.seek(COFFHDRSIZE); for (int i = 0; i < sectionCount; i++) { //if section name is stored in string tbl, we read in index & let caller deref the actual name String secname = source.getAsciiString(8); if (secname[0] == '/') { int stridx = Int32.Parse(secname.Substring(1)); secname = readString(strtbl, stridx); } //read section hdr field uint memSize = source.getFour(); //don't use - 0 in object files uint memPos = source.getFour(); uint fileSize = source.getFour(); uint filePos = source.getFour(); uint relocPos = source.getFour(); uint lineNumPos = source.getFour(); //don't use - deprecated uint relocCount = source.getTwo(); uint lineNumCount = source.getTwo(); //don't use uint flagval = source.getFour(); SectionSettings settings = SectionSettings.decodeFlags(flagval); CoffSection section = new CoffSection(secname, settings); section.owner = objfile; section.secNum = i + 1; section.memPos = memPos; section.fileSize = fileSize; section.filePos = filePos; section.relocTblPos = relocPos; section.relocTblCount = relocCount; objfile.sections.Add(section); objfile.secNames[section.name] = section; } //load symbols source.seek(symbolTblAddr); loadSymbols(source, symbolCount, strtbl, objfile); foreach (CoffSection section in objfile.sections) { //load section data section.data = new List <Byte>(source.getRange(section.filePos, section.fileSize)); //load sectionrelocs loadRelocations(source, section, objfile); } return(objfile); }
//leaf node of resource directory tree, this rec points to actual data private void parseResourceData(BinaryIn source) { uint datapos = source.getFour(); uint datasize = source.getFour(); uint codepage = source.getFour(); uint reserved = source.getFour(); datapos -= resourceRVA; byte[] resdata = source.getRange(datapos, datasize); //get resource data //get the store type/id/lang vals we stored in our decent to this node uint restype = resIdNameValues[0]; uint resid = resIdNameValues[1]; String resname = (resid >= 0x80000000) ? getResourceName(source, resid) : null; uint reslang = resIdNameValues[2]; switch (restype) { case 1: ResData curdata = new ResData(resid, resname, reslang, resdata); cursorItems.Add(curdata); break; case 2: Bitmap bmp = ResBitmap.parseData(resdata); addBitmap(resid, resname, reslang, bmp); getDataItem(bitmaps, resid, resname).getItem(reslang).dataBuf = resdata; break; case 3: ResData icondata = new ResData(resid, resname, reslang, resdata); iconItems.Add(icondata); break; case 4: addMenu(resid, resname, reslang, resdata); //List<String> menu = ResMenu.parseData(resdata); //addMenu(resid, resname, reslang, menu); getDataItem(menus, resid, resname).getItem(reslang).dataBuf = resdata; break; case 5: addDialog(resid, resname, reslang, resdata); //List<String> dlg = ResDialog.parseData(resdata); //addDialog(resid, resname, reslang, dlg); getDataItem(dialogs, resid, resname).getItem(reslang).dataBuf = resdata; break; case 6: List<String> strings = ResStringTable.parseData(resdata); addStringTable(resid, resname, reslang, strings); getDataItem(stringtable, resid, resname).getItem(reslang).dataBuf = resdata; break; case 7: addFontDirectory(resid, resname, reslang, resdata); getDataItem(fontDirectories, resid, resname).getItem(reslang).dataBuf = resdata; break; case 8: addFont(resid, resname, reslang, resdata); getDataItem(fonts, resid, resname).getItem(reslang).dataBuf = resdata; break; case 9: List<String> accel = ResAccelerator.parseData(resdata); addAccelerator(resid, resname, reslang, accel); getDataItem(accelerators, resid, resname).getItem(reslang).dataBuf = resdata; break; case 10: addUserData(resid, resname, reslang, resdata); getDataItem(userData, resid, resname).getItem(reslang).dataBuf = resdata; break; case 12: ResImageGroupData cg = ResImageGroupData.parseData(resdata); addCursorGroup(resid, resname, reslang, cg); getDataItem(cursorGroups, resid, resname).getItem(reslang).dataBuf = resdata; break; case 14: ResImageGroupData ig = ResImageGroupData.parseData(resdata); addIconGroup(resid, resname, reslang, ig); getDataItem(iconGroups, resid, resname).getItem(reslang).dataBuf = resdata; break; case 16: addVersion(resid, resname, reslang, resdata); //List<String> version = ResVersion.parseData(resdata); //addVersion(resid, resname, reslang, version); getDataItem(versions, resid, resname).getItem(reslang).dataBuf = resdata; break; default: addUserData(resid, resname, reslang, resdata); getDataItem(userData, resid, resname).getItem(reslang).dataBuf = resdata; break; } }