qemu-devel
[Top][All Lists]
Advanced

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

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


From: Viktor Prutyanov
Subject: Re: [PATCH v1 3/3] contrib/elf2dmp: add PE name check and Windows Server 2022 support
Date: Wed, 22 Feb 2023 22:55:53 +0300

On Wed, Feb 22, 2023 at 10:07 PM Annie.li <annie.li@oracle.com> wrote:
>
>
> On 11/29/2022 7:03 PM, Viktor Prutyanov 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@daynix.com>
> > 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 f3052b3c64..f7de82a03e 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"
>
> As what has been clarified earlier in the meeting, this elf2dmp is only for
> 64bits systems, so the name "ntoskrnl.exe" suffices here. Otherwise, it
> won't work
> for 32bits PAE systems.
>
> A question about elf2dmp on ARM platform, has it been validated there?
>
> Thanks
>
> Annie
>
> >
> >   #define INITIAL_MXCSR   0x1f80
> >
> > @@ -400,6 +401,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)
> >   {
> > @@ -484,6 +504,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]);
> > @@ -531,11 +552,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 {

Hi Annie,

Thank you for the review!
At the moment, elf2dmp only addresses the x86_64 platform.

Best regards,
Viktor Prutyanov



reply via email to

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