2012-02-16 94 views
2

有没有办法让我检测/启动 - 创伤 - 写入字符串而不使用mprotect(我不能使用)?检测写入字符串

目前我只能在下面的读取中检测到写入,但这太迟了(以下读取可能来自完全不同的lib)。

注意:将gdb与观察点一起使用失败,原因是优化程序在进程内存中移动字符串。

编辑:有问题的变量是一个类成员(char *),它包含一些元数据作为字符串的前缀。字符串是需要不可变的部分,并且前缀必须是可写的。我在静态哈希类中有几百万个这样的对象,并且可以从我们的代码中的任何地方访问它们。

+1

如何在未优化的代码上使用gdb观察点? – 2012-02-16 09:09:04

+0

因为我不能在另一台机器上重现错误,并且将所有libs \ execs替换为未优化的将需要重新安装操作系统(这是非常低级的代码) – Neowizard 2012-02-16 09:12:55

+0

不是'watch myString'独立于优化器放置了你的字符串'myString'?找出内存中的'myString'是不是调试器的头痛? – 2012-02-16 10:18:34

回答

1

你可以试着将所有写入内存的代码封装在预处理器宏中,这些代码检查你正在使用的地址,但由于大多数人喜欢使用裸骨指针(而不是封装事物的库调用),它会可能是很多努力。

唯一的其他选项是mprotect(2)或GDB,它们都使用CPU的特殊部件来观察地址总线以访问有问题的存储器。

既然你不能使用它,最后的选择是打印在纸上的代码,并坐在一个安静的角落几天来阅读它。这通常会起作用,但大多数人会避免这种努力(并且因为它看起来不像“真正的”工作;-)。

+0

我希望能够看看所有相关的代码,但它远远超过数百万潜在的代码行。目前我正试图挑选有罪的图书馆来缩小搜索范围。 – Neowizard 2012-02-16 10:23:50

+0

如果它总是出现乱码的字符串,那么有问题的代码必须以某种方式得到它的地址。这意味着它不能与创建/使用字符串的代码完全无关。 – 2012-02-16 13:38:58

+1

的确,这是一个过程,但这是一个巨大的过程。无论如何,我确实已经设法将其缩小到相关的流程流程,从那里开始,它只是一个非常注意阅读代码的问题......太过于我看起来像“真正”(并且最终非常有效)的工作:)。 – Neowizard 2012-02-17 08:09:27

0

我不确定在gdb中是否有类似于dbx中的“trace”的命令,但是在dbx中我记得使用了一个名为“trace”的命令,它可以用于跟踪代码中的各个变量,并向您显示当变量值在执行过程中发生变化时。

+0

'痕迹'不会做你在这里说的。根据DBX文档“跟踪 - 在程序执行时跟踪打印的信息”。事实上,'停止'这样做!参考DBX docs -'stop-当达到给定行时停止执行,输入过程或函数,变量更改,模块加载或卸载,或条件为真' 而'watch'是GDB中最接近的'stop' – 2012-02-16 10:16:19

+0

是的,跟踪信息意味着当程序执行时特定变量中的值发生变化时它会打印。如果希望程序一旦变量中的值发生变化就停止,则可以使用Stop。每次变量值更改时跟踪都会继续执行打印。 – 2012-02-16 10:20:56