qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 3/3] contrib/elf2dmp: add PE name check and Windows Server 20


From: Yuri Benditovich
Subject: Re: [PATCH 3/3] contrib/elf2dmp: add PE name check and Windows Server 2022 support
Date: Thu, 4 Nov 2021 13:47:27 +0200

On Wed, Nov 3, 2021 at 6:13 PM Viktor Prutyanov
<viktor.prutyanov@phystech.edu> wrote:
>
> Since its inception elf2dmp has checked MZ signatures within an
> address space above IDT[0] interrupt vector and took first PE image
> found as Windows Kernel.
> But in Windows Server 2022 memory dump this address space range is
> full of invalid PE fragments and the tool must check that PE image
> is 'ntoskrnl.exe' actually.
> So, introduce additional validation by checking image name from
> Export Directory against 'ntoskrnl.exe'.
>
> Signed-off-by: Viktor Prutyanov <viktor.prutyanov@phystech.edu>
Tested-by: Yuri Benditovich <yuri.benditovich@daynix.com>
> ---
>  contrib/elf2dmp/main.c | 28 ++++++++++++++++++++++++++--
>  contrib/elf2dmp/pe.h   | 15 +++++++++++++++
>  2 files changed, 41 insertions(+), 2 deletions(-)
>
> diff --git a/contrib/elf2dmp/main.c b/contrib/elf2dmp/main.c
> index a62fde23cc..04cdd07292 100644
> --- a/contrib/elf2dmp/main.c
> +++ b/contrib/elf2dmp/main.c
> @@ -17,6 +17,7 @@
>
>  #define SYM_URL_BASE    "https://msdl.microsoft.com/download/symbols/";
>  #define PDB_NAME    "ntkrnlmp.pdb"
> +#define PE_NAME     "ntoskrnl.exe"
>
>  #define INITIAL_MXCSR   0x1f80
>
> @@ -399,6 +400,25 @@ static int write_dump(struct pa_space *ps,
>      return fclose(dmp_file);
>  }
>
> +static bool pe_check_export_name(uint64_t base, void *start_addr,
> +        struct va_space *vs)
> +{
> +    IMAGE_EXPORT_DIRECTORY export_dir;
> +    const char *pe_name;
> +
> +    if (pe_get_data_dir_entry(base, start_addr, IMAGE_FILE_EXPORT_DIRECTORY,
> +                &export_dir, sizeof(export_dir), vs)) {
> +        return false;
> +    }
> +
> +    pe_name = va_space_resolve(vs, base + export_dir.Name);
> +    if (!pe_name) {
> +        return false;
> +    }
> +
> +    return !strcmp(pe_name, PE_NAME);
> +}
> +
>  static int pe_get_pdb_symstore_hash(uint64_t base, void *start_addr,
>          char *hash, struct va_space *vs)
>  {
> @@ -483,6 +503,7 @@ int main(int argc, char *argv[])
>      uint64_t KdDebuggerDataBlock;
>      KDDEBUGGER_DATA64 *kdbg;
>      uint64_t KdVersionBlock;
> +    bool kernel_found = false;
>
>      if (argc != 3) {
>          eprintf("usage:\n\t%s elf_file dmp_file\n", argv[0]);
> @@ -530,11 +551,14 @@ int main(int argc, char *argv[])
>          }
>
>          if (*(uint16_t *)nt_start_addr == 0x5a4d) { /* MZ */
> -            break;
> +            if (pe_check_export_name(KernBase, nt_start_addr, &vs)) {
> +                kernel_found = true;
> +                break;
> +            }
>          }
>      }
>
> -    if (!nt_start_addr) {
> +    if (!kernel_found) {
>          eprintf("Failed to find NT kernel image\n");
>          err = 1;
>          goto out_ps;
> diff --git a/contrib/elf2dmp/pe.h b/contrib/elf2dmp/pe.h
> index 807d006364..71126af1ac 100644
> --- a/contrib/elf2dmp/pe.h
> +++ b/contrib/elf2dmp/pe.h
> @@ -88,6 +88,20 @@ typedef struct IMAGE_NT_HEADERS64 {
>      IMAGE_OPTIONAL_HEADER64 OptionalHeader;
>  } __attribute__ ((packed)) IMAGE_NT_HEADERS64;
>
> +typedef struct IMAGE_EXPORT_DIRECTORY {
> +    uint32_t    Characteristics;
> +    uint32_t    TimeDateStamp;
> +    uint16_t    MajorVersion;
> +    uint16_t    MinorVersion;
> +    uint32_t    Name;
> +    uint32_t    Base;
> +    uint32_t    NumberOfFunctions;
> +    uint32_t    NumberOfNames;
> +    uint32_t    AddressOfFunctions;
> +    uint32_t    AddressOfNames;
> +    uint32_t    AddressOfNameOrdinals;
> +} __attribute__ ((packed)) IMAGE_EXPORT_DIRECTORY;
> +
>  typedef struct IMAGE_DEBUG_DIRECTORY {
>      uint32_t Characteristics;
>      uint32_t TimeDateStamp;
> @@ -102,6 +116,7 @@ typedef struct IMAGE_DEBUG_DIRECTORY {
>  #define IMAGE_DEBUG_TYPE_CODEVIEW   2
>  #endif
>
> +#define IMAGE_FILE_EXPORT_DIRECTORY 0
>  #define IMAGE_FILE_DEBUG_DIRECTORY  6
>
>  typedef struct guid_t {
> --
> 2.31.1
>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]