/* returns a windows PE export from an RVA*/ char* windows_rva_to_export( vmi_instance_t vmi, addr_t rva, const access_context_t *ctx) { access_context_t _ctx = *ctx; struct export_table et; addr_t et_rva; size_t et_size; // get export table structure if (peparse_get_export_table(vmi, ctx, &et, &et_rva, &et_size) != VMI_SUCCESS) { dbprint(VMI_DEBUG_PEPARSE, "--PEParse: failed to get export table\n"); return NULL; } if (rva>=et_rva && rva < et_rva+et_size) { dbprint(VMI_DEBUG_PEPARSE, "--PEParse: symbol @ 0x%"PRIx64" is forwarded\n", ctx->addr+rva); return NULL; } addr_t base1 = ctx->addr + et.address_of_names; addr_t base2 = ctx->addr + et.address_of_name_ordinals; addr_t base3 = ctx->addr + et.address_of_functions; uint32_t i = 0; for (; i < et.number_of_functions; ++i) { uint32_t name_rva = 0; uint16_t ordinal = 0; uint32_t loc = 0; _ctx.addr = base2 + i * sizeof(uint16_t); if (VMI_FAILURE==vmi_read_16(vmi, &_ctx, &ordinal)) continue; _ctx.addr = base3 + ordinal * sizeof(uint32_t); if (VMI_FAILURE==vmi_read_32(vmi, &_ctx, &loc)) continue; if (loc==rva) { _ctx.addr = base1 + i * sizeof(uint32_t); if (i < et.number_of_names && VMI_SUCCESS==vmi_read_32(vmi, &_ctx, &name_rva) && name_rva) { _ctx.addr = ctx->addr + name_rva; return vmi_read_str(vmi, &_ctx); } dbprint(VMI_DEBUG_PEPARSE, "--PEParse: symbol @ 0x%"PRIx64" is exported by ordinal only\n", ctx->addr+rva); break; } } return NULL; }
/* returns a windows PE export from an RVA*/ char* windows_rva_to_export( vmi_instance_t vmi, addr_t rva, addr_t base_vaddr, vmi_pid_t pid) { struct export_table et; addr_t et_rva; size_t et_size; int aon_index = -1; int aof_index = -1; char* symbol = NULL; // get export table structure if (peparse_get_export_table(vmi, base_vaddr, pid, &et, &et_rva, &et_size) != VMI_SUCCESS) { dbprint(VMI_DEBUG_MISC, "--PEParse: failed to get export table\n"); return NULL; } if(rva>=et_rva && rva < et_rva+et_size) { dbprint(VMI_DEBUG_MISC, "--PEParse: symbol @ %u:0x%"PRIx64" is forwarded\n", pid, base_vaddr+rva); return NULL; } addr_t base1 = base_vaddr + et.address_of_names; addr_t base2 = base_vaddr + et.address_of_name_ordinals; addr_t base3 = base_vaddr + et.address_of_functions; uint32_t i = 0; for (; i < et.number_of_functions; ++i) { uint32_t name_rva = 0; uint16_t ordinal = 0; uint32_t loc = 0; if(VMI_FAILURE==vmi_read_16_va(vmi, base2 + i * sizeof(uint16_t), pid, &ordinal)) continue; if(VMI_FAILURE==vmi_read_32_va(vmi, base3 + ordinal + sizeof(uint32_t), pid, &loc)) continue; if(loc==rva) { if(i < et.number_of_names && VMI_SUCCESS==vmi_read_32_va(vmi, base1 + i * sizeof(uint32_t), pid, &name_rva) && name_rva) { symbol = rva_to_string(vmi, (addr_t)name_rva, base_vaddr, pid); return symbol; } dbprint(VMI_DEBUG_MISC, "--PEParse: symbol @ %u:0x%"PRIx64" is exported by ordinal only\n", pid, base_vaddr+rva); break; } } return NULL; }
/* returns the rva value for a windows PE export */ status_t windows_export_to_rva( vmi_instance_t vmi, const access_context_t *ctx, const char *symbol, addr_t *rva) { struct export_table et; addr_t et_rva; size_t et_size; int aon_index = -1; int aof_index = -1; // get export table structure if (peparse_get_export_table(vmi, ctx, &et, &et_rva, &et_size) != VMI_SUCCESS) { dbprint(VMI_DEBUG_PEPARSE, "--PEParse: failed to get export table\n"); return VMI_FAILURE; } // find AddressOfNames index for export symbol aon_index = get_aon_index(vmi, symbol, &et, ctx); if ( -1 == aon_index ) { dbprint(VMI_DEBUG_PEPARSE, "--PEParse: failed to get aon index\n"); return VMI_FAILURE; } // find AddressOfFunctions index for export symbol aof_index = get_aof_index(vmi, aon_index, &et, ctx); if ( -1 == aof_index ) { dbprint(VMI_DEBUG_PEPARSE, "--PEParse: failed to get aof index\n"); return VMI_FAILURE; } // find RVA value for export symbol if (VMI_SUCCESS==get_export_rva(vmi, rva, aof_index, &et, ctx)) { // handle forwarded functions // If the function's RVA is inside the exports section (as given by the // VirtualAddress and Size fields in the idd), the symbol is forwarded. if (*rva>=et_rva && *rva < et_rva+et_size) { dbprint(VMI_DEBUG_PEPARSE, "--PEParse: %s @ 0x%p is forwarded\n", symbol, ctx); return VMI_FAILURE; } else { return VMI_SUCCESS; } } else { return VMI_FAILURE; } }
/* returns the rva value for a windows PE export */ status_t windows_export_to_rva( vmi_instance_t vmi, addr_t base_vaddr, vmi_pid_t pid, const char *symbol, addr_t *rva) { struct export_table et; addr_t et_rva; size_t et_size; int aon_index = -1; int aof_index = -1; // get export table structure if (peparse_get_export_table(vmi, base_vaddr, pid, &et, &et_rva, &et_size) != VMI_SUCCESS) { dbprint(VMI_DEBUG_MISC, "--PEParse: failed to get export table\n"); return VMI_FAILURE; } // find AddressOfNames index for export symbol if ((aon_index = get_aon_index(vmi, symbol, &et, base_vaddr, pid)) == -1) { dbprint(VMI_DEBUG_MISC, "--PEParse: failed to get aon index\n"); return VMI_FAILURE; } // find AddressOfFunctions index for export symbol if ((aof_index = get_aof_index(vmi, aon_index, &et, base_vaddr, pid)) == -1) { dbprint(VMI_DEBUG_MISC, "--PEParse: failed to get aof index\n"); return VMI_FAILURE; } // find RVA value for export symbol if(VMI_SUCCESS==get_export_rva(vmi, rva, aof_index, &et, base_vaddr, pid)) { // handle forwarded functions // If the function's RVA is inside the exports section (as given by the // VirtualAddress and Size fields in the idd), the symbol is forwarded. if(*rva>=et_rva && *rva < et_rva+et_size) { dbprint(VMI_DEBUG_MISC, "--PEParse: %s @ %u:0x%"PRIx64" is forwarded\n", symbol, pid, base_vaddr); return VMI_FAILURE; } else { return VMI_SUCCESS; } } else { return VMI_FAILURE; } }