From bec84f48e8bec60a13883fdd0b65702c58e2576b Mon Sep 17 00:00:00 2001 From: dd86k Date: Mon, 18 Mar 2024 21:22:15 -0400 Subject: [PATCH] objects: Improve errors --- src/adbg/error.d | 42 +++-- src/adbg/object/format/ar.d | 17 +- src/adbg/object/format/elf.d | 73 +++++++-- src/adbg/object/format/lx.d | 50 +++--- src/adbg/object/format/macho.d | 280 ++++++++++++++++----------------- src/adbg/object/format/mz.d | 20 ++- src/adbg/object/format/pdb.d | 22 ++- src/adbg/object/format/pe.d | 273 ++++++++++++++++++++++---------- 8 files changed, 485 insertions(+), 292 deletions(-) diff --git a/src/adbg/error.d b/src/adbg/error.d index 69431fc7..51a09634 100644 --- a/src/adbg/error.d +++ b/src/adbg/error.d @@ -28,6 +28,8 @@ import adbg.include.capstone : csh, cs_errno, cs_strerror; // adbg_ensure_params(lvalue, "name") // - returns string if null found // - automatically set error code +// adbg_errorn(AdbgError) +// - returns null extern (C): @@ -37,19 +39,24 @@ enum AdbgError { // 0-99: Generic // success = 0, - invalidArgument = 1, - emptyArgument = 2, - uninitiated = 4, // Only when user value is important like for fopen - invalidOption = 5, - invalidOptionValue = 6, + invalidArgument = 1, /// Argument is null or zero nullArgument = invalidArgument, // Old alias for invalidArgument + emptyArgument = 2, /// Argument contains an empty dataset + uninitiated = 4, /// Instance was not initiated + invalidOption = 5, /// Invalid option + invalidValue = 6, /// Invalid value for option + invalidOptionValue = invalidValue, + offsetBounds = 7, /// File offset is outside of file size + indexBounds = 8, /// Index is outside of bounds of list + unavailable = 9, /// Feature or item is unavailable + unfindable = 10, /// Item cannot be found in list // // 100-199: Debugger // - debuggerUnattached = 100, - debuggerUnpaused = 101, - debuggerInvalidAction = 102, /// Wrong action from creation method. - debuggerPresent = 103, /// Debugger already present in remote process + debuggerUnattached = 100, + debuggerUnpaused = 101, + debuggerInvalidAction = 102, /// Wrong action from creation method. + debuggerPresent = 103, /// Debugger already present in remote process // Old meanings notAttached = debuggerUnattached, /// Old value for debuggerUnattached notPaused = debuggerUnpaused, /// Old value for debuggerUnpaused @@ -57,10 +64,10 @@ enum AdbgError { // // 200-299: Disasembler // - disasmUnsupportedMachine = 202, - disasmIllegalInstruction = 220, - disasmEndOfData = 221, - disasmOpcodeLimit = 221, + disasmUnsupportedMachine = 202, + disasmIllegalInstruction = 220, + disasmEndOfData = 221, + disasmOpcodeLimit = 221, // Old meanings unsupportedPlatform = disasmUnsupportedMachine, illegalInstruction = disasmIllegalInstruction, @@ -80,7 +87,7 @@ enum AdbgError { objectInvalidEndian = 313, objectInvalidType = 314, objectInvalidABI = 315, - objectOutsideBounds = 320, + objectOutsideBounds = offsetBounds, // Old meanings unknownObjFormat = objectUnknownFormat, unsupportedObjFormat = objectUnsupportedFormat, @@ -130,7 +137,7 @@ private __gshared adbg_error_t error; //TODO: Strongly consider string, provides .ptr and .length private struct adbg_error_msg_t { - uint code; + int code; const(char) *msg; } private immutable const(char) *defaultMsg = "Unknown error occured."; @@ -143,6 +150,10 @@ private immutable adbg_error_msg_t[] errors_msg = [ { AdbgError.uninitiated, "Object or structure is uninitiated." }, { AdbgError.invalidOption, "Option unknown." }, { AdbgError.invalidOptionValue, "Option received invalid value." }, + { AdbgError.offsetBounds, "File offset outside file size." }, + { AdbgError.indexBounds, "Index outside of list." }, + { AdbgError.unavailable, "Feature or item is unavailable." }, + { AdbgError.unfindable, "Index outside of list." }, // // Debugger // @@ -171,7 +182,6 @@ private immutable adbg_error_msg_t[] errors_msg = [ { AdbgError.objectInvalidEndian, "Invalid endianess value for object." }, { AdbgError.objectInvalidType, "Invalid object type." }, { AdbgError.objectInvalidABI, "Invalid ABI value for object." }, - { AdbgError.objectOutsideBounds, "Access outside file or module bounds." }, // // Symbols // diff --git a/src/adbg/object/format/ar.d b/src/adbg/object/format/ar.d index 998fa13c..54c48ae7 100644 --- a/src/adbg/object/format/ar.d +++ b/src/adbg/object/format/ar.d @@ -106,17 +106,25 @@ int adbg_object_ar_load(adbg_object_t *o) { return 0; } +//TODO: Can this be transformed into functions with _start & _next? ar_member_header* adbg_object_ar_header(adbg_object_t *o, size_t index) { - if (o == null) + if (o == null) { + adbg_oops(AdbgError.invalidArgument); return null; + } version (Trace) trace("index=%zu", index); ar_member_header *p = cast(ar_member_header*)(o.buffer + ar_file_header.sizeof); void *max = o.buffer + 0x8000_0000; // 2 GiB limit for (size_t i; p < max; ++i) { - if (i == index) - return p.EndMarker == AR_EOL ? p : null; + if (i == index) { + if (p.EndMarker != AR_EOL) { + adbg_oops(AdbgError.offsetBounds); + return null; + } + return p; + } // Adjust pointer size_t offset = atoi(p.Size.ptr) + ar_member_header.sizeof; @@ -130,6 +138,7 @@ ar_member_header* adbg_object_ar_header(adbg_object_t *o, size_t index) { } } + adbg_oops(AdbgError.unfindable); return null; } @@ -158,7 +167,7 @@ void* adbg_object_ar_data(adbg_object_t *o, ar_member_header *mhdr) { return null; } if (adbg_object_outboundpl(o, p, size)) { - adbg_oops(AdbgError.objectOutsideBounds); + adbg_oops(AdbgError.offsetBounds); return null; } return p; diff --git a/src/adbg/object/format/elf.d b/src/adbg/object/format/elf.d index a7b28f54..41d4ba31 100644 --- a/src/adbg/object/format/elf.d +++ b/src/adbg/object/format/elf.d @@ -416,7 +416,7 @@ enum ELF_SHT_HIPROC = 0x7fffffff; /// Processor specific enum ELF_SHT_LOUSER = 0x80000000; /// Application specific enum ELF_SHT_HIUSER = 0xffffffff; /// Application specific /// This section contains unwind function table entries for stack unwinding -enum ELF_SHT_X86_64_UNWIND = 0x70000001; +enum ELF_SHT_X86_64_UNWIND = 0x70000001; // ELF_SHT_LOPROC + 1? // Section flags @@ -701,6 +701,7 @@ struct Elf64_Chdr { //TODO: Move them to some include folder +// There's adbg.include.linux.user struct elf_prstatus32_timeval { uint tv_sec; @@ -1123,15 +1124,27 @@ int adbg_object_elf_load(adbg_object_t *o) { } Elf32_Ehdr* adbg_object_elf_ehdr32(adbg_object_t *o) { - if (o == null) return null; + if (o == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } // Return as-is, already swapped return o.i.elf32.ehdr; } Elf32_Phdr* adbg_object_elf_phdr32(adbg_object_t *o, size_t index) { - if (o == null) return null; - if (o.i.elf32.phdr == null) return null; - if (index >= o.i.elf32.ehdr.e_phnum) return null; + if (o == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } + if (o.i.elf32.phdr == null) { + adbg_oops(AdbgError.unavailable); + return null; + } + if (index >= o.i.elf32.ehdr.e_phnum) { + adbg_oops(AdbgError.indexBounds); + return null; + } Elf32_Phdr *phdr = &o.i.elf32.phdr[index]; if (o.p.reversed && o.i.elf32.reversed_phdr[index] == false) { @@ -1149,9 +1162,18 @@ Elf32_Phdr* adbg_object_elf_phdr32(adbg_object_t *o, size_t index) { } Elf32_Shdr* adbg_object_elf_shdr32(adbg_object_t *o, size_t index) { - if (o == null) return null; - if (o.i.elf32.shdr == null) return null; - if (index >= o.i.elf32.ehdr.e_shnum) return null; + if (o == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } + if (o.i.elf32.shdr == null) { + adbg_oops(AdbgError.unavailable); + return null; + } + if (index >= o.i.elf32.ehdr.e_shnum) { + adbg_oops(AdbgError.indexBounds); + return null; + } Elf32_Shdr *shdr = &o.i.elf32.shdr[index]; if (o.p.reversed && o.i.elf32.reversed_phdr[index] == false) { @@ -1171,15 +1193,27 @@ Elf32_Shdr* adbg_object_elf_shdr32(adbg_object_t *o, size_t index) { } Elf64_Ehdr* adbg_object_elf_ehdr64(adbg_object_t *o) { - if (o == null) return null; + if (o == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } // Return as-is, already swapped return o.i.elf64.ehdr; } Elf64_Phdr* adbg_object_elf_phdr64(adbg_object_t *o, size_t index) { - if (o == null) return null; - if (o.i.elf64.phdr == null) return null; - if (index >= o.i.elf64.ehdr.e_phnum) return null; + if (o == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } + if (o.i.elf64.phdr == null) { + adbg_oops(AdbgError.unavailable); + return null; + } + if (index >= o.i.elf64.ehdr.e_phnum) { + adbg_oops(AdbgError.indexBounds); + return null; + } Elf64_Phdr *phdr = &o.i.elf64.phdr[index]; if (o.p.reversed && o.i.elf64.reversed_phdr[index] == false) { @@ -1197,9 +1231,18 @@ Elf64_Phdr* adbg_object_elf_phdr64(adbg_object_t *o, size_t index) { } Elf64_Shdr* adbg_object_elf_shdr64(adbg_object_t *o, size_t index) { - if (o == null) return null; - if (o.i.elf64.shdr == null) return null; - if (index >= o.i.elf64.ehdr.e_shnum) return null; + if (o == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } + if (o.i.elf64.shdr == null) { + adbg_oops(AdbgError.unavailable); + return null; + } + if (index >= o.i.elf64.ehdr.e_shnum) { + adbg_oops(AdbgError.indexBounds); + return null; + } Elf64_Shdr *shdr = &o.i.elf64.shdr[index]; if (o.p.reversed && o.i.elf64.reversed_phdr[index] == false) { diff --git a/src/adbg/object/format/lx.d b/src/adbg/object/format/lx.d index a968ca30..a4956f7c 100644 --- a/src/adbg/object/format/lx.d +++ b/src/adbg/object/format/lx.d @@ -267,35 +267,35 @@ enum { } struct lx_flat_bundle_prefix { - ubyte b32_cnt; - ubyte b32_type; - ushort b32_obj; + ubyte b32_cnt; + ubyte b32_type; + ushort b32_obj; } struct flat_null_prefix { - ubyte b32_cnt; - ubyte b32_type; + ubyte b32_cnt; + ubyte b32_type; } /* values for the b32_type field */ alias bundle_types = int; enum { - FLT_BNDL_EMPTY = 0, - FLT_BNDL_ENTRY16, - FLT_BNDL_GATE16, - FLT_BNDL_ENTRY32, - FLT_BNDL_ENTRYFWD + FLT_BNDL_EMPTY = 0, + FLT_BNDL_ENTRY16, + FLT_BNDL_GATE16, + FLT_BNDL_ENTRY32, + FLT_BNDL_ENTRYFWD } struct lx_flat_bundle_entry32 { - ubyte e32_flags; /* flag bits are same as in OS/2 1.x */ - uint e32_offset; + ubyte e32_flags; /* flag bits are same as in OS/2 1.x */ + uint e32_offset; } struct lx_flat_bundle_gate16 { - ubyte e32_flags; /* flag bits are same as in OS/2 1.x */ - ushort offset; - ushort callgate; + ubyte e32_flags; /* flag bits are same as in OS/2 1.x */ + ushort offset; + ushort callgate; } /* @@ -303,22 +303,22 @@ struct lx_flat_bundle_gate16 { */ struct lx_flat_bundle_entry16 { - ubyte e32_flags; /* flag bits are same as in OS/2 1.x */ - ushort e32_offset; + ubyte e32_flags; /* flag bits are same as in OS/2 1.x */ + ushort e32_offset; } struct lx_flat_bundle_entryfwd { - ubyte e32_flags; /* flag bits are same as in OS/2 1.x */ - ushort modord; - uint value; + ubyte e32_flags; /* flag bits are same as in OS/2 1.x */ + ushort modord; + uint value; } struct lx_flat_res_table { - ushort type_id; - ushort name_id; - uint res_size; - ushort object; - uint offset; + ushort type_id; + ushort name_id; + uint res_size; + ushort object; + uint offset; } /* fixup record source flags */ diff --git a/src/adbg/object/format/macho.d b/src/adbg/object/format/macho.d index fe8e9d26..4842192e 100644 --- a/src/adbg/object/format/macho.d +++ b/src/adbg/object/format/macho.d @@ -60,59 +60,59 @@ struct macho_load_command { alias int vm_prot_t; struct macho_segment_command { /* for 32-bit architectures */ - uint cmd; /// LC_SEGMENT - uint cmdsize; /// includes sizeof section structs - char[16] segname; /// segment name - uint vmaddr; /// memory address of this segment - uint vmsize; /// memory size of this segment - uint fileoff; /// file offset of this segment - uint filesize; /// amount to map from the file - vm_prot_t maxprot; /// maximum VM protection - vm_prot_t initprot; /// initial VM protection - uint nsects; /// number of sections in segment - uint flags; /// flags + uint cmd; /// LC_SEGMENT + uint cmdsize; /// includes sizeof section structs + char[16] segname; /// segment name + uint vmaddr; /// memory address of this segment + uint vmsize; /// memory size of this segment + uint fileoff; /// file offset of this segment + uint filesize; /// amount to map from the file + vm_prot_t maxprot; /// maximum VM protection + vm_prot_t initprot; /// initial VM protection + uint nsects; /// number of sections in segment + uint flags; /// flags } struct macho_segment_command_64 { /* for 64-bit architectures */ - uint cmd; /// LC_SEGMENT_64 - uint cmdsize; /// includes sizeof section_64 structs - char[16] segname; /// segment name - ulong vmaddr; /// memory address of this segment - ulong vmsize; /// memory size of this segment - ulong fileoff; /// file offset of this segment - ulong filesize; /// amount to map from the file - vm_prot_t maxprot; /// maximum VM protection - vm_prot_t initprot; /// initial VM protection - uint nsects; /// number of sections in segment - uint flags; /// flags + uint cmd; /// LC_SEGMENT_64 + uint cmdsize; /// includes sizeof section_64 structs + char[16] segname; /// segment name + ulong vmaddr; /// memory address of this segment + ulong vmsize; /// memory size of this segment + ulong fileoff; /// file offset of this segment + ulong filesize; /// amount to map from the file + vm_prot_t maxprot; /// maximum VM protection + vm_prot_t initprot; /// initial VM protection + uint nsects; /// number of sections in segment + uint flags; /// flags } alias cpu_type_t = int; enum { - MACHO_CPUTYPE_ANY = -1, + MACHO_CPUTYPE_ANY = -1, /// Used as a bitmask to mark cputype as 64-bit - MACHO_CPUTYPE_ABI64 = 0x1000000, - MACHO_CPUTYPE_VAX = 1, - MACHO_CPUTYPE_ROMP = 2, - MACHO_CPUTYPE_NS32032 = 4, - MACHO_CPUTYPE_NS32332 = 5, - MACHO_CPUTYPE_MC680x0 = 6, - MACHO_CPUTYPE_I386 = 7, - MACHO_CPUTYPE_X86_64 = MACHO_CPUTYPE_I386 | MACHO_CPUTYPE_ABI64, - MACHO_CPUTYPE_MIPS = 8, - MACHO_CPUTYPE_NS32532 = 9, - MACHO_CPUTYPE_HPPA = 11, - MACHO_CPUTYPE_ARM = 12, - MACHO_CPUTYPE_ARM64 = MACHO_CPUTYPE_ARM | MACHO_CPUTYPE_ABI64, - MACHO_CPUTYPE_MC88000 = 13, - MACHO_CPUTYPE_SPARC = 14, - MACHO_CPUTYPE_I860 = 15, // big-endian - MACHO_CPUTYPE_I860_LITTLE = 16, // little-endian - MACHO_CPUTYPE_RS6000 = 17, - MACHO_CPUTYPE_MC98000 = 18, - MACHO_CPUTYPE_POWERPC = 18, - MACHO_CPUTYPE_POWERPC64 = MACHO_CPUTYPE_POWERPC | MACHO_CPUTYPE_ABI64, - MACHO_CPUTYPE_VEO = 255 + MACHO_CPUTYPE_ABI64 = 0x100_0000, + MACHO_CPUTYPE_VAX = 1, + MACHO_CPUTYPE_ROMP = 2, + MACHO_CPUTYPE_NS32032 = 4, + MACHO_CPUTYPE_NS32332 = 5, + MACHO_CPUTYPE_MC680x0 = 6, + MACHO_CPUTYPE_I386 = 7, + MACHO_CPUTYPE_X86_64 = MACHO_CPUTYPE_I386 | MACHO_CPUTYPE_ABI64, + MACHO_CPUTYPE_MIPS = 8, + MACHO_CPUTYPE_NS32532 = 9, + MACHO_CPUTYPE_HPPA = 11, + MACHO_CPUTYPE_ARM = 12, + MACHO_CPUTYPE_ARM64 = MACHO_CPUTYPE_ARM | MACHO_CPUTYPE_ABI64, + MACHO_CPUTYPE_MC88000 = 13, + MACHO_CPUTYPE_SPARC = 14, + MACHO_CPUTYPE_I860 = 15, // big-endian + MACHO_CPUTYPE_I860_LITTLE = 16, // little-endian + MACHO_CPUTYPE_RS6000 = 17, + MACHO_CPUTYPE_MC98000 = 18, + MACHO_CPUTYPE_POWERPC = 18, + MACHO_CPUTYPE_POWERPC64 = MACHO_CPUTYPE_POWERPC | MACHO_CPUTYPE_ABI64, + MACHO_CPUTYPE_VEO = 255 } // ============================= @@ -121,37 +121,37 @@ enum { // VAX subtypes enum { // SUBTYPE_VAX - MACHO_SUBTYPE_VAX_ALL = 0, - MACHO_SUBTYPE_VAX780 = 1, - MACHO_SUBTYPE_VAX785 = 2, - MACHO_SUBTYPE_VAX750 = 3, - MACHO_SUBTYPE_VAX730 = 4, - MACHO_SUBTYPE_UVAXI = 5, - MACHO_SUBTYPE_UVAXII = 6, - MACHO_SUBTYPE_VAX8200 = 7, - MACHO_SUBTYPE_VAX8500 = 8, - MACHO_SUBTYPE_VAX8600 = 9, - MACHO_SUBTYPE_VAX8650 = 10, - MACHO_SUBTYPE_VAX8800 = 11, - MACHO_SUBTYPE_UVAXIII = 12 + MACHO_SUBTYPE_VAX_ALL = 0, + MACHO_SUBTYPE_VAX780 = 1, + MACHO_SUBTYPE_VAX785 = 2, + MACHO_SUBTYPE_VAX750 = 3, + MACHO_SUBTYPE_VAX730 = 4, + MACHO_SUBTYPE_UVAXI = 5, + MACHO_SUBTYPE_UVAXII = 6, + MACHO_SUBTYPE_VAX8200 = 7, + MACHO_SUBTYPE_VAX8500 = 8, + MACHO_SUBTYPE_VAX8600 = 9, + MACHO_SUBTYPE_VAX8650 = 10, + MACHO_SUBTYPE_VAX8800 = 11, + MACHO_SUBTYPE_UVAXIII = 12 } // ROMP subtypes enum { // SUBTYPE_ROMP - MACHO_SUBTYPE_RT_ALL = 0, - MACHO_SUBTYPE_RT_PC = 1, - MACHO_SUBTYPE_RT_APC = 2, - MACHO_SUBTYPE_RT_135 = 3 + MACHO_SUBTYPE_RT_ALL = 0, + MACHO_SUBTYPE_RT_PC = 1, + MACHO_SUBTYPE_RT_APC = 2, + MACHO_SUBTYPE_RT_135 = 3 } // 32032/32332/32532 subtypes enum { // SUBTYPE_32032 - MACHO_SUBTYPE_MMAX_ALL = 0, - MACHO_SUBTYPE_MMAX_DPC = 1, /* 032 CPU */ - MACHO_SUBTYPE_SQT = 2, - MACHO_SUBTYPE_MMAX_APC_FPU = 3, /* 32081 FPU */ - MACHO_SUBTYPE_MMAX_APC_FPA = 4, /* Weitek FPA */ - MACHO_SUBTYPE_MMAX_XPC = 5, /* 532 CPU */ + MACHO_SUBTYPE_MMAX_ALL = 0, + MACHO_SUBTYPE_MMAX_DPC = 1, /* 032 CPU */ + MACHO_SUBTYPE_SQT = 2, + MACHO_SUBTYPE_MMAX_APC_FPU = 3, /* 32081 FPU */ + MACHO_SUBTYPE_MMAX_APC_FPA = 4, /* Weitek FPA */ + MACHO_SUBTYPE_MMAX_XPC = 5, /* 532 CPU */ } private @@ -161,95 +161,95 @@ template SUBTYPE_INTEL(short f, short m) { // x86 subtypes enum { // SUBTYPE_I386 - MACHO_SUBTYPE_I386_ALL = 3, - MACHO_SUBTYPE_X86_64_ALL = MACHO_SUBTYPE_I386_ALL, - MACHO_SUBTYPE_i386 = 3, - MACHO_SUBTYPE_i486 = 4, - MACHO_SUBTYPE_i486SX = 4 + 128, // "4 + 128" - MACHO_SUBTYPE_i586 = 5, - MACHO_SUBTYPE_PENT = SUBTYPE_INTEL!(5, 0), - MACHO_SUBTYPE_PENPRO = SUBTYPE_INTEL!(6, 1), - MACHO_SUBTYPE_PENTII_M3 = SUBTYPE_INTEL!(6, 3), - MACHO_SUBTYPE_PENTII_M5 = SUBTYPE_INTEL!(6, 5), - MACHO_SUBTYPE_PENTIUM_4 = SUBTYPE_INTEL!(10, 0), + MACHO_SUBTYPE_I386_ALL = 3, + MACHO_SUBTYPE_X86_64_ALL = MACHO_SUBTYPE_I386_ALL, + MACHO_SUBTYPE_i386 = 3, + MACHO_SUBTYPE_i486 = 4, + MACHO_SUBTYPE_i486SX = 4 + 128, // "4 + 128" + MACHO_SUBTYPE_i586 = 5, + MACHO_SUBTYPE_PENT = SUBTYPE_INTEL!(5, 0), + MACHO_SUBTYPE_PENPRO = SUBTYPE_INTEL!(6, 1), + MACHO_SUBTYPE_PENTII_M3 = SUBTYPE_INTEL!(6, 3), + MACHO_SUBTYPE_PENTII_M5 = SUBTYPE_INTEL!(6, 5), + MACHO_SUBTYPE_PENTIUM_4 = SUBTYPE_INTEL!(10, 0), } // MIPS subty enum { // SUBTYPE_MIPS - MACHO_SUBTYPE_MIPS_ALL = 0, - MACHO_SUBTYPE_R2300 = 1, - MACHO_SUBTYPE_R2600 = 2, - MACHO_SUBTYPE_R2800 = 3, - MACHO_SUBTYPE_R2800a = 4 + MACHO_SUBTYPE_MIPS_ALL = 0, + MACHO_SUBTYPE_R2300 = 1, + MACHO_SUBTYPE_R2600 = 2, + MACHO_SUBTYPE_R2800 = 3, + MACHO_SUBTYPE_R2800a = 4 } // 680x0 subtypes (m68k) enum { // SUBTYPE_680x0 - MACHO_SUBTYPE_MC680x0_ALL = 1, - MACHO_SUBTYPE_MC68030 = 1, - MACHO_SUBTYPE_MC68040 = 2, - MACHO_SUBTYPE_MC68030_ONLY = 3, + MACHO_SUBTYPE_MC680x0_ALL = 1, + MACHO_SUBTYPE_MC68030 = 1, + MACHO_SUBTYPE_MC68040 = 2, + MACHO_SUBTYPE_MC68030_ONLY = 3, } // HPPA subtypes enum { // SUBTYPE_HPPA - MACHO_SUBTYPE_HPPA7100 = 0, - MACHO_SUBTYPE_HPPA7100LC = 1, - MACHO_SUBTYPE_HPPA_ALL = 0, + MACHO_SUBTYPE_HPPA7100 = 0, + MACHO_SUBTYPE_HPPA7100LC = 1, + MACHO_SUBTYPE_HPPA_ALL = 0, } // Acorn subtypes enum { // SUBTYPE_ARM - MACHO_SUBTYPE_ACORN_ALL = 0, - MACHO_SUBTYPE_A500_ARCH = 1, - MACHO_SUBTYPE_A500 = 2, - MACHO_SUBTYPE_A440 = 3, - MACHO_SUBTYPE_M4 = 4, - MACHO_SUBTYPE_V4T = 5, - MACHO_SUBTYPE_V6 = 6, - MACHO_SUBTYPE_V5TEJ = 7, - MACHO_SUBTYPE_XSCALE = 8, - MACHO_SUBTYPE_V7 = 9, - MACHO_SUBTYPE_V8 = 13, + MACHO_SUBTYPE_ACORN_ALL = 0, + MACHO_SUBTYPE_A500_ARCH = 1, + MACHO_SUBTYPE_A500 = 2, + MACHO_SUBTYPE_A440 = 3, + MACHO_SUBTYPE_M4 = 4, + MACHO_SUBTYPE_V4T = 5, + MACHO_SUBTYPE_V6 = 6, + MACHO_SUBTYPE_V5TEJ = 7, + MACHO_SUBTYPE_XSCALE = 8, + MACHO_SUBTYPE_V7 = 9, + MACHO_SUBTYPE_V8 = 13, } // MC88000 subtypes enum { // SUBTYPE_MC88000 - MACHO_SUBTYPE_MC88000_ALL = 0, - MACHO_SUBTYPE_MMAX_JPC = 1, - MACHO_SUBTYPE_MC88100 = 1, - MACHO_SUBTYPE_MC88110 = 2, + MACHO_SUBTYPE_MC88000_ALL = 0, + MACHO_SUBTYPE_MMAX_JPC = 1, + MACHO_SUBTYPE_MC88100 = 1, + MACHO_SUBTYPE_MC88110 = 2, } // MC98000 (PowerPC) subtypes enum { // SUBTYPE_MC98000 - MACHO_SUBTYPE_MC98000_ALL = 0, - MACHO_SUBTYPE_MC98601 = 1, + MACHO_SUBTYPE_MC98000_ALL = 0, + MACHO_SUBTYPE_MC98601 = 1, } // I860 subtypes enum { // SUBTYPE_I860 - MACHO_SUBTYPE_I860_ALL = 0, - MACHO_SUBTYPE_I860 = 1, + MACHO_SUBTYPE_I860_ALL = 0, + MACHO_SUBTYPE_I860 = 1, } // I860_LITTLE subtypes enum { // SUBTYPE_I860_LITTLE - MACHO_SUBTYPE_I860_LITTLE_ALL = 0, - MACHO_SUBTYPE_I860_LITTLE = 1 + MACHO_SUBTYPE_I860_LITTLE_ALL = 0, + MACHO_SUBTYPE_I860_LITTLE = 1 } // RS6000 subtypes enum { // SUBTYPE_RS6000 - MACHO_SUBTYPE_RS6000_ALL = 0, - MACHO_SUBTYPE_RS6000 = 1, + MACHO_SUBTYPE_RS6000_ALL = 0, + MACHO_SUBTYPE_RS6000 = 1, } // Sun4 subtypes (port done at CMU (?)) enum { // SUBTYPE_Sun4 - MACHO_SUBTYPE_SUN4_ALL = 0, - MACHO_SUBTYPE_SUN4_260 = 1, - MACHO_SUBTYPE_SUN4_110 = 2, + MACHO_SUBTYPE_SUN4_ALL = 0, + MACHO_SUBTYPE_SUN4_260 = 1, + MACHO_SUBTYPE_SUN4_110 = 2, } // SPARC subtypes @@ -259,27 +259,27 @@ enum { // SUBTYPE_Sun4 // PowerPC subtypes enum { // SUBTYPE_PowerPC - MACHO_SUBTYPE_POWERPC_ALL = 0, - MACHO_SUBTYPE_POWERPC_601 = 1, - MACHO_SUBTYPE_POWERPC_602 = 2, - MACHO_SUBTYPE_POWERPC_603 = 3, - MACHO_SUBTYPE_POWERPC_603e = 4, - MACHO_SUBTYPE_POWERPC_603ev = 5, - MACHO_SUBTYPE_POWERPC_604 = 6, - MACHO_SUBTYPE_POWERPC_604e = 7, - MACHO_SUBTYPE_POWERPC_620 = 8, - MACHO_SUBTYPE_POWERPC_750 = 9, - MACHO_SUBTYPE_POWERPC_7400 = 10, - MACHO_SUBTYPE_POWERPC_7450 = 11, - MACHO_SUBTYPE_POWERPC_970 = 100, + MACHO_SUBTYPE_POWERPC_ALL = 0, + MACHO_SUBTYPE_POWERPC_601 = 1, + MACHO_SUBTYPE_POWERPC_602 = 2, + MACHO_SUBTYPE_POWERPC_603 = 3, + MACHO_SUBTYPE_POWERPC_603e = 4, + MACHO_SUBTYPE_POWERPC_603ev = 5, + MACHO_SUBTYPE_POWERPC_604 = 6, + MACHO_SUBTYPE_POWERPC_604e = 7, + MACHO_SUBTYPE_POWERPC_620 = 8, + MACHO_SUBTYPE_POWERPC_750 = 9, + MACHO_SUBTYPE_POWERPC_7400 = 10, + MACHO_SUBTYPE_POWERPC_7450 = 11, + MACHO_SUBTYPE_POWERPC_970 = 100, } // VEO subtypes enum { // SUBTYPE_VEO - MACHO_SUBTYPE_VEO_1 = 1, - MACHO_SUBTYPE_VEO_2 = 2, - MACHO_SUBTYPE_VEO_3 = 3, - MACHO_SUBTYPE_VEO_4 = 4, + MACHO_SUBTYPE_VEO_1 = 1, + MACHO_SUBTYPE_VEO_2 = 2, + MACHO_SUBTYPE_VEO_3 = 3, + MACHO_SUBTYPE_VEO_4 = 4, //VEO_ALL = VEO_2, } @@ -488,15 +488,15 @@ macho_fat_arch* adbg_object_macho_fat_arch(adbg_object_t *o, size_t index) { return null; // not loaded } if (o.i.macho.fat == false) { - adbg_oops(AdbgError.invalidArgument); + adbg_oops(AdbgError.unavailable); return null; } if (index >= LIMIT_FAT_ARCH) { - adbg_oops(AdbgError.objectMalformed); + adbg_oops(AdbgError.indexBounds); return null; } if (index >= o.i.macho.fat_header.nfat_arch) { - adbg_oops(AdbgError.objectMalformed); + adbg_oops(AdbgError.indexBounds); return null; } @@ -525,15 +525,15 @@ macho_load_command* adbg_object_macho_load_command(adbg_object_t *o, size_t inde return null; // not loaded } if (o.i.macho.fat) { - adbg_oops(AdbgError.invalidArgument); + adbg_oops(AdbgError.unavailable); return null; } if (index >= LIMIT_COMMANDS) { - adbg_oops(AdbgError.objectMalformed); + adbg_oops(AdbgError.indexBounds); return null; } if (index >= o.i.macho.header.ncmds) { - adbg_oops(AdbgError.objectMalformed); + adbg_oops(AdbgError.indexBounds); return null; } diff --git a/src/adbg/object/format/mz.d b/src/adbg/object/format/mz.d index 94d9fc22..2cb21121 100644 --- a/src/adbg/object/format/mz.d +++ b/src/adbg/object/format/mz.d @@ -112,14 +112,26 @@ int adbg_object_mz_load(adbg_object_t *o) { } mz_hdr* adbg_object_mz_header(adbg_object_t *o) { - if (o == null) return null; + if (o == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } return o.i.mz.header; } mz_reloc* adbg_object_mz_reloc(adbg_object_t *o, size_t index) { - if (o == null) return null; - if (o.i.mz.relocs == null) return null; // no relocations available - if (index >= o.i.mz.header.e_crlc) return null; + if (o == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } + if (o.i.mz.relocs == null) { + adbg_oops(AdbgError.unavailable); + return null; // no relocations available + } + if (index >= o.i.mz.header.e_crlc) { + adbg_oops(AdbgError.indexBounds); + return null; + } mz_reloc *reloc = &o.i.mz.relocs[index]; if (o.p.reversed && o.i.mz.reversed_relocs[index] == false) { diff --git a/src/adbg/object/format/pdb.d b/src/adbg/object/format/pdb.d index 31de337c..ebc353b5 100644 --- a/src/adbg/object/format/pdb.d +++ b/src/adbg/object/format/pdb.d @@ -462,7 +462,7 @@ int adbg_object_pdb70_load(adbg_object_t *o, size_t offset = 0) { uint *dirblk = void; if (adbg_object_offsetl(o, cast(void**)&dirblk, diroff, header.PageSize)) { free(dir); - return adbg_oops(AdbgError.assertion); + return adbg_oops(AdbgError.offsetBounds); } // Load stream directory blocks into the memory buffer @@ -472,7 +472,7 @@ int adbg_object_pdb70_load(adbg_object_t *o, size_t offset = 0) { void *block = void; if (adbg_object_offsetl(o, &block, blockoff, header.PageSize)) { free(dir); - return adbg_oops(AdbgError.assertion); + return adbg_oops(AdbgError.offsetBounds); } memcpy(dir + (dirblkidx * header.PageSize), block, header.PageSize); @@ -538,20 +538,26 @@ bool adbg_object_pdb70_block_free(adbg_object_t *o, uint num) { } ubyte* adbg_object_pdb70_get_block(adbg_object_t *o, uint num) { - if (o == null) + if (o == null) { + adbg_oops(AdbgError.invalidArgument); return null; + } pdb70_file_header *header = o.i.pdb70.header; // Check with selected FPM if block is allocated - if (adbg_object_pdb70_block_free(o, num)) + if (adbg_object_pdb70_block_free(o, num)) { + adbg_oops(AdbgError.unavailable); return null; + } // Get block ubyte *block = void; if (adbg_object_offsetl(o, cast(void**)&block, - num * header.PageSize, header.PageSize)) + num * header.PageSize, header.PageSize)) { + adbg_oops(AdbgError.offsetBounds); return null; + } return block; } @@ -590,7 +596,7 @@ int adbg_object_pdb70_stream_open(adbg_object_t *o, void **ubuffer, uint *usize, if (adbg_object_offsetl(o, &block, fileoff, readsz)) { free(sbuffer); *ubuffer = null; - return adbg_oops(AdbgError.assertion); + return adbg_oops(AdbgError.offsetBounds); } // Adjust read size on last block @@ -605,8 +611,10 @@ int adbg_object_pdb70_stream_open(adbg_object_t *o, void **ubuffer, uint *usize, return 0; } void adbg_object_pdb70_stream_close(adbg_object_t *o, void **ubuffer) { - if (o == null || ubuffer == null) + if (o == null || ubuffer == null) { + adbg_oops(AdbgError.invalidArgument); return; + } if (*ubuffer) { free(*ubuffer); diff --git a/src/adbg/object/format/pe.d b/src/adbg/object/format/pe.d index f7fce01e..2107fd69 100644 --- a/src/adbg/object/format/pe.d +++ b/src/adbg/object/format/pe.d @@ -893,32 +893,33 @@ int adbg_object_pe_load(adbg_object_t *o) { Reserved.size = adbg_bswap32(Reserved.size); } - if (o.p.reversed) { - if (o.i.pe.header.NumberOfSections) { - o.i.pe.reversed_sections = cast(bool*) - calloc(o.i.pe.header.NumberOfSections, bool.sizeof); - if (o.i.pe.reversed_sections == null) - return adbg_oops(AdbgError.crt); - } - with (o.i.pe.directory.ExportTable) if (size && rva) { - size_t count = size / PE_EXPORT_DESCRIPTOR.sizeof; - o.i.pe.reversed_dir_exports = false; - o.i.pe.reversed_dir_export_entries = cast(bool*)calloc(count, bool.sizeof); - if (o.i.pe.reversed_dir_export_entries == null) - return adbg_oops(AdbgError.crt); - } - with (o.i.pe.directory.ImportTable) if (size && rva) { - size_t count = size / PE_IMPORT_DESCRIPTOR.sizeof; - o.i.pe.reversed_dir_imports = cast(bool*)calloc(count, bool.sizeof); - if (o.i.pe.reversed_dir_imports == null) - return adbg_oops(AdbgError.crt); - } - with (o.i.pe.directory.DebugDirectory) if (size && rva) { - size_t count = size / PE_DEBUG_DIRECTORY.sizeof; - o.i.pe.reversed_dir_debug = cast(bool*)calloc(count, bool.sizeof); - if (o.i.pe.reversed_dir_debug == null) - return adbg_oops(AdbgError.crt); - } + if (o.p.reversed == false) + return 0; + + if (o.i.pe.header.NumberOfSections) { + o.i.pe.reversed_sections = cast(bool*) + calloc(o.i.pe.header.NumberOfSections, bool.sizeof); + if (o.i.pe.reversed_sections == null) + return adbg_oops(AdbgError.crt); + } + with (o.i.pe.directory.ExportTable) if (size && rva) { + size_t count = size / PE_EXPORT_DESCRIPTOR.sizeof; + o.i.pe.reversed_dir_exports = false; + o.i.pe.reversed_dir_export_entries = cast(bool*)calloc(count, bool.sizeof); + if (o.i.pe.reversed_dir_export_entries == null) + return adbg_oops(AdbgError.crt); + } + with (o.i.pe.directory.ImportTable) if (size && rva) { + size_t count = size / PE_IMPORT_DESCRIPTOR.sizeof; + o.i.pe.reversed_dir_imports = cast(bool*)calloc(count, bool.sizeof); + if (o.i.pe.reversed_dir_imports == null) + return adbg_oops(AdbgError.crt); + } + with (o.i.pe.directory.DebugDirectory) if (size && rva) { + size_t count = size / PE_DEBUG_DIRECTORY.sizeof; + o.i.pe.reversed_dir_debug = cast(bool*)calloc(count, bool.sizeof); + if (o.i.pe.reversed_dir_debug == null) + return adbg_oops(AdbgError.crt); } return 0; @@ -929,7 +930,10 @@ int adbg_object_pe_load(adbg_object_t *o) { // maps rva to section if found void* adbg_object_pe_locate(adbg_object_t *o, uint rva) { - if (o == null) return null; + if (o == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } uint sections = o.i.pe.header.NumberOfSections; for (uint si; si < sections; ++si) { @@ -944,43 +948,68 @@ void* adbg_object_pe_locate(adbg_object_t *o, uint rva) { void* a = o.buffer + (s.PointerToRawData + (rva - va)); if (adbg_object_outboundp(o, a)) { - adbg_oops(AdbgError.objectOutsideBounds); + adbg_oops(AdbgError.offsetBounds); return null; } return a; } version (Trace) trace("null"); + adbg_oops(AdbgError.unfindable); return null; } PE_HEADER* adbg_object_pe_header(adbg_object_t *o) { - if (o == null) return null; + if (o == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } return o.i.pe.header; } PE_OPTIONAL_HEADER* adbg_object_pe_optheader(adbg_object_t *o) { - if (o == null) return null; + if (o == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } return o.i.pe.opt_header; } PE_OPTIONAL_HEADER64* adbg_object_pe_optheader64(adbg_object_t *o) { - if (o == null) return null; + if (o == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } return o.i.pe.opt_header64; } PE_OPTIONAL_HEADERROM* adbg_object_pe_optheaderrom(adbg_object_t *o) { - if (o == null) return null; + if (o == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } return o.i.pe.opt_headerrom; } PE_SECTION_ENTRY* adbg_object_pe_section(adbg_object_t *o, size_t index) { version (Trace) trace("o=%p index=%u", o, cast(uint)index); - if (o == null) return null; - if (o.i.pe.sections == null) return null; - if (index > MAXIMUM_SECTIONS) return null; - if (index >= o.i.pe.header.NumberOfSections) return null; + if (o == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } + if (o.i.pe.sections == null) { + adbg_oops(AdbgError.unavailable); + return null; + } + if (index >= MAXIMUM_SECTIONS) { + adbg_oops(AdbgError.indexBounds); + return null; + } + if (index >= o.i.pe.header.NumberOfSections) { + adbg_oops(AdbgError.indexBounds); + return null; + } PE_SECTION_ENTRY *section = &o.i.pe.sections[index]; if (o.p.reversed && o.i.pe.reversed_sections[index] == false) with (section) { @@ -1025,23 +1054,34 @@ PE_SECTION_ENTRY* adbg_object_pe_section(adbg_object_t *o, size_t index) { // RVA -> hint + entry PE_EXPORT_DESCRIPTOR* adbg_object_pe_export(adbg_object_t *o) { - if (o == null) return null; - if (o.i.pe.directory == null) return null; + if (o == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } + if (o.i.pe.directory == null) { + adbg_oops(AdbgError.unavailable); // Due to PE-ROM + return null; + } // Set base - with (o.i.pe) - if (directory_exports == null) { + with (o.i.pe) if (directory_exports == null) { directory_exports = cast(PE_EXPORT_DESCRIPTOR*) adbg_object_pe_locate(o, directory.ExportTable.rva); // Not found - if (directory_exports == null) return null; + if (directory_exports == null) { + adbg_oops(AdbgError.unavailable); + return null; + } } // adbg_object_pe_locate checked pointer bounds PE_EXPORT_DESCRIPTOR* exportdir = o.i.pe.directory_exports; // ExportFlags must be zero - if (exportdir.ExportFlags != 0) return null; + if (exportdir.ExportFlags != 0) { + adbg_oops(AdbgError.unavailable); + return null; + } if (o.p.reversed && o.i.pe.reversed_dir_exports == false) with (exportdir) { ExportFlags = adbg_bswap32(ExportFlags); @@ -1062,9 +1102,14 @@ PE_EXPORT_DESCRIPTOR* adbg_object_pe_export(adbg_object_t *o) { } const(char)* adbg_object_pe_export_name(adbg_object_t *o, PE_EXPORT_DESCRIPTOR *export_) { - if (o == null || export_ == null) return null; - if (o.i.pe.directory == null) return null; - if (o.i.pe.directory_exports == null) return null; + if (o == null || export_ == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } + if (o.i.pe.directory == null || o.i.pe.directory_exports == null) { + adbg_oops(AdbgError.unavailable); // Due to PE-ROM + return null; + } const(char) *name = cast(const(char)*)o.i.pe.directory_exports @@ -1072,7 +1117,7 @@ const(char)* adbg_object_pe_export_name(adbg_object_t *o, PE_EXPORT_DESCRIPTOR * + export_.Name; if (adbg_object_outboundp(o, cast(void*)name)) { - adbg_oops(AdbgError.objectOutsideBounds); + adbg_oops(AdbgError.offsetBounds); return null; } @@ -1080,24 +1125,32 @@ const(char)* adbg_object_pe_export_name(adbg_object_t *o, PE_EXPORT_DESCRIPTOR * } PE_EXPORT_ENTRY* adbg_object_pe_export_name_entry(adbg_object_t *o, PE_EXPORT_DESCRIPTOR *export_, size_t index) { - if (o == null || export_ == null) return null; - if (o.i.pe.directory == null) return null; - if (o.i.pe.directory_exports == null) return null; - if (index >= export_.NumberOfNamePointers) return null; + if (o == null || export_ == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } + if (o.i.pe.directory == null || o.i.pe.directory_exports == null) { + adbg_oops(AdbgError.unavailable); // Due to PE-ROM + return null; + } + if (index >= export_.NumberOfNamePointers) { + adbg_oops(AdbgError.indexBounds); + return null; + } // Check bounds with table RVA void *base = cast(void*)o.i.pe.directory_exports - o.i.pe.directory.ExportTable.rva + export_.NamePointer; if (adbg_object_outboundp(o, base)) { - adbg_oops(AdbgError.objectOutsideBounds); + adbg_oops(AdbgError.offsetBounds); return null; } // Check bounds with name pointer and requested index PE_EXPORT_ENTRY *entry = cast(PE_EXPORT_ENTRY*)base + index; if (adbg_object_outboundp(o, entry)) { - adbg_oops(AdbgError.objectOutsideBounds); + adbg_oops(AdbgError.offsetBounds); return null; } @@ -1110,8 +1163,10 @@ PE_EXPORT_ENTRY* adbg_object_pe_export_name_entry(adbg_object_t *o, PE_EXPORT_DE } const(char)* adbg_object_pe_export_name_string(adbg_object_t *o, PE_EXPORT_DESCRIPTOR *export_, PE_EXPORT_ENTRY *entry) { - if (o == null || export_ == null || entry == null) + if (o == null || export_ == null || entry == null) { + adbg_oops(AdbgError.invalidArgument); return null; + } // NOTE: Export Table bounds // If the address specified is not within the export section (as @@ -1128,7 +1183,7 @@ const(char)* adbg_object_pe_export_name_string(adbg_object_t *o, PE_EXPORT_DESCR void *base = cast(void*)o.i.pe.directory_exports - o.i.pe.directory.ExportTable.rva + entry.Export; if (adbg_object_outboundp(o, base)) { - adbg_oops(AdbgError.objectOutsideBounds); + adbg_oops(AdbgError.offsetBounds); return null; } return cast(const(char)*)base; @@ -1139,20 +1194,36 @@ const(char)* adbg_object_pe_export_name_string(adbg_object_t *o, PE_EXPORT_DESCR // PE_IMPORT_DESCRIPTOR* adbg_object_pe_import(adbg_object_t *o, size_t index) { - if (o == null) return null; - if (o.i.pe.directory == null) return null; + if (o == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } + if (o.i.pe.directory == null) { + adbg_oops(AdbgError.unavailable); // Due to PE-ROM + return null; + } size_t count = o.i.pe.directory.ImportTable.size / PE_IMPORT_DESCRIPTOR.sizeof; - if (index >= count) return null; + if (index >= count) { + adbg_oops(AdbgError.indexBounds); + return null; + } // Set base if (o.i.pe.directory_imports == null) { o.i.pe.directory_imports = cast(PE_IMPORT_DESCRIPTOR*) adbg_object_pe_locate(o, o.i.pe.directory.ImportTable.rva); // Not found - if (o.i.pe.directory_imports == null) return null; + if (o.i.pe.directory_imports == null) { + adbg_oops(AdbgError.unavailable); + return null; + } } PE_IMPORT_DESCRIPTOR* import_ = o.i.pe.directory_imports + index; + if (import_.Characteristics == 0) { + adbg_oops(AdbgError.unavailable); + return null; + } if (o.p.reversed && o.i.pe.reversed_dir_imports[index] == false) with (import_) { Characteristics = adbg_bswap32(Characteristics); TimeDateStamp = adbg_bswap32(TimeDateStamp); @@ -1161,18 +1232,23 @@ PE_IMPORT_DESCRIPTOR* adbg_object_pe_import(adbg_object_t *o, size_t index) { FirstThunk = adbg_bswap32(FirstThunk); o.i.pe.reversed_dir_imports[index] = true; } - if (import_.Characteristics == 0) return null; return import_; } char* adbg_object_pe_import_name(adbg_object_t *o, PE_IMPORT_DESCRIPTOR *import_) { - if (o == null || import_ == null) return null; - if (o.i.pe.directory == null) return null; - - char *s = cast(char*)o.i.pe.directory_imports - o.i.pe.directory.ImportTable.rva + import_.Name; + if (o == null || import_ == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } + if (o.i.pe.directory == null) { + adbg_oops(AdbgError.unavailable); + return null; + } + char *s = cast(char*)o.i.pe.directory_imports - + o.i.pe.directory.ImportTable.rva + import_.Name; if (adbg_object_outboundp(o, s)) { - adbg_oops(AdbgError.objectOutsideBounds); + adbg_oops(AdbgError.offsetBounds); return null; } @@ -1182,15 +1258,20 @@ char* adbg_object_pe_import_name(adbg_object_t *o, PE_IMPORT_DESCRIPTOR *import_ //TODO: Byte-swap import look-up table entries PE_IMPORT_ENTRY32* adbg_object_pe_import_entry32(adbg_object_t *o, PE_IMPORT_DESCRIPTOR *import_, size_t index) { - if (o == null || import_ == null) return null; - if (o.i.pe.directory_imports == null) return null; + if (o == null || import_ == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } + if (o.i.pe.directory_imports == null) { + adbg_oops(AdbgError.unavailable); + return null; + } PE_IMPORT_ENTRY32* lte32 = cast(PE_IMPORT_ENTRY32*) (cast(char*)o.i.pe.directory_imports + (import_.Characteristics - o.i.pe.directory.ImportTable.rva)) + index; - if (adbg_object_outboundp(o, lte32) || lte32.ordinal == 0) { - adbg_oops(AdbgError.objectOutsideBounds); + adbg_oops(AdbgError.offsetBounds); return null; } @@ -1198,13 +1279,19 @@ PE_IMPORT_ENTRY32* adbg_object_pe_import_entry32(adbg_object_t *o, PE_IMPORT_DES } ushort* adbg_object_pe_import_entry32_hint(adbg_object_t *o, PE_IMPORT_DESCRIPTOR *import_, PE_IMPORT_ENTRY32 *im32) { - if (o == null || import_ == null) return null; - if (o.i.pe.directory_imports == null) return null; + if (o == null || import_ == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } + if (o.i.pe.directory_imports == null) { + adbg_oops(AdbgError.unavailable); + return null; + } ushort* base = cast(ushort*) ((cast(char*)o.i.pe.directory_imports - o.i.pe.directory.ImportTable.rva) + im32.rva); if (adbg_object_outboundp(o, base)) { - adbg_oops(AdbgError.objectOutsideBounds); + adbg_oops(AdbgError.offsetBounds); return null; } @@ -1212,8 +1299,14 @@ ushort* adbg_object_pe_import_entry32_hint(adbg_object_t *o, PE_IMPORT_DESCRIPTO } PE_IMPORT_ENTRY64* adbg_object_pe_import_entry64(adbg_object_t *o, PE_IMPORT_DESCRIPTOR *import_, size_t index) { - if (o == null || import_ == null) return null; - if (o.i.pe.directory_imports == null) return null; + if (o == null || import_ == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } + if (o.i.pe.directory_imports == null) { + adbg_oops(AdbgError.unavailable); + return null; + } PE_IMPORT_ENTRY64* lte64 = cast(PE_IMPORT_ENTRY64*) (cast(char*)o.i.pe.directory_imports + (import_.Characteristics - o.i.pe.directory.ImportTable.rva)) @@ -1222,7 +1315,7 @@ PE_IMPORT_ENTRY64* adbg_object_pe_import_entry64(adbg_object_t *o, PE_IMPORT_DES version (Trace) trace("imports=%p lte64=%p fs=%zx", o.i.pe.directory_imports, lte64, o.file_size); if (adbg_object_outboundp(o, lte64) || lte64.ordinal == 0) { - adbg_oops(AdbgError.objectOutsideBounds); + adbg_oops(AdbgError.offsetBounds); return null; } @@ -1230,8 +1323,14 @@ PE_IMPORT_ENTRY64* adbg_object_pe_import_entry64(adbg_object_t *o, PE_IMPORT_DES } ushort* adbg_object_pe_import_entry64_hint(adbg_object_t *o, PE_IMPORT_DESCRIPTOR *import_, PE_IMPORT_ENTRY64 *im64) { - if (o == null || import_ == null) return null; - if (o.i.pe.directory_imports == null) return null; + if (o == null || import_ == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } + if (o.i.pe.directory_imports == null) { + adbg_oops(AdbgError.unavailable); + return null; + } ushort* base = cast(ushort*) ((cast(char*)o.i.pe.directory_imports - o.i.pe.directory.ImportTable.rva) + im64.rva); @@ -1239,7 +1338,7 @@ ushort* adbg_object_pe_import_entry64_hint(adbg_object_t *o, PE_IMPORT_DESCRIPTO version (Trace) trace("base=%p fs=%zx", base, o.file_size); if (adbg_object_outboundp(o, base)) { - adbg_oops(AdbgError.objectOutsideBounds); + adbg_oops(AdbgError.offsetBounds); return null; } @@ -1270,17 +1369,29 @@ ushort* adbg_object_pe_import_entry64_hint(adbg_object_t *o, PE_IMPORT_DESCRIPTO // PE_DEBUG_DIRECTORY* adbg_object_pe_debug_directory(adbg_object_t *o, size_t index) { - if (o == null) return null; - if (o.i.pe.directory == null) return null; + if (o == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } + if (o.i.pe.directory == null) { + adbg_oops(AdbgError.unavailable); // Due to PE-ROM + return null; + } size_t count = o.i.pe.directory.DebugDirectory.size / PE_DEBUG_DIRECTORY.sizeof; - if (index >= count) return null; + if (index >= count) { + adbg_oops(AdbgError.indexBounds); + return null; + } // Set base if (o.i.pe.directory_debug == null) { o.i.pe.directory_debug = cast(PE_DEBUG_DIRECTORY*) adbg_object_pe_locate(o, o.i.pe.directory.DebugDirectory.rva); // Not found - if (o.i.pe.directory_debug == null) return null; + if (o.i.pe.directory_debug == null) { + adbg_oops(AdbgError.unavailable); + return null; + } } PE_DEBUG_DIRECTORY* debug_ = o.i.pe.directory_debug + index;