diff options
| -rw-r--r-- | .gdb_history | 13 | ||||
| -rw-r--r-- | build.zig | 39 | ||||
| -rw-r--r-- | mise.toml | 2 | ||||
| -rw-r--r-- | src/elfo.zig | 54 | ||||
| -rw-r--r-- | src/hooks.zig | 32 | ||||
| -rw-r--r-- | src/shock.zig | 45 | ||||
| -rw-r--r-- | study-samples/flag.txt | 1 | ||||
| -rwxr-xr-x | study-samples/frog | bin | 0 -> 16176 bytes | |||
| -rwxr-xr-x | study-samples/libImageUtils.so | bin | 0 -> 125280 bytes | |||
| -rw-r--r-- | study-samples/sol.py | 5 | ||||
| -rwxr-xr-x | study-samples/split | bin | 0 -> 8664 bytes | |||
| -rwxr-xr-x | study-samples/split_armv5 | bin | 0 -> 8436 bytes | |||
| -rw-r--r-- | study-samples/split_armv5.zip | bin | 0 -> 3108 bytes | |||
| -rwxr-xr-x | tests/c/a.out | bin | 0 -> 15904 bytes | |||
| -rw-r--r-- | tests/c/hello-world.c | 9 |
15 files changed, 139 insertions, 61 deletions
diff --git a/.gdb_history b/.gdb_history new file mode 100644 index 0000000..013a8e1 --- /dev/null +++ b/.gdb_history @@ -0,0 +1,13 @@ +c +r +si +ni +n +r +s +ni +s +r +r +s +finish @@ -23,6 +23,16 @@ pub fn build(b: *std.Build) !void { }), }); + const shock = b.addExecutable(.{ + .name = "shock", + .root_module = b.createModule(.{ + .root_source_file = b.path("src/shock.zig"), + .target = target, + .optimize = optimize, + .link_libc = true, + }), + }); + const capstone_lib = capstone(b, .{ .optimize = optimize, .target = target, @@ -50,9 +60,9 @@ pub fn build(b: *std.Build) !void { b.installArtifact(elfo); b.installArtifact(gloves); - const gdb_opt = b.option(bool, "gdb", "Run executable under gdb") orelse false; + const opt_gdb = b.option(bool, "gdb", "Run executable under gdb") orelse false; const comp_opts = b.addOptions(); - comp_opts.addOption(bool, "gdb", gdb_opt); + comp_opts.addOption(bool, "gdb", opt_gdb); const unit_tests = b.addTest(.{ .root_module = b.createModule(.{ @@ -62,23 +72,44 @@ pub fn build(b: *std.Build) !void { }), }); - const test_step = b.step("test", "Test the library"); + // Looooopy + const gcc_test = b.addSystemCommand(&.{"gcc"}); + gcc_test.addFileArg(b.path("tests/c/hello-world.c")); + gcc_test.addArg("-o"); + const gcc_hello_file = gcc_test.addOutputFileArg("hello-world"); + + const runner = b.addRunArtifact(shock); + runner.addFileArg(gcc_hello_file); + runner.addFileArg(gcc_hello_file); + + const loop_step = b.step("loop", "Interative Programming Loop! you should run it with watch: i.e. zig build loop --watch"); + loop_step.dependOn(&runner.step); + // --- + const test_step = b.step("test", "Run unit tests"); const run_elfo_step = b.step("elfo", "See the pretty elfo!"); + const run_shock_step = b.step("shock", "SHOCK something!"); const run_gloves_step = b.step("gloves", "See the pretty gloves!"); + const zls_check = b.step("check", "Check if the program compiles"); + zls_check.dependOn(&elfo.step); + zls_check.dependOn(&shock.step); + zls_check.dependOn(&unit_tests.step); + const run_steps = [_]struct { *std.Build.Step, *std.Build.Step.Compile }{ .{ test_step, unit_tests }, .{ run_elfo_step, elfo }, .{ run_gloves_step, gloves }, + .{ run_shock_step, shock }, }; + const gdbscript = b.addWriteFile("gdbscript", \\r ); for (run_steps) |run| { run.@"1".root_module.addOptions("meta", comp_opts); - if (gdb_opt) { + if (opt_gdb) { const run_gdb = b.addSystemCommand(&.{"gdb"}); run_gdb.addArg("-x"); run_gdb.addFileArg(gdbscript.getDirectory().path(b, "gdbscript")); diff --git a/mise.toml b/mise.toml new file mode 100644 index 0000000..3b9ae66 --- /dev/null +++ b/mise.toml @@ -0,0 +1,2 @@ +[tools] +zig = "master" diff --git a/src/elfo.zig b/src/elfo.zig index 5e0d780..264ba4d 100644 --- a/src/elfo.zig +++ b/src/elfo.zig @@ -1,7 +1,7 @@ const std = @import("std"); const cs = @import("capstone"); const hooks = @import("hooks.zig"); -const meta_opts = @import("meta"); +const meta = @import("meta"); pub fn main(init: std.process.Init.Minimal) !void { var debug_alloc: std.heap.DebugAllocator(.{}) = .init; @@ -21,21 +21,22 @@ pub fn main(init: std.process.Init.Minimal) !void { var buffer: [64]u8 = undefined; const stderr = try io.lockStderr(&buffer, .escape_codes); - const hook = hooks.init( - if (meta_opts.gdb) .breakpoint else .none, - // TODO: this needs to be comptime, it'd be cool to don't need that - std.heap.page_allocator, - false, - ); + // const hook = hooks.init( + // if (meta.gdb) .breakpoint else .none, + // // TODO: this needs to be comptime, it'd be cool to don't need that + // std.heap.page_allocator, + // false, + // ); - const mem_config: cs.cs_opt_mem = .{ - .malloc = @ptrCast(&hook.malloc), - .free = @ptrCast(&hook.free), - .calloc = @ptrCast(&hook.calloc), - .realloc = @ptrCast(&hook.realloc), - .vsnprintf = @ptrCast(&hook.vsnprintf), - }; - std.debug.assert(cs.cs_option(0, cs.CS_OPT_MEM, @intFromPtr(&mem_config)) == cs.CS_ERR_OK); + // const mem_config: cs.cs_opt_mem = .{ + // .malloc = @ptrCast(&hook.malloc), + // .free = @ptrCast(&hook.free), + // .calloc = @ptrCast(&hook.calloc), + // .realloc = @ptrCast(&hook.realloc), + // // TODO: this function needs to be properly implemented. + // .vsnprintf = @ptrCast(&hook.vsnprintf), + // }; + // std.debug.assert(cs.cs_option(0, cs.CS_OPT_MEM, @intFromPtr(&mem_config)) == cs.CS_ERR_OK); try printElf( alloc, @@ -43,8 +44,8 @@ pub fn main(init: std.process.Init.Minimal) !void { args.next() orelse "./study-samples/split", stderr.terminal(), .{ - .show_unaddressable_sections = true, - .skip_sections_content = true, + // .show_unaddressable_sections = true, + // .skip_sections_content = true, }, ); } @@ -73,7 +74,7 @@ pub fn printElf( const opts: struct { arch: u64, mode: u64 } = switch (header.machine) { .X86_64 => .{ .arch = cs.CS_ARCH_X86, .mode = cs.CS_MODE_64 }, // The arm mode isn't working with symbols on the .text section correctly - .ARM => .{ .arch = cs.CS_ARCH_ARM, .mode = cs.CS_MODE_ARM }, + .ARM => .{ .arch = cs.CS_ARCH_ARM, .mode = if (header.is_64) cs.CS_MODE_64 else cs.CS_MODE_32 }, else => { std.debug.print("found machine: {any}\n", .{header.machine}); @panic("unhandled arch"); @@ -258,10 +259,11 @@ pub fn printElf( section.sh_addr + section.sh_size, section.sh_type, }); + try term.setColor(.bright_green); if (elf_shstrtab_slice != null) try bw.print("{s}", .{std.mem.sliceTo(elf_shstrtab_slice.?[section.sh_name..], 0)}); - try bw.print("", .{}); + try bw.print("\n", .{}); try term.setColor(.reset); // -- @@ -292,9 +294,9 @@ pub fn printElf( break :blk insn[0..count]; }; - try dumpInstr(gpa, bw, term, instrs, symbols_index.items); + try printDisassembly(gpa, bw, term, instrs, symbols_index.items); } else { - try dumpHexFallible(u64, bw, term, section_slice.?, section.sh_addr); + try printHexdump(u64, bw, term, section_slice.?, section.sh_addr); } } } @@ -332,7 +334,7 @@ pub fn printElf( } }; if (section_slice != null and !options.skip_sections_content) { - try dumpHexFallible(u64, bw, term, section_slice.?, section.sh_addr); + try printHexdump(u64, bw, term, section_slice.?, section.sh_addr); } } } @@ -375,7 +377,7 @@ fn allocComment( return null; } -fn dumpInstr( +fn printDisassembly( gpa: std.mem.Allocator, bw: *std.Io.Writer, term: std.Io.Terminal, @@ -407,8 +409,8 @@ fn dumpInstr( try term.setColor(.reset); const mnemonic_strlen: u64 = @intCast(std.mem.find(u8, &instr.mnemonic, &.{0}).?); - const mnemonic_pad: u64 = 10; - for (0..(mnemonic_pad - mnemonic_strlen)) |_| { + const mnemonic_pad: u64 = 5; + for (0..(if (mnemonic_pad >= mnemonic_strlen) mnemonic_pad - mnemonic_strlen else 0)) |_| { try bw.printAsciiChar(' ', .{}); } try bw.print("{s}", .{instr.op_str}); @@ -427,7 +429,7 @@ fn dumpInstr( } /// Prints a hexadecimal view of the bytes, returning any error that occurs. -pub fn dumpHexFallible( +pub fn printHexdump( _: type, bw: *std.Io.Writer, term: std.Io.Terminal, diff --git a/src/hooks.zig b/src/hooks.zig index 549d871..2fda734 100644 --- a/src/hooks.zig +++ b/src/hooks.zig @@ -7,35 +7,6 @@ pub const Kind = enum { const Self = @This(); pub const Hook = @This(); -// pub fn init(comptime kind: Kind, comptime alloc: std.mem.Allocator) type { -// return struct { -// alloc: std.mem.Allocator = alloc, - -// pub fn malloc(size: usize) callconv(.c) ?*anyopaque { -// if (kind == .breakpoint) @breakpoint(); -// return std.c.malloc(size); -// } - -// pub fn calloc(n: usize, size: usize) callconv(.c) ?*anyopaque { -// if (kind == .breakpoint) @breakpoint(); -// return std.c.calloc(n, size); -// } -// pub fn realloc(ptr: ?*anyopaque, size: usize) callconv(.c) ?*anyopaque { -// if (kind == .breakpoint) @breakpoint(); -// return std.c.realloc(ptr, size); -// } -// pub fn free(ptr: ?*anyopaque) callconv(.c) void { -// if (kind == .breakpoint) @breakpoint(); -// return std.c.free(ptr); -// } -// pub fn vsnprintf(_: [*c]u8, _: usize, _: [*c]const u8, _: [*c]u8) callconv(.c) ?*anyopaque { -// if (kind == .breakpoint) @breakpoint(); -// return null; -// } -// }; -// } -// - pub fn init(comptime kind: Kind, comptime alloc: std.mem.Allocator, comptime uselibc: bool) type { return struct { alloc: std.mem.Allocator = alloc, @@ -108,8 +79,7 @@ pub fn init(comptime kind: Kind, comptime alloc: std.mem.Allocator, comptime use } pub fn vsnprintf(_: [*c]u8, _: usize, _: [*c]const u8, _: [*c]u8) callconv(.c) ?*anyopaque { - if (kind == .breakpoint) @breakpoint(); - return null; + @compileError("Unimplemented!"); } }; } diff --git a/src/shock.zig b/src/shock.zig new file mode 100644 index 0000000..262b176 --- /dev/null +++ b/src/shock.zig @@ -0,0 +1,45 @@ +const std = @import("std"); + +pub fn main(init: std.process.Init.Minimal) !void { + var args = init.args.iterate(); + _ = args.skip(); + const subject = args.next() orelse "./study-samples/frog"; + + std.debug.print("arg: {s}\n", .{subject}); + + var debug_alloc: std.heap.DebugAllocator(.{}) = .init; + const alloc = debug_alloc.allocator(); + + // var threaded: std.Io.Threaded = .init(alloc, .{ + // .argv0 = .init(init.args), + // .environ = init.environ, + // }); + // defer threaded.deinit(); + // const io = threaded.io(); + + var evented: std.Io.Evented = undefined; + try evented.init(alloc, .{ + .argv0 = .init(init.args), + .environ = init.environ, + .backing_allocator_needs_mutex = false, + }); + defer evented.deinit(); + const io = evented.io(); + + // const f = try std.Io.Dir.cwd().openFile(io, subject, .{ .mode = .read_only }); + // std.debug.print("file: {any}\n", .{f}); + var child = try std.process.spawn(io, .{ + .argv = &.{subject}, + .stdout = .pipe, + .stdin = .inherit, + }); + + const buf = try alloc.alloc(u8, 0x400); + defer alloc.free(buf); + _ = try child.stdout.?.readPositionalAll(io, buf, 0); + + std.debug.print("spawned child: {any}\n", .{child}); + + const term = try child.wait(io); + std.debug.print("waited term: {any}\n", .{term}); +} diff --git a/study-samples/flag.txt b/study-samples/flag.txt new file mode 100644 index 0000000..918aaf6 --- /dev/null +++ b/study-samples/flag.txt @@ -0,0 +1 @@ +ROPE{a_placeholder_32byte_flag!} diff --git a/study-samples/frog b/study-samples/frog Binary files differnew file mode 100755 index 0000000..078c44d --- /dev/null +++ b/study-samples/frog diff --git a/study-samples/libImageUtils.so b/study-samples/libImageUtils.so Binary files differnew file mode 100755 index 0000000..0ea45b2 --- /dev/null +++ b/study-samples/libImageUtils.so diff --git a/study-samples/sol.py b/study-samples/sol.py new file mode 100644 index 0000000..48b09a5 --- /dev/null +++ b/study-samples/sol.py @@ -0,0 +1,5 @@ +from pwn import * + +io = process('./split', aslr=False, stdout=PIPE, stderr=PIPE) + +io.interactive() diff --git a/study-samples/split b/study-samples/split Binary files differnew file mode 100755 index 0000000..030e358 --- /dev/null +++ b/study-samples/split diff --git a/study-samples/split_armv5 b/study-samples/split_armv5 Binary files differnew file mode 100755 index 0000000..93b2cb8 --- /dev/null +++ b/study-samples/split_armv5 diff --git a/study-samples/split_armv5.zip b/study-samples/split_armv5.zip Binary files differnew file mode 100644 index 0000000..c10a387 --- /dev/null +++ b/study-samples/split_armv5.zip diff --git a/tests/c/a.out b/tests/c/a.out Binary files differnew file mode 100755 index 0000000..ef80bc7 --- /dev/null +++ b/tests/c/a.out diff --git a/tests/c/hello-world.c b/tests/c/hello-world.c new file mode 100644 index 0000000..e0a0dd1 --- /dev/null +++ b/tests/c/hello-world.c @@ -0,0 +1,9 @@ +#include <stdio.h> + +void a() {} +void bcd() {} + +int main() { + printf("Heeeello, world! %d\n", 42); + return 0; +} |
