C++ 从exe生成外壳代码?

C++ 从exe生成外壳代码?,c++,c,exe,shellcode,C++,C,Exe,Shellcode,因此,最近我一直在学习汇编等低级编程语言,据我所知,汇编语言只是符号二进制语言,并且遇到了外壳编码,例如.\x4D。。。我发现可以将外壳代码输入C/C++应用程序,然后执行它-我的问题是,是否可以从现有的exe应用程序生成外壳代码,然后在C/C++应用程序中使用生成的外壳代码?我是否误解了外壳编码的可能性?非常感谢-一个对低级编程知识非常有限的人 是否可以从现有的exe应用程序生成外壳代码,然后在C/C++应用程序中使用生成的外壳代码 答:不是。外壳代码是独立于基的,可执行PE文件有大量的头文件

因此,最近我一直在学习汇编等低级编程语言,据我所知,汇编语言只是符号二进制语言,并且遇到了外壳编码,例如.\x4D。。。我发现可以将外壳代码输入C/C++应用程序,然后执行它-我的问题是,是否可以从现有的exe应用程序生成外壳代码,然后在C/C++应用程序中使用生成的外壳代码?我是否误解了外壳编码的可能性?非常感谢-一个对低级编程知识非常有限的人

是否可以从现有的exe应用程序生成外壳代码,然后在C/C++应用程序中使用生成的外壳代码

答:不是。外壳代码是独立于基的,可执行PE文件有大量的头文件,等等,在执行某些操作之前不能执行它/

外壳代码-这是一个非常大的问题

首先,您需要知道外部库(如kernel32、user32libs等)的函数地址存储在导入地址表中,该表由windows loader在启动时填写。所有的内存工作都是通过地址进行的,即在编译阶段进行计算。所以你需要自己去找addreses

要从外壳代码调用函数,您必须拥有自己的函数地址加载程序。此加载程序必须加载kernel32.dll库,搜索GetProcAddress函数并填充IAT

你不知道你的外壳代码将被加载到什么地址,你可以从这样的代码中知道它,调用delta offset

call    delta
 delta:
pop     ebp
sub     ebp,offset delta
现在在ebp中,实际addreses的偏移量,因此要获得函数地址的变量,需要加上偏移量,例如:

lea eax, [variable]
add eax, ebp; adding a delta-offset
mov ecx, dword ptr DS:[eax]
要编译代码供将来使用,您应该使用类似FASM的东西,编译后使用WinHex编辑器->复制->复制所有->GREP C源代码

您将得到\x00\x28等,要调用它,您需要设置外壳代码数组的执行权限,并通过命令处理程序(如jmp/call/etc)更改EIP

有一个示例显示在Windows系统Hello,World MessageBox中

# include <stdlib.h>
# include <stdio.h>
# include <string.h>

# include <windows.h>


int
main(void)
{
  char *shellcode = "\x33\xc9\x64\x8b\x49\x30\x8b\x49\x0c\x8b"
    "\x49\x1c\x8b\x59\x08\x8b\x41\x20\x8b\x09"
    "\x80\x78\x0c\x33\x75\xf2\x8b\xeb\x03\x6d"
    "\x3c\x8b\x6d\x78\x03\xeb\x8b\x45\x20\x03"
    "\xc3\x33\xd2\x8b\x34\x90\x03\xf3\x42\x81"
    "\x3e\x47\x65\x74\x50\x75\xf2\x81\x7e\x04"
    "\x72\x6f\x63\x41\x75\xe9\x8b\x75\x24\x03"
    "\xf3\x66\x8b\x14\x56\x8b\x75\x1c\x03\xf3"
    "\x8b\x74\x96\xfc\x03\xf3\x33\xff\x57\x68"
    "\x61\x72\x79\x41\x68\x4c\x69\x62\x72\x68"
    "\x4c\x6f\x61\x64\x54\x53\xff\xd6\x33\xc9"
    "\x57\x66\xb9\x33\x32\x51\x68\x75\x73\x65"
    "\x72\x54\xff\xd0\x57\x68\x6f\x78\x41\x01"
    "\xfe\x4c\x24\x03\x68\x61\x67\x65\x42\x68"
    "\x4d\x65\x73\x73\x54\x50\xff\xd6\x57\x68"
    "\x72\x6c\x64\x21\x68\x6f\x20\x57\x6f\x68"
    "\x48\x65\x6c\x6c\x8b\xcc\x57\x57\x51\x57"
    "\xff\xd0\x57\x68\x65\x73\x73\x01\xfe\x4c"
    "\x24\x03\x68\x50\x72\x6f\x63\x68\x45\x78"
    "\x69\x74\x54\x53\xff\xd6\x57\xff\xd0";

  DWORD why_must_this_variable;
  BOOL ret = VirtualProtect (shellcode, strlen(shellcode),
    PAGE_EXECUTE_READWRITE, &why_must_this_variable);

  if (!ret) {
    printf ("VirtualProtect\n");
    return EXIT_FAILURE;
  }

  printf("strlen(shellcode)=%d\n", strlen(shellcode));

  ((void (*)(void))shellcode)();

  return EXIT_SUCCESS;
}
您可能正在寻找RunPE算法。该算法可以在另一个内部执行PE可执行文件。您正在打开另一个进程、复制节、填写IAT表并从新入口点恢复目标进程。这是一个代码注入技术,使用我的恶意软件。因此,我不会解释如何实现这一点

是否可以从现有的exe应用程序生成外壳代码,然后在C/C++应用程序中使用生成的外壳代码

答:不是。外壳代码是独立于基的,可执行PE文件有大量的头文件,等等,在执行某些操作之前不能执行它/

外壳代码-这是一个非常大的问题

首先,您需要知道外部库(如kernel32、user32libs等)的函数地址存储在导入地址表中,该表由windows loader在启动时填写。所有的内存工作都是通过地址进行的,即在编译阶段进行计算。所以你需要自己去找addreses

要从外壳代码调用函数,您必须拥有自己的函数地址加载程序。此加载程序必须加载kernel32.dll库,搜索GetProcAddress函数并填充IAT

你不知道你的外壳代码将被加载到什么地址,你可以从这样的代码中知道它,调用delta offset

call    delta
 delta:
pop     ebp
sub     ebp,offset delta
现在在ebp中,实际addreses的偏移量,因此要获得函数地址的变量,需要加上偏移量,例如:

lea eax, [variable]
add eax, ebp; adding a delta-offset
mov ecx, dword ptr DS:[eax]
要编译代码供将来使用,您应该使用类似FASM的东西,编译后使用WinHex编辑器->复制->复制所有->GREP C源代码

您将得到\x00\x28等,要调用它,您需要设置外壳代码数组的执行权限,并通过命令处理程序(如jmp/call/etc)更改EIP

有一个示例显示在Windows系统Hello,World MessageBox中

# include <stdlib.h>
# include <stdio.h>
# include <string.h>

# include <windows.h>


int
main(void)
{
  char *shellcode = "\x33\xc9\x64\x8b\x49\x30\x8b\x49\x0c\x8b"
    "\x49\x1c\x8b\x59\x08\x8b\x41\x20\x8b\x09"
    "\x80\x78\x0c\x33\x75\xf2\x8b\xeb\x03\x6d"
    "\x3c\x8b\x6d\x78\x03\xeb\x8b\x45\x20\x03"
    "\xc3\x33\xd2\x8b\x34\x90\x03\xf3\x42\x81"
    "\x3e\x47\x65\x74\x50\x75\xf2\x81\x7e\x04"
    "\x72\x6f\x63\x41\x75\xe9\x8b\x75\x24\x03"
    "\xf3\x66\x8b\x14\x56\x8b\x75\x1c\x03\xf3"
    "\x8b\x74\x96\xfc\x03\xf3\x33\xff\x57\x68"
    "\x61\x72\x79\x41\x68\x4c\x69\x62\x72\x68"
    "\x4c\x6f\x61\x64\x54\x53\xff\xd6\x33\xc9"
    "\x57\x66\xb9\x33\x32\x51\x68\x75\x73\x65"
    "\x72\x54\xff\xd0\x57\x68\x6f\x78\x41\x01"
    "\xfe\x4c\x24\x03\x68\x61\x67\x65\x42\x68"
    "\x4d\x65\x73\x73\x54\x50\xff\xd6\x57\x68"
    "\x72\x6c\x64\x21\x68\x6f\x20\x57\x6f\x68"
    "\x48\x65\x6c\x6c\x8b\xcc\x57\x57\x51\x57"
    "\xff\xd0\x57\x68\x65\x73\x73\x01\xfe\x4c"
    "\x24\x03\x68\x50\x72\x6f\x63\x68\x45\x78"
    "\x69\x74\x54\x53\xff\xd6\x57\xff\xd0";

  DWORD why_must_this_variable;
  BOOL ret = VirtualProtect (shellcode, strlen(shellcode),
    PAGE_EXECUTE_READWRITE, &why_must_this_variable);

  if (!ret) {
    printf ("VirtualProtect\n");
    return EXIT_FAILURE;
  }

  printf("strlen(shellcode)=%d\n", strlen(shellcode));

  ((void (*)(void))shellcode)();

  return EXIT_SUCCESS;
}
您可能正在寻找RunPE算法。该算法可以在另一个内部执行PE可执行文件。您正在打开另一个进程、复制节、填写IAT表并从新入口点恢复目标进程。这是一个代码注入技术,使用我的恶意软件。因此,我将不解释如何认识到它是一种机器代码,它被用作攻击的有效载荷,例如一个。根据其使用的漏洞,它可能有限制,例如最大长度或某些字节值,例如不允许为零。对于什么是外壳代码,没有一个一刀切的答案

不过,一般来说:是的,原则上可以在外壳代码中嵌入完整的程序。它可以采用一个小包装器的形式,可能是用汇编手工编写的,将程序写入一个新的.exe文件,然后运行它,也可以使用更复杂的技术替换内存中的当前程序。可能有自动工具来创建这种外壳代码,尽管我不知道有什么具体的工具

然而,你问题的语气让我觉得你可能是mi 理解一些重要的事情:

我发现您可以将外壳代码输入到C/C++应用程序中,然后执行它

这是一个bug,不是一个特性。能够将新代码注入正在运行的程序(该程序并不特别允许这样做)是一个主要的安全缺陷。在过去的几十年中,这类事情一直是许多安全漏洞的根源,开发人员花费了大量精力试图阻止这种情况的发生

如果可以向程序中注入外壳代码,则该程序将被破坏。

是用作漏洞(如漏洞)有效载荷的机器代码。根据其使用的漏洞,它可能有限制,例如最大长度或某些字节值,例如不允许为零。对于什么是外壳代码,没有一个一刀切的答案

不过,一般来说:是的,原则上可以在外壳代码中嵌入完整的程序。它可以采用一个小包装器的形式,可能是用汇编手工编写的,将程序写入一个新的.exe文件,然后运行它,也可以使用更复杂的技术替换内存中的当前程序。可能有自动工具来创建这种外壳代码,尽管我不知道有什么具体的工具

然而,你问题的语气让我觉得你可能误解了一些重要的事情:

我发现您可以将外壳代码输入到C/C++应用程序中,然后执行它

这是一个bug,不是一个特性。能够将新代码注入正在运行的程序(该程序并不特别允许这样做)是一个主要的安全缺陷。在过去的几十年中,这类事情一直是许多安全漏洞的根源,开发人员花费了大量精力试图阻止这种情况的发生


如果可以向程序中注入外壳代码,则程序将被破坏。

注意:汇编是机器代码的符号形式,是一系列数字,告诉CPU要做什么,二进制只是一种写入数字的方式,而不是特定于机器代码,而且\x4D是一种十六进制表示法,它也只是一种写数字的方法,而不是外壳代码特有的。外壳代码只是用作攻击有效载荷的机器代码。注意:汇编是机器代码的一种符号形式,它是一个数字序列,告诉CPU做什么,二进制只是一种写数字的方式,而不是特定于机器代码,而且\x4D是一种十六进制表示法,它也只是一种写数字的方法,而不是外壳代码特有的。外壳代码只是用作漏洞利用有效载荷的机器代码。