Exemplo n.º 1
0
status_t
peparse_get_export_table(
    vmi_instance_t vmi,
    addr_t base_vaddr,
    vmi_pid_t pid,
    struct export_table *et,
    addr_t *export_table_rva,
    size_t *export_table_size)
{
    // Note: this function assumes a "normal" PE where all the headers are in
    // the first page of the PE and the field DosHeader.OffsetToPE points to
    // an address in the first page.

    addr_t export_header_rva = 0;
    addr_t export_header_va = 0;
    size_t export_header_size = 0;
    size_t nbytes = 0;

#define MAX_HEADER_BYTES 1024   // keep under 1 page
    uint8_t image[MAX_HEADER_BYTES];

    if(VMI_FAILURE == peparse_get_image_virt(vmi, base_vaddr, pid, MAX_HEADER_BYTES, image)) {
        return VMI_FAILURE;
    }

    void *optional_header = NULL;
    uint16_t magic = 0;

    peparse_assign_headers(image, NULL, NULL, &magic, &optional_header, NULL, NULL);
    export_header_rva = peparse_get_idd_rva(IMAGE_DIRECTORY_ENTRY_EXPORT, &magic, optional_header, NULL, NULL);
    export_header_size = peparse_get_idd_size(IMAGE_DIRECTORY_ENTRY_EXPORT, &magic, optional_header, NULL, NULL);

    if(export_table_rva) {
        *export_table_rva=export_header_rva;
    }

    if(export_table_size) {
        *export_table_size=export_header_size;
    }

    /* Find & read the export header; assume a different page than the headers */
    export_header_va = base_vaddr + export_header_rva;

    dbprint
        (VMI_DEBUG_MISC, "--PEParse: found export table at [VA] 0x%.16"PRIx64" = 0x%.16"PRIx64" + 0x%"PRIx64"\n",
         export_header_va, ((windows_instance_t)vmi->os_data)->ntoskrnl_va,
         export_header_rva);

    nbytes = vmi_read_va(vmi, export_header_va, pid, et, sizeof(*et));
    if (nbytes != sizeof(struct export_table)) {
        dbprint(VMI_DEBUG_MISC, "--PEParse: failed to map export header\n");
        return VMI_FAILURE;
    }

    /* sanity check */
    if (et->export_flags || !et->name) {
        dbprint(VMI_DEBUG_MISC, "--PEParse: bad export directory table\n");
        return VMI_FAILURE;
    }

    return VMI_SUCCESS;
}
Exemplo n.º 2
0
status_t
peparse_get_export_table(
    vmi_instance_t vmi,
    const access_context_t *ctx,
    struct export_table *et,
    addr_t *export_table_rva,
    size_t *export_table_size)
{
    // Note: this function assumes a "normal" PE where all the headers are in
    // the first page of the PE and the field DosHeader.OffsetToPE points to
    // an address in the first page.

    access_context_t _ctx = *ctx;
    addr_t export_header_rva = 0;
    size_t export_header_size = 0;

#define MAX_HEADER_BYTES 1024   // keep under 1 page
    uint8_t image[MAX_HEADER_BYTES];

    if (VMI_FAILURE == peparse_get_image(vmi, ctx, MAX_HEADER_BYTES, image)) {
        return VMI_FAILURE;
    }

    void *optional_header = NULL;
    uint16_t magic = 0;

    peparse_assign_headers(image, NULL, NULL, &magic, &optional_header, NULL, NULL);
    export_header_rva = peparse_get_idd_rva(IMAGE_DIRECTORY_ENTRY_EXPORT, &magic, optional_header, NULL, NULL);
    export_header_size = peparse_get_idd_size(IMAGE_DIRECTORY_ENTRY_EXPORT, &magic, optional_header, NULL, NULL);

    if (export_table_rva) {
        *export_table_rva=export_header_rva;
    }

    if (export_table_size) {
        *export_table_size=export_header_size;
    }

    dbprint(VMI_DEBUG_PEPARSE, "--PEParse: DLL base 0x%.16"PRIx64". Export header [RVA] 0x%.16"PRIx64". Size %" PRIu64 ".\n",
            ctx->addr, export_header_rva, export_header_size);

    _ctx.addr = ctx->addr + export_header_rva;
    if ( VMI_FAILURE == vmi_read(vmi, &_ctx,  sizeof(struct export_table), et, NULL) ) {
        dbprint(VMI_DEBUG_PEPARSE, "--PEParse: failed to map export header\n");

        /*
         * Sometimes Windows maps the export table on page-boundaries,
         * such that the first export_flags field (which is reserved) is.
         * not actually accessible (the page is not mapped). See Issue #260.
         */
        if (!((_ctx.addr+4) & 0xfff)) {
            dbprint(VMI_DEBUG_PEPARSE, "--PEParse: export table is mapped on page boundary\n");
            _ctx.addr += 4;
            if ( VMI_FAILURE == vmi_read(vmi, &_ctx, sizeof(struct export_table)-4, (void*)((char*)et+4), NULL) ) {
                dbprint(VMI_DEBUG_PEPARSE, "--PEParse: still failed to map export header\n");
                return VMI_FAILURE;
            }

            // Manually set the reserved field to zero in this case
            et->export_flags = 0;
        } else {
            return VMI_FAILURE;
        }
    }

    /* sanity check */
    if (et->export_flags || !et->name) {
        dbprint(VMI_DEBUG_PEPARSE, "--PEParse: bad export directory table\n");
        return VMI_FAILURE;
    }

    return VMI_SUCCESS;
}