//- 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); }
//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 } }
private String getResourceName(BinaryIn source, uint pos) { uint curPos = source.getPos(); pos = (pos & 0x7FFFFFFF); source.seek(pos); int strLen = (int)source.getTwo(); pos += 2; StringBuilder str = new StringBuilder(strLen); for (int i = 0; i < strLen; i++) { uint ch = source.getTwo(); str.Append(Convert.ToChar(ch)); pos += 2; } source.seek(curPos); return str.ToString(); }
//- 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 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++; } } }