简体   繁体   English

最短的C ++代码导致访问冲突

[英]Shortest C++ code to cause an access violation

Can we go shorter (character-wise) or more elegant than: 我们可以比以下字符更短(从字符角度)或更优雅:

*(int*)0=0;

The goal is to raise an access violation. 目标是引发访问冲突。 Platform independent solutions are preferred. 平台无关的解决方案是首选。

Assuming you are not including includes into your character count 假设您不包括要包括在内的字符数

For Linux: 对于Linux:

raise(11); //SIGSEGV

For Windows: 对于Windows:

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

There is no portable way of causing a segmentation violation or another similar error. 没有可移植的方式来导致分段违规或其他类似错误。

Compilers can and do assume that undefined behavior never occurs. 编译器可以并且确实假定从未发生未定义的行为。 If they detect UB in a certain branch of code, they have every right to optimize the entire branch out of existence. 如果他们在某个代码分支中检测到UB,则他们有权优化整个分支而不存在。

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

A compiler can translate this block of code to a no-op. 编译器可以将此代码块转换为无操作。

raise(SIGSEGV) may or may not cause an actual violation, but it is the only portable way of cause a program to behave as if a violation has occurred. raise(SIGSEGV)可能会或可能不会导致实际的违规,但这是使程序表现发生违规的唯一可移植方式。

Here is the closest I could come using a different approach from the OP and MasterID: 这是我可能使用与OP和MasterID不同的方法得出的最接近的结果:

asm("ret");

The idea is to manipulate the stack as clumsily as possible. 这个想法是尽可能笨拙地操纵堆栈。 I believe gcc will compile this. 我相信gcc会编译这个。

From a Unix (mostly Linux) perspective: 从Unix(主要是Linux)的角度来看:

If we define "access violation" as "any signal" that fills in the si_addr field of siginfo_t , then according to sigaction(2) that is: SIGILL, SIGFPE, SIGSEGV, SIGBUS, and SIGTRAP . 如果将“访问冲突”定义为siginfo_tsi_addr字段中填充的“任何信号”,则根据sigaction(2)SIGILL, SIGFPE, SIGSEGV, SIGBUS, and SIGTRAP

  • SIGILL can be generated by executing any invalid instruction, including permanently invalid instructions such as ud2 on x86 (encoded as 0x0F 0x0B ), but jumping to a random point often generates this anyway. SIGILL可以通过执行任何无效指令来生成,包括永久无效的指令,例如x86上的ud2 (编码为0x0F 0x0B ),但是无论如何跳转到随机点通常都会生成此指令。

  • SIGFPE can be generated by dividing any integer by 0 or dividing the most negative integer by -1 可以通过将任何整数除以0或将最大负整数除以-1来生成SIGFPE

  • SIGSEGV can be generated by a read or write to any unmapped or PROT_NONE 'd page, or a write to a read-only page. SIGSEGV可以通过对任何未映射的页面或PROT_NONE的页面进行读取或写入,或者对只读页面的写入来生成。

  • SIGBUS I have never figured out where it comes from. SIGBUS我从未弄清楚它的来源。

  • SIGTRAP can be generated by your arch's breakpoint instruction, which on x86 is int3 , which is the single byte 0xcc . 可以通过arch的断点指令生成SIGTRAP ,该指令在x86上是int3 ,即单字节0xcc From one perspective, that is the shortest possible code. 从一个角度来看,这是最短的代码。 If you insist on the shorest possible C code you'd have to wrap it in an asm block according to your compiler's whims. 如果您坚持使用最可行的C代码,则必须根据编译器的要求将其包装在asm块中。

There are also other examples involving syscalls such as kill . 还有其他涉及syscall的示例,例如kill

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM