免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: scutan
打印 上一主题 下一主题

[函数] 关于指针与函数的几点小结 [复制链接]

论坛徽章:
0
1 [报告]
发表于 2008-02-08 01:03 |显示全部楼层
再加一个知识点:

  1. void foo()
  2. {
  3.        printf("hello\n");
  4. }

  5. int main()
  6. {
  7.       void (*pf)() = foo;

  8.       pf();

  9.       return 0;
  10. }
复制代码


类似以上通过指针间接调用的代码,在x86上,gcc通常是产生类似以下这种调用的编码方式:

  1. movl $foo, %eax
  2. call    *%eax
复制代码


x86 只能通过间接调用函数,并无直接调用某个目标地址的指令编码,当然也可以像以下这种调用
movl $foo,%eax
movl %eax, -4(%ebp)                // 通过某一变量进行间接调用
call  *-4(%ebp)

以下这种调用方式是错误的,x86并不支持这种编码,只能直接远程直接调用,如: call 0040:00401240
  1. call $foo
复制代码




明白以上一点,在写 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 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP