Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在运行时组合函数体 这听起来很有点尖刻,但是有人知道在C++中运行时方法体组合的方法吗?我目前正在获取函数的地址,然后将memcopy复制到可执行内存,但它存在不需要的prolog/epilog的问题_C++ - Fatal编程技术网

在运行时组合函数体 这听起来很有点尖刻,但是有人知道在C++中运行时方法体组合的方法吗?我目前正在获取函数的地址,然后将memcopy复制到可执行内存,但它存在不需要的prolog/epilog的问题

在运行时组合函数体 这听起来很有点尖刻,但是有人知道在C++中运行时方法体组合的方法吗?我目前正在获取函数的地址,然后将memcopy复制到可执行内存,但它存在不需要的prolog/epilog的问题,c++,C++,基本上,我有几十个简单的操作,它们接受相同的参数,但不返回任何内容,我想在运行时用这些简单的操作构建一个函数。为什么不使用汇编?为什么不使用汇编?它有点重,所以可能不是您想要的,但是您可以尝试使用您的代码。它有点重,因此可能不是您想要的,但您可以尝试使用您的代码。实现您想要的功能的一个简单解决方案是将函数指针存储在数组中。 然后,您可以在运行时创建脚本中的函数指针列表。 通过迭代列表并调用函数来执行脚本。一个简单的解决方案是将函数指针存储在数组中。 然后,您可以在运行时创建脚本中的函数指针列表。

基本上,我有几十个简单的操作,它们接受相同的参数,但不返回任何内容,我想在运行时用这些简单的操作构建一个函数。

为什么不使用汇编?

为什么不使用汇编?

它有点重,所以可能不是您想要的,但是您可以尝试使用您的代码。

它有点重,因此可能不是您想要的,但您可以尝试使用您的代码。

实现您想要的功能的一个简单解决方案是将函数指针存储在数组中。 然后,您可以在运行时创建脚本中的函数指针列表。
通过迭代列表并调用函数来执行脚本。

一个简单的解决方案是将函数指针存储在数组中。 然后,您可以在运行时创建脚本中的函数指针列表。
您可以通过迭代列表并调用函数来执行脚本。

它不起作用,但我告诉您我所知道的。您可以使用setjmp获取当前进程计数器位置,并在您获得的已填写结构中工作

如果我必须像你要求的那样做,我会在例程的开头和结尾放两个setjmp,分配可执行内存,这可能吗?我以为文本部分是只读的,但是是的。。。缓冲区溢出漏洞利用是通过执行堆栈来工作的,所以是的,我想您可以,除非您有NX technostuff,然后从四个setjmp括号中复制块。在这个过程中,您将遇到一堆不可重定位的操作码,我想,就像它们引用汇编代码中其他操作码的绝对地址一样。当然,如果您复制,这个地址必须相应地更改


祝你好运。

这行不通,但我告诉你我所知道的。您可以使用setjmp获取当前进程计数器位置,并在您获得的已填写结构中工作

如果我必须像你要求的那样做,我会在例程的开头和结尾放两个setjmp,分配可执行内存,这可能吗?我以为文本部分是只读的,但是是的。。。缓冲区溢出漏洞利用是通过执行堆栈来工作的,所以是的,我想您可以,除非您有NX technostuff,然后从四个setjmp括号中复制块。在这个过程中,您将遇到一堆不可重定位的操作码,我想,就像它们引用汇编代码中其他操作码的绝对地址一样。当然,如果您复制,这个地址必须相应地更改

祝你好运。

模板

如果您有:

template <int Operations>
struct Foo
{

  static void Do(int a, int b)
  {
    if (Operations & 1)
    {
      /// op 1 
    }

    if (Operations & 2)
    {
      /// op 2
    }
    if (Operations & 4)
    {
      /// op 3 
    }
    //...
  }
};
优化器将丢弃与您的专业化无关的块,例如

Foo::Do77,88

将只处理第二和第三步,而不为第一步生成代码

您应该检查编译器的输出,但大多数应该能够。我用它来检查选定的数组属性,在VC6和更高版本的编译器下工作,比如charm

模板

如果您有:

template <int Operations>
struct Foo
{

  static void Do(int a, int b)
  {
    if (Operations & 1)
    {
      /// op 1 
    }

    if (Operations & 2)
    {
      /// op 2
    }
    if (Operations & 4)
    {
      /// op 3 
    }
    //...
  }
};
优化器将丢弃与您的专业化无关的块,例如

Foo::Do77,88

将只处理第二和第三步,而不为第一步生成代码


您应该检查编译器的输出,但大多数应该能够。我用它来检查选定的数组属性,在VC6和更高版本的编译器下工作,比如charm,以获得真正的动态解决方案。。。将它们物理地结合在一起:

假设您的操作使用的指令数量大致相同。 确保参数保持不变,即堆栈和调用寄存器保持不变。 用一个罕见的指令标记结尾。 现在,您已经准备好构建指令向量:

struct Op {
    char code[MAX_OP_SIZE];
    public Op(const void (*op)()) { 
        /* fill code with no-ops */ 
        const char* opCode = (char*)op;
        char* opCodeCopy = &code[0];
        while (*opCode != GUARD_INSTRUCTION) {
            *opCodeCopy++ = *opCode++;
        }
    }
}

std::vector<Op> combinedOperation;

combinedOperation.push_back(op1);
// ...

void (*combinedOpFunc)(params) = void *()(params)&combinedOperation[0]; // not sure about syntax here

combinedOpFunc(data);
// start praying
成功 typedef void*OPTYPEparamtype

void op1(paramtype param, OPTYPE nextop, jmp_buf returnFrame)
{
     // ...
     if (nextop) {
         // place (paramtype+1) into argument slot 2  (assume +1 does pointer arithmetic)
         // update program counter to value of paramtype
     } else {
         longjmp(returnFrame, 0);
     }
}
然后列出操作列表:

std::vector<OPTYPE> ops; ops.push_back(&op1); // ...

对于真正的动态解决方案。。。将它们物理地结合在一起:

假设您的操作使用的指令数量大致相同。 确保参数保持不变,即堆栈和调用寄存器保持不变。 用一个罕见的指令标记结尾。 现在,您已经准备好构建指令向量:

struct Op {
    char code[MAX_OP_SIZE];
    public Op(const void (*op)()) { 
        /* fill code with no-ops */ 
        const char* opCode = (char*)op;
        char* opCodeCopy = &code[0];
        while (*opCode != GUARD_INSTRUCTION) {
            *opCodeCopy++ = *opCode++;
        }
    }
}

std::vector<Op> combinedOperation;

combinedOperation.push_back(op1);
// ...

void (*combinedOpFunc)(params) = void *()(params)&combinedOperation[0]; // not sure about syntax here

combinedOpFunc(data);
// start praying
成功 typedef void*OPTYPEparamtype

void op1(paramtype param, OPTYPE nextop, jmp_buf returnFrame)
{
     // ...
     if (nextop) {
         // place (paramtype+1) into argument slot 2  (assume +1 does pointer arithmetic)
         // update program counter to value of paramtype
     } else {
         longjmp(returnFrame, 0);
     }
}
然后列出操作列表:

std::vector<OPTYPE> ops; ops.push_back(&op1); // ...

我看不出这有什么实际用途,除了它:-

所以首先你应该决定一个平台。 你根本不可能以跨平台的方式做到这一点。 实际上,即使在同一个平台上,以跨多个编译器工作的方式来实现这一点可能相当困难。 当然,还有处理器类型:-

然后,您应该以某种方式检查您正在复制的代码是否可以重新加载 被解雇了。不是所有的东西都能像你想的那样移动

您必须非常了解调用约定,以确保不会弄乱堆栈

了解编译器如何生成prolog/epilog。你可以通过在函数的开头和结尾添加一些不起任何作用的代码序列来作弊,但你可以使用它们作为签名,然后查找ie.nop;否;否;异或ax,ax;否;推斧;爆裂斧;否;否;没有。请确保编译器未对其进行优化:-

确保您可以编写/执行该代码。现代CPU和操作系统通常不允许写入代码段或执行非代码段。因此,您必须找出哪些方法可以更改100%特定于操作系统的权限

然后玩一些有趣的战斗,比如地址空间布局随机化、堆栈随机化、数据执行预防、堆随机化

无论如何,有很多工作要做。而且毫无意义,除了享受一个好的挑战,并在这个过程中学习一些汇编和操作系统内部。 或者证明自己是1337,但是,如果你问我,在stackoverflow上问怎么做并不完全是1337:-


无论如何,祝你好运。

我看不出这有什么实际用途,除了它:-

所以首先你应该决定一个平台。 你根本不可能以跨平台的方式做到这一点。 实际上,即使在同一个平台上,以跨多个编译器工作的方式来实现这一点可能相当困难。 当然,还有处理器类型:-

然后,您应该以某种方式检查正在复制的代码是否可以重新定位。不是所有的东西都能像你想的那样移动

您必须非常了解调用约定,以确保不会弄乱堆栈

了解编译器如何生成prolog/epilog。你可以通过在函数的开头和结尾添加一些不起任何作用的代码序列来作弊,但你可以使用它们作为签名,然后查找ie.nop;否;否;异或ax,ax;否;推斧;爆裂斧;否;否;没有。请确保编译器未对其进行优化:-

确保您可以编写/执行该代码。现代CPU和操作系统通常不允许写入代码段或执行非代码段。因此,您必须找出哪些方法可以更改100%特定于操作系统的权限

然后玩一些有趣的战斗,比如地址空间布局随机化、堆栈随机化、数据执行预防、堆随机化

无论如何,有很多工作要做。而且毫无意义,除了享受一个好的挑战,并在这个过程中学习一些汇编和操作系统内部。 或者证明自己是1337,但是,如果你问我,在stackoverflow上问怎么做并不完全是1337:-



无论如何,祝你好运。

@Hippiehunter:是的,听起来真的很不错hackish@RageZ:是的,但看起来也很整洁。我想是禁果吧。你的意思是你想把功能和操作联系起来?最终目标是什么?表演是否易于提及该特定操作组?好奇?仅仅做一个来自地狱的黑客是不够的吗?@Hippiehunter:是的,听起来很不错hackish@RageZ:是的,但看起来也很整洁。我想是禁果吧。你的意思是你想把功能和操作联系起来?最终目标是什么?表演是否易于提及该特定操作组?好奇?做一个来自地狱的黑客还不够吗?@Stefano Borini,对@Hippiehunter,你可以在微软或你自己制造的系统上这样做。@Stefano Borini,对@Hippiehunter,你可以在microsoft或你自己制作的系统上这样做。这种方法不会避免调用。这种方法不会避免调用。堆执行不是问题。只有几个调用,任何东西都是可执行的,实际上我已经在简单的情况下实现了这一点。我想我被不可移动的指令烧坏了。但是现在已经提到了罕见的指令或setjmp,这听起来像是一种获取内存位置进行复制的好方法。我会给你答案,因为这是最完整的答案,但完整的答案似乎需要很多技巧。嗨,Mihai-你介意我问你是否已经完全放弃了对你非常酷的ansi econsole产品的所有支持?我无法在最新的eclipse Luna中安装它。我可以在插件区域手动放置一些东西并显示图标,但是控制台没有显示esc代码。说它依赖于Java6SE,但我认为Luna是7。不确定这是否是一个因素。你的网站关闭了吗?我看到其他人的评论说,在我访问捆绑包和您的github项目之后,他们在尝试从市场安装时遇到了相同的错误。不,我仍然支持它。看起来我的ISP遇到了一些麻烦,但我认为这是暂时的。我已经在GitHub上准备了一个备用站点,如果错误继续,我将把它移到那里。但这应该与Java6无关。。。你能在上提交一个错误信息吗?
如果您没有github帐户,也可以在这里留言:非常感谢。堆执行不是问题,只需几个调用,任何东西都是可执行的,实际上我已经在简单的情况下实现了这一点。我想我被不可移动的指令烧坏了。但是现在已经提到了罕见的指令或setjmp,这听起来像是一种获取内存位置进行复制的好方法。我会给你答案,因为这是最完整的答案,但完整的答案似乎需要很多技巧。嗨,Mihai-你介意我问你是否已经完全放弃了对你非常酷的ansi econsole产品的所有支持?我无法在最新的eclipse Luna中安装它。我可以在插件区域手动放置一些东西并显示图标,但是控制台没有显示esc代码。说它依赖于Java6SE,但我认为Luna是7。不确定这是否是一个因素。你的网站关闭了吗?我看到其他人的评论说,在我访问捆绑包和您的github项目之后,他们在尝试从市场安装时遇到了相同的错误。不,我仍然支持它。看起来我的ISP遇到了一些麻烦,但我认为这是暂时的。我已经在GitHub上准备了一个备用站点,如果错误继续,我将把它移到那里。但这应该与Java6无关。。。你能在上提交一个错误信息吗?如果您没有github帐户,请在此处留言:非常感谢。因为这是在运行时,请纠正我的错误。如果我错了,请纠正我,我需要在运行时执行汇编程序的工作,我想我只是对这么多工作不感兴趣。因为这是在运行时,如果我错了,请纠正我,我需要在运行时执行汇编程序的工作,我想我只是对这么多工作不感兴趣。