在实际函数的副本中调用C函数

时间:2015-12-17 22:08:48

标签: c metaprogramming

Hello其他程序员:) 我在以前复制的其他函数中间的函数调用有问题。 我不确定我的问题是否可以理解,所以我已经包含了代码和评论。

void DeleteP2(int num){
    printf("NUM: %d\n",num);
    asm("leave");//I don't want to return to Delete(), but to main()
}

void Delete(){
    int num = 50;
    DeleteP2(num);      //<==It's crashing
    printf("ERROR\n");  //<==If I comment DeleteP2(num), this one is crashing too
}
/*           Assembly code of Delete();
   0x00401521 <+0>: push   ebp
   0x00401522 <+1>: mov    ebp,esp
   0x00401524 <+3>: sub    esp,0x28
   0x00401527 <+6>: mov    DWORD PTR [ebp-0xc],0x32
   0x0040152e <+13>:    mov    eax,DWORD PTR [ebp-0xc]
   0x00401531 <+16>:    mov    DWORD PTR [esp],eax
   0x00401534 <+19>:    call   0x401500 <DeleteP2>
   0x00401539 <+24>:    mov    DWORD PTR [esp],0x404009
   0x00401540 <+31>:    call   0x4026e0 <puts>
   0x00401545 <+36>:    leave  
   0x00401546 <+37>:    ret
*/

typedef void (*DelFunc)(void);

DelFunc Create(){//Make a copy of Delete() function
    unsigned char *code = VirtualAlloc(NULL,38,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
    unsigned char *func = (unsigned char*)Delete;
    for(int i=0;i<38;++i)code[i]=func[i];
    return (DelFunc)code;
}

int main(int argc, char *argv[]) {
    DelFunc f = Create();

    Delete();//<== That one is not crashing
    f();//<<== Stack trace error

    VirtualFree(f,0,MEM_RELEASE);
    return 0;
}

这可能是偏移的问题吗?我的意思是f()可能需要不同的函数地址,而不是Delete()但是我不确定是不是这样。 我会很高兴从简短的解释和文章,我将能够了解它是如何工作的。

2 个答案:

答案 0 :(得分:1)

将函数的字节复制到其他位置并尝试调用它将不起作用,除非编译器生成position independent code - 并非所有目标的所有编译器都可以这样做,或者默认情况下可能不会这样做。 / p>

答案 1 :(得分:0)

问题在于补偿。 mah的评论指示了我一点,现在我知道该怎么做了。

void DeleteP2(int num){
    printf("NUM: %d\n",num);
    asm("leave");//I don't want to return to Delete(), but to main()
}
void (*Delete2)(int);//Get location of DeleteP2
void Delete(){
    int num = 50;
    Delete2(num); //I don't want generated offset but a exact location.
}

现在效果很好。谢谢你 Ps我不需要位置独立的代码生成器,这个技巧就是我所需要的:D