Introduce bug

This commit is contained in:
Johannes Maier
2024-01-13 13:44:11 +01:00
parent 338f0eda4d
commit 50405ab89a

45
vuln.c
View File

@@ -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!");