[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