- 论坛徽章:
- 0
|
再加一个知识点:
- void foo()
- {
- printf("hello\n");
- }
- int main()
- {
- void (*pf)() = foo;
- pf();
- return 0;
- }
复制代码
类似以上通过指针间接调用的代码,在x86上,gcc通常是产生类似以下这种调用的编码方式:
- movl $foo, %eax
- call *%eax
复制代码
x86 只能通过间接调用函数,并无直接调用某个目标地址的指令编码,当然也可以像以下这种调用
movl $foo,%eax
movl %eax, -4(%ebp) // 通过某一变量进行间接调用
call *-4(%ebp)
以下这种调用方式是错误的,x86并不支持这种编码,只能直接远程直接调用,如: call 0040:00401240
明白以上一点,在写 shellcode 代码时,是有用处的,但一般人不会用到以上这一点知识。
例:
void foo()
{
printf("hello\n");
}
int main()
{
char c[7];
int pf = (int)foo;
c[0] = 0xff;
c[1] = 0x15;
*(((int*)&c[2])) = (int)&pf;
c[6] = 0xc3;
((void (*)())&c)();
return 0;
} |
以上代码,可以算是极简单一段 shellcode, 利用 stack 的一个数组执行一段程序。
蓝色部分:写入被调用函数间接存放的变量地址。
若直接写入函数地址,则会出错,因为 call 指令只能做到 call [fun] 而不能做到 call fun
红色部分:调用数组时,要用&间接方式,若 ((void (*)())c)() 则同样会出错。
[ 本帖最后由 mik 于 2008-2-8 01:07 编辑 ] |
|