免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1713 | 回复: 1
打印 上一主题 下一主题

[应用] typedef 应用 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-05-11 16:27 |只看该作者 |倒序浏览
一下这段代码中:
  1.                 /**
  2. * @brief
  3. *
  4. * @file heap_exe.c
  5. * @author blueshycool
  6. * @time 12/06/08 20:41:54
  7. * @version 0.1
  8. *
  9. * CopyRight (C) blueshycool(yangyoufa) @2007~2010@
  10. *
  11. **/
  12. #include stdio.h>
  13. #include stdlib.h>
  14. #include sys/mman.h>
  15. #define EXE_SIZE 128
  16. #define LINE_W 32
  17. #define PROT_ALL PROT_READ|PROT_WRITE|PROT_EXEC
  18. void dump_mem(void* start)
  19. {
  20.     if(start == NULL)
  21.         return ;
  22.    
  23.     char* words = (char*)start;
  24.     int i, j, l;
  25.     l = 0;
  26.     fprintf(stderr, "0x%04x", l);
  27.     for(i=0, j=0; iEXE_SIZE; i++, ++j)
  28.     {   
  29.         if(j >= LINE_W)
  30.         {   
  31.             fprintf(stderr, "\n");
  32.             j = 0;
  33.             fprintf(stderr, "0x%04x", ++l);
  34.         }   
  35.         fprintf(stderr, " %02x", (unsigned char)*(words+i));   
  36.     }   
  37.     fprintf(stderr, "\n");
  38. }
  39. void fill_mem(void* start)
  40. {
  41.     char* code = NULL;
  42.     if(start == NULL)
  43.         return ;
  44.     int i = 0;
  45.     code = (char*)start;
  46.     code[i++] = 0x55;
  47.     code[i++] = 0x89;
  48.     code[i++] = 0xe5;
  49.     code[i++] = 0xb8;
  50.     code[i++] = 0x10;
  51.     code[i++] = 0x00;
  52.     code[i++] = 0x00;
  53.     code[i++] = 0x00;
  54.     code[i++] = 0xc9;
  55.     code[i++] = 0xc3;
  56.     /* 这段代码是x86的汇编代码,它是一个完整的函数
  57.      * 调用过程的结构,就是给eax赋值为0x10,
  58.      * 因为exec_mem所调用的start()并没有要求返回值
  59.      * 但却由这段汇编代码给eax(eax是x86的返回值寄存器)
  60.      * 一个值为0x10的值,那么当start()返回后,exec_mem
  61.      * 并没有对eax的操作,所以exec_mem()的返回值就是
  62.      * start()的返回值也就是我那段在mmap空间时的汇编
  63.      * 代码所赋的值.所以程序输出的结果为16(0x10).
  64.      * 这一功能可以发散它,继续使用,可以想像Linux上的
  65.      * 动态库是怎么实现的.或者说一个解释程序的JIT可能
  66.      * 也是基于这一简单的理论实现的.
  67.     */
  68. }
  69. int exec_mem(void* start)
  70. {
  71.     typedef void (*f)(void);
  72.     ((f)start)();
  73. }
  74. int main(int argc, char* argv[])
  75. {
  76.     void* start = NULL;
  77.     start = mmap(NULL, EXE_SIZE, PROT_ALL, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  78.     dump_mem(start);
  79.     fill_mem(start);
  80.     dump_mem(start);
  81.     int ret = exec_mem(start);
  82.     fprintf(stderr, "ret:%d\n", ret);
  83.     munmap(start, EXE_SIZE);
  84.     return 0;
  85. }
复制代码
其中,这个两句代码的意思不是清楚,请教一下。
  1.     typedef void (*f)(void);
  2.     ((f)start)();
复制代码

论坛徽章:
0
2 [报告]
发表于 2012-05-11 16:42 |只看该作者
因为我觉得f是函数指针,当使用((f)start)来强制类型转换start为函数指针类型,如果要使用这个函数指针的时候,应该是(*((f)start))(),而不应该是((f)start)()。就像如下这段代码:
  1. #include <stdio.h>

  2. int print(void)
  3. {
  4.         printf("hello world");
  5.         return 0;
  6. }

  7. int main()
  8. {
  9.         int (*ptr) (void);
  10.         ptr = print;
  11.         (*ptr)();
  12.         return 0;
  13. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP