编译器的一些参数

    继续昨天的话题,用WDK6001编译驱动用了这么一些关键选项:

(CL.exe)

/Zl:省略 .obj 文件中的默认 C 运行时库名称。默认情况下,编译器将库名放入 .obj 文件中,以便使链接器指向正确的库。

/Oi:生成内部函数,前一篇文章已经讲过了,(Cheack模式有,Free模式却没有)

 

(Link.exe)

/NODEFAULTLIB  在解析外部引用时忽略所有(或指定的)默认库

/RELEASE 选项在 .exe 文件头中设置校验和。

操作系统要求设备驱动程序的校验和。为设备驱动程序的发布版本设置校验和,以确保与未来的操作系统兼容。

当指定 /SUBSYSTEM:NATIVE 选项时,默认情况下设置 /RELEASE 选项。

/entry:GsDriverEntry@8 指定入口点

/subsystem:native,6.00

 

从上面看出C运行时库是肯定无法连接了,甚至用#pragma comment( lib, "" )也不行了,因为会被/NODEFAULTLIB忽略,可以看一下啊MSDN上的说明:

lib Places a library-search record in the object file. This comment type must be accompanied by a commentstring parameter containing the name (and possibly the path) of the library that you want the linker to search. The library name follows the default library-search records in the object file; the linker searches for this library just as if you had named it on the command line provided that the library is not specified with /nodefaultlib. You can place multiple library-search records in the same source file; each record appears in the object file in the same order in which it is encountered in the source file.

 

解决的办法是有的,可以在source里改:TARGETLIBS= $(DDK_LIB_PATH)/your.lib

linker

Places a linker option in the object file. You can use this comment-type to specify a linker option instead of passing it to the command line or specifying it in the development environment. For example, you can specify the /include option to force the inclusion of a symbol:

#pragma comment(linker, "/include:__mySymbol")
Only the following ( comment-type ) linker options are available to be passed to the linker identifier:
  • /DEFAULTLIB

  • /EXPORT

  • /INCLUDE

  • /MANIFESTDEPENDENCY

  • /MERGE

  • /SECTION

/DEFAULTLIB 选项将一个 library 添加到 LINK 在解析引用时搜索的库列表。用 /DEFAULTLIB 指定的库在命令行上指定的库之后和 .obj 文件中指定的默认库之前被搜索。

忽略所有默认库 (/NODEFAULTLIB) 选项重写 /DEFAULTLIB:library 。如果在两者中指定了相同的 library 名称,忽略库 (/NODEFAULTLIB:library ) 选项将重写 /DEFAULTLIB:library

 

现在的编译器似乎跟vc的有很多区别了,,有些是还很智能,如果它发现某些函数是显而易见的结果甚至不编译函数了(直接给结果),真是神奇啊…………

 

再说说程序入口点:

/ENTRY 选项指定一个入口点函数作为 .exe 文件或 DLL 的起始地址。

必须用 __stdcall 调用约定来定义函数。必须按 WinMain (对于 .exe 文件)或 DllEntryPoint (对于 DLL)的 Win32 API 中记录的内容定义参数和返回值。建议让链接器设置入口点,以便 C 运行时库正确初始化,并执行静态对象的 C++ 构造函数。

默认情况下,起始地址为 C 运行时库中的函数名。链接器根据程序的属性来选择该函数,如下表所示。

函数名

...的默认值

mainCRTStartup (或 wmainCRTStartup

使用 /SUBSYSTEM:CONSOLE 的应用程序;调用 main (或 wmain

WinMainCRTStartup (或 wWinMainCRTStartup

使用 /SUBSYSTEM:WINDOWS 的应用程序;调用 WinMain (或 wWinMain ),它必须用 __stdcall 来定义

_DllMainCRTStartup

DLL;调用 DllMain (如果存在),DllMain 必须用 __stdcall 来定义

如果未指定 /DLL 或 /SUBSYSTEM 选项,则链接器将根据是否定义了 mainWinMain 来选择子系统和入口点。

函数 mainWinMainDllMain 是三种用户定义的入口点形式。

 

上面说的非常清楚了,但是驱动程序并不连接C库函数,没有什么main。但/entry:GsDriverEntry@8我知道,关键是GsDriverEntry在哪里?哈哈,在这里WINDDK/6001~1.180/lib/wlh/i386/BufferOverflowK.lib,这个函数非常简单:

NTSTATUS GsDriverEntry(IN PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegPath)
{
    LARGE_INTEGER tickCount;
    KeQueryTickCount(&tickCount);
    if(!___security_cookie || ___security_cookie == 0xbb40)
    {
        ULONG temp = (ULONG)&___security_cookie;
        temp = ((temp >> 8) ^ tickCount.u.LowPart) & 0xffff;
        if(temp)
          ___security_cookie = temp;
        else
          ___security_cookie = tickCount.u.LowPart & 0xffff;
    }

    ___security_cookie_complement = ~___security_cookie;
    return DriverEntry(DriverObject,RegPath);
}

 

哦!这里还有一个很大的问题:

"/Oi:生成内部函数(Cheack模式有,Free模式却没有)"那Free模式怎么办!!!!!!!!

我看到Free模式时有 /Oxs(完全优化)

看看/Oxs的说明:

/Ox 可与 /Os (/Oxs ) 结合使用以利于生成较小的代码大小(优化大小)。

通常,/O2 应该优先于 /Ox ,而 /O1 优先于 /Oxs

使用 /Ox 的作用与使用下列选项的作用相同:

晕!又有/Oi,,用IDA看看它们的代码,有惊人的差别……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值