继我之前的问题之后,大多数评论都说“不要这样做,你处于一种不确定的状态,你必须杀死一切并重新开始”。还有一个“安全”的解决方法。
我不明白的是为什么分段错误本质上是不可恢复的。
写入受保护内存的时刻被捕获 - 否则,将SIGSEGV不会被发送。
如果可以捕获写入受保护内存的时刻,我不明白为什么 - 理论上 - 它不能在某个低级别上恢复,并且不能将 SIGSEGV 转换为标准软件异常。
请解释为什么在分段错误之后程序处于不确定状态,因为很明显,在内存实际更改之前抛出了错误(我可能是错的,不明白为什么)。如果它被抛出,人们可以创建一个程序来更改受保护的内存,一次一个字节,出现分段错误,并最终重新编程内核 - 这种安全风险并不存在,因为我们可以看到世界仍然存在。
SIGSEGV)?我很清楚这个问题的丑陋,我还是想知道它是否可能:
当程序尝试读取/写入无效指针(NULL,未分配的块等)时,窗口会使应用程序崩溃并发生访问冲突异常.
问题是,有没有办法检查这个指针在尝试使用它之前会产生异常,否则,有没有办法捕获这个异常?
我的观察是,如果free( ptr )调用if ptr不是指向系统分配的内存的有效指针,则会发生访问冲突.让我们说我这样称呼free:
LPVOID ptr = (LPVOID)0x12345678;
free( ptr );
Run Code Online (Sandbox Code Playgroud)
这肯定会导致访问冲突.有没有办法测试指向的内存位置ptr是否是有效的系统分配内存?
在我看来,Windows操作系统内核的内存管理部分必须知道已分配了哪些内存以及剩余的内存用于分配.否则,它怎么知道是否有足够的内存来满足给定的请求?(修辞) 也就是说,似乎有理由断定必须有一个函数(或一组函数)允许用户确定指针是否是有效的系统分配内存.也许微软没有公开这些功能.如果微软没有提供这样的API,我只能假定它是出于故意和特定的原因.提供这样一个钩子进入系统是否会对系统安全造成重大威胁?
情况报告
虽然知道内存指针是否有效在许多情况下都很有用,但这是我的特殊情况:
我正在为新的硬件编写驱动程序,以替换通过USB连接到PC的现有硬件.我的任务是编写新的驱动程序,以便对当前驱动程序的现有API的调用将继续在使用它的PC应用程序中工作.因此,对现有应用程序唯一需要的更改是在启动时加载适当的驱动程序DLL.这里的问题是现有的驱动程序使用回调将接收到的串行消息发送给应用程序; 指向包含消息的已分配内存的指针通过回调从驱动程序传递到应用程序.然后,应用程序负责调用另一个驱动程序API,通过将相同的指针从应用程序传递给驱动程序来释放内存.在这种情况下,第二个API无法确定应用程序是否实际传回了指向有效内存的指针.
设置:
我正在尝试编写即使启用 ASLR 也应该能够在内存中找到结构的代码。遗憾的是,我找不到对这些区域的任何静态引用,所以我猜我必须使用暴力方式并扫描进程内存。我试图做的是扫描应用程序的整个地址空间,但这不起作用,因为某些内存区域未分配,因此SIGSEGV在访问时会产生收益。现在我认为最好getpid()使用 pid 来访问/proc/$PID/maps并尝试从那里解析数据。
但我想知道,是否有更好的方法来识别分配的区域?也许甚至是一种不需要我访问 libc (= getpid, open, close) 或摆弄字符串的方法?