免费注册 查看新帖 |

Chinaunix

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

[C] 去伪存真——品悟C的优雅与严谨(获奖名单已公布-2012-10-30) [复制链接]

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
241 [报告]
发表于 2012-09-30 23:37 |只看该作者
回复 239# OwnWaterloo


    我擦……就是这种!

有没有绝对地址的call?

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
242 [报告]
发表于 2012-09-30 23:38 |只看该作者
回复 238# starwing83

恰好就是木有执行权限。。。

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
243 [报告]
发表于 2012-09-30 23:39 |只看该作者
回复 242# OwnWaterloo


    ????绝对有的。我删了传参和E8以后,相当于一个空函数,调用就成功了。

看来就是这个E8的问题鸟…………我擦啊……

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
244 [报告]
发表于 2012-09-30 23:39 |只看该作者
回复 241# starwing83

有:
mov eax operand
call eax
这个好像可以用函数指针产生。。


还有一个直接 call 的操作数不是相对的, 我忘了。。。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
245 [报告]
发表于 2012-09-30 23:41 |只看该作者
回复 243# starwing83

也有可能是你没开DEP?

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
246 [报告]
发表于 2012-09-30 23:51 |只看该作者
回复 241# starwing83

  1. int foo(int x);
  2. int (*bar)(int x) = foo;
  3. int foo(int x) { return bar(x+1); }

  4. int main(void) { return 0; }
复制代码
gcc -Wall -O2

004012f0 <_foo>:
  4012f0:        55                           push   ebp
  4012f1:        89 e5                        mov    ebp,esp
  4012f3:        ff 45 08                     inc    DWORD PTR [ebp+0x8]
  4012f6:        8b 0d 00 20 40 00            mov    ecx,DWORD PTR ds:0x402000
  4012fc:        5d                           pop    ebp
  4012fd:        ff e1                        jmp    ecx ; 传说中的尾调用优化
  4012ff:        90                           nop   


这个函数就可以纯copy。
操作数不是相对形式的call指令。。。 我真忘记怎么诱导编译器产生了。。。  可能是直接写汇编得到的。。。

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
247 [报告]
发表于 2012-10-01 00:37 |只看该作者
回复 246# OwnWaterloo


    学到了……objdump是个好东西………………

我以前一直是-Wa,-a的说………………

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
248 [报告]
发表于 2012-10-01 00:41 |只看该作者
回复 241# starwing83

已经无所不用其极了。。。

  1. #include <stdio.h>

  2. int bar(int x) { return printf("bar(%d)\n", x); }

  3. #pragma data_seg(push, ".at")
  4. int (*bar_)(int) = bar;
  5. #pragma code_seg(pop)

  6. __declspec(naked)
  7. int foo(int x)
  8. {
  9.       _asm _emit 0xff _asm _emit 0x25
  10.       _asm _emit 0x00 _asm _emit 0x40 _asm _emit 0x40 _asm _emit 0x00
  11. }

  12. int foo_(int x) { return bar_(x); }

  13. int main(void)
  14. {
  15.       foo(12);
  16.       foo_(26);
  17.       return 0;
  18. }
复制代码
1. foo里的 FF 15 ?? ?? ?? ?? 是call, 不过我懒得传参数就用 FF 25 ?? ?? ?? ?? jmp了。。。
2. 之后foo_ 又给试出来了。。。

cl -FAs -Os -MD
dumpbin -disasm
_foo:
  00000015: FF 25 00 40 40 00  jmp         dword ptr ds:[404000h]
_foo_:
  0000001B: 55                 push        ebp
  0000001C: 8B EC              mov         ebp,esp
  0000001E: FF 75 08           push        dword ptr [ebp+8]
  00000021: FF 15 00 00 00 00  call        dword ptr [_bar_]
  00000027: 59                 pop         ecx
  00000028: 5D                 pop         ebp
  00000029: C3                 ret

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
249 [报告]
发表于 2012-10-01 00:45 |只看该作者
回复 248# OwnWaterloo


    你真狠……我这儿没有dumpbin和cl,只有objdump和gcc……

不玩了,这种底层的活儿玩不赢你……

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
250 [报告]
发表于 2012-10-01 01:04 |只看该作者
回复 249# starwing83

  1. #include <stdio.h>

  2. int bar(int x) { return printf("bar(%d)\n", x); }

  3. __attribute__((section (".at")))
  4. int (*bar_)(int) = bar;

  5. int foo(int x)
  6. {
  7.       asm(".short 0x25ff");
  8.       asm(".long 0x406000");
  9. }


  10. int foo_(int x) { return bar_(x); }

  11. int main(void)
  12. {
  13.       foo(12);
  14.       foo_(26);
  15.       return 0;
  16. }
复制代码
gcc -Wall -fomit-frame-pointer -Wl,--section-start,.at=406000
objdump -d


0040130b <_foo>:
  40130b:        ff 25 00 60 40 00            jmp    DWORD PTR ds:0x406000
  401311:        c3                           ret   

00401312 <_foo_>:
  401312:        83 ec 0c                     sub    esp,0xc
  401315:        8b 44 24 10                  mov    eax,DWORD PTR [esp+0x10]
  401319:        89 04 24                     mov    DWORD PTR [esp],eax
  40131c:        a1 00 60 40 00               mov    eax,ds:0x406000
  401321:        ff d0                        call   eax
  401323:        83 c4 0c                     add    esp,0xc
  401326:        c3                           ret   

都可以copy。 不过还是没能让gcc产生ff 25或ff 15。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP