在Demystifying the Execve Shellcode中解释了一种编写execve shellcode的方法:
#include<stdio.h>
#include<string.h>
unsigned char code[] =
"\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";
main()
{
printf("Shellcode Length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;
ret();
}
int (*ret)() = (int(*)())code;
行有什么作用?
答案 0 :(得分:16)
int (*ret)() = (int(*)())code;
~~~~~~~~~~~~ ~~~~~~~~~~~~~~
1 2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3
它将ret
定义为指向函数的指针,该函数没有参数()
并返回int
。因此,那些()
表示函数参数的定义。
用于将code
转换为指向函数的指针,该函数没有参数()
并返回int
。
将code
转换为函数并将其分配给ret
。之后,您可以拨打ret();
。
unsigned char code[] = "\x31\xc0\x50\x68\x6e\x2f\...
它是由十六进制值表示的一系列机器指令。它将作为函数注入代码。
答案 1 :(得分:0)
int行通过指向code []数组来声明ret()函数;换句话说,该函数被映射到code []二进制指令。
\ x构造是一种在字符串中嵌入十六进制字符的安全方法。例如,您可以将“\ x31”替换为“1”,因为字符代码“1”为49或十六进制31。
答案 2 :(得分:0)
可以用更简单的形式重写这个函数指针部分吗?
我不知道你是否认为这更简单,但可能:
#include <stdio.h>
#include <string.h>
unsigned char code[] =
"\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";
typedef int(*shellcode_t)();
int main(int argc, char ** argv) {
printf("Shellcode Length: %ld\n", strlen(code));
shellcode_t ret = (shellcode_t)code;
ret();
}
答案 3 :(得分:0)
(*(void(*)())shellcode)()
==
p = (void(*)()) shellcode;
(*p)();