char sh[] = "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\x52\x68\x6e\x2f\x73\x68"
"\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80";为什么程序员要对这个字符串使用十六进制编码?例如,为什么第一个字符使用\x31而不是1
发布于 2012-10-28 20:42:32
尽管sh是一个由char元素组成的数组,但它也可以看作是一个字节数组。好吧,假设char是8位宽,通常是这样的。
因此,如果此变量包含代码,则将其表示为字节数组比文本数组更清晰。例如,可能存在不容易表示为可打印字符的元素。由于内容将由编译器或汇编器生成,因此它最初将是二进制代码块的形式。最简单、最清晰的方法就是将其转换为您所呈现的十六进制表示。
发布于 2012-10-28 20:59:08
我用反汇编程序运行了你的代码。该数组似乎包含一些用于x86 linux的外壳代码:
804a014: 31 c0 xor %eax,%eax #set registers to zero
804a016: 31 db xor %ebx,%ebx
804a018: 31 c9 xor %ecx,%ecx
804a01a: 31 d2 xor %edx,%edx
804a01c: 52 push %edx #push a null word
804a01d: 68 6e 2f 73 68 push $0x68732f6e #push "/bin/sh"
804a022: 68 2f 2f 62 69 push $0x69622f2f
804a027: 89 e3 mov %esp,%ebx
804a029: 52 push %edx #push another null word
804a02a: 53 push %ebx #push pointer to string
804a02b: 89 e1 mov %esp,%ecx
804a02d: b0 0b mov $0xb,%al #system call 11: execve
804a02f: cd 80 int $0x80 #call the system显然,它在内存中组装字符串/bin/sh,然后尝试调用该程序。
发布于 2012-10-28 20:44:56
它是十六进制的转义序列。
C11 (n1570),§6.4.4.4 Character constants
十六进制转义序列中反斜杠和字母x后面的十六进制数字被视为整数字符常量的单个字符或宽字符常量的单个宽字符构造的一部分。这样形成的十六进制整数的数值指定所需字符或宽字符的值。
要执行它,你可以使用funcion指针类型转换。
void (*shell)();
shell = (void(*)()) (&sh);
shell();https://stackoverflow.com/questions/13108856
复制相似问题