很久以前,我注意到在FreeBSD上的GDB中使用

设置跟随叉模式子对象

并不能真正起作用。在各种Capture The Flag竞赛中遇到了一些挑战。
例如,服务器将生成一个处理连接的子代。
子代代码有一个我想调试的漏洞,但是gdb永远不会跟着
孩子执行死刑,我还不能真正观察到被触发的漏洞。
到目前为止,我已经通过两种方式解决了这个问题:


连接,等待孩子产生,而不是将GDB附加到它。
之所以可行,是因为产生的孩子具有可以附加的自己的PID,但由于首先我必须从一个会话建立连接而感到非常痛苦,在另一个数据库中附加GDB,然后在第一个中发送有效负载/继续连接。


在fork调用之后修补二进制文件,以继续在父进程中执行而不是在t他的孩子。
这也很痛苦,因为那时我必须重新启动整个父进程以创建另一个调试会话。


还有其他一些技巧可以使用,但是这些足以说明我的观点。
现在我知道FreeBSD对此有一些限制,但是有什么改进吗?
有没有办法修补GDB以添加此功能?有什么建议可以解决这个问题吗?

评论

在我的Linux机器上,我必须设置“ fork-fork-mode”子节点,但同时也要捕获fork,以使GDB在fork调用中停止并跟随该子节点。

在linux上很好,bsd出现了fork-fork-mode的问题...而且似乎仍然存在...

#1 楼

如果您想同时为父母和孩子,请尝试在fork上设置捕获点。

set-follow-fork-mode ask 
catch fork 


关于第二点,我在.gdbinit中有这个宏(相信最终来自Tavis Ormandy)。在许多情况下,包括您自己的情况下,它几乎很有用。

define assemble
 # dont enter routine again if user hits enter
 dont-repeat
 if ($argc)
  if (*$arg0 = *$arg0)
    # check if we have a valid address by dereferencing it,
    # if we havnt, this will cause the routine to exit.
  end
  printf "Instructions will be written to %#x.\n", $arg0
 else
  printf "Instructions will be written to stdout.\n"
 end
 printf "Type instructions, one per line.\n"
 printf "End with a line saying just \"end\".\n"
 if ($argc)
  # argument specified, assemble instructions into memory
  # at address specified.
  shell nasm -f bin -o /dev/stdout /dev/stdin \
    <<< "$( echo "BITS 32"; while read -ep '>' r && test "$r" != end; \
                do echo -E "$r"; done )" | hexdump -ve \
        '1/1 "set *((unsigned char *) $arg0 + %#2_ax) = %#02x\n"' \
            > ~/.gdbassemble
  # load the file containing set instructions
  source ~/.gdbassemble
  # all done.
  shell rm -f ~/.gdbassemble
 else
  # no argument, assemble instructions to stdout
  shell nasm -f bin -o /dev/stdout /dev/stdin \
    <<< "$( echo "BITS 32"; while read -ep '>' r && test "$r" != end; \
                do echo -E "$r"; done )" | ndisasm -i -b32 /dev/stdin
 end
end
document assemble
Assemble instructions using nasm.
Type a line containing "end" to indicate the end.
If an address is specified, insert instructions at that address.
If no address is specified, assembled instructions are printed to stdout.
Use the pseudo instruction "org ADDR" to set the base address.
end


评论


漂亮的宏,我肯定会用它!呵呵,这是zsh不友好的:p

– dna
2013年6月15日9:38



对于zsh,应将read -ep'>'r替换为read r

– dna
13年6月15日在10:43

因为有一个很好的宏,所以接受了答案,这很有帮助:)特别是由于没有真正的解决方案(至少我还没有找到一个解决方案,请参见我的答案),问题是后叉模式没有在bsd上工作,但尚未解决...

–0xea
2013年6月17日10:59

#2 楼

我对此进行了深入研究,并通过mrduclaw在SO上找到了这个问题(原始文章中的链接已消失,但Web存档中有此链接)。他有和我完全一样的问题,并且寻找解决方案的动机也完全一样。

所以我在研究更多东西,直到不久前Freebsd才不再支持fork。这是ptrace。提交了一个补丁,但我真的不知道是否应用了该补丁。我会尝试自己应用它,然后看看它是否将开始工作。