Initial commit
This commit is contained in:
3
.gdb_history
Normal file
3
.gdb_history
Normal file
@@ -0,0 +1,3 @@
|
||||
exit
|
||||
exit
|
||||
exit
|
||||
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
sdb
|
||||
*.o
|
||||
18
Makefile
Normal file
18
Makefile
Normal file
@@ -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
|
||||
BIN
hw3_testcase.zip
Normal file
BIN
hw3_testcase.zip
Normal file
Binary file not shown.
37
logger.h
Normal file
37
logger.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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__)
|
||||
116
main.c
Normal file
116
main.c
Normal file
@@ -0,0 +1,116 @@
|
||||
#include "sdb.h"
|
||||
#include "vector.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/limits.h>
|
||||
|
||||
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;
|
||||
}
|
||||
410
sdb.c
Normal file
410
sdb.c
Normal file
@@ -0,0 +1,410 @@
|
||||
#include "sdb.h"
|
||||
#include "logger.h"
|
||||
#include "vector.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <capstone/capstone.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
52
sdb.h
Normal file
52
sdb.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/user.h>
|
||||
|
||||
#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;
|
||||
24
test/1.ans
Normal file
24
test/1.ans
Normal file
@@ -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.
|
||||
44
test/2.ans
Normal file
44
test/2.ans
Normal file
@@ -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.
|
||||
9
test/2.in
Normal file
9
test/2.in
Normal file
@@ -0,0 +1,9 @@
|
||||
./sdb ./hello
|
||||
break 0x401005
|
||||
break 40102b
|
||||
info break
|
||||
si
|
||||
si
|
||||
cont
|
||||
info reg
|
||||
cont
|
||||
49
test/3.ans
Normal file
49
test/3.ans
Normal file
@@ -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.
|
||||
14
test/3.in
Normal file
14
test/3.in
Normal file
@@ -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
|
||||
45
test/4.ans
Normal file
45
test/4.ans
Normal file
@@ -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.
|
||||
9
test/4.in
Normal file
9
test/4.in
Normal file
@@ -0,0 +1,9 @@
|
||||
./sdb ./hello
|
||||
break 0x401005
|
||||
break 40102b
|
||||
cont
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
32
test/5.ans
Normal file
32
test/5.ans
Normal file
@@ -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.
|
||||
9
test/5.in
Normal file
9
test/5.in
Normal file
@@ -0,0 +1,9 @@
|
||||
./sdb ./guess
|
||||
patch 0x4010e8 0x9090 2
|
||||
break 0x4010e8
|
||||
cont
|
||||
1
|
||||
break 4010ea
|
||||
patch 4010ea 0x03ba 4
|
||||
cont
|
||||
cont
|
||||
27
test/6.ans
Normal file
27
test/6.ans
Normal file
@@ -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.
|
||||
35
test/7.ans
Normal file
35
test/7.ans
Normal file
@@ -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.
|
||||
8
test/7.in
Normal file
8
test/7.in
Normal file
@@ -0,0 +1,8 @@
|
||||
./sdb ./hello
|
||||
break 0x401030
|
||||
break 0x401040
|
||||
syscall
|
||||
syscall
|
||||
cont
|
||||
syscall
|
||||
syscall
|
||||
8
test/Makefile
Normal file
8
test/Makefile
Normal file
@@ -0,0 +1,8 @@
|
||||
all:
|
||||
chmod +x run_examples.py guess hello
|
||||
|
||||
test: all
|
||||
./run_examples.py
|
||||
|
||||
clean:
|
||||
rm -f *.out diff.txt
|
||||
BIN
test/guess
Executable file
BIN
test/guess
Executable file
Binary file not shown.
BIN
test/hello
Executable file
BIN
test/hello
Executable file
Binary file not shown.
134
test/run_examples.py
Executable file
134
test/run_examples.py
Executable file
@@ -0,0 +1,134 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from typing import List
|
||||
from pwn import process, context
|
||||
|
||||
context.log_level = "error"
|
||||
|
||||
cases_to_run = ["1", "2", "3", "4", "5", "6", "7"]
|
||||
|
||||
TIMEOUT_SECONDS = 0.01
|
||||
|
||||
|
||||
def wrap_recvrepeat(r):
|
||||
if r.poll() is not None:
|
||||
return b""
|
||||
return r.recvrepeat(TIMEOUT_SECONDS)
|
||||
|
||||
|
||||
def recvrepeats(r):
|
||||
output = wrap_recvrepeat(r)
|
||||
while output == b"":
|
||||
if r.poll() is not None:
|
||||
break
|
||||
output = wrap_recvrepeat(r)
|
||||
|
||||
ret = b""
|
||||
|
||||
while output != b"":
|
||||
ret += output
|
||||
output = wrap_recvrepeat(r)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def execute_process(
|
||||
case: str, command: List[str], stdin: List[str]
|
||||
) -> 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")
|
||||
13
test_case/Makefile
Normal file
13
test_case/Makefile
Normal file
@@ -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
|
||||
BIN
test_case/deep
Executable file
BIN
test_case/deep
Executable file
Binary file not shown.
BIN
test_case/game
Executable file
BIN
test_case/game
Executable file
Binary file not shown.
BIN
test_case/guess
Executable file
BIN
test_case/guess
Executable file
Binary file not shown.
BIN
test_case/hello
Executable file
BIN
test_case/hello
Executable file
Binary file not shown.
6
test_case/in/1.in
Normal file
6
test_case/in/1.in
Normal file
@@ -0,0 +1,6 @@
|
||||
../sdb
|
||||
si
|
||||
load ./hello
|
||||
si
|
||||
si
|
||||
cont
|
||||
9
test_case/in/2.in
Normal file
9
test_case/in/2.in
Normal file
@@ -0,0 +1,9 @@
|
||||
../sdb ./hello
|
||||
break 0x401005
|
||||
break 40102b
|
||||
info break
|
||||
si
|
||||
si
|
||||
cont
|
||||
info reg
|
||||
cont
|
||||
14
test_case/in/3.in
Normal file
14
test_case/in/3.in
Normal file
@@ -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
|
||||
9
test_case/in/4.in
Normal file
9
test_case/in/4.in
Normal file
@@ -0,0 +1,9 @@
|
||||
../sdb ./hello
|
||||
break 0x401005
|
||||
break 40102b
|
||||
cont
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
13
test_case/in/h1.in
Normal file
13
test_case/in/h1.in
Normal file
@@ -0,0 +1,13 @@
|
||||
../sdb ./game
|
||||
break 401005
|
||||
break 401009
|
||||
info break
|
||||
syscall
|
||||
syscall
|
||||
delete 0
|
||||
cont
|
||||
2
|
||||
break 401005
|
||||
info break
|
||||
cont
|
||||
2
|
||||
9
test_case/in/h2.in
Normal file
9
test_case/in/h2.in
Normal file
@@ -0,0 +1,9 @@
|
||||
../sdb ./game
|
||||
break 401005
|
||||
cont
|
||||
patch 40101a 0x02f88348 4
|
||||
cont
|
||||
1
|
||||
patch 40101a 0x01f88348 4
|
||||
cont
|
||||
1
|
||||
6
test_case/in/h3.in
Normal file
6
test_case/in/h3.in
Normal file
@@ -0,0 +1,6 @@
|
||||
../sdb
|
||||
si
|
||||
load ./deep
|
||||
si
|
||||
si
|
||||
cont
|
||||
9
test_case/in/h4.in
Normal file
9
test_case/in/h4.in
Normal file
@@ -0,0 +1,9 @@
|
||||
../sdb ./deep
|
||||
break 401136
|
||||
break 40113d
|
||||
info break
|
||||
si
|
||||
si
|
||||
cont
|
||||
info reg
|
||||
cont
|
||||
12
test_case/in/h5.in
Normal file
12
test_case/in/h5.in
Normal file
@@ -0,0 +1,12 @@
|
||||
../sdb ./deep
|
||||
break 40109c
|
||||
info break
|
||||
break 401031
|
||||
info break
|
||||
delete 0
|
||||
info break
|
||||
delete 3
|
||||
info break
|
||||
cont
|
||||
info break
|
||||
cont
|
||||
9
test_case/in/h6.in
Normal file
9
test_case/in/h6.in
Normal file
@@ -0,0 +1,9 @@
|
||||
../sdb ./game
|
||||
break 0x4010f1
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
syscall
|
||||
3
|
||||
syscall
|
||||
syscall
|
||||
19
test_case/out/1.ans
Normal file
19
test_case/out/1.ans
Normal file
@@ -0,0 +1,19 @@
|
||||
** please load a program first.
|
||||
** 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]
|
||||
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
|
||||
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
|
||||
hello world!
|
||||
** the target program terminated.
|
||||
36
test_case/out/2.ans
Normal file
36
test_case/out/2.ans
Normal file
@@ -0,0 +1,36 @@
|
||||
** 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.
|
||||
Num Address
|
||||
0 0x401005
|
||||
1 0x40102b
|
||||
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
|
||||
** 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
|
||||
$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
|
||||
hello world!
|
||||
** the target program terminated.
|
||||
37
test_case/out/3.ans
Normal file
37
test_case/out/3.ans
Normal file
@@ -0,0 +1,37 @@
|
||||
** 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
|
||||
** set a breakpoint at 0x4010de.
|
||||
guess a number >
|
||||
** 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.
|
||||
37
test_case/out/4.ans
Normal file
37
test_case/out/4.ans
Normal file
@@ -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.
|
||||
44
test_case/out/h1.ans
Normal file
44
test_case/out/h1.ans
Normal file
@@ -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
|
||||
26
test_case/out/h2.ans
Normal file
26
test_case/out/h2.ans
Normal file
@@ -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.
|
||||
21
test_case/out/h3.ans
Normal file
21
test_case/out/h3.ans
Normal file
@@ -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.
|
||||
38
test_case/out/h4.ans
Normal file
38
test_case/out/h4.ans
Normal file
@@ -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.
|
||||
31
test_case/out/h5.ans
Normal file
31
test_case/out/h5.ans
Normal file
@@ -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.
|
||||
44
test_case/out/h6.ans
Normal file
44
test_case/out/h6.ans
Normal file
@@ -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
|
||||
44
test_case/output.txt
Normal file
44
test_case/output.txt
Normal file
@@ -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
|
||||
71
test_case/run.py
Normal file
71
test_case/run.py
Normal file
@@ -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 <test case id>")
|
||||
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)
|
||||
7
tmp
Normal file
7
tmp
Normal file
@@ -0,0 +1,7 @@
|
||||
[36m** program 'test/hello' loaded. entry point 0x401000
|
||||
[m[m 401000: [m[mf3 0f 1e fa endbr64
|
||||
[m[m 401004: [m[m55 push rbp
|
||||
[m[m 401005: [m[m48 89 e5 mov rbp, rsp
|
||||
[m[m 401008: [m[mba 0e 00 00 00 mov edx, 0xe
|
||||
[m[m 40100d: [m[m48 8d 05 ec 0f 00 00 lea rax, [rip + 0xfec]
|
||||
[m[m(sdb) [m
|
||||
27
vector.c
Normal file
27
vector.c
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "vector.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
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++;
|
||||
}
|
||||
Reference in New Issue
Block a user