利用驱动程序读取硬盘序列号(下)
相关的例子:下载>>> 作者:电子管 于2007-3-20上传 

  翻看精华贴的时候发现有篇文章我只写了一半,今天把它补全,了却一桩心事。

这里有个小程序hdsn32.asm,是我2000年写的,在win9x下读取硬盘的序列号,它利用了类似CIH病毒的办法获得ring0权限,在win2000下不能运行.
      ;   hdsn32.asm
      .386
      .model flat, stdcall  ; 32 bit memory model
      option casemap :none  ; case sensitive
      
      include \masm32\include\windows.inc
      include \MASM32\INCLUDE\shell32.inc
      include \MASM32\INCLUDE\masm32.inc
      include \masm32\include\user32.inc
      include \masm32\include\kernel32.inc
      
      


      includelib \MASM32\LIB\shell32.lib
      includelib \MASM32\LIB\masm32.lib
      includelib \masm32\lib\user32.lib
      includelib \masm32\lib\kernel32.lib
      

.data

IDTR        df 0            ; This will receive the contents of the IDTR
                            ; register

SavedGate   dq 0            ; We save the gate we replace in here

OurGate     dw 0            ; Offset low-order word
            dw 028h         ; Segment selector
            dw 0EE00h       ;
            dw 0            ; Offset high-order word
BUFF1 DW 256 DUP(20H)             
hdsn_1 db '硬盘C序列号:',0DH,0AH
hdsn_2 db 256 dup(0)
hdsn_3 db 20 dup(0)
szCaption db 'hdsn32 v1.0 for win9x 山东海化集团 盛玉增 编制 2000.12.21',0
name_buffer db 'hdsn.bin',0

.data?
hFile HANDLE ?
SizeReadWrite DWORD ?

.code
Start:
      mov      eax, offset Ring0Proc
      mov      [OurGate], ax              ; Put the offset words
      shr      eax, 16                    ; into our descriptor
      mov      [OurGate+6], ax

      sidt     fword ptr IDTR
      mov      ebx, dword ptr [IDTR+2]    ; load IDT Base Address
      add      ebx, 8*3                   ; Address of int 3 descriptor in ebx

      mov      edi, offset SavedGate
      mov      esi, ebx
      movsd                               ; Save the old descriptor
      movsd                               ; into SavedGate

      mov      edi, ebx
      mov      esi, offset OurGate
      movsd                               ; Replace the old handler
      movsd                               ; with our new one

      int    3h                           ; Trigger the exception, thus
                                          ; passing control to our Ring0
                                          ; procedure

      mov      edi, ebx
      mov      esi, offset SavedGate
      movsd                               ; Restore the old handler
      movsd
      
      invoke MessageBox,NULL,addr hdsn_1,addr szCaption,MB_OK

   invoke CreateFile,ADDR name_buffer,\
             GENERIC_READ or GENERIC_WRITE ,\
             FILE_SHARE_READ or FILE_SHARE_WRITE,\
             NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,\
             NULL
   mov hFile,eax
      push offset hdsn_2
      pop esi
      push offset hdsn_3
      pop edi
      mov ecx,20
jm_1:      
      lodsb
      xor al,36h
      stosb
      loop jm_1
   invoke WriteFile,hFile,ADDR hdsn_3,20,\
             ADDR SizeReadWrite,NULL
   invoke CloseHandle,hFile
      invoke ExitProcess,eax

Ring0Proc PROC
start_1:
      mov edx,1f7h
      in al,dx
      cmp al,50h
      jnz start_1
      dec dx
      mov al,0a0h
      out dx,al
      mov dx,1f7h
      mov al,0ech
      out dx,al
      mov dx,1f7h
st_1: 
      in al,dx
      cmp al,58h
      jnz st_1
      mov dx,1f0h
      mov edi,offset BUFF1
      mov ecx,0
      mov cx,256
st_2: 
      in ax,dx
      xchg ah,al
      stosw
      loop st_2
      sti
      push offset BUFF1[20]
      pop esi
      push offset hdsn_2
      pop edi
      mov ecx,20
      rep movsb
      iretd
     
Ring0Proc ENDP
    end Start

(要忙工作了,等有空接着写,等我啊)

以上部分写于2004年7月3日
(后来由于工作忙,也就把kmdkit放下了.没想到一放就是两年多。在网上搜索经常会搜到这篇文章,文章的题目是《利用驱动程序读取硬盘序列

号》,有兴趣者可以在网上搜搜看,看看有多少个不道德的网站:-) 不少网站都不厚道,转载时不仅作者变成了佚名,就连里面提到的本站网

址都改掉了。看到这种情况,感到很不舒服。这篇文章只有半截,明显的文不对题,只实现了在win98下读取硬盘序列号。现在再补上本文的下

半部分)
插个广告,看累了请休息一下。转载时请保留:-)
山东海化集团潍坊海源工程建设监理有限公司,主要从事化工、建筑、市政工程的监理业务。我们的工作目标是:让业主满意,让用户放心。

公司对承揽业务和提供信息的人员实行提成和奖励,如果你发现有需要开工建设的项目,请及时和本文作者 盛玉增 联系。
办公电话:0536-5329032
公司网址:http://www.wfhyjl.cn 
e-mail:syz@wfhyjl.cn qq:5611409

为了在win2000和xp下读取硬盘序列号,写了一个很小的驱动d_test.sys,它的源代码d_test.bat内容如下:
;goto make
;文件名d_test.bat 作者:盛玉增 2006年12月13日用masm32v8和kmdkit1.8调试成功
.386
.model flat, stdcall
option casemap:none
include \masm32\include\w2k\ntstatus.inc
include \masm32\include\w2k\ntddk.inc
include \masm32\include\w2k\ntoskrnl.inc
includelib \masm32\lib\w2k\ntoskrnl.lib
include \masm32\Macros\Strings.mac

IOCTL_GET_INFO equ CTL_CODE(FILE_DEVICE_UNKNOWN, 800h, METHOD_BUFFERED, FILE_READ_ACCESS + FILE_WRITE_ACCESS)


.const
CCOUNTED_UNICODE_STRING    "\\Device\\d_test", g_usDeviceName, 4
CCOUNTED_UNICODE_STRING    "\\??\\d_test", g_usSymbolicLinkName, 4
;CCOUNTED_UNICODE_STRING    "\\DosDevices\\d_test", g_usSymbolicLinkName, 4

.data

BUFF1  db 512 dup (0)

.code

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                   DispatchCreateClose                                             
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

DispatchCreateClose proc pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP

    ; CreateFile was called, to get driver handle
    ; CloseHandle was called, to close driver handle
    ; In both cases we are in user process context here

    mov eax, pIrp
    assume eax:ptr _IRP
    mov [eax].IoStatus.Status, STATUS_SUCCESS
    and [eax].IoStatus.Information, 0
    assume eax:nothing

    fastcall IofCompleteRequest, pIrp, IO_NO_INCREMENT

    mov eax, STATUS_SUCCESS
    ret

DispatchCreateClose endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                     DispatchControl                                               
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

DispatchControl proc uses esi edi pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP

local status:NTSTATUS
local dwBytesReturned:DWORD    ;实际返回的字节数

    and dwBytesReturned, 0

    mov esi, pIrp
    assume esi:ptr _IRP

    IoGetCurrentIrpStackLocation esi
    mov edi, eax
    assume edi:ptr IO_STACK_LOCATION

    .if [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_GET_INFO
        .if [edi].Parameters.DeviceIoControl.OutputBufferLength >= 20

            mov eax, [esi].AssociatedIrp.SystemBuffer
                      
                       pushad
                       push eax
                       

start_1:           ;读取硬盘序列号
      mov edx,1f7h
      in al,dx
      cmp al,50h
      jnz start_1
      dec dx
      mov al,0a0h
      out dx,al
      mov dx,1f7h
      mov al,0ech
      out dx,al
      mov dx,1f7h
st_1: 
      in al,dx
      cmp al,58h
      jnz st_1
      mov dx,1f0h
      mov edi,offset BUFF1
      mov ecx,0
      mov cx,256
st_2: 
      in ax,dx
      xchg ah,al
      stosw
      loop st_2
      sti
      push offset BUFF1[20]
      pop esi
                        pop edi
                        mov ecx,20
                        rep movsb
  
                        popad

            mov dwBytesReturned, 20
            mov status, STATUS_SUCCESS
        .else
            mov status, STATUS_BUFFER_TOO_SMALL
        .endif
    .else
        mov status, STATUS_INVALID_DEVICE_REQUEST
    .endif

    assume edi:nothing

    push status
    pop [esi].IoStatus.Status

    push dwBytesReturned
    pop [esi].IoStatus.Information

    assume esi:nothing

    fastcall IofCompleteRequest, esi, IO_NO_INCREMENT

    mov eax, status
    ret

DispatchControl endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                       DriverUnload                                                
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

DriverUnload proc pDriverObject:PDRIVER_OBJECT

    ; ControlService,,SERVICE_CONTROL_STOP was called
    ; We are in System process (pid = 8) context here

    invoke IoDeleteSymbolicLink, addr g_usSymbolicLinkName

    mov eax, pDriverObject
    invoke IoDeleteDevice, (DRIVER_OBJECT PTR [eax]).DeviceObject

    ret

DriverUnload endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                              D I S C A R D A B L E   C O D E                                      
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

.code INIT

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                       DriverEntry                                                 
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

DriverEntry proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING

    ; StartService was called
    ; We are in System process (pid = 8) context here

local status:NTSTATUS
local pDeviceObject:PDEVICE_OBJECT

    mov status, STATUS_DEVICE_CONFIGURATION_ERROR

    invoke IoCreateDevice, pDriverObject, 0, addr g_usDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, addr pDeviceObject
    .if eax == STATUS_SUCCESS
        invoke IoCreateSymbolicLink, addr g_usSymbolicLinkName, addr g_usDeviceName
        .if eax == STATUS_SUCCESS
            mov eax, pDriverObject
            assume eax:ptr DRIVER_OBJECT
            mov [eax].MajorFunction[IRP_MJ_CREATE*(sizeof PVOID)],            offset DispatchCreateClose
            mov [eax].MajorFunction[IRP_MJ_CLOSE*(sizeof PVOID)],            offset DispatchCreateClose
            mov [eax].MajorFunction[IRP_MJ_DEVICE_CONTROL*(sizeof PVOID)],    offset DispatchControl
            mov [eax].DriverUnload,                                            

offset DriverUnload
            assume eax:nothing
            mov status, STATUS_SUCCESS
        .else
            invoke IoDeleteDevice, pDeviceObject
        .endif
    .endif

    mov eax, status
    ret

DriverEntry endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                                                                                   
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

end DriverEntry

:make

set drv=d_test

\masm32\bin\ml /nologo /c /coff %drv%.bat
\masm32\bin\link /nologo /driver /base:0x10000 /align:32 /out:%drv%.sys /subsystem:native /ignore:4078 %drv%.obj 

del %drv%.obj

pause


它的格式是bat文件,也就是自编译,只要双击它就编译成功。

细心的读者可能看出来了,它的读序列号的部分和上面的win98下的ring0部分是相同的,是直接复制过来的。
对于这个小驱动程序,重要的是DispatchControl部分,其他的部分所有的驱动程序都大同小异,直接抄来用即可。
控制这个驱动的是hdsn_xp.asm,它的源代码如下:

;文件名hdsn_xp.asm 作者:盛玉增 2006年12月13日用masm32v8和kmdkit1.8调试成功
;在winxp下用驱动程序读取硬盘序列号
.386
.model flat, stdcall
option casemap:none

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                  I N C L U D E   F I L E S                                        
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

include \masm32\include\windows.inc

include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\advapi32.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\advapi32.lib

include \masm32\include\winioctl.inc

include \masm32\Macros\Strings.mac

IOCTL_GET_INFO equ CTL_CODE(FILE_DEVICE_UNKNOWN, 800h, METHOD_BUFFERED, FILE_READ_ACCESS + FILE_WRITE_ACCESS)
; Macro definition for defining IOCTL and FSCTL function control codes.  Note
; that function codes 0-2047 are reserved for Microsoft Corporation, and
; 2048-4095 are reserved for customers.
;CTL_CODE MACRO DeviceType:=<0>, Function:=<0>, Method:=<0>, Access:=<0>
;    EXITM %(((DeviceType) SHL 16) OR ((Access) SHL 14) OR ((Function) SHL 2) OR (Method))
;ENDM


.const
.data
sysname db "d_test.sys",0
device db "d_test",0
driver db "d_test Driver",0
abyOutBuffer db 512 dup(0)
dwBytesReturned dd 0
.data?

.code

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                       start                                                       
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

start proc uses esi edi

local hSCManager:HANDLE
local hService:HANDLE
local acModulePath[MAX_PATH]:CHAR
local _ss:SERVICE_STATUS
local hDevice:HANDLE

local acVersion[16]:CHAR

    ; Open a handle to the SC Manager database
    invoke OpenSCManager, NULL, NULL, SC_MANAGER_ALL_ACCESS
    .if eax != NULL
        mov hSCManager, eax

        ;invoke GetCurrentDirectory, sizeof g_acBuffer, addr g_acBuffer
        push eax
        invoke GetFullPathName, addr sysname, sizeof acModulePath, addr acModulePath, esp
        pop eax

        ; Install service
        invoke CreateService, hSCManager, addr device, addr driver, \
            SERVICE_START + SERVICE_STOP + DELETE, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, \
            SERVICE_ERROR_IGNORE, addr acModulePath, NULL, NULL, NULL, NULL, NULL

        .if eax != NULL
            mov hService, eax

            ; Driver's DriverEntry procedure will be called
            invoke StartService, hService, 0, NULL
            .if eax != 0

                ; Driver will receive I/O request packet (IRP) of type IRP_MJ_CREATE
                invoke CreateFile, $CTA0("\\\\.\\d_test"), GENERIC_READ + GENERIC_WRITE, \
                                0, NULL, OPEN_EXISTING, 0, NULL

                .if eax != INVALID_HANDLE_VALUE
                    mov hDevice, eax

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

                    ; Driver will receive IRP of type IRP_MJ_DEVICE_CONTROL
                    invoke DeviceIoControl, hDevice, IOCTL_GET_INFO, NULL, 0, \
                                        addr abyOutBuffer, sizeof abyOutBuffer, addr 

dwBytesReturned, NULL

                    .if ( eax != 0 ) && ( dwBytesReturned != 0 )

                        lea eax, abyOutBuffer
                        
                        invoke MessageBox, NULL, addr abyOutBuffer, $CTA0("硬盘序列号"), MB_OK + 

MB_ICONINFORMATION
                    .else
                        invoke MessageBox, NULL, $CTA0("发送控制失败."), NULL, MB_OK + MB_ICONSTOP
                    .endif

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

                    
                    invoke CloseHandle, hDevice  ; Driver will received IRP of type IRP_MJ_CLOSE
                .else
                    invoke MessageBox, NULL, $CTA0("Device is not present."), NULL, MB_ICONSTOP
                .endif
                
                invoke ControlService, hService, SERVICE_CONTROL_STOP, addr _ss 
                                        ; DriverUnload proc in our driver will be called
            .else
                invoke MessageBox, NULL, $CTA0("Can't start driver."), NULL, MB_OK + MB_ICONSTOP
            .endif

            invoke DeleteService, hService
            invoke CloseServiceHandle, hService
        .else
            invoke MessageBox, NULL, $CTA0("Can't register driver."), NULL, MB_OK + MB_ICONSTOP
        .endif
        invoke CloseServiceHandle, hSCManager
    .else
        invoke MessageBox, NULL, $CTA0("Can't connect to Service Control Manager."), NULL, MB_OK + MB_ICONSTOP
    .endif

    invoke ExitProcess, 0

start endp

end start

这个程序的编译方法是直接点击masm32v8的project菜单的build all.

我觉得初学编写驱动最重要的不是驱动本身,而是用户程序和驱动程序之间的通讯接口。驱动只是提供一个在ring0下工作的支持,驱动写出来

后要在用户程序的控制下工作。

DeviceIoControl函数就是实现这个通讯功能的,它的原型如下:
BOOL DeviceIoControl(

    HANDLE  hDevice,    // handle to device of interest
    DWORD  dwIoControlCode,    // control code of operation to perform
    LPVOID  lpInBuffer,    // pointer to buffer to supply input data
    DWORD  nInBufferSize,    // size of input buffer
    LPVOID  lpOutBuffer,    // pointer to buffer to receive output data
    DWORD  nOutBufferSize,    // size of output buffer
    LPDWORD  lpBytesReturned,    // pointer to variable to receive output byte count
    LPOVERLAPPED  lpOverlapped     // pointer to overlapped structure for asynchronous operation
   );
译成中文:

BOOL DeviceIoControl(
    HANDLE hDevice,              // 设备句柄
    DWORD dwIoControlCode,       // 控制码
    LPVOID lpInBuffer,           // 输入数据缓冲区指针
    DWORD nInBufferSize,         // 输入数据缓冲区长度
    LPVOID lpOutBuffer,          // 输出数据缓冲区指针
    DWORD nOutBufferSize,        // 输出数据缓冲区长度
    LPDWORD lpBytesReturned,     // 输出数据实际长度字节数
    LPOVERLAPPED lpOverlapped    // 重叠操作结构指针
);

设备句柄用来标识你所访问的设备。 

发送不同的控制码,可以调用设备驱动程序的不同类型的功能。详细说明请看相关资料。
;;;;;;;
以下是广告,转载时请保留:-)
山东海化集团潍坊海源工程建设监理有限公司,面向全国
承担化工、石油、建筑、市政工程的监理业务。我们的工作
目标是:让业主满意,让用户放心。公司对承揽业务和提
供信息的人员实行提成和奖励,如果你发现有需要开工建设的项
目,请及时和本文作者盛玉增联系。
办公电话:0536-5329032
公司网址:http://www.wfhyjl.cn 
e-mail:syz@wfhyjl.cn qq:5611409




<<<上一篇
欢迎访问AoGo汇编小站:http://www.aogosoft.com
下一篇>>>