《利用驱动程序读取BIOS》由会员分享,可在线阅读,更多相关《利用驱动程序读取BIOS(19页珍藏版)》请在金锄头文库上搜索。
1、利用驱动程序读取BIOS 作者: 日期:利用驱动程序读取BIOS 用BIOS的内容作为硬标记进行加密,应用程序可以通过检测bios的特定内容,如主板日期、厂家信息等。如果符合要求,就让程序正常运行;如不符合要求,就判断为盗版,禁止运行。这样可以起到一定的加密锁的作用。 如何得到bios的内容呢?我们已经通过驱动程序进入ring0,在ring0中是无所不能的,有一个简单的函数,可以帮助我们达到目的。它就是MmMapIoSpace函数,在DDK文档中看到该函数的说明如下:PVOID MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress,IN ULONG
2、NumberOfBytes,IN MEMORY_CACHING_TYPE CacheType );在Masm32v8中声明的有4个形参MmMapIoSpaceproto stdcall :DWORD, :DWORD, :DWORD, :DWORD为什么参数个数会有不同呢?原因是MmMapIoSpace第一个参数传递的是一个结构而非结构的指针,而该结构实际的大小是 2 个双字,结果在masm32中表现为总共4个 dword 参数。调用非常简单,invoke MmMapIoSpace,物理地址低32位,0,长度,MmNonCached若成功该函数返回影射后的线性地址,否则返回NULL。这样就可以间
3、接达到读取物理地址中内容的目的。bios开始地址在实模式下是F000:0,也就是0f0000h,长度是64k,也就是10000h这样我们就可以用一句 invoke MmMapIoSpace,0f0000h,0,64*1024,MmNonCached ;把BIOS的物理地址映射为线性地址,返回值在eax中。然后把eax指向的线性地址中的内容复制到系统的缓冲区中,让驱动程序传给ring3下的应用程序。bios_test.bat是驱动源码。bios_test.asm是调用驱动的ring3级程序,它把驱动传回的bios内容写入文件bios_tst.bin,是16进制的,可以用16进制编辑器来查看。实际
4、使用时,可以传递一个随机的密钥给驱动程序,驱动程序负责把bios内容加密后返回,这样可以一定程度上增加解密的难度。程序中已经预留了接口,实现起来很简单,有兴趣者可以自己实现。 以下是程序源代码:已在xp和vista下调试通过。;goto make;文件名bios_test.bat 作者:盛玉增 2009年10月20日用masm32v8和kmdkit1.8在winxp及vista下调试成功。.386.model flat, stdcalloption casemap:noneinclude masm32includew2kntstatus.incinclude masm32includew2kn
5、tddk.incinclude masm32includew2kntoskrnl.incincludelib masm32libw2kntoskrnl.libinclude masm32MacrosStrings.macIOCTL_GET_INFO equ CTL_CODE(FILE_DEVICE_UNKNOWN, 800h, METHOD_BUFFERED, FILE_READ_ACCESS + FILE_WRITE_ACCESS).constCCOUNTED_UNICODE_STRINGDevicebios_test, g_usDeviceName, 4CCOUNTED_UNICODE_S
6、TRING?bios_test, g_usSymbolicLinkName, 4.databuff1db 128*512 dup (0f6h) ;key_1db 32 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
7、are in user process context heremov eax, pIrpassume eax:ptr _IRPmov eax.IoStatus.Status, STATUS_SUCCESSand eax.IoStatus.Information, 0assume eax:nothingfastcall IofCompleteRequest, pIrp, IO_NO_INCREMENTmov eax, STATUS_SUCCESSretDispatchCreateClose endp;:; DispatchControl ;:DispatchControl proc uses
8、esi edi pDeviceObject:PDEVICE_OBJECT, pIrp:PIRPlocal status:NTSTATUSlocal dwBytesReturned:DWORD;实际返回的字节数and dwBytesReturned, 0mov esi, pIrpassume esi:ptr _IRPIoGetCurrentIrpStackLocation esimov edi, eaxassume edi:ptr IO_STACK_LOCATION.if edi.Parameters.DeviceIoControl.IoControlCode = IOCTL_GET_INFO.
9、if edi.Parameters.DeviceIoControl.OutputBufferLength = 30mov eax, esi.AssociatedIrp.SystemBuffer pushad push eax mov esi,eax mov ecx,30 mov edi,offset key_1 cld rep movsb;保存传过来的数据到key_1,以备做密钥,加密数据后返回。 invoke MmMapIoSpace,0f0000h,0,64*1024,MmNonCached ;物理地址映射为线性地址,返回值在eaxcmp eax,0 ;eax=0,失败jnz next_1
10、jmp next_2 next_1: mov esi,eaxpop edimov ecx,10000hrep movsbpopadmov dwBytesReturned, 128*512mov status, STATUS_SUCCESSjmp next_3next_2:pop eax popad mov status, STATUS_INVALID_DEVICE_REQUESTnext_3:.elsemov status, STATUS_BUFFER_TOO_SMALL.endif.elsemov status, STATUS_INVALID_DEVICE_REQUEST.endifassume edi:nothingpush statuspop esi.IoStatus.Statuspush dwBytesReturnedpop esi.IoStatus.Informationassume esi:nothingfastcall IofCompleteRequest, esi, IO_NO_INCREMENTmov eax, statusretDispatchControl endp;:; DriverUnload