在真实函数的副本中调用 C 函数
Calling C function inside copy of a real function
各位程序员大家好:)
我在之前复制的其他函数中间的函数调用有问题。
我不确定我的问题是否可以理解,所以我包含了代码和注释。
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() 但我不确定是否是这种情况。
我会很高兴得到简短的解释,也许还有一篇我可以了解它是如何工作的文章。
将函数的字节复制到不同的位置并尝试调用它是行不通的,除非编译器生成 position independent code - 并非所有目标的所有编译器都可以这样做,或者默认情况下可能不会这样做.
好吧,问题出在偏移量上。 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
各位程序员大家好:) 我在之前复制的其他函数中间的函数调用有问题。 我不确定我的问题是否可以理解,所以我包含了代码和注释。
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() 但我不确定是否是这种情况。 我会很高兴得到简短的解释,也许还有一篇我可以了解它是如何工作的文章。
将函数的字节复制到不同的位置并尝试调用它是行不通的,除非编译器生成 position independent code - 并非所有目标的所有编译器都可以这样做,或者默认情况下可能不会这样做.
好吧,问题出在偏移量上。 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