通过黑客堆栈等效于C中的std :: bind

时间:2014-08-13 09:17:48

标签: c function-pointers

经过一些研究后,我找不到在C中实现std :: bind的好方法。

我构建了一个小程序,它通过攻击堆栈在C中实现了等效的std :: bind。

我将尝试使用预定义的参数绑定到函数的两个函数。

我的问题是此代码仅在Windows下运行。在Linux下,这是一团糟。我的问题是我对堆栈的了解以及参数存储在内存中的方式。

谢谢,

请在下面找到我的代码:

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

我要绑定的两个函数:

void test1 (int nombre, char t, int nombre2)
{
    printf ("test 1 : %d%c%d\n", nombre, t, nombre2);
}

void test2 (char t, int nombre, int nombre2)
{
    printf ("test 2 : %c%d%d\n", t, nombre, nombre2);
}

两个将存储每个函数的参数的结构(字段的顺序很重要)。

typedef struct {
    int nombre;
    char t;
    int nombre2;
} struct1;

typedef struct {
    char t;
    int nombre;
    int nombre2;
} struct2;

这个“假”结构将用于通过取消引用structvoid *变量来写入堆栈。

// Size must be bigger than every struct*
typedef struct {
    int i[10];
} structvoid;

主要功能。

int main(int argc, char** argv) {
    // Variables to store the two functions and their arguments.
    void * functions[2];
    structvoid * data[2];

    void *func1 = (void *)&test1;
    void *func2 = (void *)&test2;

    void (*functionPtrc)(structurevoid);

    // Definition of the argument of the first function test1
    struct1 data1;
    data1.nombre = 15;
    data1.t = 'c';
    data1.nombre2 = 30;

    // and storing data.
    void *datac = malloc (sizeof (structvoid));
    memcpy(datac, &data1, sizeof (struct1));
    data[0] = (structvoid*)datac;
    functions[0] = func1;

    // Same thing with function 2.
    struct2 data2;
    data2.t = 'a';
    data2.nombre = 5;
    data2.nombre2 = 10;

    datac = malloc (sizeof (structvoid));
    memcpy(datac, &data2, sizeof (struct2));
    data[1] = (structvoid*)datac;
    functions[1] = func2;

    // Get the pointer to the first function (test1);
    functionPtrc = functions[0];
    // All the hack is here. By dereferencing the data, this will write on the stack all arguments need by the test1 function.
    functionPtrc(*data[0]);
    functionPtrc = functions[1];
    functionPtrc(*data[1]);
    // To check the result.
    test1 (data1.nombre, data1.t, data1.nombre2);
    test2 (data2.t, data2.nombre, data2.nombre2);

    return 0;
}

修改 这里是通过调用约定调用函数的程序的新版本。我只写了新的一行。这种方法的问题是我只能在“void *”字段中存储数据。如果我增加structvoid的大小,我就会有垃圾行为。

// Structure that memories each argument
typedef struct {
    void *i[1];
} structvoid;

int main(int argc, char** argv) {
    // Variables to store the two functions and their arguments.
    void * functions[2];
    structvoid * data[2];

    void *func1 = (void *)&test1;

    // Let's start with a maximum of 5 arguments
    void (*functionPtrc)(structurevoid, structurevoid, structurevoid, structurevoid, structurevoid);

    // Definition of the argument of the first function test1
    struct1 data1;
    data1.nombre = 15;
    data1.t = 'c';
    data1.nombre2 = 30;

    // and storing data.
    structvoid *datac = malloc (sizeof (structvoid)*5);
    memcpy(&datac[0], &data1.nombre, sizeof (data1.nombre));
    memcpy(&datac[1], &data1.t, sizeof (data1.t));
    memcpy(&datac[2], &data1.nombre2, sizeof (data1.nombre2));
    data[0] = datac;
    functions[0] = func1;

    // Get the pointer to the first function (test1);
    functionPtrc = functions[0];
    // Call the function with the arguments. The unused argument will be ignored.
    functionPtrc(data[0][0], data[0][1], data[0][2], data[0][3], data[0][4]);
}

0 个答案:

没有答案