【问题标题】:Shortest C++ code to cause an access violation导致访问冲突的最短 C++ 代码
【发布时间】:2016-07-10 07:02:21
【问题描述】:

我们可以比以下更短(按字符)或更优雅:

*(int*)0=0;

目标是引发访问冲突。首选独立于平台的解决方案。

【问题讨论】:

  • 如果在别处隐藏单个字符 typedef(可能是模板参数),则可以省去 2 个字符。

标签: c++ obfuscation


【解决方案1】:

假设您的字符数中不包含包含

对于 Linux:

raise(11); //SIGSEGV

对于 Windows:

raise(SIGSEGV); // I don't know the SIGSEGV value for sure so more characters required

【讨论】:

  • 对于 Windows,它没有那么简短和甜蜜:RaiseException(STATUS_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE,0,NULL); msdn.microsoft.com/en-us/library/windows/desktop/…
  • 你必须爱上我们的团队:)
  • 抱歉,这比最初建议的要长,需要一个 ifdef 来区分。
  • @ChristopherOezbek,raise(11) 的长度为 9 个字符。建议的选项长度为 10 个字符。它是非便携式的,但它更小。对于 Windows,您所要做的就是 printf("%d",SIGSEGV) 然后替换值。
【解决方案2】:

这是我可以使用与 OP 和 MasterID 不同的方法得出的最接近的结果:

asm("ret");

我们的想法是尽可能笨拙地操作堆栈。我相信 gcc 会编译这个。

【讨论】:

    【解决方案3】:

    没有可移植的方式导致分段违规或其他类似错误。

    编译器可以并且确实假设未定义的行为永远不会发生。如果他们在某个代码分支中检测到 UB,他们完全有权优化整个分支以使其不存在。

    if (x == 5) 
    {
      std::cout << "Gonna crash";
      *(int*)0 = 42;
    }
    

    编译器可以将此代码块转换为无操作。

    raise(SIGSEGV) 可能会或可能不会导致实际违规,但它是导致程序表现得好像发生违规的唯一可移植方式。

    【讨论】:

    • 哪个编译器会这样做? GCC、MSVC、XCode 或 Clang 中的任何一个?
    • 我不知道当前的编译器可以做到这一点,但有些编译器会做非常相似的事情。看here。该程序应该在第三次迭代时崩溃了,对吧?为什么循环没有结束?
    • clang 会警告您“将删除非易失性空指针的间接,而不是陷阱”,但 AFAICT 它实际上并没有删除间接。见this
    • 有时它确实有效...ideone.com/P3AeRi - 我同意编译器可能会干扰访问冲突,但在 ideone.com 的情况下,我猜他们使用的异常处理程序可能只是继续...
    • 不,这里的问题是i*1000000000i &gt;= 3时溢出,所以编译器假定i永远不是&gt;=3,并删除所有对应的检查和分支。
    【解决方案4】:

    从 Unix(主要是 Linux)的角度来看:

    如果我们将“访问冲突”定义为填写siginfo_tsi_addr字段的“任何信号”,那么根据sigaction(2)即为:SIGILL, SIGFPE, SIGSEGV, SIGBUS, and SIGTRAP

    • SIGILL 可以通过执行任何无效指令来生成,包括永久无效指令,例如 x86 上的 ud2(编码为 0x0F 0x0B),但无论如何跳转到随机点通常都会生成这种情况。

    • SIGFPE可以通过任何整数除以0或最大负整数除以-1生成

    • SIGSEGV 可以通过读取或写入任何未映射或PROT_NONE'd 页面或写入只读页面来生成。

    • SIGBUS我一直不知道它是从哪里来的。

    • SIGTRAP可以由你的arch的断点指令生成,在x86上是int3,也就是单字节0xcc。从一个角度来看,这是最短的代码。如果您坚持使用最可能的 C 代码,则必须根据编译器的想法将其包装在 asm 块中。

    还有其他涉及系统调用的示例,例如kill

    【讨论】:

    • 提高(SIGSEGV);似乎最接近,但代码仍然不短。
    猜你喜欢
    • 1970-01-01
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    • 2012-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-22
    相关资源
    最近更新 更多