//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(SourceFile 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 } }
public void loadStringTable(SourceFile source) { uint pos = symbolTblAddr + (symbolCount * 0x12); source.seek(pos); uint len = source.getFour() - 4; byte[] data = source.getRange(len); String str = ""; int idx = 4; for (int i = 0; i < len; i++) { if (data[i] != 0) { str += (char)data[i]; } else { stringTbl.Add(idx, str); str = ""; idx = i + 5; } } }
private String getResourceName(SourceFile 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 ---------------------------------------------------------------- public void readFile(String _filename) { filename = _filename; SourceFile source = new SourceFile(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"); } readCoffHeader(source); readOptionalHeader(source); loadSections(source); foreach (Section section in sections) { section.imageBase = imageBase; //sections in exe/dll have an image base } //getResourceTable(source); }