From aa66855054691437330480603087aff6e5cf5dbf Mon Sep 17 00:00:00 2001 From: Yi-Ting Shih Date: Sat, 12 Apr 2025 08:26:23 +0800 Subject: [PATCH] Initial commit --- .gdb_history | 3 + .gitignore | 2 + Makefile | 18 ++ hw3_testcase.zip | Bin 0 -> 13115 bytes logger.h | 37 ++++ main.c | 116 ++++++++++++ sdb.c | 410 +++++++++++++++++++++++++++++++++++++++++++ sdb.h | 52 ++++++ test.zip | Bin 0 -> 9079 bytes test/1.ans | 24 +++ test/1.in | 6 + test/2.ans | 44 +++++ test/2.in | 9 + test/3.ans | 49 ++++++ test/3.in | 14 ++ test/4.ans | 45 +++++ test/4.in | 9 + test/5.ans | 32 ++++ test/5.in | 9 + test/6.ans | 27 +++ test/6.in | 6 + test/7.ans | 35 ++++ test/7.in | 8 + test/Makefile | 8 + test/guess | Bin 0 -> 9704 bytes test/hello | Bin 0 -> 9424 bytes test/run_examples.py | 134 ++++++++++++++ test_case/Makefile | 13 ++ test_case/deep | Bin 0 -> 13568 bytes test_case/game | Bin 0 -> 9648 bytes test_case/guess | Bin 0 -> 9704 bytes test_case/hello | Bin 0 -> 9424 bytes test_case/in/1.in | 6 + test_case/in/2.in | 9 + test_case/in/3.in | 14 ++ test_case/in/4.in | 9 + test_case/in/h1.in | 13 ++ test_case/in/h2.in | 9 + test_case/in/h3.in | 6 + test_case/in/h4.in | 9 + test_case/in/h5.in | 12 ++ test_case/in/h6.in | 9 + test_case/out/1.ans | 19 ++ test_case/out/2.ans | 36 ++++ test_case/out/3.ans | 37 ++++ test_case/out/4.ans | 37 ++++ test_case/out/h1.ans | 44 +++++ test_case/out/h2.ans | 26 +++ test_case/out/h3.ans | 21 +++ test_case/out/h4.ans | 38 ++++ test_case/out/h5.ans | 31 ++++ test_case/out/h6.ans | 44 +++++ test_case/output.txt | 44 +++++ test_case/run.py | 71 ++++++++ tmp | 7 + vector.c | 27 +++ vector.h | 14 ++ 57 files changed, 1702 insertions(+) create mode 100644 .gdb_history create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 hw3_testcase.zip create mode 100644 logger.h create mode 100644 main.c create mode 100644 sdb.c create mode 100644 sdb.h create mode 100644 test.zip create mode 100644 test/1.ans create mode 100644 test/1.in create mode 100644 test/2.ans create mode 100644 test/2.in create mode 100644 test/3.ans create mode 100644 test/3.in create mode 100644 test/4.ans create mode 100644 test/4.in create mode 100644 test/5.ans create mode 100644 test/5.in create mode 100644 test/6.ans create mode 100644 test/6.in create mode 100644 test/7.ans create mode 100644 test/7.in create mode 100644 test/Makefile create mode 100755 test/guess create mode 100755 test/hello create mode 100755 test/run_examples.py create mode 100644 test_case/Makefile create mode 100755 test_case/deep create mode 100755 test_case/game create mode 100755 test_case/guess create mode 100755 test_case/hello create mode 100644 test_case/in/1.in create mode 100644 test_case/in/2.in create mode 100644 test_case/in/3.in create mode 100644 test_case/in/4.in create mode 100644 test_case/in/h1.in create mode 100644 test_case/in/h2.in create mode 100644 test_case/in/h3.in create mode 100644 test_case/in/h4.in create mode 100644 test_case/in/h5.in create mode 100644 test_case/in/h6.in create mode 100644 test_case/out/1.ans create mode 100644 test_case/out/2.ans create mode 100644 test_case/out/3.ans create mode 100644 test_case/out/4.ans create mode 100644 test_case/out/h1.ans create mode 100644 test_case/out/h2.ans create mode 100644 test_case/out/h3.ans create mode 100644 test_case/out/h4.ans create mode 100644 test_case/out/h5.ans create mode 100644 test_case/out/h6.ans create mode 100644 test_case/output.txt create mode 100644 test_case/run.py create mode 100644 tmp create mode 100644 vector.c create mode 100644 vector.h diff --git a/.gdb_history b/.gdb_history new file mode 100644 index 0000000..b1e6163 --- /dev/null +++ b/.gdb_history @@ -0,0 +1,3 @@ +exit +exit +exit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0aaf326 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +sdb +*.o diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a464ace --- /dev/null +++ b/Makefile @@ -0,0 +1,18 @@ +.PHONY: all debug clean test + +all: sdb + +sdb: $(patsubst %.c,%.o,$(wildcard *.c)) + gcc -o $@ $^ -lcapstone -std=gnu17 -g -fsanitize=address,undefined -fanalyzer + +%.o: %.c + gcc -o $@ -c $^ -std=gnu17 -Wall -Wextra \ + -g -fsanitize=address,undefined -fanalyzer \ + -Wno-unused-value #-DDEBUG + +clean: + - rm -f sdb *.o + make -C test clean + +test: sdb + make -C test_case diff --git a/hw3_testcase.zip b/hw3_testcase.zip new file mode 100644 index 0000000000000000000000000000000000000000..4bfd38c57eef9e845b5ad2746b7218db6144c774 GIT binary patch literal 13115 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 +#include + +#define ANSI_ESC_RED "\x1B[31m" +#define ANSI_ESC_GREEN "\x1B[32m" +#define ANSI_ESC_YELLOW "\x1B[33m" +#define ANSI_ESC_BLUE "\x1B[34m" +#define ANSI_ESC_MAGENTA "\x1B[35m" +#define ANSI_ESC_CYAN "\x1B[36m" +#define ANSI_ESC_COLOR_RESET "\x1B[m" + +#define ANSI_ESC_CLEAR "\x1B[2J" +#define ANSI_ESC_CURSOR_RESET "\x1B[;H" + +#ifdef DEBUG +#define PRINT(file, color, prompt, format, ...) \ + fprintf(file, "%s%s", color, prompt), \ + fprintf(file, format, ##__VA_ARGS__), \ + fprintf(file, "%s", ANSI_ESC_COLOR_RESET) +#define ERROR(format, ...) \ + PRINT(stderr, ANSI_ESC_RED, "[ERROR] ", format, ##__VA_ARGS__) +#define DEBUG(format, ...) \ + PRINT(stderr, ANSI_ESC_YELLOW, "[DEBUG] ", format, ##__VA_ARGS__) +#else +#define PRINT(file, color, prompt, format, ...) \ + fprintf(file, "%s", prompt), \ + fprintf(file, format, ##__VA_ARGS__) +#define ERROR(format, ...) +#define DEBUG(format, ...) +#endif + +#define INFO(format, ...) \ + PRINT(stdout, ANSI_ESC_CYAN, "** ", format, ##__VA_ARGS__) +#define OUTPUT(format, ...) \ + PRINT(stdout, ANSI_ESC_COLOR_RESET, "", format, ##__VA_ARGS__) diff --git a/main.c b/main.c new file mode 100644 index 0000000..6767d8f --- /dev/null +++ b/main.c @@ -0,0 +1,116 @@ +#include "sdb.h" +#include "vector.h" +#include "logger.h" + +#include +#include +#include +#include +#include +#include + +static inline enum instruction prompt(void) +{ + static char *input; + static size_t input_len; + + OUTPUT("(sdb) "); + getline(&input, &input_len, stdin); + + char *op = strtok(input, " \t\n"); + if (op == NULL) return INST_NOP; + + if (strcmp(op, "exit") == 0) return INST_EXIT; + if (strcmp(op, "load") == 0) return INST_LOAD; + if (strcmp(op, "show") == 0) return INST_SHOW; + if (strcmp(op, "info") == 0) return INST_INFO; + if (strcmp(op, "break") == 0) return INST_BREAK; + if (strcmp(op, "delete") == 0) return INST_DELETE; + if (strcmp(op, "patch") == 0) return INST_PATCH; + if (strcmp(op, "si") == 0) return INST_SI; + if (strcmp(op, "cont") == 0) return INST_CONT; + if (strcmp(op, "syscall") == 0) return INST_SYSCALL; + + return INST_INVALID; +} + +int main(int argc, char *argv[]) +{ + setvbuf(stdin, NULL, _IONBF, 0); + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + + char *filename = ""; + if (argc > 1) { + filename = malloc(strlen(argv[1]) + 1); + strcpy(filename, argv[1]); + if (access(filename, F_OK) != 0) { + perror("main file open"); + exit(1); + } + } + + if (access(filename, F_OK) != 0) { +load_retry: + enum instruction op = prompt(); + + switch (op) { + case INST_NOP: + goto load_retry; + case INST_EXIT: + goto exit; + + case INST_LOAD: + inst_load(&filename); + if (access(filename, F_OK) == 0) + break; + else { + INFO("file invalid\n"); + goto load_retry; + } + + default: + INFO("please load a program first.\n"); + goto load_retry; + } + } + + DEBUG("filename = %s\n", filename); + run(filename); + + sync_regs(); + disassemble_addr = regs.rip; + disassemble(); + + for (;;) { + enum instruction op = prompt(); + DEBUG("op = 0x%x\n", (int)op); + + switch (op) { + case INST_NOP: break; + case INST_EXIT: goto exit; + case INST_SHOW: disassemble(); break; + case INST_INFO: inst_info(); break; + + case INST_BREAK: inst_break(); break; + case INST_DELETE: inst_delete(); break; + case INST_PATCH: inst_patch(); break; + + case INST_SI: inst_si(); disassemble(); break; + case INST_CONT: inst_cont(); disassemble(); break; + case INST_SYSCALL: inst_syscall(); disassemble(); break; + + default: + INFO("invalid command\n"); + } + + DEBUG("disassemble_addr = %p\n", (void *)disassemble_addr); + if (disassemble_addr == 0x00) + goto exit; + } + +exit: + free(filename); + free(bps); + return 0; +} diff --git a/sdb.c b/sdb.c new file mode 100644 index 0000000..352c49a --- /dev/null +++ b/sdb.c @@ -0,0 +1,410 @@ +#include "sdb.h" +#include "logger.h" +#include "vector.h" + +#include +#include +#include +#include +#include +#include + +int child; +int status; + +struct user_regs_struct regs; +uint64_t disassemble_addr; + +long syscall_nr = 0xffff; + +void sync_regs(void) +{ + if (ptrace(PTRACE_GETREGS, child, NULL, ®s) != 0) { + ERROR("sync_regs ptrace getregs\n"); + perror("sync_regs"); + exit(1); + } +} + +uint8_t poke(uint64_t addr, uint8_t data) +{ + uint64_t ret = ptrace(PTRACE_PEEKTEXT, child, addr, NULL); + ptrace(PTRACE_POKETEXT, child, addr, (ret & ~0xff) | data); + return ret & 0xff; +} + +void run(const char *filename) +{ + child = fork(); + if (child < 0) { + ERROR("run fork failed\n"); + perror("run fork"); + exit(1); + } + + if (child == 0) { + DEBUG("forked\n"); + if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) < 0) { + perror("run traceme"); + exit(1); + } + execl(filename, filename, NULL); + perror("run execl"); + } + + if (waitpid(child, &status, 0) < 0) { + perror("run waitpid"); + exit(1); + } + if (WIFSTOPPED(status) == 0) { + perror("run stopped"); + exit(1); + } + ptrace(PTRACE_SETOPTIONS, child, 0, + PTRACE_O_EXITKILL | PTRACE_O_TRACESYSGOOD); + + sync_regs(); + INFO("program '%s' loaded. entry point %p.\n", filename, (void *)regs.rip); +} + +void disassemble() +{ + if (disassemble_addr == 0x00) return; + const uint64_t rip = disassemble_addr; + long ret; + uint8_t code[64], *ptr = (uint8_t *)&ret; + + for (int i = 0; i < 8; i++) { + ret = ptrace(PTRACE_PEEKTEXT, child, rip + (i << 3), NULL); + for (int j = 0; j < 8; j++) + code[i << 3 | j] = ptr[j]; + // DEBUG("\n"); + } + + for (int i = 0; i < bps_len; i++) + if (bps[i].addr && rip <= bps[i].addr && bps[i].addr < rip + 64) + code[bps[i].addr - rip] = bps[i].data; + + csh handle; + if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) != CS_ERR_OK) { + perror("disassemble cs_open"); + exit(1); + } + + cs_insn *insn; + int count = cs_disasm(handle, code, sizeof(code) - 1, rip, 0, &insn); + if (count > 0) { + for (int i = 0; i < INSTRUCTION_COUNT; i++) { + if (insn[i].size == 2 && + insn[i].bytes[0] == 0 && + insn[i].bytes[1] == 0) { + INFO("the address is out of the range of the text section.\n"); + break; + } + OUTPUT("%12lx: ", insn[i].address); + char insn_buf[25] = "", *insn_buf_ptr = insn_buf; + for (int j = 0; j < insn[i].size; j++) + insn_buf_ptr += sprintf(insn_buf_ptr, "%02x ", + (uint8_t)insn[i].bytes[j]); + OUTPUT("%-24s%-10s %s\n", insn_buf, insn[i].mnemonic, insn[i].op_str); + } + cs_free(insn, count); + } else { + perror("disassemble"); + exit(1); + } + cs_close(&handle); +} + +void inst_load(char **filename) +{ + char *token = strtok(NULL, " \t\n"); + if (token == NULL) { + perror("inst_load"); + disassemble_addr = 0x00; + return; + } + *filename = malloc(strlen(token) + 1); + strcpy(*filename, token); +} + +void inst_si(void) +{ + if (!WIFSTOPPED(status)) { + ERROR("program not running.\n"); + perror("inst_si not running"); + disassemble_addr = 0x00; + return; + } + + syscall_nr = 0xffff; + + sync_regs(); + uint64_t rip = regs.rip; + DEBUG("rip = %lx\n", rip); + + const struct bps_node *bp = find(rip); + if (bp) + poke(bp->addr, bp->data); + + ptrace(PTRACE_SINGLESTEP, child, NULL, NULL); + waitpid(child, &status, 0); + + if (bp) + poke(bp->addr, 0xcc); + + sync_regs(); + rip = regs.rip, bp = find(rip); + if (bp) + INFO("hit a breakpoint at %p.\n", (void *)rip); + + if (!WIFSTOPPED(status)) { + INFO("the target program terminated.\n"); + disassemble_addr = 0x00; + } else { + sync_regs(); + disassemble_addr = regs.rip; + } +} + +void inst_cont(void) +{ + if (!WIFSTOPPED(status)) { + ERROR("program not running.\n"); + perror("inst_cont not running"); + exit(1); + } + + syscall_nr = 0xffff; + + sync_regs(); + uint64_t rip = regs.rip; + DEBUG("rip = %lx\n", rip); + + const struct bps_node *bp = find(rip); + if (bp) { + poke(bp->addr, bp->data); + ptrace(PTRACE_SINGLESTEP, child, NULL, NULL); + waitpid(child, &status, 0); + poke(bp->addr, 0xcc); + } + + ptrace(PTRACE_CONT, child, NULL, NULL); + waitpid(child, &status, 0); + + if (!WIFSTOPPED(status)) { + INFO("the target program terminated.\n"); + disassemble_addr = 0x00; + } else { + sync_regs(); + rip = regs.rip; + bp = find(rip - 1); + + if (bp == NULL) { + perror("inst_cont bp = NULL\n"); + exit(1); + } + INFO("hit a breakpoint at %p.\n", (void *)(rip - 1)); + + poke(bp->addr, bp->data); + regs.rip -= 1; + ptrace(PTRACE_SETREGS, child, 0, ®s); + poke(bp->addr, 0xcc); + + sync_regs(); + disassemble_addr = regs.rip; + } +} + +void inst_info(void) +{ + char *op = strtok(NULL, " \t\n"); + if (op == NULL) + goto inst_info_invalid; + + if (strcmp(op, "reg") == 0) + inst_info_reg(); + else if (strcmp(op, "break") == 0) + inst_info_break(); + else + goto inst_info_invalid; + + return; + +inst_info_invalid: + ERROR("invalid command\n"); + INFO("Command: info [reg | break]\n"); +} + +void inst_info_reg(void) +{ + sync_regs(); +#define OUTPUT_REGS(a, b, c) \ + OUTPUT("$%-7s 0x%016lx\t$%-7s 0x%016lx\t$%-7s 0x%016lx\n", \ + #a, (unsigned long)regs.a, \ + #b, (unsigned long)regs.b, \ + #c, (unsigned long)regs.c) + OUTPUT_REGS(rax, rbx, rcx); + OUTPUT_REGS(rdx, rsi, rdi); + OUTPUT_REGS(rbp, rsp, r8); + OUTPUT_REGS( r9, r10, r11); + OUTPUT_REGS(r12, r13, r14); + OUTPUT_REGS(r15, rip, eflags); +#undef OUTPUT_REGS +} + +void inst_info_break(void) +{ + if (bps_cnt == 0) { + INFO("no breakpoints.\n"); + return; + } + + OUTPUT("%-6s\t%-12s\n", "Num", "Address"); + for (int i = 0; i < bps_len; i++) + if (bps[i].addr) + OUTPUT("%-6d\t0x%lx\n", i, bps[i].addr); +} + +void inst_break(void) +{ + char *token = strtok(NULL, " \t\n"); + if (token == NULL) { + ERROR("invalid command.\n"); + INFO("Command: break [hex address]\n"); + return; + } + uint64_t addr; + sscanf(token, "%lx", &addr); + + bps_push(addr, poke(addr, 0xcc)); + INFO("set a breakpoint at %p.\n", (void *)addr); +} + +void inst_delete(void) +{ + char *token = strtok(NULL, " \t\n"); + if (token == NULL) { + ERROR("invalid command.\n"); + INFO("Command: delete [id]\n"); + return; + } + + int id; + sscanf(token, "%d", &id); + + if (bps_len <= id || bps[id].addr == 0x00) + INFO("breakpoint %d does not exist.\n", id); + else { + poke(bps[id].addr, bps[id].data); + bps[id].addr = 0x00, bps_cnt--; + INFO("delete breakpoint %d.\n", id); + } +} + +void inst_patch(void) +{ + char *token = strtok(NULL, " \t\n"); + if (token == NULL) goto inst_patch_invalid; + uint64_t addr; + sscanf(token, "%lx", &addr); + + token = strtok(NULL, " \t\n"); + if (token == NULL) goto inst_patch_invalid; + uint64_t data; + sscanf(token, "%lx", &data); + + token = strtok(NULL, " \t\n"); + if (token == NULL) goto inst_patch_invalid; + int len; + sscanf(token, "%d", &len); + + uint64_t val = ptrace(PTRACE_PEEKTEXT, child, addr, NULL); + DEBUG("original val = %lx\n", val); + + uint64_t mask = ((uint64_t)1 << (len << 3)) - 1; + DEBUG("mask = %lx\n", mask); + val = (val & ~mask) | (data & mask); + DEBUG("modified val = %lx\n", val); + + for (int i = 0; i < bps_len; i++) + if (bps[i].addr && addr <= bps[i].addr && bps[i].addr < addr + len) { + int j = bps[i].addr - addr; + bps[i].data = (data >> j) & 0xff; + } + + if (ptrace(PTRACE_POKETEXT, child, addr, val) != 0) { + ERROR("inst_patch POKETEXT\n"); + perror("inst_patch ptrace"); + exit(1); + } + INFO("patch memory at address 0x%lx.\n", addr); + + return; + +inst_patch_invalid: + ERROR("invalid command.\n"); + INFO("Command: patch [hex address] [hex value] [len]\n"); +} + +void inst_syscall(void) +{ + if (!WIFSTOPPED(status)) { + ERROR("program not running.\n"); + perror("inst_syscall"); + disassemble_addr = 0x00; + return; + } + + sync_regs(); + uint64_t rip = regs.rip; + const struct bps_node *bp = find(rip); + + if (bp) { + poke(bp->addr, bp->data); + ptrace(PTRACE_SINGLESTEP, child, NULL, NULL); + waitpid(child, &status, 0); + poke(bp->addr, 0xcc); + } + + ptrace(PTRACE_SYSCALL, child, NULL, NULL); + waitpid(child, &status, 0); + + if (!WIFSTOPPED(status)) { + INFO("the target program terminated.\n"); + disassemble_addr = 0x00; + } else { + sync_regs(); + rip = regs.rip; + DEBUG("rip = %p\n", (void *)rip); + + if (WSTOPSIG(status) & 0x80) { + if (syscall_nr == 0xffff) { + syscall_nr = regs.orig_rax; + INFO("enter a syscall(%ld) at %p.\n", + syscall_nr, (void *)(rip - 2)); + } else { + INFO("leave a syscall(%ld) = %llu at %p.\n", + syscall_nr, regs.rax, (void *)(rip - 2)); + syscall_nr = 0xffff; + } + disassemble_addr = regs.rip - 2; + return; + } + + bp = find(rip - 1); + if (bp == NULL) { + ERROR("inst_syscall bp = NULL\n"); + perror("inst_syscall"); + exit(1); + } + INFO("hit a breakpoint at %p.\n", (void *)(rip - 1)); + + poke(bp->addr, bp->data); + regs.rip -= 1; + ptrace(PTRACE_SETREGS, child, 0, ®s); + poke(bp->addr, 0xcc); + + disassemble_addr = regs.rip; + } +} diff --git a/sdb.h b/sdb.h new file mode 100644 index 0000000..58217d9 --- /dev/null +++ b/sdb.h @@ -0,0 +1,52 @@ +#pragma once + +#include +#include +#include +#include + +#define INSTRUCTION_COUNT 5 + +enum instruction { + INST_NOP = 0x00, + INST_EXIT = 0x01, + INST_LOAD = 0x02, + + INST_SHOW = 0x10, + INST_INFO = 0x11, + + INST_BREAK = 0x20, + INST_DELETE = 0x21, + INST_PATCH = 0x22, + + INST_SI = 0x30, + INST_CONT = 0x31, + INST_SYSCALL = 0x32, + + INST_INVALID = 0xff, +}; + +void sync_regs(void); +uint8_t poke(uint64_t addr, uint8_t data); + +void run(const char *filename); +void disassemble(); + +void inst_load(char **filename); +void inst_si(void); +void inst_cont(void); +void inst_info(void); +void inst_info_reg(void); +void inst_info_break(void); +void inst_break(void); +void inst_delete(void); +void inst_patch(void); +void inst_syscall(void); + +extern int child; +extern int status; + +extern struct user_regs_struct regs; +extern uint64_t disassemble_addr; + +extern long syscall_nr; diff --git a/test.zip b/test.zip new file mode 100644 index 0000000000000000000000000000000000000000..7898b6f8cdb0f6802f4484921cbe3a02e89e031d GIT binary patch literal 9079 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 literal 0 HcmV?d00001 diff --git a/test/1.ans b/test/1.ans new file mode 100644 index 0000000..e2fc239 --- /dev/null +++ b/test/1.ans @@ -0,0 +1,24 @@ +(sdb) si +** please load a program first. +(sdb) load ./hello +** program './hello' loaded. entry point 0x401000. + 401000: f3 0f 1e fa endbr64 + 401004: 55 push rbp + 401005: 48 89 e5 mov rbp, rsp + 401008: ba 0e 00 00 00 mov edx, 0xe + 40100d: 48 8d 05 ec 0f 00 00 lea rax, [rip + 0xfec] +(sdb) si + 401004: 55 push rbp + 401005: 48 89 e5 mov rbp, rsp + 401008: ba 0e 00 00 00 mov edx, 0xe + 40100d: 48 8d 05 ec 0f 00 00 lea rax, [rip + 0xfec] + 401014: 48 89 c6 mov rsi, rax +(sdb) si + 401005: 48 89 e5 mov rbp, rsp + 401008: ba 0e 00 00 00 mov edx, 0xe + 40100d: 48 8d 05 ec 0f 00 00 lea rax, [rip + 0xfec] + 401014: 48 89 c6 mov rsi, rax + 401017: bf 01 00 00 00 mov edi, 1 +(sdb) cont +hello world! +** the target program terminated. diff --git a/test/1.in b/test/1.in new file mode 100644 index 0000000..a86ae27 --- /dev/null +++ b/test/1.in @@ -0,0 +1,6 @@ +./sdb +si +load ./hello +si +si +cont diff --git a/test/2.ans b/test/2.ans new file mode 100644 index 0000000..2e77f3d --- /dev/null +++ b/test/2.ans @@ -0,0 +1,44 @@ +** program './hello' loaded. entry point 0x401000. + 401000: f3 0f 1e fa endbr64 + 401004: 55 push rbp + 401005: 48 89 e5 mov rbp, rsp + 401008: ba 0e 00 00 00 mov edx, 0xe + 40100d: 48 8d 05 ec 0f 00 00 lea rax, [rip + 0xfec] +(sdb) break 0x401005 +** set a breakpoint at 0x401005. +(sdb) break 40102b +** set a breakpoint at 0x40102b. +(sdb) info break +Num Address +0 0x401005 +1 0x40102b +(sdb) si + 401004: 55 push rbp + 401005: 48 89 e5 mov rbp, rsp + 401008: ba 0e 00 00 00 mov edx, 0xe + 40100d: 48 8d 05 ec 0f 00 00 lea rax, [rip + 0xfec] + 401014: 48 89 c6 mov rsi, rax +(sdb) si +** hit a breakpoint at 0x401005. + 401005: 48 89 e5 mov rbp, rsp + 401008: ba 0e 00 00 00 mov edx, 0xe + 40100d: 48 8d 05 ec 0f 00 00 lea rax, [rip + 0xfec] + 401014: 48 89 c6 mov rsi, rax + 401017: bf 01 00 00 00 mov edi, 1 +(sdb) cont +** hit a breakpoint at 0x40102b. + 40102b: b8 01 00 00 00 mov eax, 1 + 401030: 0f 05 syscall + 401032: c3 ret + 401033: b8 00 00 00 00 mov eax, 0 + 401038: 0f 05 syscall +(sdb) info reg +$rax 0x0000000000402000 $rbx 0x0000000000000000 $rcx 0x0000000000000000 +$rdx 0x000000000000000e $rsi 0x0000000000402000 $rdi 0x0000000000000001 +$rbp 0x00007ffe0e5cd5b8 $rsp 0x00007ffe0e5cd5b0 $r8 0x0000000000000000 +$r9 0x0000000000000000 $r10 0x0000000000000000 $r11 0x0000000000000000 +$r12 0x0000000000000000 $r13 0x0000000000000000 $r14 0x0000000000000000 +$r15 0x0000000000000000 $rip 0x000000000040102b $eflags 0x0000000000000202 +(sdb) cont +hello world! +** the target program terminated. diff --git a/test/2.in b/test/2.in new file mode 100644 index 0000000..b15bc55 --- /dev/null +++ b/test/2.in @@ -0,0 +1,9 @@ +./sdb ./hello +break 0x401005 +break 40102b +info break +si +si +cont +info reg +cont diff --git a/test/3.ans b/test/3.ans new file mode 100644 index 0000000..9d12065 --- /dev/null +++ b/test/3.ans @@ -0,0 +1,49 @@ +** program './guess' loaded. entry point 0x40108b. + 40108b: f3 0f 1e fa endbr64 + 40108f: 55 push rbp + 401090: 48 89 e5 mov rbp, rsp + 401093: 48 83 ec 10 sub rsp, 0x10 + 401097: ba 12 00 00 00 mov edx, 0x12 +(sdb) break 0x4010de +** set a breakpoint at 0x4010de. +(sdb) cont +guess a number > 1 +** hit a breakpoint at 0x4010de. + 4010de: 48 89 c7 mov rdi, rax + 4010e1: e8 1a ff ff ff call 0x401000 + 4010e6: 85 c0 test eax, eax + 4010e8: 75 1b jne 0x401105 + 4010ea: ba 06 00 00 00 mov edx, 6 +(sdb) patch 0x4010e8 0x9090 2 +** patch memory at address 0x4010e8. +(sdb) si + 4010e1: e8 1a ff ff ff call 0x401000 + 4010e6: 85 c0 test eax, eax + 4010e8: 90 nop + 4010e9: 90 nop + 4010ea: ba 06 00 00 00 mov edx, 6 +(sdb) info break +Num Address +0 0x4010de +(sdb) delete 0 +** delete breakpoint 0. +(sdb) break 0x4010ea +** set a breakpoint at 0x4010ea. +(sdb) delete 0 +** breakpoint 0 does not exist. +(sdb) info break +Num Address +1 0x4010ea +(sdb) cont +** hit a breakpoint at 0x4010ea. + 4010ea: ba 06 00 00 00 mov edx, 6 + 4010ef: 48 8d 05 1f 0f 00 00 lea rax, [rip + 0xf1f] + 4010f6: 48 89 c6 mov rsi, rax + 4010f9: bf 01 00 00 00 mov edi, 1 + 4010fe: e8 25 00 00 00 call 0x401128 +(sdb) patch 0x402015 0x4e49570a 4 +** patch memory at address 0x402015. +(sdb) cont + +WIN +** the target program terminated. diff --git a/test/3.in b/test/3.in new file mode 100644 index 0000000..7a25c0d --- /dev/null +++ b/test/3.in @@ -0,0 +1,14 @@ +./sdb ./guess +break 0x4010de +cont +1 +patch 0x4010e8 0x9090 2 +si +info break +delete 0 +break 0x4010ea +delete 0 +info break +cont +patch 0x402015 0x4e49570a 4 +cont diff --git a/test/4.ans b/test/4.ans new file mode 100644 index 0000000..db45492 --- /dev/null +++ b/test/4.ans @@ -0,0 +1,45 @@ +** program './hello' loaded. entry point 0x401000. + 401000: f3 0f 1e fa endbr64 + 401004: 55 push rbp + 401005: 48 89 e5 mov rbp, rsp + 401008: ba 0e 00 00 00 mov edx, 0xe + 40100d: 48 8d 05 ec 0f 00 00 lea rax, [rip + 0xfec] +(sdb) break 0x401005 +** set a breakpoint at 0x401005. +(sdb) break 40102b +** set a breakpoint at 0x40102b. +(sdb) cont +** hit a breakpoint at 0x401005. + 401005: 48 89 e5 mov rbp, rsp + 401008: ba 0e 00 00 00 mov edx, 0xe + 40100d: 48 8d 05 ec 0f 00 00 lea rax, [rip + 0xfec] + 401014: 48 89 c6 mov rsi, rax + 401017: bf 01 00 00 00 mov edi, 1 +(sdb) syscall +** hit a breakpoint at 0x40102b. + 40102b: b8 01 00 00 00 mov eax, 1 + 401030: 0f 05 syscall + 401032: c3 ret + 401033: b8 00 00 00 00 mov eax, 0 + 401038: 0f 05 syscall +(sdb) syscall +** enter a syscall(1) at 0x401030. + 401030: 0f 05 syscall + 401032: c3 ret + 401033: b8 00 00 00 00 mov eax, 0 + 401038: 0f 05 syscall + 40103a: c3 ret +(sdb) syscall +hello world! +** leave a syscall(1) = 14 at 0x401030. + 401030: 0f 05 syscall + 401032: c3 ret + 401033: b8 00 00 00 00 mov eax, 0 + 401038: 0f 05 syscall + 40103a: c3 ret +(sdb) syscall +** enter a syscall(60) at 0x401040. + 401040: 0f 05 syscall +** the address is out of the range of the text section. +(sdb) syscall +** the target program terminated. diff --git a/test/4.in b/test/4.in new file mode 100644 index 0000000..868f712 --- /dev/null +++ b/test/4.in @@ -0,0 +1,9 @@ +./sdb ./hello +break 0x401005 +break 40102b +cont +syscall +syscall +syscall +syscall +syscall diff --git a/test/5.ans b/test/5.ans new file mode 100644 index 0000000..e694b67 --- /dev/null +++ b/test/5.ans @@ -0,0 +1,32 @@ +** program './guess' loaded. entry point 0x40108b. + 40108b: f3 0f 1e fa endbr64 + 40108f: 55 push rbp + 401090: 48 89 e5 mov rbp, rsp + 401093: 48 83 ec 10 sub rsp, 0x10 + 401097: ba 12 00 00 00 mov edx, 0x12 +(sdb) patch 0x4010e8 0x9090 2 +** patch memory at address 0x4010e8. +(sdb) break 0x4010e8 +** set a breakpoint at 0x4010e8. +(sdb) cont +guess a number > 1 +** hit a breakpoint at 0x4010e8. + 4010e8: 90 nop + 4010e9: 90 nop + 4010ea: ba 06 00 00 00 mov edx, 6 + 4010ef: 48 8d 05 1f 0f 00 00 lea rax, [rip + 0xf1f] + 4010f6: 48 89 c6 mov rsi, rax +(sdb) break 4010ea +** set a breakpoint at 0x4010ea. +(sdb) patch 4010ea 0x03ba 4 +** patch memory at address 0x4010ea. +(sdb) cont +** hit a breakpoint at 0x4010ea. + 4010ea: ba 03 00 00 00 mov edx, 3 + 4010ef: 48 8d 05 1f 0f 00 00 lea rax, [rip + 0xf1f] + 4010f6: 48 89 c6 mov rsi, rax + 4010f9: bf 01 00 00 00 mov edi, 1 + 4010fe: e8 25 00 00 00 call 0x401128 +(sdb) cont + +ye** the target program terminated. diff --git a/test/5.in b/test/5.in new file mode 100644 index 0000000..096adfe --- /dev/null +++ b/test/5.in @@ -0,0 +1,9 @@ +./sdb ./guess +patch 0x4010e8 0x9090 2 +break 0x4010e8 +cont +1 +break 4010ea +patch 4010ea 0x03ba 4 +cont +cont diff --git a/test/6.ans b/test/6.ans new file mode 100644 index 0000000..948f8ac --- /dev/null +++ b/test/6.ans @@ -0,0 +1,27 @@ +** program './guess' loaded. entry point 0x40108b. + 40108b: f3 0f 1e fa endbr64 + 40108f: 55 push rbp + 401090: 48 89 e5 mov rbp, rsp + 401093: 48 83 ec 10 sub rsp, 0x10 + 401097: ba 12 00 00 00 mov edx, 0x12 +(sdb) break 0x401128 +** set a breakpoint at 0x401128. +(sdb) cont +** hit a breakpoint at 0x401128. + 401128: b8 01 00 00 00 mov eax, 1 + 40112d: 0f 05 syscall + 40112f: c3 ret + 401130: b8 00 00 00 00 mov eax, 0 + 401135: 0f 05 syscall +(sdb) cont +guess a number > 1 +** hit a breakpoint at 0x401128. + 401128: b8 01 00 00 00 mov eax, 1 + 40112d: 0f 05 syscall + 40112f: c3 ret + 401130: b8 00 00 00 00 mov eax, 0 + 401135: 0f 05 syscall +(sdb) cont + +no no no +** the target program terminated. diff --git a/test/6.in b/test/6.in new file mode 100644 index 0000000..6bf6fa5 --- /dev/null +++ b/test/6.in @@ -0,0 +1,6 @@ +./sdb ./guess +break 0x401128 +cont +cont +1 +cont diff --git a/test/7.ans b/test/7.ans new file mode 100644 index 0000000..f1c0a01 --- /dev/null +++ b/test/7.ans @@ -0,0 +1,35 @@ +** program './hello' loaded. entry point 0x401000. + 401000: f3 0f 1e fa endbr64 + 401004: 55 push rbp + 401005: 48 89 e5 mov rbp, rsp + 401008: ba 0e 00 00 00 mov edx, 0xe + 40100d: 48 8d 05 ec 0f 00 00 lea rax, [rip + 0xfec] +(sdb) break 0x401030 +** set a breakpoint at 0x401030. +(sdb) break 0x401040 +** set a breakpoint at 0x401040. +(sdb) syscall +** hit a breakpoint at 0x401030. + 401030: 0f 05 syscall + 401032: c3 ret + 401033: b8 00 00 00 00 mov eax, 0 + 401038: 0f 05 syscall + 40103a: c3 ret +(sdb) syscall +** enter a syscall(1) at 0x401030. + 401030: 0f 05 syscall + 401032: c3 ret + 401033: b8 00 00 00 00 mov eax, 0 + 401038: 0f 05 syscall + 40103a: c3 ret +(sdb) cont +hello world! +** hit a breakpoint at 0x401040. + 401040: 0f 05 syscall +** the address is out of the range of the text section. +(sdb) syscall +** enter a syscall(60) at 0x401040. + 401040: 0f 05 syscall +** the address is out of the range of the text section. +(sdb) syscall +** the target program terminated. diff --git a/test/7.in b/test/7.in new file mode 100644 index 0000000..7d621d4 --- /dev/null +++ b/test/7.in @@ -0,0 +1,8 @@ +./sdb ./hello +break 0x401030 +break 0x401040 +syscall +syscall +cont +syscall +syscall diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..a71706b --- /dev/null +++ b/test/Makefile @@ -0,0 +1,8 @@ +all: + chmod +x run_examples.py guess hello + +test: all + ./run_examples.py + +clean: + rm -f *.out diff.txt diff --git a/test/guess b/test/guess new file mode 100755 index 0000000000000000000000000000000000000000..b6d0bbf89b89988df771a4be26aa69ede0184359 GIT binary patch literal 9704 zcmb<-^>JfjWMqH=CI&kO5U*Rn0W1U|85lH_!CWxmz+l0^&fvhn&AjT@T0Mg9Bz@PxJ2S(3<3d3k* zeQZ!UFy#Q%2cyA)3^3(z2FNZDJ^^*l2}X!M7_9=;2cto1K|%pfOHx2=9jH5Xpzegx zG9X0^3=A+Dq!uI;__QR29mF6K!-5Z_Uxa~yfti7U!QC&E;m_@j{|&F_PWA}y=N5Zx z^CBusN0CS)N0p6+z-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeD48suk%rEyV)T8sM zM`!H|kIvEu$6fz`eEC|x+x3q}@&%7>*B2g)7x=dcfcYmpx?LZ5FrMJw#$a)%gnh^V z|NsBLc5Qb3!w8lJDSrS~&d_q8L<24cF@nLyphN^ijH`6&4v>wphv80Xej~6;h=GB@ zqn9<7pMk-n^Voh+@B2js0|Ub@P>0u}m(@idA_3C+A|0f-)Aff(FRL9ygGVo`5?ICY z7gGQK|8G4|D!mKT{rBi)m4~Q+7^%v@!0=jf7dOa&URHi&DJ}*EhW%jUL00YnxqzSb zFxagi+J=FFfge1A0a7!HM?+vV1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU{HrZ zdTDBLu|lFkUTJPpYLSAS0)vSW16O5gF{t~?z`($jm#+XuTnr41(#+Np3=9lR3=9lc z-v9q^!oa`~|Kb1t5C#SY(A+b~ql{HS42%^5jM6;p91|EJ^V^^~?iug@|L+DVaOD$d zV{+zYV`}1I=U`v}nFs1hGk^I1e=f2-Xdc_y*-AkpG^sSNq*TGsP|sM;K-aJo%r&et zGSV|J(S!g0qjQx1_liV&=LYB1`R>TdI6AH5Vl}oU;wFyt*-$4nSp^p531e(O}#N#oQ;72 zZJmNW0|NudJwj0Tfad){=DR_~MWN!LK@X6)Cs-U|4rojRB<>3qXNIq%0FAqV#6fW? zz<^K>5(D9AsCxv^+>-znXJW8Gb3X$(f$1eP#K*h)g~q#j#JdGK`ntw@xCAkzC1&O@ zB7L+i= zr=}#9Br?RO=A|&CR%DhiFz6Lm=9VNTG3XVS6hY_=7%MNoBvmgxuT(FoG&3hfH#3Dn zuOzjigh8(;A8d+VYDRooQDSatd`3zU1Dwa8msDKLpqHGVo120kp0I zly^WT!Pbw!)|J54kAUPr7_^=PM8hyBeSp$3EIwiDWMB(c;Ok_d8bE5HOfUt?s~|C$ z{jl{i4AAu{+F(@(0+v2tBA`5qtRI#?VC!2zc^sw|M5DXki-7^WRtRRl2Q+sB(xV1_p*XQ2WvS5ArKW5i$*PJ4hUc zPeAq0fGPx)A0WSj+zL_yD&IgfNF45VkN^}XC_xyh5DHF0jf3+Ap=*2K0#L?LsQx4< JA4Z|;2LP;~8G8T# literal 0 HcmV?d00001 diff --git a/test/hello b/test/hello new file mode 100755 index 0000000000000000000000000000000000000000..47aabfbe42cf1756f2fdf5d031424768a99ffd43 GIT binary patch literal 9424 zcmb<-^>JfjWMqH=CI&kOFi*e%ECeAL7y^{QTrlClV8Ot~;K0DezzJ5%0v3f4FdYzj z3)nCQ1{lpC08s}LW(6^!d3Bk<7Yj*10({XZ5S9B_`#ickjN+=4S~@R7!85Z5Eu=C(GVC7 zfzc2c4S~@R7!85Z5Eu=C(GVD{A&`-plasGdo?n!cq6q5lGfFdCgXW(>efLVZO`H>~kc9y@KM&?Y z-6+Vw%m7;_02=N9$$^$N2rw`)Xv5YYfCL#B7>pPg7=##@7+~uWzr=}#9Br?RO=A|&CR%DhiFz6Lm z=9VNTG3XVS6hY_=7%MNoBvmgxuT(FoG&3hfH#3DnuOzjigh8(;A8d+VYDRooQDSat zd`3zU1Dwa8mzWeCuy6#8U?Hz30ZT&ELYZL71galqKPWAf9kQxwlT4#Htz YU=U tuple[int, bytes]: + """Returns the exit code and output of the process (including stdin and stderr)""" + print(f"Running case {case} with command: {command}") + try: + r = process(command, shell=False) + output = b"" + for line in stdin: + ret = recvrepeats(r) + output += ret + output += line.encode("utf-8") + if r.poll() is None: # Only send if the process is still running + r.send(line.encode("utf-8")) + output += recvrepeats(r) + r.close() + + except Exception as e: + print(f"Error: {e}") + return 1, b"" + + return 0, output + + +if __name__ == "__main__": + # Clean up the diff file + with open("diff.txt", "w") as f: + f.write("") + + for case in cases_to_run: + + with open(f"{case}.in", "r") as f: + lines = f.readlines() + run_command: List[str] = lines[0].split() + input = lines[1:] + + _, output = execute_process(case, run_command, input) + + # Remove the last prompt + if output.endswith(b"(sdb) "): + output = output[:-6] + + # Remove null bytes + output = output.replace(b"\x00", b"") + + # Write the output to a file + with open(f"{case}.out", "wb") as f: + f.write(output) + + diff_command = f"diff -w -B -u {case}.out {case}.ans" + diff_process = process(diff_command, shell=True) + diff_output = diff_process.recvall() + diff_process.close() + + diff_lines = diff_output.decode("utf-8").split("\n") + diff_lines = [ + line for line in diff_lines if line.startswith("-") or line.startswith("+") + ] + diff_lines = [line for line in diff_lines if not line.startswith("---")] + diff_lines = [line for line in diff_lines if not line.startswith("+++")] + + i = 0 + while True: + if i + 1 >= len(diff_lines): + break + + if "-$rbp" in diff_lines[i] and "+$rbp" in diff_lines[i + 1]: + output_line = diff_lines.pop(i)[1:].split() + expected_line = diff_lines.pop(i)[1:].split() + + if len(output_line) != 6: + diff_lines.append(f"error") + break + + output_rbp = int(output_line[1], 16) + output_rsp = int(output_line[3], 16) + output_r8 = int(output_line[5], 16) + expected_rbp = int(expected_line[1], 16) + expected_rsp = int(expected_line[3], 16) + expected_r8 = int(expected_line[5], 16) + + if ( + output_rbp - output_rsp != expected_rbp - expected_rsp + or output_r8 != expected_r8 + ): + diff_lines.append(f"error") + break + + continue + + i += 1 + + # Print the diff output if there is a difference + print(f"Case {case}: {'PASS' if len(diff_lines) == 0 else 'FAIL'}", end="\n\n") + + # Print the diff output to `diff.txt` + if len(diff_lines) > 0: + with open("diff.txt", "a") as f: + f.write(diff_output.decode("utf-8")) + f.write("\n\n") diff --git a/test_case/Makefile b/test_case/Makefile new file mode 100644 index 0000000..98c2918 --- /dev/null +++ b/test_case/Makefile @@ -0,0 +1,13 @@ +.PHONY: all + +all: ../sdb + python run.py 1 + python run.py 2 + python run.py 3 + python run.py 4 + python run.py h1 + python run.py h2 + python run.py h3 + python run.py h4 + python run.py h5 + python run.py h6 diff --git a/test_case/deep b/test_case/deep new file mode 100755 index 0000000000000000000000000000000000000000..56b3e8d30e2a3aeb2c10be17b1500ab24ca379ab GIT binary patch literal 13568 zcmb<-^>JfjWMqH=CI&kO5YJH10W1U|85kOjz+5olz+l0^&fvhn#lQ(x%K{dK5ilJP z`VGi11_lNg%^(0#2NGrlF`;}00f>4ST?$gbz`y{bk@bP?QvhjZU|>*y>Vwj6pu#X3 zSsxon&HzL(Ffcek^+9P~s4$F%=>ypX!Y82aIl&0g2cuP>`d~CjEl4QfX-Nv0jl-QL zAVmxe3@{q3mVtpG@M%d3J5-Js3Ko1I{UQtu49pA+4DNoR3^(VA6xqfFj?)nE5SjSy|fT-8v-L5}8X7F!wVg1a%??Cel14h?B z&8|Nfn`?hC*FElb{Syl}1mubxAWbh){{R0EVa@*k|9_|JpKjMb%?G#;_JNchcl}nH zmsyc^-1Qe1!!90>>v~zW^pPA{&AmNpt9Y0vhuJ7W87AiN;6x7=AglS(hvXt2QV-&IDYv5zkq>(q3y%}{}UJ(7&dA-q`x9X5HKFR;pz6V62Mi1h zR#0)+eg^QE00RR9Xf_{YP8ymyreO0~8F-=l0$}EY#xevLFvUHf>IKl$`$Fw?gt`Yj z*1^EQ5X!*7AjrT9-+utxZx9Dn58M9$vJYf;D%gA`hCDQPGNh!Y7U(52#K*h)g~q#j z#JdGK`ntw@xCAle=BK12mLxKi7iE^DGJqFy6fqQ~CZ;gN$0rpR#}}6*7L_o>r-Bv5 zr{<+V)TA0QfD=P;NfA_lA+;j2gn>b?xH7jSF^NI1xTFX|XTVr_`6a1(>3OAkNu`-N zDY}^{40Cx*#grDr6KtR%3)w&@PX4N?Od prvuTP&^;?4HZtB}2;pTxC^!i<4$c?EpJfjWMqH=CI&kOFi*e%ECeAL7(OV2xnRP9!GeLA!GVFDfeoyd1uP09U^*c5 z3#c%RW)Oe~fb3ueF`;}0sC_V+8>E1NfdNJ%>th4yQveYR3=9eodtkISRM-GY!}P(p zqx5J9jE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6nN5ZDRognKmqWGIn;0qQ%y zh+$x0cu~Z_z~IsRgRw;L#X%7B|H;?4U(8`(V0g{?q6(zo7y|=C;0{n9eLsls=r!HU z&%m%th=GBDpEdF@s?-crDNr!)2N52OUdBJ= zfCvA!1L!6PfV6YKwS&~c++z!p;>0SY4Uz&4B7mH_!v^F*!~guCfB@M)ibq3WGz3ON zU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtyxYKzeCvaj`<8LSAWZQfiTcl>%2~eyKuv zW*(T%$uCajDlf{Sp4IE z(69iQ2_?e8G!ug+n)+0*I5UF|ns_!?oRNVQww?jZXJFU~rWqNu(8Sk6#SPKK3!vg= zXyT<%acea3W~g`=n)n2$cp;kjY^Zn-n)phn_y#ob%~0{vXyW^z;?K~;PeH{Q1)=LR zzlunt6I0?d^9o8!7?SgI3lfV`p*)D5^2|J_dXO`q zOt95plj94D^3#hFa~a~}lZuPui%SxVN*Ll(QxZ!O8RAp(QWzNYiYs$V5|bG8ic5+h zbOwx7l3G#1pa)i~msDH~jQ|QMX$A&R>@mRe2`nC=>v-Vnb)fb@g`qqK21TfTW|#;p z{-Eo5Kx2?FDG-giwupg2oq>S?R0hEG!}6atR6n|UbUvt@0*yC<%tporQ2h&_lAzH* z38-Blbs#o~29+l;yFq*yzMuqQy@yb65@a8o!@$5G$iTpWP5*xA`YIh{#n7-q76Jgi CzU$rq literal 0 HcmV?d00001 diff --git a/test_case/guess b/test_case/guess new file mode 100755 index 0000000000000000000000000000000000000000..b6d0bbf89b89988df771a4be26aa69ede0184359 GIT binary patch literal 9704 zcmb<-^>JfjWMqH=CI&kO5U*Rn0W1U|85lH_!CWxmz+l0^&fvhn&AjT@T0Mg9Bz@PxJ2S(3<3d3k* zeQZ!UFy#Q%2cyA)3^3(z2FNZDJ^^*l2}X!M7_9=;2cto1K|%pfOHx2=9jH5Xpzegx zG9X0^3=A+Dq!uI;__QR29mF6K!-5Z_Uxa~yfti7U!QC&E;m_@j{|&F_PWA}y=N5Zx z^CBusN0CS)N0p6+z-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeD48suk%rEyV)T8sM zM`!H|kIvEu$6fz`eEC|x+x3q}@&%7>*B2g)7x=dcfcYmpx?LZ5FrMJw#$a)%gnh^V z|NsBLc5Qb3!w8lJDSrS~&d_q8L<24cF@nLyphN^ijH`6&4v>wphv80Xej~6;h=GB@ zqn9<7pMk-n^Voh+@B2js0|Ub@P>0u}m(@idA_3C+A|0f-)Aff(FRL9ygGVo`5?ICY z7gGQK|8G4|D!mKT{rBi)m4~Q+7^%v@!0=jf7dOa&URHi&DJ}*EhW%jUL00YnxqzSb zFxagi+J=FFfge1A0a7!HM?+vV1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU{HrZ zdTDBLu|lFkUTJPpYLSAS0)vSW16O5gF{t~?z`($jm#+XuTnr41(#+Np3=9lR3=9lc z-v9q^!oa`~|Kb1t5C#SY(A+b~ql{HS42%^5jM6;p91|EJ^V^^~?iug@|L+DVaOD$d zV{+zYV`}1I=U`v}nFs1hGk^I1e=f2-Xdc_y*-AkpG^sSNq*TGsP|sM;K-aJo%r&et zGSV|J(S!g0qjQx1_liV&=LYB1`R>TdI6AH5Vl}oU;wFyt*-$4nSp^p531e(O}#N#oQ;72 zZJmNW0|NudJwj0Tfad){=DR_~MWN!LK@X6)Cs-U|4rojRB<>3qXNIq%0FAqV#6fW? zz<^K>5(D9AsCxv^+>-znXJW8Gb3X$(f$1eP#K*h)g~q#j#JdGK`ntw@xCAkzC1&O@ zB7L+i= zr=}#9Br?RO=A|&CR%DhiFz6Lm=9VNTG3XVS6hY_=7%MNoBvmgxuT(FoG&3hfH#3Dn zuOzjigh8(;A8d+VYDRooQDSatd`3zU1Dwa8msDKLpqHGVo120kp0I zly^WT!Pbw!)|J54kAUPr7_^=PM8hyBeSp$3EIwiDWMB(c;Ok_d8bE5HOfUt?s~|C$ z{jl{i4AAu{+F(@(0+v2tBA`5qtRI#?VC!2zc^sw|M5DXki-7^WRtRRl2Q+sB(xV1_p*XQ2WvS5ArKW5i$*PJ4hUc zPeAq0fGPx)A0WSj+zL_yD&IgfNF45VkN^}XC_xyh5DHF0jf3+Ap=*2K0#L?LsQx4< JA4Z|;2LP;~8G8T# literal 0 HcmV?d00001 diff --git a/test_case/hello b/test_case/hello new file mode 100755 index 0000000000000000000000000000000000000000..47aabfbe42cf1756f2fdf5d031424768a99ffd43 GIT binary patch literal 9424 zcmb<-^>JfjWMqH=CI&kOFi*e%ECeAL7y^{QTrlClV8Ot~;K0DezzJ5%0v3f4FdYzj z3)nCQ1{lpC08s}LW(6^!d3Bk<7Yj*10({XZ5S9B_`#ickjN+=4S~@R7!85Z5Eu=C(GVC7 zfzc2c4S~@R7!85Z5Eu=C(GVD{A&`-plasGdo?n!cq6q5lGfFdCgXW(>efLVZO`H>~kc9y@KM&?Y z-6+Vw%m7;_02=N9$$^$N2rw`)Xv5YYfCL#B7>pPg7=##@7+~uWzr=}#9Br?RO=A|&CR%DhiFz6Lm z=9VNTG3XVS6hY_=7%MNoBvmgxuT(FoG&3hfH#3DnuOzjigh8(;A8d+VYDRooQDSat zd`3zU1Dwa8mzWeCuy6#8U?Hz30ZT&ELYZL71galqKPWAf9kQxwlT4#Htz YU=U +** hit a breakpoint at 0x4010de. + 4010de: 48 89 c7 mov rdi, rax + 4010e1: e8 1a ff ff ff call 0x401000 + 4010e6: 85 c0 test eax, eax + 4010e8: 75 1b jne 0x401105 + 4010ea: ba 06 00 00 00 mov edx, 6 +** patch memory at address 0x4010e8. + 4010e1: e8 1a ff ff ff call 0x401000 + 4010e6: 85 c0 test eax, eax + 4010e8: 90 nop + 4010e9: 90 nop + 4010ea: ba 06 00 00 00 mov edx, 6 +Num Address +0 0x4010de +** delete breakpoint 0. +** set a breakpoint at 0x4010ea. +** breakpoint 0 does not exist. +Num Address +1 0x4010ea +** hit a breakpoint at 0x4010ea. + 4010ea: ba 06 00 00 00 mov edx, 6 + 4010ef: 48 8d 05 1f 0f 00 00 lea rax, [rip + 0xf1f] + 4010f6: 48 89 c6 mov rsi, rax + 4010f9: bf 01 00 00 00 mov edi, 1 + 4010fe: e8 25 00 00 00 call 0x401128 +** patch memory at address 0x402015. + +WIN +** the target program terminated. diff --git a/test_case/out/4.ans b/test_case/out/4.ans new file mode 100644 index 0000000..ec529e1 --- /dev/null +++ b/test_case/out/4.ans @@ -0,0 +1,37 @@ +** program './hello' loaded. entry point 0x401000. + 401000: f3 0f 1e fa endbr64 + 401004: 55 push rbp + 401005: 48 89 e5 mov rbp, rsp + 401008: ba 0e 00 00 00 mov edx, 0xe + 40100d: 48 8d 05 ec 0f 00 00 lea rax, [rip + 0xfec] +** set a breakpoint at 0x401005. +** set a breakpoint at 0x40102b. +** hit a breakpoint at 0x401005. + 401005: 48 89 e5 mov rbp, rsp + 401008: ba 0e 00 00 00 mov edx, 0xe + 40100d: 48 8d 05 ec 0f 00 00 lea rax, [rip + 0xfec] + 401014: 48 89 c6 mov rsi, rax + 401017: bf 01 00 00 00 mov edi, 1 +** hit a breakpoint at 0x40102b. + 40102b: b8 01 00 00 00 mov eax, 1 + 401030: 0f 05 syscall + 401032: c3 ret + 401033: b8 00 00 00 00 mov eax, 0 + 401038: 0f 05 syscall +** enter a syscall(1) at 0x401030. + 401030: 0f 05 syscall + 401032: c3 ret + 401033: b8 00 00 00 00 mov eax, 0 + 401038: 0f 05 syscall + 40103a: c3 ret +hello world! +** leave a syscall(1) = 14 at 0x401030. + 401030: 0f 05 syscall + 401032: c3 ret + 401033: b8 00 00 00 00 mov eax, 0 + 401038: 0f 05 syscall + 40103a: c3 ret +** enter a syscall(60) at 0x401040. + 401040: 0f 05 syscall +** the address is out of the range of the text section. +** the target program terminated. diff --git a/test_case/out/h1.ans b/test_case/out/h1.ans new file mode 100644 index 0000000..f28ed48 --- /dev/null +++ b/test_case/out/h1.ans @@ -0,0 +1,44 @@ +** program './game' loaded. entry point 0x401000. + 401000: b9 05 00 00 00 mov ecx, 5 + 401005: 48 83 f9 00 cmp rcx, 0 + 401009: 74 1f je 0x40102a + 40100b: e8 2b 00 00 00 call 0x40103b + 401010: e8 5c 00 00 00 call 0x401071 +** set a breakpoint at 0x401005. +** set a breakpoint at 0x401009. +Num Address +0 0x401005 +1 0x401009 +** hit a breakpoint at 0x401005. + 401005: 48 83 f9 00 cmp rcx, 0 + 401009: 74 1f je 0x40102a + 40100b: e8 2b 00 00 00 call 0x40103b + 401010: e8 5c 00 00 00 call 0x401071 + 401015: e8 72 00 00 00 call 0x40108c +** hit a breakpoint at 0x401009. + 401009: 74 1f je 0x40102a + 40100b: e8 2b 00 00 00 call 0x40103b + 401010: e8 5c 00 00 00 call 0x401071 + 401015: e8 72 00 00 00 call 0x40108c + 40101a: 48 83 f8 01 cmp rax, 1 +** delete breakpoint 0. +guess a number : +wrong +** hit a breakpoint at 0x401009. + 401009: 74 1f je 0x40102a + 40100b: e8 2b 00 00 00 call 0x40103b + 401010: e8 5c 00 00 00 call 0x401071 + 401015: e8 72 00 00 00 call 0x40108c + 40101a: 48 83 f8 01 cmp rax, 1 +** set a breakpoint at 0x401005. +Num Address +1 0x401009 +2 0x401005 +guess a number : +wrong +** hit a breakpoint at 0x401005. + 401005: 48 83 f9 00 cmp rcx, 0 + 401009: 74 1f je 0x40102a + 40100b: e8 2b 00 00 00 call 0x40103b + 401010: e8 5c 00 00 00 call 0x401071 + 401015: e8 72 00 00 00 call 0x40108c diff --git a/test_case/out/h2.ans b/test_case/out/h2.ans new file mode 100644 index 0000000..0d709fe --- /dev/null +++ b/test_case/out/h2.ans @@ -0,0 +1,26 @@ +** program './game' loaded. entry point 0x401000. + 401000: b9 05 00 00 00 mov ecx, 5 + 401005: 48 83 f9 00 cmp rcx, 0 + 401009: 74 1f je 0x40102a + 40100b: e8 2b 00 00 00 call 0x40103b + 401010: e8 5c 00 00 00 call 0x401071 +** set a breakpoint at 0x401005. +** hit a breakpoint at 0x401005. + 401005: 48 83 f9 00 cmp rcx, 0 + 401009: 74 1f je 0x40102a + 40100b: e8 2b 00 00 00 call 0x40103b + 401010: e8 5c 00 00 00 call 0x401071 + 401015: e8 72 00 00 00 call 0x40108c +** patch memory at address 0x40101a. +guess a number : +wrong +** hit a breakpoint at 0x401005. + 401005: 48 83 f9 00 cmp rcx, 0 + 401009: 74 1f je 0x40102a + 40100b: e8 2b 00 00 00 call 0x40103b + 401010: e8 5c 00 00 00 call 0x401071 + 401015: e8 72 00 00 00 call 0x40108c +** patch memory at address 0x40101a. +guess a number : +you win +** the target program terminated. diff --git a/test_case/out/h3.ans b/test_case/out/h3.ans new file mode 100644 index 0000000..7aa13dd --- /dev/null +++ b/test_case/out/h3.ans @@ -0,0 +1,21 @@ +** please load a program first. +** program './deep' loaded. entry point 0x401131. + 401131: f3 0f 1e fa endbr64 + 401135: 55 push rbp + 401136: 48 89 e5 mov rbp, rsp + 401139: 48 83 ec 10 sub rsp, 0x10 + 40113d: b8 00 00 00 00 mov eax, 0 + 401135: 55 push rbp + 401136: 48 89 e5 mov rbp, rsp + 401139: 48 83 ec 10 sub rsp, 0x10 + 40113d: b8 00 00 00 00 mov eax, 0 + 401142: e8 3f ff ff ff call 0x401086 + 401136: 48 89 e5 mov rbp, rsp + 401139: 48 83 ec 10 sub rsp, 0x10 + 40113d: b8 00 00 00 00 mov eax, 0 + 401142: e8 3f ff ff ff call 0x401086 + 401147: 89 45 fc mov dword ptr [rbp - 4], eax +this is callee +hello world +hello unix +** the target program terminated. diff --git a/test_case/out/h4.ans b/test_case/out/h4.ans new file mode 100644 index 0000000..120a85a --- /dev/null +++ b/test_case/out/h4.ans @@ -0,0 +1,38 @@ +** program './deep' loaded. entry point 0x401131. + 401131: f3 0f 1e fa endbr64 + 401135: 55 push rbp + 401136: 48 89 e5 mov rbp, rsp + 401139: 48 83 ec 10 sub rsp, 0x10 + 40113d: b8 00 00 00 00 mov eax, 0 +** set a breakpoint at 0x401136. +** set a breakpoint at 0x40113d. +Num Address +0 0x401136 +1 0x40113d + 401135: 55 push rbp + 401136: 48 89 e5 mov rbp, rsp + 401139: 48 83 ec 10 sub rsp, 0x10 + 40113d: b8 00 00 00 00 mov eax, 0 + 401142: e8 3f ff ff ff call 0x401086 +** hit a breakpoint at 0x401136. + 401136: 48 89 e5 mov rbp, rsp + 401139: 48 83 ec 10 sub rsp, 0x10 + 40113d: b8 00 00 00 00 mov eax, 0 + 401142: e8 3f ff ff ff call 0x401086 + 401147: 89 45 fc mov dword ptr [rbp - 4], eax +** hit a breakpoint at 0x40113d. + 40113d: b8 00 00 00 00 mov eax, 0 + 401142: e8 3f ff ff ff call 0x401086 + 401147: 89 45 fc mov dword ptr [rbp - 4], eax + 40114a: b8 00 00 00 00 mov eax, 0 + 40114f: e8 5d ff ff ff call 0x4010b1 +$rax 0x0000000000000000 $rbx 0x0000000000000000 $rcx 0x0000000000000000 +$rdx 0x0000000000000000 $rsi 0x0000000000000000 $rdi 0x0000000000000000 +$rbp 0x00007fffffffe0a8 $rsp 0x00007fffffffe098 $r8 0x0000000000000000 +$r9 0x0000000000000000 $r10 0x0000000000000000 $r11 0x0000000000000000 +$r12 0x0000000000000000 $r13 0x0000000000000000 $r14 0x0000000000000000 +$r15 0x0000000000000000 $rip 0x000000000040113d $eflags 0x0000000000000202 +this is callee +hello world +hello unix +** the target program terminated. diff --git a/test_case/out/h5.ans b/test_case/out/h5.ans new file mode 100644 index 0000000..93dfc56 --- /dev/null +++ b/test_case/out/h5.ans @@ -0,0 +1,31 @@ +** program './deep' loaded. entry point 0x401131. + 401131: f3 0f 1e fa endbr64 + 401135: 55 push rbp + 401136: 48 89 e5 mov rbp, rsp + 401139: 48 83 ec 10 sub rsp, 0x10 + 40113d: b8 00 00 00 00 mov eax, 0 +** set a breakpoint at 0x40109c. +Num Address +0 0x40109c +** set a breakpoint at 0x401031. +Num Address +0 0x40109c +1 0x401031 +** delete breakpoint 0. +Num Address +1 0x401031 +** breakpoint 3 does not exist. +Num Address +1 0x401031 +** hit a breakpoint at 0x401031. + 401031: 48 89 c6 mov rsi, rax + 401034: bf 01 00 00 00 mov edi, 1 + 401039: e8 20 01 00 00 call 0x40115e + 40103e: 90 nop + 40103f: c9 leave +Num Address +1 0x401031 +this is callee +hello world +hello unix +** the target program terminated. diff --git a/test_case/out/h6.ans b/test_case/out/h6.ans new file mode 100644 index 0000000..b3cc494 --- /dev/null +++ b/test_case/out/h6.ans @@ -0,0 +1,44 @@ +** program './game' loaded. entry point 0x401000. + 401000: b9 05 00 00 00 mov ecx, 5 + 401005: 48 83 f9 00 cmp rcx, 0 + 401009: 74 1f je 0x40102a + 40100b: e8 2b 00 00 00 call 0x40103b + 401010: e8 5c 00 00 00 call 0x401071 +** set a breakpoint at 0x4010f1. +** enter a syscall(1) at 0x401052. + 401052: 0f 05 syscall + 401054: 59 pop rcx + 401055: c3 ret + 401056: 51 push rcx + 401057: b8 01 00 00 00 mov eax, 1 +guess a number : +** leave a syscall(1) = 18 at 0x401052. + 401052: 0f 05 syscall + 401054: 59 pop rcx + 401055: c3 ret + 401056: 51 push rcx + 401057: b8 01 00 00 00 mov eax, 1 +** enter a syscall(0) at 0x401088. + 401088: 0f 05 syscall + 40108a: 59 pop rcx + 40108b: c3 ret + 40108c: 51 push rcx + 40108d: b8 00 00 00 00 mov eax, 0 +** leave a syscall(0) = 2 at 0x401088. + 401088: 0f 05 syscall + 40108a: 59 pop rcx + 40108b: c3 ret + 40108c: 51 push rcx + 40108d: b8 00 00 00 00 mov eax, 0 +** hit a breakpoint at 0x4010f1. + 4010f1: 48 8d 35 2b 0f 00 00 lea rsi, [rip + 0xf2b] + 4010f8: ba 06 00 00 00 mov edx, 6 + 4010fd: 0f 05 syscall + 4010ff: 59 pop rcx + 401100: c3 ret +** enter a syscall(1) at 0x4010fd. + 4010fd: 0f 05 syscall + 4010ff: 59 pop rcx + 401100: c3 ret + 401101: b8 3c 00 00 00 mov eax, 0x3c + 401106: 48 31 ff xor rdi, rdi diff --git a/test_case/output.txt b/test_case/output.txt new file mode 100644 index 0000000..b5b9ada --- /dev/null +++ b/test_case/output.txt @@ -0,0 +1,44 @@ +** program './game' loaded. entry point 0x401000. + 401000: b9 05 00 00 00 mov ecx, 5 + 401005: 48 83 f9 00 cmp rcx, 0 + 401009: 74 1f je 0x40102a + 40100b: e8 2b 00 00 00 call 0x40103b + 401010: e8 5c 00 00 00 call 0x401071 +** set a breakpoint at 0x4010f1. +** enter a syscall(1) at 0x401052. + 401052: 0f 05 syscall + 401054: 59 pop rcx + 401055: c3 ret + 401056: 51 push rcx + 401057: b8 01 00 00 00 mov eax, 1 +guess a number : +** leave a syscall(1) = 18 at 0x401052. + 401052: 0f 05 syscall + 401054: 59 pop rcx + 401055: c3 ret + 401056: 51 push rcx + 401057: b8 01 00 00 00 mov eax, 1 +** enter a syscall(0) at 0x401088. + 401088: 0f 05 syscall + 40108a: 59 pop rcx + 40108b: c3 ret + 40108c: 51 push rcx + 40108d: b8 00 00 00 00 mov eax, 0 +** leave a syscall(0) = 2 at 0x401088. + 401088: 0f 05 syscall + 40108a: 59 pop rcx + 40108b: c3 ret + 40108c: 51 push rcx + 40108d: b8 00 00 00 00 mov eax, 0 +** hit a breakpoint at 0x4010f1. + 4010f1: 48 8d 35 2b 0f 00 00 lea rsi, [rip + 0xf2b] + 4010f8: ba 06 00 00 00 mov edx, 6 + 4010fd: 0f 05 syscall + 4010ff: 59 pop rcx + 401100: c3 ret +** enter a syscall(1) at 0x4010fd. + 4010fd: 0f 05 syscall + 4010ff: 59 pop rcx + 401100: c3 ret + 401101: b8 3c 00 00 00 mov eax, 0x3c + 401106: 48 31 ff xor rdi, rdi diff --git a/test_case/run.py b/test_case/run.py new file mode 100644 index 0000000..d3167af --- /dev/null +++ b/test_case/run.py @@ -0,0 +1,71 @@ +from pwn import * +import time +import sys +import difflib + +def read_file(filename): + """Read a file and return its contents as a list of lines.""" + with open(filename, "r") as f: + return f.readlines() + +def normalize_line(line): + """Normalize a line by stripping leading/trailing whitespace and reducing internal whitespace to a single space.""" + return ' '.join(line.split()) + +def compare_files(file1, file2): + """Compare two files and print the differences or 'accept' if they are the same.""" + content1 = read_file(file1) + content2 = read_file(file2) + + # Normalize lines to ignore whitespace differences + normalized1 = [normalize_line(line) for line in content1] + normalized2 = [normalize_line(line) for line in content2] + + diff = difflib.unified_diff(normalized1, normalized2, fromfile=file1, tofile=file2) + + + # Convert the generator to a list to check if there are any differences + diff_list = list(diff) + + if not diff_list: + print("accept") + else: + for line in diff_list: + print(line) + +if __name__ == "__main__": + if len(sys.argv) < 2: + print("Usage: ./run.py ") + sys.exit(1) + + filename = "./in/" + sys.argv[1] + ".in" + f = open(filename) + input_lines = f.read().splitlines() + + # start process + p_run = input_lines[0].split(" ") + if len(p_run) == 1: + p = process([p_run[0]]) + else: + p = process([p_run[0]] + [p_run[1]]) + + for i in range(1, len(input_lines)): + # info(input_lines[i]) + p.sendline(input_lines[i].encode()) + time.sleep(0.2) + + # wait + time.sleep(1) + + # \x00, (sdb)... + with open("output.txt", "w", encoding="utf-8") as f: + output = p.recvall(timeout=1).decode("utf-8") + output = output.replace("\x00", "") # \x00 terminate + output = output.replace("(sdb) ", "") + output = output.replace("guess a number > ", "guess a number > \n") + f.write(output) + p.close() + + ans_file = "./out/" + sys.argv[1] + ".ans" + info(ans_file) + compare_files("output.txt", ans_file) diff --git a/tmp b/tmp new file mode 100644 index 0000000..0f4c36c --- /dev/null +++ b/tmp @@ -0,0 +1,7 @@ +** program 'test/hello' loaded. entry point 0x401000 + 401000: f3 0f 1e fa endbr64 + 401004: 55 push rbp + 401005: 48 89 e5 mov rbp, rsp + 401008: ba 0e 00 00 00 mov edx, 0xe + 40100d: 48 8d 05 ec 0f 00 00 lea rax, [rip + 0xfec] +(sdb)  \ No newline at end of file diff --git a/vector.c b/vector.c new file mode 100644 index 0000000..0e17b36 --- /dev/null +++ b/vector.c @@ -0,0 +1,27 @@ +#include "vector.h" + +#include + +struct bps_node *bps = NULL; +int bps_len = 0, bps_cnt = 0, bps_max = 0; + +const struct bps_node *find(uint64_t addr) +{ + for (int i = 0; i < bps_len; i++) + if (bps[i].addr && bps[i].addr == addr) + return &bps[i]; + return NULL; +} + +int bps_push(uint64_t addr, uint8_t data) +{ + if (bps_max == 0) + bps = malloc((bps_max = 1) * sizeof(struct bps_node)); + if (bps_len + 1 >= bps_max) + bps = realloc(bps, (bps_max <<= 1) * sizeof(struct bps_node)); + + bps[bps_len].addr = addr; + bps[bps_len].data = data; + bps_cnt++; + return bps_len++; +} diff --git a/vector.h b/vector.h new file mode 100644 index 0000000..cfe08a3 --- /dev/null +++ b/vector.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +struct bps_node { + uint64_t addr; + uint8_t data; +}; + +const struct bps_node *find(uint64_t addr); +int bps_push(uint64_t addr, uint8_t data); + +extern struct bps_node *bps; +extern int bps_len, bps_cnt, bps_max;