15

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;有什么作用?

4

4 回答 4

18
  int (*ret)() = (int(*)())code;
  ~~~~~~~~~~~~   ~~~~~~~~~~~~~~
        1              2

  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
               3
  1. 它定义ret为指向没有参数()并返回的函数的指针int。因此,那些()表示函数参数的定义。

  2. 它用于转换code为指向没有参数()并返回的函数的指针int

  3. 转换code为函数并将其分配给ret. 之后,您可以调用ret();.

 

unsigned char code[] =  "\x31\xc0\x50\x68\x6e\x2f\...

它是由十六进制值表示的机器指令序列。它将作为函数注入到代码中。

于 2013-05-18T17:38:35.997 回答
2
    (*(void(*)())shellcode)()

==

    p = (void(*)()) shellcode;
    (*p)();
于 2016-03-28T03:26:53.387 回答
0

int 行通过指向 code[] 数组来声明 ret() 函数;换句话说,函数映射到 code[] 二进制指令。

\x 构造是在字符串中嵌入十六进制字符的安全方法。例如,您可以将“\x31”替换为“1”,因为“1”的字符代码是 49 或十六进制 31。

于 2013-05-18T17:16:35.793 回答
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();
}
于 2015-07-28T12:18:05.310 回答