diff --git a/app/dump/elf.d b/app/dump/elf.d index 01a27bb2..8b77ddc9 100644 --- a/app/dump/elf.d +++ b/app/dump/elf.d @@ -22,7 +22,7 @@ int dump_elf(adbg_object_t *o, uint flags) { if (flags & DumpOpt.sections) dump_elf_sections(o); - if (flags & DumpOpt.disasm) + if (flags & DumpOpt.disasm_any) dump_elf_disasm(o, flags); return 0; diff --git a/app/dump/pe.d b/app/dump/pe.d index 31ba1142..68aa64f1 100644 --- a/app/dump/pe.d +++ b/app/dump/pe.d @@ -45,7 +45,7 @@ int dump_pe(adbg_object_t *o, uint flags) { if (flags & DumpOpt.debug_) dump_pe_debug(o); - if (flags & DumpOpt.disasm) + if (flags & DumpOpt.disasm_any) dump_pe_disasm(o, flags); return EXIT_SUCCESS; diff --git a/app/dumper.d b/app/dumper.d index 31c881cb..df04e879 100644 --- a/app/dumper.d +++ b/app/dumper.d @@ -50,7 +50,7 @@ enum DumpOpt { dynrelocs = BIT!13, /// Disassemble executable sections - disasm_code = BIT!22, + disasm = BIT!22, /// Disassembly statistics disasm_stats = BIT!23, /// Disassemble all sections @@ -64,8 +64,8 @@ enum DumpOpt { symbols | debug_ | tls | loadcfg | exports | imports | sections, - /// Wants to disassemble at least something - disasm = disasm_code | disasm_stats | disasm_all, + /// Any form of dissasembler is requested + disasm_any = disasm | disasm_stats | disasm_all, } /// Dump given file to stdout. @@ -121,6 +121,8 @@ int app_dump() { // or dprint(group_name, // header, program_header, etc. // spec, name, value, ...) // or consider struct DumperPrinter or similar +//TODO: object aware dumps +// generic: dump_import(lib, name), etc. private enum FORMAT_FIELD = " %-30s: "; @@ -136,8 +138,9 @@ void dprint_warn(const(char) *message) { printf("warning: %s\n", message); } void dprint_error(const(char) *message) { + import core.stdc.stdlib : exit; printf("error: %s\n", message); - panic(); + exit(1); } void dprint_section(uint count, const(char) *section, uint max) { @@ -288,9 +291,7 @@ int dprint_disassemble_object(adbg_object_t *o, void* data, ulong size, uint flags) { - if (size >= o.buffer_size || - data < o.buffer || - data + size >= o.buffer) { + if (data + size >= o.buffer + o.file_size) { dprint_error("Buffer outside file"); } @@ -309,7 +310,6 @@ int dprint_disassemble(AdbgMachine machine, adbg_disassembler_t *dasm = cast(adbg_disassembler_t*)malloc(adbg_disassembler_t.sizeof); if (dasm == null) panic(AdbgError.crt); - scope(exit) free(dasm); if (adbg_dasm_open(dasm, machine)) @@ -323,37 +323,41 @@ int dprint_disassemble(AdbgMachine machine, // stats mode if (flags & DumpOpt.disasm_stats) { - uint s_avg; /// instruction average size - uint s_min; /// smallest instruction size - uint s_max; /// longest instruction size - uint s_cnt; /// instruction count - uint s_ill; /// Number of illegal instructions + uint stat_avg; /// instruction average size + uint stat_min = uint.max; /// smallest instruction size + uint stat_max; /// longest instruction size + uint stat_total; /// total instruction count + uint stat_illegal; /// Number of illegal instructions L_STAT: switch (adbg_dasm(dasm, &op)) with (AdbgError) { case success: - s_avg += op.size; - ++s_cnt; - if (op.size > s_max) - s_max = op.size; - if (op.size < s_min) - s_min = op.size; + stat_avg += op.size; + ++stat_total; + if (op.size > stat_max) stat_max = op.size; + if (op.size < stat_min) stat_min = op.size; goto L_STAT; case illegalInstruction: - s_avg += op.size; - ++s_cnt; - ++s_ill; - goto L_DISASM; + stat_avg += op.size; + ++stat_total; + ++stat_illegal; + goto L_STAT; case outOfData: break; default: panic(); } printf( "Opcode statistics\n"~ - "average size : %.3f\n"~ - "smallest size: %u\n"~ - "biggest size : %u\n"~ - "illegal : %u\n"~ - "total : %u\n", - cast(float)s_avg / s_cnt, s_min, s_max, s_ill, s_cnt + "average size : %.3f Bytes\n"~ + "shortest : %u Bytes\n"~ + "largest : %u Bytes\n"~ + "illegal : %u instructions\n"~ + "valid : %u instructions\n"~ + "total : %u instructions\n", + cast(float)stat_avg / stat_total, + stat_min, + stat_max, + stat_illegal, + stat_total - stat_illegal, + stat_total ); return 0; } diff --git a/app/main.d b/app/main.d index 357149d8..dd64a800 100644 --- a/app/main.d +++ b/app/main.d @@ -83,6 +83,10 @@ struct option_t { extern(C) int function(const(char)*) fa; } } +//TODO: --dump-offset/--dump-seek/--dump-start - Starting offset for raw blob +//TODO: --dump-length/--dump-end - Length or end +//TODO: --dump-imports-names - Shared library names only +//TODO: --dump-imports-all - Dependency walker immutable option_t[] options = [ // general { 'a', "arch", "Select architecture for disassembler (default=platform)", true, fa: &cli_march }, @@ -104,7 +108,7 @@ immutable option_t[] options = [ // { 0, "dump-debug", "Dump object's debug information", false, &cli_dump_debug }, { 0, "dump-disasm", "Dump object's disassembly", false, &cli_dump_disasm }, { 0, "dump-disasm-all", "Dump object's disassembly for all sections", false, &cli_dump_disasm_all }, - { 0, "dump-disasm-stats", "Dump object's disassembly statistics", false, &cli_dump_disasm_stats }, + { 0, "dump-disasm-stats", "Dump object's disassembly statistics for executable sections", false, &cli_dump_disasm_stats }, { 0, "dump-blob", "Dump as raw binary blob", false, &cli_dump_blob }, // pages { 'h', "help", "Show this help screen and exit", false, &cli_help }, diff --git a/src/adbg/error.d b/src/adbg/error.d index b9d0e7c5..b3d4bb8c 100644 --- a/src/adbg/error.d +++ b/src/adbg/error.d @@ -29,8 +29,6 @@ version (Windows) { extern (C): /// Error codes. -/// -/// These aren't really meant to be used directly. enum AdbgError { // // 0-99: Generic @@ -143,7 +141,7 @@ private immutable adbg_error_msg_t[] errors_msg = [ { AdbgError.invalidOption, "Invalid disassembler option." }, { AdbgError.invalidOptionValue, "Invalid value for disassembler option." }, { AdbgError.illegalInstruction, "Illegal instruction." }, - { AdbgError.outOfData, "The input buffer has been depleted in an unexpected fashion." }, + { AdbgError.outOfData, "The input buffer has been depleted." }, { AdbgError.opcodeLimit, "The opcode exhausted its architectural limit." }, // // Object server