- 论坛徽章:
- 2
|
回复 #36 swordfish.cn 的帖子
原帖由 swordfish.cn 于 2010-1-30 17:42 发表 ![]()
是我的话,我就直接加编译参数了。所以这个offset是可计算的。所以,回到我的出发点,我就觉得anchor有点多余了。
发现整天对着计算机,要和人解释清楚自己的想法还真不是一般的难啊。
嘿, 我也有同感。 附加一个 : 要理解别人的想法还真不是一般的难。
难道你觉得让代码的行为依赖于编译参数是很好的做法? 你依然觉得anchor多余?
这是你的审美观, 我不作评价。
该说的我都说了, 我不觉得anchor是多余的。
原帖由 swordfish.cn 于 2010-1-30 17:42 发表 ![]()
另,我在Linux试了一下,即使是mprotect改了权限,也不能把printf改写,怎么办?
unsigned long page = ((unsigned long)printf >> 12) << 12;
unsigned long offset = ((unsigned long)printf) % 4096;
mprotect(page, 4096, PROT_WRITE|PROT_READ);
memcpy((void*)printf, "12345", 5);
会segfault的。
mprotect首个参数的类型是long???
你可以先检查一下mprotect的返回值。 看是否执行成功。
而且, 你将printf的执行权限给取消了。
另外, 附一段代码, Windows下的, msvc8 和mingw4.4.0 通过。
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <windows.h>
void f(const char* s) {
puts("f");
puts(s);
}
void forwarding2f(char* function)
{
long offset = (long)&f - (long)function - 5;
unsigned char jmp = 0xe9;
DWORD old = 0;
VirtualProtect(function, 5, PAGE_EXECUTE_READWRITE, &old);
memcpy(function, &jmp, 1);
memcpy(function+1, &offset, sizeof offset);
}
void g(const char* s) {
puts("g");
puts(s);
}
int main(void)
{
forwarding2f( (char*)&g );
g("hello");
forwarding2f( (char*)&printf );
printf("printf");
return 0;
}
|
输出 :
f
hello
f
printf |
|