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

Re: [Xen-devel] [PATCH V2] kdd.c: Add support for initial handshake in KD protocol for Win 7, 8 and 10 (64 bit)



On Thu, 14 Nov 2019 at 04:57, Julian Tuminaro <julian.tuminaro@xxxxxxxxx> wrote:
>
> From: Julian Tuminaro and Jenish Rakholiya <julian.tuminaro@xxxxxxxxx and 
> rakholiyajenish.07@xxxxxxxxx>
>
> Current implementation of find_os is based on the hard-coded values for
> different Windows version. It uses the value for get the address to
> start looking for DOS header in the given specified range. However, this
> is not scalable to all version of Windows as it will require us to keep
> adding new entries and also due to KASLR, chances of not hitting the PE
> header is significant. We implement a way for 64-bit systems to use IDT
> entry to get a valid exception/interrupt handler and then move back into
> the memory to find the valid DOS header. Since IDT entries are protected
> by PatchGuard, we think our assumption that IDT entries will not be
> corrupted is valid for our purpose. Once we have the image base, we
> search for the DBGKD_GET_VERSION64 structure type in .data section to
> get information required for handshake.
>
> Currently, this is a work in progress feature and current patch only
> supports the handshake and memory read/write on 64-bit systems.
>
> NOTE: This is the Updated version of the previous patch submitted
> NOTE: This has currently been only tested when debugging was not enabled
> on the guest Windows.
>
> Signed-off-by: Jenish Rakholiya <rjenish@xxxxxxx>
> Signed-off-by: Julian Tuminaro <jtuminar@xxxxxxxxxxxxxx>

LGTM.

Reviewed-by: Paul Durrant <paul@xxxxxxx>

> ---
>  tools/debugger/kdd/kdd.c | 392 ++++++++++++++++++++++++++++++++++++---
>  1 file changed, 366 insertions(+), 26 deletions(-)
>
> diff --git a/tools/debugger/kdd/kdd.c b/tools/debugger/kdd/kdd.c
> index fb8c645355..6d3febefda 100644
> --- a/tools/debugger/kdd/kdd.c
> +++ b/tools/debugger/kdd/kdd.c
> @@ -41,6 +41,7 @@
>  #include <errno.h>
>  #include <inttypes.h>
>  #include <netdb.h>
> +#include <stddef.h>
>
>  #include <sys/socket.h>
>  #include <sys/types.h>
> @@ -51,6 +52,16 @@
>
>  #include "kdd.h"
>
> +/*
> + * TODO: kdd_os is a type which is used to represent os array. Adding a
> + * variable here would result in adding a new field to each element in array.
> + * However, since most of the fields are part of the same struct that we are
> + * trying to read from memory, we have added kddl to this structure. If
> + * required, we can possibly separate the kddl value to someplace else
> + *
> + * We also use kddl of size uint32_t which is actually used to represent the
> + * offset from image base rather than actual address
> + */
>  /* Windows version details */
>  typedef struct {
>      uint32_t build;
> @@ -62,6 +73,7 @@ typedef struct {
>      uint32_t version;           /* +-> NtBuildNumber */
>      uint32_t modules;           /* +-> PsLoadedModuleList */
>      uint32_t prcbs;             /* +-> KiProcessorBlock */
> +    uint32_t kddl;              /* +-> KdDebuggerList */
>  } kdd_os;
>
>  /* State of the debugger stub */
> @@ -85,6 +97,117 @@ typedef struct {
>      kdd_os os;                                 /* OS-specific magic numbers 
> */
>  } kdd_state;
>
> +/**
> + * @brief Structure to represent DBGKD_GET_VERSION64
> + *
> + * reference: 
> https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdbgexts/ns-wdbgexts-_dbgkd_get_version64
> + */
> +typedef struct {
> +    uint16_t MajorVersion;                     /* usually 0xf for free build 
> */
> +    uint16_t MinorVersion;                      /* build number of target OS 
> */
> +    uint8_t ProtocolVersion;             /* version of the debugger protocol 
> */
> +    uint8_t KdSecondaryVersion;                  /* secondary version number 
> */
> +    uint16_t Flags;    /* set of bit flags for the current debugging session 
> */
> +    uint16_t MachineType;                  /* type of the target's processor 
> */
> +    uint8_t MaxPacketType;     /* one plus the highest number for a debugger 
> */
> +                                     /* packet type recognized by the target 
> */
> +    uint8_t MaxStateChagne;       /* one plus the highest number for a state 
> */
> +                                           /* change generated by the target 
> */
> +    uint8_t MaxManipulate;   /* one more that the highest number, recognized 
> */
> +                    /* by the target, for a command to manipulate the target 
> */
> +    uint8_t Simulation;    /* indication if target is in simulated execution 
> */
> +    uint16_t Unused[1];
> +    uint64_t KernBase;                   /* base address of the kernel image 
> */
> +    uint64_t PsLoadedModuleList;             /* value of the kernel variable 
> */
> +                                                       /* PsLoadedModuleList 
> */
> +    uint64_t DebuggerDataList;               /* value of the kernel variable 
> */
> +                                                      /* KdDebuggerDataBlock 
> */
> +} PACKED DBGKD_GET_VERSION64;
> +
> +/**
> + * @brief Structure to represent the section in PE headers
> + *
> + * reference: 
> https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#section-table-section-headers
> + */
> +typedef struct {
> +    uint8_t Name[8];                /* name of section */
> +    uint32_t VirtualSize;           /* total size of section in memory */
> +    uint32_t VirtualAddr;           /* offset from image base */
> +    uint32_t SizeOfRawData;         /* size of section in for object files */
> +    uint32_t PointerToRawData;      /* file pointer to first page in COFF */
> +    uint32_t PointerToRelocations;  /* file pointer to beginning of 
> relocation entry */
> +    uint32_t PointerToLinenumbers;  /* file pointer to the beginning of 
> line-number entries */
> +    uint16_t NumberOfRelocations;   /* number of relocation entries for the 
> section */
> +    uint16_t NumberOfLinenumbers;   /* number of line-number entries for the 
> section */
> +    uint32_t Characteristics;       /* flags that describe the 
> characteristics of the section */
> +} PACKED PE_SECTION_ENTRY;
> +
> +/**
> + * @brief Size of pointer on 64 machine
> + */
> +#define SIZE_PTR64 8
> +
> +/**
> + * @brief Size of pointer on 32 machine
> + */
> +#define SIZE_PTR32 4
> +
> +
> +/*****************************************************************************
> + * PE and DOS Header related offsets
> + */
> +
> +/**
> + * @brief Offset in DOS header to look for PE header
> + */
> +#define DOS_HDR_PE_OFF 0x3c
> +
> +/**
> + * @brief Size of PE header offset field in DOS header
> + */
> +#define DOS_HDR_PE_SZ 4
> +
> +/**
> + * @brief Offset of number of sections field in PE header
> + */
> +#define PE_NUM_SECTION_OFF 0x6
> +
> +/**
> + * @brief Size of number of sections field in PE header
> + */
> +#define PE_NUM_SECTION_SZ 2
> +
> +/**
> + * @brief Offset of optional header size field in PE header
> + */
> +#define PE_OPT_HDR_SZ_OFF 0x14
> +
> +/**
> + * @brief Size of optional header size field in PE header
> + */
> +#define PE_OPT_HDR_SZ_SZ 2
> +
> +/**
> + * @brief Size of PE header
> + */
> +#define PE_HDR_SZ 0x18
> +
> +/**
> + * @brief MZ header
> + */
> +#define MZ_HEADER 0x5a4d
> +
> +/**
> + * @brief Limit on the number of sections to look for while iterating through
> + * PE sections
> + */
> +#define NUM_SECT_LIMIT 100
> +
> +/**
> + * @brief Major Version for the DBGKD_GET_VERSION64 structure
> + */
> +#define NT_MAJOR_VERSION 0xf
> +
>  
> /*****************************************************************************
>   *  Utility functions
>   */
> @@ -293,41 +416,41 @@ static uint32_t kdd_write_virtual(kdd_state *s, int 
> cpuid, uint64_t addr,
>   */
>
>  static kdd_os os[] = {
> - /* Build  64 MP Name                 &Kernel search base    Range       
> +Version    +Modules    +PRCBs (64b) */
> -    {2195, 0, 0, "w2k sp4 x32 UP",    0xffffffff80400000ULL, 0x00000000, 
> 0x0006d57c, 0x0006e1b8, 0x0},
> -    {2195, 0, 1, "w2k sp4 x32 SMP",   0xffffffff80400000ULL, 0x00000000, 
> 0x0006fa1c, 0x00084520, 0x0},
> + /* Build  64 MP Name                 &Kernel search base    Range       
> +Version    +Modules    +PRCBs (64b)  +KDDL */
> +    {2195, 0, 0, "w2k sp4 x32 UP",    0xffffffff80400000ULL, 0x00000000, 
> 0x0006d57c, 0x0006e1b8, 0x0,          0},
> +    {2195, 0, 1, "w2k sp4 x32 SMP",   0xffffffff80400000ULL, 0x00000000, 
> 0x0006fa1c, 0x00084520, 0x0,          0},
>      // PAE/UP, PAE/SMP
>
> -    {2600, 0, 0, "xp sp2 x32 UP",     0xffffffff804d7000ULL, 0x00000000, 
> 0x00075568, 0x00083b20, 0x0},
> -    {2600, 0, 1, "xp sp2 x32 SMP",    0xffffffff804d7000ULL, 0x00000000, 
> 0x0007d0e8, 0x0008d4a0, 0x0},
> +    {2600, 0, 0, "xp sp2 x32 UP",     0xffffffff804d7000ULL, 0x00000000, 
> 0x00075568, 0x00083b20, 0x0,          0},
> +    {2600, 0, 1, "xp sp2 x32 SMP",    0xffffffff804d7000ULL, 0x00000000, 
> 0x0007d0e8, 0x0008d4a0, 0x0,          0},
>      // PAE/UP, PAE/SMP
>
> -    {2600, 0, 0, "xp sp3 x32 UP",     0xffffffff804d7000ULL, 0x00000000, 
> 0x00075be8, 0x000841c0, 0x0},
> -    {2600, 0, 1, "xp sp3 x32 SMP",    0xffffffff804d7000ULL, 0x00000000, 
> 0x0007c0e8, 0x0008c4c0, 0x0},
> -    {2600, 0, 0, "xp sp3 x32p UP",    0xffffffff804d7000ULL, 0x00000000, 
> 0x0006e8e8, 0x0007cfc0, 0x0},
> -    {2600, 0, 1, "xp sp3 x32p SMP",   0xffffffff804d7000ULL, 0x00000000, 
> 0x000760e8, 0x00086720, 0x0},
> +    {2600, 0, 0, "xp sp3 x32 UP",     0xffffffff804d7000ULL, 0x00000000, 
> 0x00075be8, 0x000841c0, 0x0,          0},
> +    {2600, 0, 1, "xp sp3 x32 SMP",    0xffffffff804d7000ULL, 0x00000000, 
> 0x0007c0e8, 0x0008c4c0, 0x0,          0},
> +    {2600, 0, 0, "xp sp3 x32p UP",    0xffffffff804d7000ULL, 0x00000000, 
> 0x0006e8e8, 0x0007cfc0, 0x0,          0},
> +    {2600, 0, 1, "xp sp3 x32p SMP",   0xffffffff804d7000ULL, 0x00000000, 
> 0x000760e8, 0x00086720, 0x0,          0},
>
> -    {3790, 0, 0, "w2k3 sp2 x32 UP",   0xffffffff80800000ULL, 0x00000000, 
> 0x00097128, 0x000a8e48, 0x0},
> -    {3790, 0, 1, "w2k3 sp2 x32 SMP",  0xffffffff80800000ULL, 0x00000000, 
> 0x0009d128, 0x000af9c8, 0x0},
> -    {3790, 0, 0, "w2k3 sp2 x32p UP",  0xffffffff80800000ULL, 0x00000000, 
> 0x0008e128, 0x0009ffa8, 0x0},
> -    {3790, 0, 1, "w2k3 sp2 x32p SMP", 0xffffffff80800000ULL, 0x00000000, 
> 0x00094128, 0x000a6ea8, 0x0},
> -    {3790, 1, 0, "w2k3 sp2 x64 UP",   0xfffff80001000000ULL, 0x00000000, 
> 0x001765d0, 0x0019aae0, 0x0017b100},
> -    {3790, 1, 1, "w2k3 sp2 x64 SMP",  0xfffff80001000000ULL, 0x00000000, 
> 0x001b05e0, 0x001d5100, 0x001b5300},
> +    {3790, 0, 0, "w2k3 sp2 x32 UP",   0xffffffff80800000ULL, 0x00000000, 
> 0x00097128, 0x000a8e48, 0x0,          0},
> +    {3790, 0, 1, "w2k3 sp2 x32 SMP",  0xffffffff80800000ULL, 0x00000000, 
> 0x0009d128, 0x000af9c8, 0x0,          0},
> +    {3790, 0, 0, "w2k3 sp2 x32p UP",  0xffffffff80800000ULL, 0x00000000, 
> 0x0008e128, 0x0009ffa8, 0x0,          0},
> +    {3790, 0, 1, "w2k3 sp2 x32p SMP", 0xffffffff80800000ULL, 0x00000000, 
> 0x00094128, 0x000a6ea8, 0x0,          0},
> +    {3790, 1, 0, "w2k3 sp2 x64 UP",   0xfffff80001000000ULL, 0x00000000, 
> 0x001765d0, 0x0019aae0, 0x0017b100,   0},
> +    {3790, 1, 1, "w2k3 sp2 x64 SMP",  0xfffff80001000000ULL, 0x00000000, 
> 0x001b05e0, 0x001d5100, 0x001b5300,   0},
>
> -    {6000, 0, 1, "vista sp0 x32p",    0xffffffff81800000ULL, 0x00000000, 
> 0x000a4de4, 0x00111db0, 0x0},
> -    {6001, 0, 1, "vista sp1 x32p",    0xffffffff81000000ULL, 0x0f000000, 
> 0x000af0c4, 0x00117c70, 0x0},
> +    {6000, 0, 1, "vista sp0 x32p",    0xffffffff81800000ULL, 0x00000000, 
> 0x000a4de4, 0x00111db0, 0x0,          0},
> +    {6001, 0, 1, "vista sp1 x32p",    0xffffffff81000000ULL, 0x0f000000, 
> 0x000af0c4, 0x00117c70, 0x0,          0},
>
> -    {6001, 1, 1, "w2k8 sp0 x64",      0xfffff80001000000ULL, 0x0f000000, 
> 0x00140bf0, 0x001c5db0, 0x00229640},
> +    {6001, 1, 1, "w2k8 sp0 x64",      0xfffff80001000000ULL, 0x0f000000, 
> 0x00140bf0, 0x001c5db0, 0x00229640,   0},
>
> -    {7600, 1, 1, "win7 sp0 x64",      0xfffff80001000000ULL, 0x0f000000, 
> 0x001af770, 0x0023de50, 0x002a8900},
> +    {7600, 1, 1, "win7 sp0 x64",      0xfffff80001000000ULL, 0x0f000000, 
> 0x001af770, 0x0023de50, 0x002a8900,   0},
>
> -    {7601, 0, 1, "win7 sp1 x32p",     0xffffffff81800000ULL, 0x0f000000, 
> 0x000524c4, 0x00149850, 0x0},
> -    {7601, 1, 1, "win7 sp1 x64",      0xfffff80001000000ULL, 0x0f000000, 
> 0x001b2770, 0x00240e90, 0x002ab900},
> +    {7601, 0, 1, "win7 sp1 x32p",     0xffffffff81800000ULL, 0x0f000000, 
> 0x000524c4, 0x00149850, 0x0,          0},
> +    {7601, 1, 1, "win7 sp1 x64",      0xfffff80001000000ULL, 0x0f000000, 
> 0x001b2770, 0x00240e90, 0x002ab900,   0},
>  };
>
>  // 1381, 0, 0, "NT4 sp?", 0xffffffff80100000, ?, ?
>
> -static kdd_os unknown_os = {0, 0, 0, "unknown OS", 0, 0, 0, 0, 0};
> +static kdd_os unknown_os = {0, 0, 0, "unknown OS", 0, 0, 0, 0, 0, 0};
>
>  static int check_os(kdd_state *s)
>  {
> @@ -367,11 +490,226 @@ static int check_os(kdd_state *s)
>      return 1;
>  }
>
> +/**
> + * @brief Parse the memory at \a filebase as a valid DOS header and get 
> virtual
> + * address offset and size for any given section name (if it exists)
> + *
> + * @param s Pointer to the kdd_state structure
> + * @param filebase Base address of the file structure
> + * @param sectname Pointer to the section name c-string to look for
> + * @param vaddr Pointer to write the virtual address of section start to
> + * (if found)
> + * @param visze Pointer to write the section size to (if found)
> + *
> + * @return -1 on failure to find the section name
> + * @return 0 on success
> + */
> +static int get_pe64_sections(kdd_state *s, uint64_t filebase, char *sectname,
> +        uint64_t *vaddr, uint32_t *vsize)
> +{
> +    uint64_t pe_hdr = 0;
> +    uint64_t sect_start = 0;
> +    uint16_t num_sections = 0;
> +    uint16_t opt_hdr_sz = 0;
> +    PE_SECTION_ENTRY pe_sect;
> +
> +    if (!s->os.w64)
> +        return -1;
> +
> +    /* read PE header offset */
> +    if (kdd_read_virtual(s, s->cpuid, filebase + DOS_HDR_PE_OFF, 
> DOS_HDR_PE_SZ,
> +                &pe_hdr) != DOS_HDR_PE_SZ)
> +        return -1;
> +
> +    pe_hdr += filebase;
> +
> +    /* read number of sections */
> +    if (kdd_read_virtual(s, s->cpuid, pe_hdr + PE_NUM_SECTION_OFF,
> +                PE_NUM_SECTION_SZ, &num_sections) != PE_NUM_SECTION_SZ)
> +        return -1;
> +
> +    /* read number of section upto a limit */
> +    if (num_sections > NUM_SECT_LIMIT)
> +        num_sections = NUM_SECT_LIMIT;
> +
> +    /* read size of optional header */
> +    if (kdd_read_virtual(s, s->cpuid, pe_hdr + PE_OPT_HDR_SZ_OFF,
> +                PE_OPT_HDR_SZ_SZ, &opt_hdr_sz) != PE_OPT_HDR_SZ_SZ)
> +        return -1;
> +
> +    /* 0x18 is the size of PE header */
> +    sect_start = pe_hdr + PE_HDR_SZ + opt_hdr_sz;
> +
> +    for (int i = 0; i < num_sections; i++) {
> +        if (kdd_read_virtual(s, s->cpuid, sect_start + (i * sizeof(pe_sect)),
> +                    sizeof(pe_sect), &pe_sect) != sizeof(pe_sect))
> +            return -1;
> +
> +        if (!strncmp(sectname, (char *)pe_sect.Name, sizeof(pe_sect.Name))) {
> +            *vaddr = filebase + pe_sect.VirtualAddr;
> +            *vsize = pe_sect.VirtualSize;
> +            return 0;
> +        }
> +    }
> +
> +    return -1;
> +}
> +
> +/**
> + * @brief Get the OS information like base address, minor version,
> + * PsLoadedModuleList and DebuggerDataList (basically the fields of
> + * DBGKD_GET_VERSION64 struture required to do handshake?).
> + *
> + * This is done by reading the IDT entry for divide-by-zero exception and
> + * searching back into the memory for DOS header (which is our kernel base).
> + * Once we have the kernel base, we parse the PE header and look for kernel
> + * base address in the .data section. Once we have possible values, we look 
> for
> + * DBGKD_GET_VERSION64 block by using following heuristics on the address 
> which
> + * has the kernel base:
> + *
> + *  - at address [-0x10], it should have 0xf as the MajorVersion
> + *  - at address [+0x8], it should have a valid kernel memory address 
> pointing
> + *  in .data
> + *  - at address [+0x10], it should have a valid kernel memory address 
> pointing
> + *  in .data
> + *
> + * @param s Pointer to the kdd state
> + */
> +static void get_os_info_64(kdd_state *s)
> +{
> +    kdd_ctrl ctrl;
> +    int ret;
> +    uint64_t buf;
> +    uint64_t idt0_addr;
> +    uint64_t base;
> +    uint64_t caddr;
> +    uint64_t data_base;
> +    uint32_t data_size;
> +    uint64_t modptr = 0;
> +    uint64_t kddl = 0;
> +    uint16_t minor = 0;
> +    uint64_t dbgkd_addr;
> +    DBGKD_GET_VERSION64 dbgkd_get_version64;
> +    /* Maybe 1GB is too big for the limit to search? */
> +    uint32_t search_limit = (1024 * 1024 * 1024) / PAGE_SIZE; 
> /*1GB/PageSize*/
> +    uint64_t efer;
> +
> +    /* if we are not in 64-bit mode, fail */
> +    if (kdd_rdmsr(s->guest, s->cpuid, 0xc0000080, &efer) || !(efer & (1 << 
> 8)))
> +        goto fail;
> +
> +    s->os.w64 = 1;
> +
> +    /* get control registers for our os */
> +    ret = kdd_get_ctrl(s->guest, s->cpuid, &ctrl, s->os.w64);
> +    if (ret)
> +        goto fail;
> +
> +    /* read the div-by-zero handler function address */
> +    kdd_read_virtual(s, s->cpuid, ctrl.c64.idt_base + 8, 8, &buf);
> +    idt0_addr = ((uint64_t)buf << 32) & 0xffffffff00000000;
> +
> +    kdd_read_virtual(s, s->cpuid, ctrl.c64.idt_base, 8, &buf);
> +    idt0_addr |= ((buf >> 32) & 0xffff0000);
> +    idt0_addr |= (buf & 0xffff);
> +
> +    KDD_LOG(s, "idt0 addr: %p\n", (void *)idt0_addr);
> +
> +    /*
> +     * get the page start and look for "MZ" file header - we limit the search
> +     * in 1GB range above the current page base address
> +     */
> +
> +    base = idt0_addr & ~(PAGE_SIZE - 1);
> +    KDD_LOG(s, "%p\n", (void *)base);
> +
> +    while (search_limit) {
> +        uint16_t val;
> +        if (kdd_read_virtual(s, s->cpuid, base, 2, &val) != 2) {
> +            /* just move going back?? this is bad though */
> +            KDD_LOG(s, "ran into unmapped region without finding PE 
> header\n");
> +            goto fail;
> +        }
> +
> +        if (val == MZ_HEADER) // MZ
> +            break;
> +
> +        base -= PAGE_SIZE;
> +        search_limit -= 1;
> +    }
> +
> +    KDD_LOG(s, "base: %p\n", (void *)base);
> +
> +    /* found the data section start */
> +    if (get_pe64_sections(s, base, ".data", &data_base, &data_size))
> +        goto fail;
> +
> +    /* look for addresses which has kernel base written into it */
> +    caddr = data_base;
> +
> +    search_limit = (1024 * 1024 * 512) / SIZE_PTR64;
> +    while (caddr < data_base + data_size && search_limit) {
> +        if (kdd_read_virtual(s, s->cpuid, caddr, SIZE_PTR64, &buf) !=
> +                SIZE_PTR64)
> +            goto fail;     /* reached end and found nothing */
> +
> +        /* if we found base in the memory addresses */
> +        if (buf == base) {
> +            /* read the DBGKD_GET_VERSION64 struct */
> +            dbgkd_addr = caddr - offsetof(DBGKD_GET_VERSION64, KernBase);
> +            if (kdd_read_virtual(s, s->cpuid, dbgkd_addr,
> +                        sizeof(DBGKD_GET_VERSION64), &dbgkd_get_version64) ==
> +                    sizeof(DBGKD_GET_VERSION64)) {
> +                /* check if major version is 0xf */
> +                if (dbgkd_get_version64.MajorVersion == NT_MAJOR_VERSION) {
> +
> +                    /* read minor version, PsLoadedModuleList pointer and
> +                     * DebuggerDataList
> +                     */
> +                    modptr = dbgkd_get_version64.PsLoadedModuleList;
> +                    kddl = dbgkd_get_version64.DebuggerDataList;
> +                    minor = dbgkd_get_version64.MinorVersion;
> +
> +                    /* do heuristic check */
> +                    if (modptr && kddl && modptr != kddl && kddl != base &&
> +                            base != modptr && modptr >= data_base &&
> +                            modptr < (data_base + data_size) &&
> +                            kddl >= data_base &&
> +                            kddl < (data_base + data_size))
> +                        break;
> +                }
> +            }
> +
> +        }
> +
> +        caddr += SIZE_PTR64;
> +        search_limit -= 1;
> +    }
> +
> +    if (caddr < data_base + data_size) {
> +        /* if found, set the field and return */
> +
> +        KDD_LOG(s, "base: %p\n", (void *)base);
> +        KDD_LOG(s, "modules list: %p\n", (void *)modptr);
> +        KDD_LOG(s, "kddl: %p\n", (void *)kddl);
> +        KDD_LOG(s, "minor version: 0x%hx\n", minor);
> +
> +        s->os.base = base;
> +        s->os.modules = modptr - base;
> +        s->os.kddl = kddl - base;
> +        s->os.build = (uint32_t) minor;
> +        return;
> +    }
> +
> +fail:
> +    s->os = unknown_os;
> +}
> +
>  /* Figure out what OS we're dealing with */
>  static void find_os(kdd_state *s)
>  {
>      int i;
> -    uint64_t limit;
> +    uint64_t limit;
>
>      /* We may already have the right one */
>      if (check_os(s))
> @@ -387,7 +725,8 @@ static void find_os(kdd_state *s)
>              if (check_os(s))
>                  return;
>      }
> -    s->os = unknown_os;
> +
> +    get_os_info_64(s);
>  }
>
>
> @@ -534,13 +873,14 @@ static void kdd_handle_handshake(kdd_state *s)
>  {
>      /* Figure out what we're looking at */
>      find_os(s);
> +
>      kdd_send_string(s, "[kdd: %s @0x%"PRIx64"]\r\n", s->os.name, s->os.base);
>
>      /* Respond with some details about the debugger stub we simulate */
>      s->txp.cmd.shake.u1        = 0x01010101;
>      s->txp.cmd.shake.status    = KDD_STATUS_SUCCESS;
>      s->txp.cmd.shake.u2        = 0x02020202;
> -    s->txp.cmd.shake.v_major   = 0xf;
> +    s->txp.cmd.shake.v_major   = NT_MAJOR_VERSION;
>      s->txp.cmd.shake.v_minor   = s->os.build;
>      s->txp.cmd.shake.proto     = 6;
>      s->txp.cmd.shake.flags     = (0x02 /* ??? */
> @@ -555,7 +895,7 @@ static void kdd_handle_handshake(kdd_state *s)
>      s->txp.cmd.shake.u3[2]     = 0x55;
>      s->txp.cmd.shake.kern_addr = s->os.base;
>      s->txp.cmd.shake.mods_addr = s->os.base + s->os.modules;
> -    s->txp.cmd.shake.data_addr = 0; /* Debugger data probably doesn't exist 
> */
> +    s->txp.cmd.shake.data_addr = s->os.kddl ? s->os.base + s->os.kddl : 0;
>
>      KDD_LOG(s, "Client initial handshake: %s\n", s->os.name);
>      kdd_send_cmd(s, KDD_CMD_SHAKE, 0);
> --
> 2.17.1
>

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.