技术宅的结界

 找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 1032|回复: 1
收起左侧

刚刚的发现-extern误用

[复制链接]

273

主题

451

帖子

4870

积分

用户组: 真·技术宅

UID
2
精华
61
威望
148 点
宅币
3687 个
贡献
131 次
宅之契约
0 份
在线时间
623 小时
注册时间
2014-1-25
发表于 2015-9-25 13:58:34 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有帐号?立即注册→加入我们

x
一直以来都误用了,来看这种情况:

假设要从ntoskrnl.lib导入IoDriverObjectType
extern "C"
{
  POBJECT_TYPE *IoDriverObjectType;
};

这样写可以嘛?
原先以为extern "C"这个extern已经代表了extern本身,然而发现并不是。

如果查看导入表,会发现没有符号,也就是编译器当成全局变量处理
这个例子其实很特殊,如果该符号是个函数的话,那么编译器自然按有无extern分 _imp_和非_imp_处理导入表
然而此时是个变量,外层extern "C"只做符号修饰说明,并不能代表extern 本身!

(引入函数可以用 有extern,和无extern,前者生成_imp_符号的导入表)

也就是说上述语句相当于c文件:
POBJECT_TYPE *IoDriverObjectType;

如果这是个函数,则可以正常引入,而作为变量,编译器会当做本文件声明的变量
所以正确引入方式为:
extern "C"
{
  extern POBJECT_TYPE *IoDriverObjectType;
};

分析了有无extern的区别,再来看有无__declspec(dllimport)的区别:
extern "C"
{
  __declspec(dllimport) POBJECT_TYPE *IoDriverObjectType;
};
可以发现在引用到改变量处 使用的是*(DWORD*)__imp__IoDriverObjectType
而使用extern的是__imp__IoDriverObjectType

在此抛砖引玉了,如果大家有更多发现请指出

评分

参与人数 1威望 +1 贡献 +9 收起 理由
0xAA55 + 1 + 9 好帖子

查看全部评分

回复

使用道具 举报

85

主题

260

帖子

3765

积分

用户组: 管理员

No. 418

UID
418
精华
13
威望
52 点
宅币
1969 个
贡献
1367 次
宅之契约
0 份
在线时间
252 小时
注册时间
2014-8-9
发表于 2015-9-27 19:43:58 | 显示全部楼层
赞一个!
In the beginning I was not the best.
And the world was also not the best.
But I still know that I am who I am.
Because I think that it is good.
I have been working hard.
I have been keeping growth with the world.
And it was so.
回复

使用道具 举报

本版积分规则

QQ|申请友链||Archiver|手机版|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图  

GMT+8, 2020-7-16 13:07 , Processed in 0.090649 second(s), 33 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表