翻译整理自这几片文章 链接1

作者自制了个语言 设计到底层原语的调试,需要调试器,他用 python-ptrace library, pyelftoolsdistorm3 糊了一个

下面是介绍

先安装

pip3 install python-ptrace

然后执行下面的python语句,注意: a.out 随便写个c程序,生成可执行文件,这个程序不能直接退出,否则会出现错误

ptrace.error.PtraceError: ptrace(cmd=16, pid=30165, 0, 0) error #1: Operation not permitted

这个错误会误导你以为什么系统错误,实际上不是的,进程pid不在strace肯定错误的

作者的代码是这样的

#include <stdio.h>
#include <unistd.h>

int my_var;
typedef int (*func_ptr_t)(void);

void test_function(){
  printf("Called test_function! Probably from the debugger.\n");
  printf("my_var=%i\n", my_var);
}

int main(){
  printf("Starting main loop\n");
  my_var = 1;
  while (1){
    usleep(100000);
  }
}

python脚本准备

import ptrace.debugger
import subprocess
shell_command = ["./a.out"]
child_proc = subprocess.Popen(shell_command)
pid = child_proc.pid
debugger = ptrace.debugger.PtraceDebugger()
process = debugger.addProcess(pid, False)

这样就有了一个简单的调试环境,和操作gdb是一样的,不过更清晰一些

获取寄存器

regs = process.getregs()
registers = {k:getattr(regs, k) for k in dir(regs) if not k.startswith('_')}
registers
{'cs': 51, 'ds': 0, 'eflags': 582, 'es': 0, 'fs': 0, 'fs_base': 139788087355200, 'gs': 0, 'gs_base': 0, 'orig_rax': 35, 'r10': 140721172406752, 'r11': 582, 'r12': 4195536, 'r13': 140721172408432, 'r14': 0, 'r15': 0, 'r8': 18446744073709551615, 'r9': 0, 'rax': 18446744073709551100, 'rbp': 140721172408208, 'rbx': 0, 'rcx': 18446744073709551615, 'rdi': 140721172408176, 'rdx': 0, 'rip': 139788083114400, 'rsi': 0, 'rsp': 140721172408168, 'ss': 43}

读内存

import binascii
binascii.hexlify(process.readBytes(registers['rsp'], 8))
b'd4be0cf3227f0000'

单步执行汇编

process.getreg('rip')  #139788083114406
process.singleStep()
process.getreg('rip') #139788083114408

触发信号

import signal
process.waitSignals(signal.SIGTRAP)

这里是埋信号,后面主动写寄存器出发

也可以把这两步结合起来

def step():
    process.singleStep()
    process.waitSignals(signal.SIGTRAP)

Int 3触发,对应0xCC

直接写入

process.writeBytes(process.getreg('rip'), bytes(0xCC))
process.cont()
process.waitSignals(signal.SIGTRAP)

ref

  • 作者的演示代码仓库 https://github.com/asrp/ptracedbg/blob/master/
  • strace遇到错误的解决方案 https://blog.packagecloud.io/eng/2015/11/15/strace-cheat-sheet/