/** * Gets the assembly instruction at the specified virtual address. * * @param address a virtual address * @return the assembly instruction at the specified address */ public final Instruction getInstruction(AbsoluteAddress address) { Instruction instr = assemblyMap.get(address); if (instr != null) { return instr; } else { // No real instructions in prologue/epilogue if (harness.contains(address) || isStub(address)) return null; ExecutableImage module = getModule(address); long fp = -1; if (module == null) { logger.error("No module for address " + address + ". Cannot disassemble instruction!"); } else { fp = module.getFilePointer(address); // Also check whether fp is out of the int range, since the X86Disassembler actually // performs this cast in its implementation. if (fp < 0 || (int) fp < 0) { logger.error("Requested instruction outside of file area: " + address); } else { if (!module.isCodeArea(address)) { logger.error("Requested instruction outside code section: " + address); return null; } instr = module.getDisassembler().decodeInstruction(fp); if (instr == null) { logger.error("Instruction could not be disassembled at: " + address); } } } if (instr != null) putInstruction(address, instr); return instr; } }
/** * Get the module that contains the specified virtual address at runtime. * * @param a a virtual address * @return the module to which the given virtual address belongs. */ public ExecutableImage getModule(AbsoluteAddress a) { for (ExecutableImage module : modules) { if (module.getFilePointer(a) >= 0) return module; } return null; }