入手阶段,先收集了两个driver的loader的代码,两者都是通过从ntdll.dll的导出的内核函数进行动态的驱动加载,这两个方式都是通常比较常见的方式.我这里对收集到的代码进行了整理,分离,修改,并在我机器WinXP SP2+VS 2005下编译测试.
ps: 更常见的通过SCM加载驱动的代码就不表了,其实最后就是调用ZwLoadDriver.

最后附上Windows NT 2000 Native API Reference里的几段相关的文字:
SystemLoadAndCallImage
Unlike ZwLoadDriver,which loads the module in the context of the system process,ZwSetSystemInformation loads the module and invokes the entry point in the context of the current process.

ZwLoadDriver
SeLoadDriverPrivilege is required to load a driver.
StartService directs the Service Control Manager process to
The Win32 function
execute this function on behalf of the caller.
”riverServiceName of the form
The Service Control Managerprocess provides a
°
/Registry/Machine/System/8urrent8ontrolSet/Services/Tcpip.°

程序代码如下:
ZwSetSystemInformation方式,代码修改自 http://www.xfocus.net/articles/200309/619.html
复制内容到剪贴板
代码:
#include <windows.h>
#include <stdio.h>
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define SystemLoadAndCallImage 38

typedef struct _UNICODE_STRING {
  USHORT Length;
  USHORT MaximumLength;
  PVOID Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

typedef unsigned long NTSTATUS;

typedef struct _SYSTEM_LOAD_AND_CALL_IMAGE
{
  UNICODE_STRING ModuleName;
} SYSTEM_LOAD_AND_CALL_IMAGE, *PSYSTEM_LOAD_AND_CALL_IMAGE;

typedef DWORD (CALLBACK* ZWSETSYSTEMINFORMATION)(DWORD, PVOID, ULONG);
ZWSETSYSTEMINFORMATION ZwSetSystemInformation;
typedef DWORD (CALLBACK* RTLINITUNICODESTRING)(PUNICODE_STRING,PCWSTR );
RTLINITUNICODESTRING RtlInitUnicodeString;
typedef DWORD (CALLBACK* RTLANSISTRINGTOUNICODESTRING)(PVOID, PVOID,DWORD);
RTLANSISTRINGTOUNICODESTRING RtlAnsiStringToUnicodeString;

int main(int argc, char *argv[])
{
  SYSTEM_LOAD_AND_CALL_IMAGE GregsImage;
  UNICODE_STRING TmpBuff;
  char  szDrvFullPath[256],szTmp[256];
  int iBuffLen;
  
  printf("Load driver with ZwSetSystemInformation( )/r/n");
  printf("Date: 8th May 2007/r/n");
  printf("Modifed by: GaRY <wofeiwo_at_gmail_dot_com>/r/n/r/n");
  if(argc != 2 || stricmp(argv[1], "-h") ==0 || stricmp(argv[1], "-?") ==0 || stricmp(argv[1], "/?") ==0)
  {
    printf("Usage: %s <DriverPath>/r/n", argv[0]);
    exit(-1);
  }

  // 从ntll.dll获取函数
  if( !(RtlInitUnicodeString = (RTLINITUNICODESTRING) GetProcAddress( GetModuleHandle("ntdll.dll"), "RtlInitUnicodeString" )) )
  {
    printf( "GetProcAddress(/"RtlInitUnicodeString/") Error:%d/n", GetLastError() );
    exit(1);
  }
  if( !(ZwSetSystemInformation = (ZWSETSYSTEMINFORMATION) GetProcAddress( GetModuleHandle("ntdll.dll"), "ZwSetSystemInformation" )) )
  {
    printf( "GetProcAddress(/"ZwSetSystemInformation/") Error:%d/n", GetLastError() );
    exit(1);
  }
  if( !(RtlAnsiStringToUnicodeString &