博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c语言中无windows函数库,关于C语言, GCC/MSVC中,如何写出一个真正意义上的不依赖库的程序?...
阅读量:5976 次
发布时间:2019-06-20

本文共 1597 字,大约阅读时间需要 5 分钟。

在Windows平台上,如果要写一个有意义的用户态程序(以任何方式显示数据或将数据写入设备/文件等),是几乎无法不依赖库的。

如果要让数据显示到控制台、存储数据到文件、或者绘制图形界面,一定需要操作系统的支持。Windows API是通过若干用户态的动态链接库(DLL)调用的。这些动态链接库对系统服务进行了封装,向开发者暴露稳定的接口;而系统服务暴露的接口有可能发生变化。

如果需要调用Windows NT系统服务,需要将系统服务号放进EAX寄存器,然后通过int 2Eh中断或syscall指令转移到特权等级0执行系统服务处理程序。系统服务处理程序通过系统服务描述符表(System Service Descriptor Table,简称SSDT)跳转到对应的内核函数。内核函数会依照调用约定获取栈或寄存器中的参数进行处理。

这些系统服务调用被包装成C语言函数,通过ntdll.dll导出API。其中一部分可以通过Windows DDK在驱动程序中使用,接口相对稳定;而另一部分则是仅仅导出了符号,并没有收录在文档中,这些函数的使用方式有可能在未来被微软更改。

原则上只要知道了系统服务号,就可以不依赖任何库调用Windows NT的内核函数。问题在于,由于系统调用是不对开发者开放的,同一个内核函数对应的系统服务号会随着Windows版本更新而变化;而且在32位环境中,原生32位系统服务调用与WoW64下(在64位操作系统上运行32位应用)的系统服务调用是完全不同的,需要使用特殊的系统服务号,并额外借助WoW64的状态转移机制。

理论上如果要完美解决这个问题,需要记录Windows NT内核每个版本操作系统中各个内核函数对应的系统服务号,然后通过进程环境数据动态检测系统版本号和WoW64状态决定使用哪一个系统服务号以及是否使用WoW64状态转移,还要紧盯系统新版本可能带来的变化。

因此可以得出这样的结论:哪怕开发者可以绕开Windows API的kernel32.dll和user32.dll,ntdll.dll也是几乎不可逾越的障碍,绕开这个对于实际开发来说不现实。

如果抛弃版本兼容性,确实可以轻松写出不依赖任何库的程序,但是只能在特定版本的Windows中成功运行。下面举例说明做到这一点的方法。

Windows 10使用控制台驱动程序(Console Driver)与控制台进行数据交换,因此操作控制台的方式与操作其他Windows设备的方法相似。

一般情况下,用户态程序调用Windows API的DeviceIoControl函数操作设备的驱动程序进行I/O,然而这个函数依赖kernel32.dll。出于演示目的,这里绕过Windows API,直接通过底层的NtDeviceIoControlFile函数进行系统服务调用。

下面展示如何通过操作Windows 10控制台驱动程序把Brain Kernighan著名的Hello World程序改写成不依赖任何库的形式。以下是Brain Kernighan的C语言源代码:

首先需要把NtDeviceIoControlFile的系统服务调用从ntdll.dll中抽出,从而消除对ntdll.dll的依赖。下面是这个函数的MASM汇编代码:

接下来用C语言实现字符串的输出。源代码如下:

运行Visual Studio的x64本机工具命令提示,用下列命令行进行编译:

链接后生成一个非常小的可执行文件(Visual C++2019生成的文件大小为2.5 KB)。使用Dependency Walker查看这个文件,可以看到没有依赖任何库:

b0ff29385123aa5793a3f85bd8b538fd.png

在64位Windows 10(我使用的版本是Windows 1020H210.0.19042.685)的命令提示符或PowerShell中运行这个文件,即可在控制台上看到输出:

转载地址:http://qliox.baihongyu.com/

你可能感兴趣的文章
表格元素的添加和删除,计算器,全选全不反选
查看>>
数据约束
查看>>
网络营销第七课(1):制定SEO计划(网站相关数据分析)
查看>>
nginx rewrite 参数和例子
查看>>
mysqldump命令
查看>>
github上传代码步骤
查看>>
利用express搭建一个restful api 服务器
查看>>
(转)调整.NET控件WebBrowser的默认浏览器内核版本
查看>>
[导入]让你的WAP网站有更好的兼容性
查看>>
.NET Exceptionless 本地部署踩坑记录
查看>>
航电OJ-2544最短路
查看>>
CF772E Verifying Kingdom
查看>>
雨林木风U盘装系统综合教程
查看>>
V-by-one
查看>>
让我欲罢不能的node.js
查看>>
python3基础知识学习记录
查看>>
10年.NET老程序员推荐的7个开发类工具
查看>>
C#核心编程结构(2)
查看>>
rename设计思想(Perl版)
查看>>
第二次冲刺 第七天
查看>>