代码执行中的功能是什么

问题描述 投票:0回答:2

我在网上找到了以下代码

void main(void)
{
  ((void(*)()) "\xeb\x11\x59\x31\xc0\x31\xdb\x31\xd2\xb0\x04\xb3\x01\xb2\x36\xcd\x80\xeb\xf6\xe8\xea\xff\xff\xff\x48\x6f\x6c\x62\x65\x72\x74\x6f\x6e\x20\x3c\x33\x20\x40\x6b\x61\x6c\x6f\x75\x30\x30\x30\x20\x2b\x20\x40\x67\x61\x6e\x64\x69\x62\x61\x72\x20\x2b\x20\x40\x53\x74\x65\x70\x68\x61\x6e\x47\x61\x6e\x64\x69\x20\x3a\x29\x0a")();
}

编译并运行此代码正在连续打印以下内容:

Holberton <3 @kalou000 + @gandibar + @StephanGandi :)
Holberton <3 @kalou000 + @gandibar + @StephanGandi :)
Holberton <3 @kalou000 + @gandibar + @StephanGandi :)
Holberton <3 @kalou000 + @gandibar + @StephanGandi :)
Holberton <3 @kalou000 + @gandibar + @StephanGandi :)
Holberton <3 @kalou000 + @gandibar + @StephanGandi :)
Holberton <3 @kalou000 + @gandibar + @StephanGandi :)

您能告诉我这是怎么工作的吗?

我已经使用-m32标志对此进行了编译。看着strace输出,它不断调用write系统调用

write(1, "Holberton <3 @kalou000 + @gandib"..., 54Holberton <3 @kalou000 + @gandibar + @StephanGandi :)
c linux
2个回答
1
投票

在c中,您可以做不可思议的事情。这是其中之一。

您会看到一个简单的缓冲区,但事实并非如此。它是用十六进制字符串表示的机器代码。

此缓冲区强制转换为void函数,然后调用。

["\xeb\x11\x59\x31\xc0..."是机器代码中的函数体,当转换为(void(*)())时它成为代码中的函数,然后由();调用

在c中,您可以将任何内容转换为任何内容。当编译器看到();时,将跳转指令汇编到第一个字节,然后让CPU执行其余指令。

这就是它的工作方式。


0
投票

如果您想成为此类程序的大师,可以查看ioccc competition

在您粘贴的代码中,您将对象的指针转换为函数的指针,并在对象的地址处执行跳转。在那个位置有来自字符串对象的数据。您插入了实际上代表代码的字符串数据。

要查看该代码代表什么,我将其插入了反汇编程序,请参见here

Disassembly
Raw Hex (zero bytes in bold):

EB115931C031DB31D2B004B301B236CD80EBF6E8EAFFFFFF486F6C626572746F6E203C3320406B616C6F75303030202B204067616E6469626172202B20405374657068616E47616E6469203A290A   

String Literal:

"\xEB\x11\x59\x31\xC0\x31\xDB\x31\xD2\xB0\x04\xB3\x01\xB2\x36\xCD\x80\xEB\xF6\xE8\xEA\xFF\xFF\xFF\x48\x6F\x6C\x62\x65\x72\x74\x6F\x6E\x20\x3C\x33\x20\x40\x6B\x61\x6C\x6F\x75\x30\x30\x30\x20\x2B\x20\x40\x67\x61\x6E\x64\x69\x62\x61\x72\x20\x2B\x20\x40\x53\x74\x65\x70\x68\x61\x6E\x47\x61\x6E\x64\x69\x20\x3A\x29\x0A"

Array Literal:

{ 0xEB, 0x11, 0x59, 0x31, 0xC0, 0x31, 0xDB, 0x31, 0xD2, 0xB0, 0x04, 0xB3, 0x01, 0xB2, 0x36, 0xCD, 0x80, 0xEB, 0xF6, 0xE8, 0xEA, 0xFF, 0xFF, 0xFF, 0x48, 0x6F, 0x6C, 0x62, 0x65, 0x72, 0x74, 0x6F, 0x6E, 0x20, 0x3C, 0x33, 0x20, 0x40, 0x6B, 0x61, 0x6C, 0x6F, 0x75, 0x30, 0x30, 0x30, 0x20, 0x2B, 0x20, 0x40, 0x67, 0x61, 0x6E, 0x64, 0x69, 0x62, 0x61, 0x72, 0x20, 0x2B, 0x20, 0x40, 0x53, 0x74, 0x65, 0x70, 0x68, 0x61, 0x6E, 0x47, 0x61, 0x6E, 0x64, 0x69, 0x20, 0x3A, 0x29, 0x0A }

Disassembly:
0:  eb 11                   jmp    0x13
2:  59                      pop    ecx
3:  31 c0                   xor    eax,eax
5:  31 db                   xor    ebx,ebx
7:  31 d2                   xor    edx,edx
9:  b0 04                   mov    al,0x4
b:  b3 01                   mov    bl,0x1
d:  b2 36                   mov    dl,0x36
f:  cd 80                   int    0x80
11: eb f6                   jmp    0x9
13: e8 ea ff ff ff          call   0x2
18: 48                      dec    eax
19: 6f                      outs   dx,DWORD PTR ds:[esi]
1a: 6c                      ins    BYTE PTR es:[edi],dx
1b: 62 65 72                bound  esp,QWORD PTR [ebp+0x72]
1e: 74 6f                   je     0x8f
20: 6e                      outs   dx,BYTE PTR ds:[esi]
21: 20 3c 33                and    BYTE PTR [ebx+esi*1],bh
24: 20 40 6b                and    BYTE PTR [eax+0x6b],al
27: 61                      popa
28: 6c                      ins    BYTE PTR es:[edi],dx
29: 6f                      outs   dx,DWORD PTR ds:[esi]
2a: 75 30                   jne    0x5c
2c: 30 30                   xor    BYTE PTR [eax],dh
2e: 20 2b                   and    BYTE PTR [ebx],ch
30: 20 40 67                and    BYTE PTR [eax+0x67],al
33: 61                      popa
34: 6e                      outs   dx,BYTE PTR ds:[esi]
35: 64 69 62 61 72 20 2b    imul   esp,DWORD PTR fs:[edx+0x61],0x202b2072
3c: 20
3d: 40                      inc    eax
3e: 53                      push   ebx
3f: 74 65                   je     0xa6
41: 70 68                   jo     0xab
43: 61                      popa
44: 6e                      outs   dx,BYTE PTR ds:[esi]
45: 47                      inc    edi
46: 61                      popa
47: 6e                      outs   dx,BYTE PTR ds:[esi]
48: 64                      fs
49: 69                      .byte 0x69
4a: 20 3a                   and    BYTE PTR [edx],bh
4c: 29 0a                   sub    DWORD PTR [edx],ecx

这种代码不可移植。

C语言,通过允许这种构造,是homoiconic language的示例-一种有效的语言范式,“代码是数据,数据是代码”(代码和数据之间没有区别)。如果您使用类似Lisp的语言进行编程,则这种编程非常普遍。但是在C语言中很少使用。

© www.soinside.com 2019 - 2024. All rights reserved.