Introduce bug
This commit is contained in:
45
vuln.c
45
vuln.c
@@ -125,28 +125,35 @@ void write_instr(uint8_t *code, size_t *offset, const uint8_t *instr, size_t ins
|
|||||||
|
|
||||||
void gen_3B_native_instr(uint8_t opcode, uint8_t reg1_id, uint8_t reg2_id, uint8_t *code, size_t *offset) {
|
void gen_3B_native_instr(uint8_t opcode, uint8_t reg1_id, uint8_t reg2_id, uint8_t *code, size_t *offset) {
|
||||||
// REW.X prefix (we use 64bit registers) + upper bit of the second register id + upper bit of the first register id
|
// REW.X prefix (we use 64bit registers) + upper bit of the second register id + upper bit of the first register id
|
||||||
size_t native_instr = 0b01001000L + (EXTRACT_REX_BIT(reg2_id) << 2) + EXTRACT_REX_BIT(reg1_id);
|
code[*offset] = 0b01001000 + (EXTRACT_REX_BIT(reg2_id) << 2) + EXTRACT_REX_BIT(reg1_id);
|
||||||
native_instr += opcode << 8; // opcode
|
code[*offset + 1] = opcode;
|
||||||
// registers: direct addressing + lower 3 bit of second reg id + lower 3 bit of first reg id
|
// registers: direct addressing + second reg id + first reg id
|
||||||
native_instr += (0b11000000L + ((reg2_id & 0b111) << 3) + (reg1_id & 0b111)) << 16;
|
code[*offset + 2] = 0b11000000 + (reg2_id << 3) + reg1_id;
|
||||||
|
*offset += 3;
|
||||||
|
}
|
||||||
|
|
||||||
write_instr(code, offset, (uint8_t *)&native_instr, 3);
|
void gen_immediate_native_instr(uint8_t opcode, uint8_t reg_id, uint32_t imm, uint8_t *code, size_t *offset) {
|
||||||
native_instr = 0;
|
code[*offset] = 0b01001000 + EXTRACT_REX_BIT(reg_id); // REW.X prefix (we use 64bit registers) + upper bit of the first register id
|
||||||
|
code[*offset + 1] = opcode;
|
||||||
|
code[*offset + 2] = 0b11000000L + (reg_id & 0b111); // registers: direct addressing + lower 3 bit of first reg id
|
||||||
|
*(uint32_t *)(code + *offset + 3) = imm; // immediate
|
||||||
|
*offset += 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gen_code(uint8_t *code, Instruction *program, size_t program_len) {
|
void gen_code(uint8_t *code, Instruction *program, size_t program_len) {
|
||||||
// https://pyokagan.name/blog/2019-09-20-x86encoding/
|
// guides on how x64 instructions are encoded:
|
||||||
// https://wiki.osdev.org/X86-64_Instruction_Encoding
|
// https://wiki.osdev.org/X86-64_Instruction_Encoding
|
||||||
|
// https://pyokagan.name/blog/2019-09-20-x86encoding/
|
||||||
|
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
size_t acc = 0;
|
uint32_t acc = 0;
|
||||||
size_t native_instr = 0;
|
|
||||||
uint8_t reg1_id;
|
uint8_t reg1_id;
|
||||||
uint8_t reg2_id;
|
uint8_t reg2_id;
|
||||||
|
|
||||||
// prolog: zero out registers
|
// prolog: zero out registers
|
||||||
for (Register reg = Adelheid; reg < COUNT_REGISTERS; ++reg) {
|
for (Register reg = Adelheid; reg < COUNT_REGISTERS; ++reg) {
|
||||||
// xor reg, reg
|
// mov reg, 0
|
||||||
gen_3B_native_instr(0x31, register_id_lookup[reg], register_id_lookup[reg], code, &offset);
|
gen_immediate_native_instr(0xc7, register_id_lookup[reg], 0, code, &offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t pc = 0; pc < program_len; ++pc) {
|
for (size_t pc = 0; pc < program_len; ++pc) {
|
||||||
@@ -162,13 +169,7 @@ void gen_code(uint8_t *code, Instruction *program, size_t program_len) {
|
|||||||
acc += program[pc].imm;
|
acc += program[pc].imm;
|
||||||
} else {
|
} else {
|
||||||
// add reg, acc
|
// add reg, acc
|
||||||
reg1_id = register_id_lookup[instr.reg1];
|
gen_immediate_native_instr(0x81, register_id_lookup[instr.reg1], instr.imm + acc, code, &offset);
|
||||||
native_instr = (0b01001000L + EXTRACT_REX_BIT(reg1_id)); // REW.X prefix (we use 64bit registers) + upper bit of the first register id
|
|
||||||
native_instr += 0x81L << 8; // opcode
|
|
||||||
native_instr += (0b11000000L + (reg1_id & 0b111)) << 16; // registers: direct addressing + lower 3 bit of first reg id
|
|
||||||
native_instr += ((size_t)program[pc].imm + acc) << 24; // immediate
|
|
||||||
write_instr(code, &offset, (uint8_t *)&native_instr, 7);
|
|
||||||
native_instr = 0;
|
|
||||||
acc = 0;
|
acc = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -191,13 +192,7 @@ void gen_code(uint8_t *code, Instruction *program, size_t program_len) {
|
|||||||
if (pc < program_len && program[pc + 1].opcode == LOADI && instr.reg1 == program[pc + 1].reg1)
|
if (pc < program_len && program[pc + 1].opcode == LOADI && instr.reg1 == program[pc + 1].reg1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
reg1_id = register_id_lookup[instr.reg1];
|
gen_immediate_native_instr(0xc7, register_id_lookup[instr.reg1], instr.imm, code, &offset);
|
||||||
native_instr = (0b01001000L + EXTRACT_REX_BIT(reg1_id)); // REW.X prefix (we use 64bit registers) + upper bit of the first register id
|
|
||||||
native_instr += 0xc7 << 8; // opcode
|
|
||||||
native_instr += (0b11000000L + (reg1_id & 0b111)) << 16; // registers: direct addressing + lower 3 bit of first reg id
|
|
||||||
native_instr += ((size_t)program[pc].imm) << 24; // immediate
|
|
||||||
write_instr(code, &offset, (uint8_t *)&native_instr, 7);
|
|
||||||
native_instr = 0;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
puts("Found invalid instruction!");
|
puts("Found invalid instruction!");
|
||||||
|
|||||||
Reference in New Issue
Block a user