Skip to content

Commit

Permalink
The extracted symbols' data is now saved to the output txt file; Over…
Browse files Browse the repository at this point in the history
…hauled the UI; Made the registers window prettier and more functional; Added a new window for showing the symbols, categorized by the memory segments they reside in
  • Loading branch information
alibowndyn committed Sep 27, 2024
1 parent 7e419ad commit c8dce85
Show file tree
Hide file tree
Showing 8 changed files with 518 additions and 95 deletions.
36 changes: 31 additions & 5 deletions src/deserializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,26 @@ def deserialize_mem_layout_and_static_segments(self, str: str) -> None:
text_data = list(map(int, lines[5].split(' ')))
rodata_data = list(map(int, lines[6].split(' ')))

rodata_symbols: list[Symbol] = []
for line in lines[7:]:
parts = line.split(' ')
sym_bytes = list(map(int, parts[2:]))
rodata_symbols.append(Symbol(parts[1], int(parts[0]), len(sym_bytes), sym_bytes))

self._program.static_mem = StaticMemory(
text=TextSegment(
main_addr=int(lines[4]),
addr=text_data[0],
size=text_data[1],
bytes=text_data[2:]),
bytes=text_data[3:],
num_symbols=text_data[2],
symbols=[]),
rodata=MemorySegment(
addr=rodata_data[0],
size=rodata_data[1],
bytes=rodata_data[2:]))
bytes=text_data[3:],
num_symbols=rodata_data[2],
symbols=rodata_symbols))

def deserialize_insns_execution_contexts(self, contexts: list) -> None:
for c in contexts:
Expand All @@ -63,7 +73,6 @@ def deserialize_insns_execution_contexts(self, contexts: list) -> None:
context = create_empty_execution_context()

line_parts = lines[0].split(' ')
print(line_parts)
if (line_parts[0][0] == '#'):
self._program.contexts.append(context)
self._program.ex_info.has_stack_overflowed = 1
Expand All @@ -80,15 +89,32 @@ def deserialize_insns_execution_contexts(self, contexts: list) -> None:

data_data = list(map(int, lines[2].split(' ')))
bss_data = list(map(int, lines[3].split(' ')))

data_symbols: list[Symbol] = []
for line in lines[5:5+data_data[2]]:
parts = line.split(' ')
sym_bytes = list(map(int, parts[2:]))
data_symbols.append(Symbol(parts[1], int(parts[0]), len(sym_bytes), sym_bytes))

bss_symbols: list[Symbol] = []
for line in lines[5+data_data[2]:5+data_data[2]+bss_data[2]]:
parts = line.split(' ')
sym_bytes = list(map(int, parts[2:]))
bss_symbols.append(Symbol(parts[1], int(parts[0]), len(sym_bytes), sym_bytes))

context.dynamic_mem = DynamicMemory(
data=MemorySegment(
addr=data_data[0],
size=data_data[1],
bytes=data_data[2:]),
bytes=data_data[3:],
num_symbols=data_data[2],
symbols=data_symbols),
bss=MemorySegment(
addr=bss_data[0],
size=bss_data[1],
bytes=bss_data[2:]))
bytes=bss_data[3:],
num_symbols=bss_data[2],
symbols=bss_symbols))

insn_data = list(map(int, lines[4].split(' ')))
context.insn = Instruction(
Expand Down
54 changes: 23 additions & 31 deletions src/emu/emu.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,34 +42,6 @@ static uc_err _uc_err_check(uc_err err, const char *expr)



const int regs[] = { UC_X86_REG_RAX, UC_X86_REG_RBX, UC_X86_REG_RCX, UC_X86_REG_RDX, UC_X86_REG_RFLAGS,
UC_X86_REG_RIP, UC_X86_REG_RSP, UC_X86_REG_RBP, UC_X86_REG_RDI, UC_X86_REG_RSI,
UC_X86_REG_R8, UC_X86_REG_R9, UC_X86_REG_R10, UC_X86_REG_R11, UC_X86_REG_R12,
UC_X86_REG_R13, UC_X86_REG_R14, UC_X86_REG_R15 };

#define NUM_OF_REGISTERS_TO_READ ( (int)(sizeof(regs) / sizeof(int)) )
uint64_t reg_contents[NUM_OF_REGISTERS_TO_READ];

#define REG_RAX reg_contents[0]
#define REG_RBX reg_contents[1]
#define REG_RCX reg_contents[2]
#define REG_RDX reg_contents[3]
#define REG_RFLAGS reg_contents[4]
#define REG_RIP reg_contents[5]
#define REG_RSP reg_contents[6]
#define REG_RBP reg_contents[7]
#define REG_RDI reg_contents[8]
#define REG_RSI reg_contents[9]
#define REG_R8 reg_contents[10]
#define REG_R9 reg_contents[11]
#define REG_R10 reg_contents[12]
#define REG_R11 reg_contents[13]
#define REG_R12 reg_contents[14]
#define REG_R13 reg_contents[15]
#define REG_R14 reg_contents[16]
#define REG_R15 reg_contents[17]


uint8_t stack_overflowed = 0;
static void check_stack_overflow(uint64_t address)
{
Expand All @@ -93,14 +65,14 @@ static void check_valid_stack_pointer()
}

/**
* @brief Read and save the contents of the registers listed in `regs`
* @brief Read and save the contents of the registers listed in `x86_64_registers`
*/
static void read_registers()
{
puts("");
for (int i = 0; i < NUM_OF_REGISTERS_TO_READ; i++)
{
if (UC_ERR_CHECK( uc_reg_read(uc, regs[i], &reg_contents[i]) ))
if (UC_ERR_CHECK( uc_reg_read(uc, x86_64_registers[i], &reg_contents[i]) ))
ABORT()

printf(" %ld\n", reg_contents[i]);
Expand All @@ -127,6 +99,25 @@ static void read_stack()
puts("");
}

static void write_symbols_from_dynamic_memory_segments()
{
for (int i = 0; i < mem_layout.data.num_symbols; i++)
{
if (UC_ERR_CHECK( uc_mem_read(uc, mem_layout.data.symbols[i]->addr, mem_layout.data.symbols[i]->bytes, mem_layout.data.symbols[i]->size) ) )
ABORT()

write_symbol_info(mem_layout.data.symbols[i]);
}

for (int i = 0; i < mem_layout.bss.num_symbols; i++)
{
if (UC_ERR_CHECK( uc_mem_read(uc, mem_layout.bss.symbols[i]->addr, mem_layout.bss.symbols[i]->bytes, mem_layout.bss.symbols[i]->size) ) )
ABORT()

write_symbol_info(mem_layout.bss.symbols[i]);
}
}

static int should_stop_emulation(uint64_t address, uint32_t size, __uint128_t insn_bytecode)
{
uint64_t stack_at_rsp = 0;
Expand Down Expand Up @@ -171,7 +162,6 @@ static void hook_insn(uc_engine *uc, uint64_t address, uint32_t size, void *user
write_memory_layout(&mem_layout, STACK_START_ADDR, STACK_END_ADDR, 0);



int index = index_of_memory_address(assembly.addresses, assembly.num_lines, address);
if ( index != -1 )
printf("Isns at address[%#lx]: %s\n", assembly.addresses[index], assembly.lines[index]);
Expand All @@ -185,6 +175,8 @@ static void hook_insn(uc_engine *uc, uint64_t address, uint32_t size, void *user
write_instruction_info(index, size, insn_bytecode);
check_valid_stack_pointer();

write_symbols_from_dynamic_memory_segments();

// if we are about to execute the last `ret` instruction, stop the emulation
if ( should_stop_emulation(address, size, insn_bytecode) )
{
Expand Down
30 changes: 30 additions & 0 deletions src/emu/emu.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,36 @@
// Instruction constants
#define RET_INSN_BYTECODE ( 0xc3 ) // Bytecode for the `ret` instruction

// Registers
static const int x86_64_registers[] = {
UC_X86_REG_RAX, UC_X86_REG_EAX, UC_X86_REG_AX, UC_X86_REG_AH, UC_X86_REG_AL,
UC_X86_REG_RBX, UC_X86_REG_EBX, UC_X86_REG_BX, UC_X86_REG_BH, UC_X86_REG_BL,
UC_X86_REG_RCX, UC_X86_REG_ECX, UC_X86_REG_CX, UC_X86_REG_CH, UC_X86_REG_CL,
UC_X86_REG_RDX, UC_X86_REG_EDX, UC_X86_REG_DX, UC_X86_REG_DH, UC_X86_REG_DL,
UC_X86_REG_RSI, UC_X86_REG_ESI, UC_X86_REG_SI, UC_X86_REG_SIL,
UC_X86_REG_RDI, UC_X86_REG_EDI, UC_X86_REG_DI, UC_X86_REG_DIL,
UC_X86_REG_R8, UC_X86_REG_R8D, UC_X86_REG_R8W, UC_X86_REG_R8B,
UC_X86_REG_R9, UC_X86_REG_R9D, UC_X86_REG_R9W, UC_X86_REG_R9B,
UC_X86_REG_R10, UC_X86_REG_R10D, UC_X86_REG_R10W, UC_X86_REG_R10B,
UC_X86_REG_R11, UC_X86_REG_R11D, UC_X86_REG_R11W, UC_X86_REG_R11B,
UC_X86_REG_R12, UC_X86_REG_R12D, UC_X86_REG_R12W, UC_X86_REG_R12B,
UC_X86_REG_R13, UC_X86_REG_R13D, UC_X86_REG_R13W, UC_X86_REG_R13B,
UC_X86_REG_R14, UC_X86_REG_R14D, UC_X86_REG_R14W, UC_X86_REG_R14B,
UC_X86_REG_R15, UC_X86_REG_R15D, UC_X86_REG_R15W, UC_X86_REG_R15B,
UC_X86_REG_RIP, UC_X86_REG_EIP, UC_X86_REG_IP,
UC_X86_REG_RSP, UC_X86_REG_ESP, UC_X86_REG_SP, UC_X86_REG_SPL,
UC_X86_REG_RBP, UC_X86_REG_EBP, UC_X86_REG_BP, UC_X86_REG_BPL,
UC_X86_REG_RFLAGS, UC_X86_REG_EFLAGS, UC_X86_REG_FLAGS,
UC_X86_REG_CS, UC_X86_REG_DS, UC_X86_REG_SS, UC_X86_REG_ES, UC_X86_REG_FS, UC_X86_REG_GS,
};

#define NUM_OF_REGISTERS_TO_READ ( (int)(sizeof(x86_64_registers) / sizeof(int)) )
static uint64_t reg_contents[NUM_OF_REGISTERS_TO_READ];

#define REG_RAX reg_contents[0]
#define REG_RIP reg_contents[60]
#define REG_RSP reg_contents[63]



void init_emu(struct MemoryLayout *memory_layout, int *instruction_count);
Expand Down
41 changes: 32 additions & 9 deletions src/emu/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,36 @@ struct AssemblyText assembly = {0};



void dispose_segment(struct MemorySegment *seg)
{
free(seg->bytes);
seg->bytes = NULL;

for (int i = 0; i < seg->num_symbols; i++)
{
free(seg->symbols[i]->name);
seg->symbols[i]->name = NULL;

free(seg->symbols[i]->bytes);
seg->symbols[i]->bytes = NULL;

free(seg->symbols[i]);
seg->symbols[i] = NULL;
}

free(seg->symbols);
seg->symbols = NULL;
}

void dispose(struct MemoryLayout *mem, struct AssemblyText *assembly)
{
free(mem->text.seg.bytes);
free(mem->rodata.bytes);
free(mem->data.bytes);
free(mem->bss.bytes);
mem->text.seg.bytes = NULL;

dispose_segment(&mem->rodata);
dispose_segment(&mem->data);
dispose_segment(&mem->bss);


for (int i = 0; i < assembly->num_lines; i++)
{
Expand All @@ -39,7 +63,7 @@ void dispose(struct MemoryLayout *mem, struct AssemblyText *assembly)

int main(int argc, char *argv[])
{
#define DEBUG
//#define DEBUG
#ifdef DEBUG
argc = 2;
#endif
Expand All @@ -57,7 +81,7 @@ int main(int argc, char *argv[])
}

#ifdef DEBUG
system(GCC_PATH " -g ~/Desktop/assembly_files/all_segments.s -g -o " COMPILED_FILE_PATH " -no-pie");
system(GCC_PATH " -g ~/Desktop/assembly_files/printf_call.s -g -o " COMPILED_FILE_PATH " -no-pie");
#else
pid_t pid = fork();

Expand All @@ -80,12 +104,12 @@ int main(int argc, char *argv[])
{
// wait for the child process to die
waitpid(pid, NULL, 0);
// successful compilation, resume normal program execution
}
#endif

// successful compilation, resume program execution
int insn_cnt = 0;

int insn_cnt = 0;

// after compiling the assembly file, we disassemble it using objdump
// and process the resulting output
Expand Down Expand Up @@ -123,12 +147,11 @@ int main(int argc, char *argv[])
emulate(&mem_layout.text);
// #######################################################


printf("Number of instructions executed: %d\n\n", insn_cnt);


destroy_serializer();
dispose(&mem_layout, &assembly);


return EXIT_SUCCESS;
}
18 changes: 17 additions & 1 deletion src/emu/serializer.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ FILE *emu_out_fp;

static void print_segment(struct MemorySegment *seg)
{
PRINT_TO_FILE("%ld %ld ", seg->addr, seg->size)
PRINT_TO_FILE("%ld %ld %d ", seg->addr, seg->size, seg->num_symbols)

for (uint32_t i = 0; i < seg->size; i++)
{
Expand Down Expand Up @@ -51,7 +51,12 @@ void write_memory_layout(struct MemoryLayout *mem, uint64_t stack_start_addr, ui
mem->memory_start_addr, mem->memory_end_addr, stack_start_addr, stack_end_addr, mem->text.main_addr);

print_segment(&mem->text.seg);

print_segment(&mem->rodata);
for (int i = 0; i < mem->rodata.num_symbols; i++)
{
write_symbol_info(mem->rodata.symbols[i]);
}

write_separator();
}
Expand Down Expand Up @@ -84,6 +89,17 @@ void write_instruction_info(int index, uint32_t size, __uint128_t bytecode)
PRINT_TO_FILE("\n")
}

void write_symbol_info(struct Symbol *symbol)
{
PRINT_TO_FILE("%ld %s ", symbol->addr, symbol->name);
for (int i = 0; i < symbol->size; i++)
{
PRINT_TO_FILE("%u%s", symbol->bytes[i], (i == symbol->size-1) ? "" : " ")
}

PRINT_TO_FILE("\n")
}

void write_registers(int size, uint64_t *registers)
{
for (int i = 0; i < size; i++)
Expand Down
2 changes: 2 additions & 0 deletions src/emu/serializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ void write_assembly_instructions_and_addresses(struct AssemblyText *assembly);

void write_instruction_info(int index, uint32_t size, __uint128_t bytecode);

void write_symbol_info(struct Symbol *symbol);

void write_registers(int size, uint64_t *registers);

void write_stack_content(int size, uint8_t *bytes);
Expand Down
Loading

0 comments on commit c8dce85

Please sign in to comment.