• [原创]浅谈如何使用gcc开发NT核心驱动程序


    原文链接:[原创]浅谈如何使用gcc开发NT核心驱动程序

        一谈到在 Win NT 下开发核心驱动程序,可能不少人首先都会想到微软“正统”的VC来。诚然,用VC 配合 WINDDK 的确工作的不错,但或许我们可以让其变得更简单更完善一些。

        其实偶一般是用 Masm32v9 + EditPlus2 编写 NT内核驱动,仅此而已。从环境搭建的便捷性和编写代码的灵活性来说无疑这是非常高的。但汇编终归是汇编,虽然强大,但很多事都要自己动手来做,往往很简单的功能都要用比较“生硬”的方法来完成,比如:

      

     1 ;****************************************************************
     2 
     3 .data
     4 
     5 ;****************************************************************
     6 
     7          szenter db "enter driverentry",0
     8 
     9          szleave db "leave driverentry",0
    10 
    11 ;****************************************************************
    12 .code INIT
    13 ;****************************************************************
    14 
    15 DriverEntry proc pDriverObject:PDRIVER_OBJECT,/
    16 
    17         pusRegistryPath:PUNICODE_STRING
    18  
    19  local status:NTSTATUS    
    20 
    21 mov status,STATUS_DEVICE_CONFIGURATION_ERROR
    22 
    23  invoke DbgPrint,$CTA0("enter driverentry")
    24 
    25  invoke DbgPrint,addr szenter
    26 
    27 ;do someting you want!
    28 
    29 
    30  invoke DbgPrint,addr szleave
    31   
    32  mov eax, status
    33 
    34  ret
    35 
    36 DriverEntry endp
    37 ;****************************************************************
    38          end DriverEntry

        以上是一个简单的不能再简单的Driver 模版。如君所见,连字符串放在哪个段中也要自己亲手安排,小程序尚可忍受,一旦代码规模上去就非常不方便。我们也可以把数据直接放在代码段中,比如:

     

     1 ;****************************************************************
     2 .code INIT
     3 ;****************************************************************
     4 
     5 DriverEntry proc pDriverObject:PDRIVER_OBJECT,/
     6 
     7         pusRegistryPath:PUNICODE_STRING
     8  
     9  local status:NTSTATUS    
    10 
    11   jmp Real_Start
    12 
    13   szenter db "enter driverentry",0
    14   szleave db "leave driverentry",0
    15 
    16 Real_Start:
    17 
    18  mov status,STATUS_DEVICE_CONFIGURATION_ERROR
    19 
    20  invoke DbgPrint,addr szenter
    21 
    22 ;do someting you want!
    23 
    24 
    25  invoke DbgPrint,addr szleave
    26   
    27  mov eax, status
    28 
    29  ret
    30 
    31 DriverEntry endp
    32 ;****************************************************************
    33          end DriverEntry

        这样一来虽然不用自己操作段,但是毕竟稍显怪异,而且变量定义和使用还是要分开。无奈,只有用宏来解决了:

     

    1 invoke DbgPrint,$CTA0("enter driverentry")
    2  
    3  invoke DbgPrint,$CTA0("leave driverentry")

     

     

        辛勤的汇编语言工作者们多么希望能向c那样简单的方式来写啊 ^_^

     

    puts("So Cool!");

     

        但是VC对 标准 c99 的支持并不好,咋办呢?用gcc吧(不是广告哦。)有人可能会问gcc能写Windows下的驱动么?答案是肯定的。以下是偶总结出的2个方法:

    1 gcc.exe + ld.exe

    2 gcc.exe + link.exe

    前者是全部是原汁原味的gcc;而后者编译器是gcc,连接器却是MS官方的link.exe。以下便是用 gcc 写的一个类似 ASM-Driver 的模版:

     

     1 #include <stdio.h>
     2 #include "ddk/ntddk.h"
     3 
     4 _stdcall NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,/
     5  PUNICODE_STRING pRegistryPath)
     6 {
     7  NTSTATUS status = STATUS_DEVICE_CONFIGURATION_ERROR;
     8  
     9  DbgPrint("enter DriverEntry,I'm Hopy!/n");
    10  
    11  DbgPrint("Leave DriverEntry,byb :)!/n");
    12  
    13  return status;
    14 }

        简单吗?呵呵。注意开头的_stdcall一定要加,否则调用者会来平衡stack,这会造成stack异常,从而sys必须重启后才能卸载。活活,偶们可以利用gcc出色的代码优化功能来优化偶们的代码:

    gcc -O3 -o miniDrv.obj -c miniDrv.c

        注意我们并不连接只是编译,所以用 -c 选项,而且可以看见我们使用了 O3级别的优化。结果生成的PE文件只比用汇编生成的大几十字节,而且从逆向sys可以看到机器码布局非常简练几乎可以和汇编的相媲美了。

        

    总结如下:

    使用gcc编写NT下的驱动十分方便,只需要

    gcc 包 + MS link + 一个好用的编辑器 即可。 :)

     

  • 相关阅读:
    【转】awk用法介绍
    【转】Shell执行MySql操作
    curl访问nagios中Host Status Details For All Host Groups页面的方法
    【转】命令行浏览器 curl 命令详解,Linux中访问url地址
    【转】DELL R710服务器可以安装的VMWare ESX Server 4.1 全套下载带注册码
    【转】一些常用的Vi命令,可帮助脱离鼠标
    乐观处世,诚实做人,不骄不躁,积极进取; 勇于创新,踏实实现,谨慎规划,付诸实践; 事在人为
    【转】Linux方向职业分析
    【转】[Asp.net]常见数据导入Excel,Excel数据导入数据库解决方案,总有一款适合你!
    【转】Nagios安装部署与Cacti整合文档超精细版本
  • 原文地址:https://www.cnblogs.com/hopy/p/3829018.html
Copyright © 2020-2023  润新知