NtDll是否真的导出C运行时函数,我可以在我的应用程序中使用它们吗?

Vla*_*lad 2 c windows winapi crt ntdll

我一直在寻找我的Windows 10计算机上的NTDLL出口表,我发现它出口标准的C运行时功能,如memcpy,sprintf,strlen,等.

这是否意味着我可以在运行时通过LoadLibrary和动态调用它们GetProcAddress?每个Windows版本都能保证这种情况吗?

如果是这样,可以完全删除C运行时库(通过使用NtDll中的CRT函数),从而使我的程序更小?

Cod*_*ray 7

绝对没有理由将这些由NtDll导出的未记录的函数称为.Windows将所有必要的C运行时函数导出为标准系统库(即Kernel32)中的文档包装器.如果您绝对无法链接到C运行时库*,那么您应该调用这些函数.对于内存,你有基本的HeapAllocHeapFree(或者VirtualAllocVirtualFree), ,ZeroMemory,FillMemory,MoveMemory,CopyMemory等字符串处理,重要的CRT功能都没有,名字前有l:lstrlen,lstrcat,lstrcpy,lstrcmp,等异类是wsprintf(和其兄弟wvsprintf),它不仅具有不同的前缀,而且还不支持浮点值(Windows本身在这些函数首次导出和记录的早期没有浮点代码.)还有其他各种帮助器功能,那就是,在CRT复制功能,如IsCharLower,CharLower,CharLowerBuff等.

这是一篇旧的知识库文章,它记录了一些用于C运行时函数Win32等价物.如果您重新实现CRT的功能,可能还需要其他相关的Win32功能,但这些功能是直接替代.

其中一些是操作系统的基础结构绝对需要的,并且将由任何CRT实现在内部调用.此类别包括类似HeapAllocHeapFree操作系统的责任.运行时库只包装那些,提供了一个很好的标准C接口和一些其他细节,基于细节操作系统级细节.其他的,比如字符串操作函数,只是在CRT的内部Windows版本周围导出包装(除了它是CRT的旧版本,在历史的某个时候修复,除了可能已经修补的主要安全漏洞)这些年来).还有一些人几乎完全是多余的,或者看起来如此,像ZeroMemoryMoveMemory,但实际出口,使他们能够从环境中使用,那里没有C运行时库,像经典的Visual Basic(VB 6).

有趣的是指出许多"简单"的C运行时库函数是由Microsoft(和其他供应商)编译器作为内部函数实现的,具有特殊处理.这意味着它们可以高度优化.基本上,相关的目标代码是直接在应用程序的二进制文件中内联发出的,从而避免了对潜在昂贵的函数调用的需要.允许编译器为类似的东西生成内联代码,这些代码strlen一直被调用,几乎无疑会导致比向某个导出的Windows API支付函数调用成本更好的性能.编译器无法"内联" lstrlen; 它就像任何其他函数一样被调用.这可以让您回到速度和大小之间的经典权衡.有时较小的二进制文件更快,但有时它不是.不必链接CRT将产生较小的二进制文件,因为它使用函数调用而不是内联实现,但在一般情况下可能不会产生更快的代码.

*但是,您确实应该链接到与编译器捆绑在一起的C运行时库,原因有很多,其中最重要的是可以通过运行时库的更新版本分发到操作系统的所有版本的安全更新.您必须有一个非常好的理由不使用CRT,例如,如果您正在尝试构建世界上最小的可执行文件.没有这些功能只是你的第一个障碍.CRT为您处理很多通常甚至不需要考虑的事情,例如启动和运行进程,设置标准C或C++环境,解析命令行参数,运行静态初始化器,实现构造函数和析构函数(如果你正在编写C++),支持结构化异常处理(SEH,也用于C++异常)等等.我已经得到了一个简单的C应用程序,可以在不依赖CRT的情况下进行编译,但它需要花费很多时间,我当然不会推荐它用于任何远程严重的事情.很久以前Matthew Wilson撰写了一篇关于避免使用Visual C++运行时库的文章.它很大程度上已经过时了,因为它侧重于Visual C++ 6开发环境,但很多重要的东西仍然是相关的.我清楚地记得Matt Pietrek很久以前在微软期刊上写过一篇关于此的文章,但我无法在网上找到它的副本(所有的链接似乎已经死了).

如果您只关心需要在应用程序旁边分发C运行时库DLL,则可以考虑静态链接到CRT.这将代码嵌入到您的可执行文件中,并消除了对单独DLL的要求.同样,这会使您的可执行文件膨胀,但确实使部署更简单,而无需安装程序甚至ZIP文件.当然,最重要的一点是,您无法受益于CRT DLL的增量安全更新; 您必须重新编译并重新分发应用程序才能获得这些修复程序.对于没有其他依赖关系的玩具应用程序,我经常选择静态链接; 否则,动态链接仍然是推荐的方案.