/** Resolves symbols between the loaded modules. */ private void resolveSymbols() { Iterator<UnresolvedSymbol> sIter = unresolvedSymbols.iterator(); while (sIter.hasNext()) { UnresolvedSymbol unresolvedSymbol = sIter.next(); ExportedSymbol symbol = exportedSymbols.get(removeDecoration(unresolvedSymbol.getName())); if (symbol != null) { logger.debug("Resolving symbol " + unresolvedSymbol.getName()); unresolvedSymbol.resolve(symbol.getAddress()); sIter.remove(); } } }
/** For all unresolved symbols, install simple stubs. */ public void installStubs() { if (mainModule instanceof AbstractCOFFModule) { stubLibrary = new Win32StubLibrary(arch); } else if (mainModule instanceof ELFModule) { stubLibrary = new LinuxStubLibrary(arch); } Iterator<UnresolvedSymbol> sIter = unresolvedSymbols.iterator(); while (sIter.hasNext()) { UnresolvedSymbol unresolvedSymbol = sIter.next(); AbsoluteAddress address = stubLibrary.resolveSymbol(unresolvedSymbol.getFromLibrary(), unresolvedSymbol.getName()); if (address != null) { // logger.debug("Installing stack height stub for " + unresolvedSymbol.getName()); unresolvedSymbol.resolve(address); sIter.remove(); } } if (!unresolvedSymbols.isEmpty()) logger.warn("Unresolved symbols remaining: " + unresolvedSymbols); }
/** * Loads a secondary (library or stub) module for analysis. Automatically determines the correct * file type. * * @param moduleFile the file to load * @return the ExecutableImage class for the loaded module * @throws IOException * @throws BinaryParseException */ public ExecutableImage loadModule(File moduleFile) throws IOException, BinaryParseException { // First try to load it as a PE file, then object file, ELF and finally raw binary code // The right thing to do would be some smart IDing of the file type, but // this exception chaining works for now... ExecutableImage module = null; try { module = new PEModule(moduleFile, getArchitecture()); targetOS = TargetOS.WINDOWS; } catch (BinaryParseException e) { try { module = new ObjectFile(moduleFile, getArchitecture()); } catch (BinaryParseException e2) { try { module = new ELFModule(moduleFile, getArchitecture()); targetOS = TargetOS.LINUX; } catch (BinaryParseException e3) { module = new RawModule(moduleFile, getArchitecture()); } } } for (ExecutableImage existingModule : modules) { if (existingModule.getMaxAddress().getValue() >= module.getMinAddress().getValue() && existingModule.getMinAddress().getValue() <= module.getMaxAddress().getValue()) { throw new RuntimeException("Virtual addresses of modules overlap!"); } } modules.add(module); unresolvedSymbols.addAll(module.getUnresolvedSymbols()); for (ExportedSymbol symbol : module.getExportedSymbols()) { exportedSymbols.put(removeDecoration(symbol.getName()), symbol); } resolveSymbols(); return module; }