-
Notifications
You must be signed in to change notification settings - Fork 163
Open
Description
xed_agen() uses the address of the instruction instead of the one after the instruction in eip-relative addresses. There was a similar bug for the 64-bit case with rip. It appears that the previous bug fix missed the 32-bit case. The following prorgram reproduces the bug.
#define DEBUG 1 // Cause failed assertion to abort program.
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/user.h>
#include "third_party/libxed/xed-interface.h"
xed_uint64_t agen_reg_callback(xed_reg_enum_t reg, void* context,
xed_bool_t* error) {
*error = 0;
struct user_regs_struct* regs = (struct user_regs_struct*)context;
// The only register needed for the example instruction is EIP.
switch (reg) {
case XED_REG_EIP:
return (uint32_t)regs->rip;
default:
*error = 1;
return 0;
}
}
xed_uint64_t agen_segment_callback(xed_reg_enum_t reg, void* context,
xed_bool_t* error) {
// Our example instruction does not use any segment register.
*error = 1;
return 0;
}
int main(int argc, char** argv) {
xed_tables_init();
xed_agen_register_callback(agen_reg_callback, agen_segment_callback);
// mov 0x0(%eip),%al
const static uint8_t insn_bytes[] = {0x67, 0x8a, 0x05, 0x00,
0x00, 0x00, 0x00};
xed_decoded_inst_t insn;
xed_decoded_inst_zero(&insn);
xed_decoded_inst_set_mode(&insn, XED_MACHINE_MODE_LONG_64,
XED_ADDRESS_WIDTH_64b);
xed_error_enum_t xed_error =
xed_decode(&insn, insn_bytes, sizeof(insn_bytes));
assert(xed_error == XED_ERROR_NONE);
assert(xed_decoded_inst_valid(&insn));
xed_uint64_t address;
struct user_regs_struct regs;
memset(®s, 0, sizeof(regs));
const uint32_t kFakeRip = 0x1000; // Must fit in 32 bits.
regs.rip = kFakeRip;
xed_error = xed_agen(&insn, 0, ®s, &address);
assert(xed_error == XED_ERROR_NONE);
// The expected value of address 0(%eip) is kFakeRip + 7.
uint64_t expected_address = kFakeRip + xed_decoded_inst_get_length(&insn);
printf("address = 0x%lx, expected = 0x%lx\n", address, expected_address);
return address == expected_address ? EXIT_SUCCESS : EXIT_FAILURE;
}
Metadata
Metadata
Assignees
Labels
No labels