为匿名函数创建C语言附加组件是否可行?

Dmi*_*try 0 c assembly lambda functional-programming shellcode

我知道C编译器能够获取独立的代码,并针对它们所针对的特定系统从中生成独立的shellcode。

例如,在中给出以下内容anon.c

int give3() {
    return 3;
}
Run Code Online (Sandbox Code Playgroud)

我可以跑

gcc anon.c -o anon.obj -c
objdump -D anon.obj
Run Code Online (Sandbox Code Playgroud)

这给了我(在MinGW上):

anon1.obj:     file format pe-i386


Disassembly of section .text:

00000000 <_give3>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   b8 03 00 00 00          mov    $0x3,%eax
   8:   5d                      pop    %ebp
   9:   c3                      ret    
   a:   90                      nop
   b:   90                      nop
Run Code Online (Sandbox Code Playgroud)

所以我可以像这样制作main:

main.c

#include <stdio.h>
#include <stdint.h>

int main(int argc, char **argv)
{
    uint8_t shellcode[] = {
        0x55,
        0x89, 0xe5,
        0xb8, 0x03, 0x00, 0x00, 0x00,
        0x5d, 0xc3,
        0x90,
        0x90
    };

    int (*p_give3)() = (int (*)())shellcode;
    printf("%d.\n", (*p_give3)());
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,自动化转换自包含匿名函数的过程是否可行,该匿名函数不引用不在其范围或参数之内的任何东西?

例如:

#include <stdio.h>
#include <stdint.h>

int main(int argc, char **argv)
{
    uint8_t shellcode[] = [@[
        int anonymous() {
            return 3;
        }
    ]];

    int (*p_give3)() = (int (*)())shellcode;
    printf("%d.\n", (*p_give3)());
}
Run Code Online (Sandbox Code Playgroud)

哪个可以将文本编译为shellcode,并将其放入缓冲区?

我问的原因是因为我真的很喜欢编写C,但是制作pthreads,回调是非常痛苦的。并且一旦您在C语言上走了一步就得到了“ lambdas”的概念,就会失去语言的ABI(例如,C ++具有lambda,但是您在C ++中所做的一切突然依赖于实现)和“ Lisplike”脚本附加项(例如,插入Lisp,Perl,JavaScript / V8,任何其他已经知道如何泛化回调的运行时)都使回调非常容易,但是比扔掉shellcode的开销要大得多。

如果可行,则可以将仅被调用一次的函数放入调用它的函数主体中,从而减少全局范围的污染。这也意味着您不需要为要定位的每个系统手动生成shellcode,因为每个系统的C编译器已经知道如何将自包含的C转换为程序集,因此为什么要为此而做,并且破坏了其可读性自己的代码和一堆二进制Blob。

因此,问题是:这是否实用(对于完全独立的函数,例如,即使它们要调用puts,put也必须作为参数提供或在参数的哈希表/结构内提供)?还是有一些问题使这无法实现?

dus*_*uff 5

苹果公司在clang中实现了一个非常相似的功能,即“块”。这是一个示例:

int main(int argc, char **argv)
{
    int (^blk_give3)(void) = ^(void) {
        return 3;
    };

    printf("%d.\n", blk_give3());

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

更多信息: