From 9046f42f199b8e9d904ace3e7baf9c3bd4714b8d Mon Sep 17 00:00:00 2001 From: fervagar Date: Fri, 14 Mar 2025 00:25:18 +0100 Subject: [PATCH] bindings/zig: Fix sample_riscv_zig partial writes and logging - Use full code length (instead of subtracting 1) when writing instructions. - Uniformly zero-pad addresses in logs and print hexadecimal. - Correct the instruction-hook callback in test_riscv2. --- bindings/zig/sample/sample_riscv_zig.zig | 30 ++++++++++++------------ 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/bindings/zig/sample/sample_riscv_zig.zig b/bindings/zig/sample/sample_riscv_zig.zig index 6012d81ff2..cda1cc3651 100644 --- a/bindings/zig/sample/sample_riscv_zig.zig +++ b/bindings/zig/sample/sample_riscv_zig.zig @@ -18,18 +18,18 @@ pub fn main() !void { fn hook_block(uc: ?*unicornC.uc_engine, address: u64, size: u32, user_data: ?*anyopaque) callconv(.C) void { _ = user_data; _ = uc; - log.info(">>> Tracing basic block at 0x{}, block size = 0x{}", .{ address, size }); + log.info(">>> Tracing basic block at 0x{x:0>4}, block size = 0x{x:0>4}", .{ address, size }); } fn hook_code(uc: ?*unicornC.uc_engine, address: u64, size: u32, user_data: ?*anyopaque) callconv(.C) void { _ = user_data; _ = uc; - log.info(">>> Tracing instruction at 0x{}, instruction size = 0x{}", .{ address, size }); + log.info(">>> Tracing instruction at 0x{x:0>4}, instruction size = 0x{x:0>4}", .{ address, size }); } fn hook_code3(uc: ?*unicornC.uc_engine, address: u64, size: u32, user_data: ?*anyopaque) callconv(.C) void { _ = user_data; - log.info(">>> Tracing instruction at 0x{}, instruction size = 0x{}", .{ address, size }); + log.info(">>> Tracing instruction at 0x{x:0>4}, instruction size = 0x{x:0>4}", .{ address, size }); if (address == ADDRESS) { log.info("stop emulation"); unicorn.uc_emu_stop(uc) catch |err| log.err("Error: {}", .{err}); @@ -41,7 +41,7 @@ fn hook_memalloc(uc: ?*unicornC.uc_engine, @"type": unicornC.uc_mem_type, addres const algined_address = address & 0xFFFFFFFFFFFFF000; const aligned_size = (@as(u32, @intCast(size / 0x1000)) + 1) * 0x1000; - log.info(">>> Allocating block at 0x{} (0x{}), block size = 0x{} (0x{})", .{ address, algined_address, size, aligned_size }); + log.info(">>> Allocating block at 0x{x:0>4} (aligned: 0x{x:0>4}), block size = 0x{x:0>4} (aligned: 0x{x:0>4})", .{ address, algined_address, size, aligned_size }); unicorn.uc_mem_map(uc, algined_address, aligned_size, unicornC.UC_PROT_ALL) catch |err| log.err("Error: {}", .{err}); @@ -81,7 +81,7 @@ fn test_recover_from_illegal() !void { try unicorn.uc_hook_add(uc, &trace2, unicornC.UC_HOOK_CODE, @as(?*anyopaque, @ptrCast(@constCast(&hook_code))), null, 1, 0); // write machine code to be emulated to memory - try unicorn.uc_mem_write(uc, ADDRESS, RISCV_CODE, RISCV_CODE.len - 1); + try unicorn.uc_mem_write(uc, ADDRESS, RISCV_CODE, RISCV_CODE.len); // emulate 1 instruction, wrong address, illegal code unicorn.uc_emu_start(uc, 0x1000, @as(u64, @bitCast(@as(i64, -1))), 0, 1) catch |err| @@ -97,8 +97,8 @@ fn test_recover_from_illegal() !void { try unicorn.uc_reg_read(uc, unicornC.UC_RISCV_REG_A0, @as(?*anyopaque, @ptrCast(@constCast(&a0)))); try unicorn.uc_reg_read(uc, unicornC.UC_RISCV_REG_A1, @as(?*anyopaque, @ptrCast(@constCast(&a1)))); - log.info(">>> A0 = 0x{}", .{a0}); - log.info(">>> A1 = 0x{}", .{a1}); + log.info(">>> A0 = 0x{x:0>4}", .{a0}); + log.info(">>> A1 = 0x{x:0>4}", .{a1}); try unicorn.uc_close(uc); } @@ -124,7 +124,7 @@ fn test_riscv_func_return() !void { try unicorn.uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, unicornC.UC_PROT_ALL); // write machine code to be emulated to memory - try unicorn.uc_mem_write(uc, ADDRESS, CODE, CODE.len - 1); + try unicorn.uc_mem_write(uc, ADDRESS, CODE, CODE.len); // tracing all basic blocks with customized callback try unicorn.uc_hook_add(uc, &trace1, unicornC.UC_HOOK_BLOCK, @as(?*anyopaque, @ptrCast(@constCast(&hook_block))), null, 1, 0); @@ -143,7 +143,7 @@ fn test_riscv_func_return() !void { try unicorn.uc_reg_read(uc, unicornC.UC_RISCV_REG_PC, @as(?*anyopaque, @ptrCast(@constCast(&pc)))); if (pc != ra) { - log.info("Error after execution: PC is: 0x{}, expected was 0x{}", .{ pc, ra }); + log.info("Error after execution: PC is: 0x{x:0>4}, expected was 0x{x:0>4}", .{ pc, ra }); if (pc == 0x10004) { log.info(" PC did not change during execution", .{}); } @@ -177,7 +177,7 @@ fn test_riscv2() !void { try unicorn.uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, unicornC.UC_PROT_ALL); // write machine code to be emulated to memory - try unicorn.uc_mem_write(uc, ADDRESS, RISCV_CODE, RISCV_CODE.len - 1); + try unicorn.uc_mem_write(uc, ADDRESS, RISCV_CODE, RISCV_CODE.len); // initialize machine registers try unicorn.uc_reg_write(uc, unicornC.UC_RISCV_REG_A0, @as(?*anyopaque, @ptrCast(@constCast(&a0)))); @@ -187,7 +187,7 @@ fn test_riscv2() !void { try unicorn.uc_hook_add(uc, &trace1, unicornC.UC_HOOK_BLOCK, @as(?*anyopaque, @ptrCast(@constCast(&hook_block))), null, 1, 0); // tracing all instruction - try unicorn.uc_hook_add(uc, &trace2, unicornC.UC_HOOK_CODE, @as(?*anyopaque, @ptrCast(@constCast(&hook_block))), null, 1, 0); + try unicorn.uc_hook_add(uc, &trace2, unicornC.UC_HOOK_CODE, @as(?*anyopaque, @ptrCast(@constCast(&hook_code))), null, 1, 0); // emulate 1 instruction unicorn.uc_emu_start(uc, ADDRESS, ADDRESS + 4, 0, 0) catch |err| { @@ -197,8 +197,8 @@ fn test_riscv2() !void { try unicorn.uc_reg_read(uc, unicornC.UC_RISCV_REG_A0, @as(?*anyopaque, @ptrCast(@constCast(&a0)))); try unicorn.uc_reg_read(uc, unicornC.UC_RISCV_REG_A1, @as(?*anyopaque, @ptrCast(@constCast(&a1)))); - log.info(">>> A0 = 0x{}", .{a0}); - log.info(">>> A1 = 0x{}", .{a1}); + log.info(">>> A0 = 0x{x:0>4}", .{a0}); + log.info(">>> A1 = 0x{x:0>4}", .{a1}); // emulate one more instruction unicorn.uc_emu_start(uc, ADDRESS + 4, ADDRESS + 8, 0, 0) catch |err| { @@ -211,8 +211,8 @@ fn test_riscv2() !void { try unicorn.uc_reg_read(uc, unicornC.UC_RISCV_REG_A0, @as(?*anyopaque, @ptrCast(@constCast(&a0)))); try unicorn.uc_reg_read(uc, unicornC.UC_RISCV_REG_A1, @as(?*anyopaque, @ptrCast(@constCast(&a1)))); - log.info(">>> A0 = 0x{}", .{a0}); - log.info(">>> A1 = 0x{}", .{a1}); + log.info(">>> A0 = 0x{x:0>4}", .{a0}); + log.info(">>> A1 = 0x{x:0>4}", .{a1}); try unicorn.uc_close(uc); }