【问题标题】:Tamper system calls behavior with QEMU使用 QEMU 篡改系统调用行为
【发布时间】:2021-09-07 09:31:18
【问题描述】:

我不知道这是否是正确的地方,但我不知道在哪里可以问。 我想改变 QEMU 内部的系统调用行为(如果我可以临时修改的话,甚至可以在内核内部),例如,如果我调用 read(fd) 调用,我想挂钩这个调用并可能改变文件描述符或内容本身。 我想要一个像这样的一般结构,可能是通过使用插件或者我不知道是什么:

syscall_interceptor(syscall, syscall_parameters){
    new_parameters = tamper(syscall_parameters)
    syscall(new_parameters )
}

类似的东西。可能吗?怎么样?

【问题讨论】:

  • 这个问题是关于 x64 架构的吗?是关于 QEMU 仿真模式(TCG 加速器)吗?
  • @nevilad 是的,它是关于 x64 架构的,是的,我说的是 QEMU 仿真和 TCG。我想我可以写一个插件,但如果我是正确的,我只能拦截调用,而不能篡改它
  • 你可以用 ptrace 做这种事情,完全不涉及 QEMU,如果这对你有用的话。 QEMU 本身并没有为此提供任何机制。

标签: linux-kernel system-calls qemu


【解决方案1】:

要使用 qemu 解决这个问题,您可以将 syscall 处理程序更改为 x64 TCG 模式。这是qemu\target\i386\seg_helper.c 源文件中名为helper_syscall 的函数。您需要第二个(#else 分支 #if defined(CONFIG_USER_ONLY))。更改代码后,您必须构建 qemu。

根据this sys_read 系统调用应该有: rax = 0,rdi = fd,rsi = buf,rdx = count。

您可以在处理程序的顶部添加更改:

void helper_syscall(CPUX86State *env, int next_eip_addend)
{
    int selector;

    if (0 == env->regs[R_EAX]) {
      //sys_read syscall
      //env->regs[R_EDI] - fd, change it, to change fd value:
      // env->regs[R_EDI] = newFd;
      //env->regs[R_ESI] - buf pointer
      //env->regs[R_EDX] - count

      //To rewrite buf contents, use cpu_memory_rw_debug
      //and set write address to rsi:
      //CPUState *cpu = env_cpu(env);
      //if (cpu_memory_rw_debug(cpu, env->regs[R_ESI], 
      //                     (uint8_t *)&newContents, newContents size, 1))
      //{
      //  handle buf write error here.
      //}
    }
    .....

查看代码 sn-p 中的 cmets,在重写缓冲区之前不要忘记检查缓冲区大小。

【讨论】:

    猜你喜欢
    • 2015-09-18
    • 1970-01-01
    • 2012-11-05
    • 2013-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-17
    • 1970-01-01
    相关资源
    最近更新 更多