[转帖]2000/xp下读硬盘序列号[汇编]
我可没这个水平.686p
.model flat, stdcall
option casemap :none ; case sensitive
; #########################################################################
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\advapi32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\advapi32.lib
DEBUG = TRUE
HMODULE typedef dword
NTSTATUS typedef dword
PACL typedef dword
PSECURITY_DESCRIPTOR typedef dword
OBJ_INHERIT=2
OBJ_PERMANENT=10h
OBJ_EXCLUSIVE=20h
OBJ_CASE_INSENSITIVE=40h
OBJ_OPENIF=80h
OBJ_OPENLINK =100h
OBJ_KERNEL_HANDLE=200
OBJ_VALID_ATTRIBUTES=3F2h
SE_KERNEL_OBJECT = 6
GRANT_ACCESS =1
NO_INHERITANCE =0
TRUSTEE_IS_NAME=1
TRUSTEE_IS_USER=1
STATUS_SUCCESS =0
STATUS_ACCESS_DENIED =0C0000022h
STATUS_ACCESS_VIOLATION equ 0C0000005h
STATUS_INFO_LENGTH_MISMATCH equ 0C0000004h
SystemModuleInformation equ 11
PVOIDTYPEDEF DWORD
UNLONG TYPEDEF DWORD
CHAR TYPEDEF BYTE
UNICODE_STRING struct
nLength word ?
MaximumLength word ?
Buffer dword ?
UNICODE_STRING ends
OBJECT_ATTRIBUTES struct
nLength dword ?
RootDirectory HANDLE ?
ObjectName dword ?;PUNICODE_STRING
Attributes dword ?;
SecurityDescriptor dword ?; PVOID // Points to type SECURITY_DESCRIPTOR
SecurityQualityOfService dword ?;PVOID// Points to type SECURITY_QUALITY_OF_SERVICE
OBJECT_ATTRIBUTES ends
TRUSTEE struct
pMultipleTrustee dword ?;PTRUSTEE
MultipleTrusteeOperation dword ?; MULTIPLE_TRUSTEE_OPERATION
TrusteeForm dword ?;TRUSTEE_FORM
TrusteeType dword ?;TRUSTEE_TYPE
ptstrName dword ?;LPTSTR
TRUSTEE ends
EXPLICIT_ACCESSstruct
grfAccessPermissions DWORD ?
grfAccessModedword ? ;ACCESS_MODE
grfInheritance DWORD ? ;
Trustee TRUSTEE<> ;
EXPLICIT_ACCESS ends
MyGATE struct ;门结构类型定义
OFFSETLWORD ?;32位偏移的低16位
SELECTOR WORd ?;选择子
DCOUNT BYTE ?;双字计数字段
GTYPE BYTE ?;类型
OFFSETHWORD ?;32位偏移的高16位
MyGATE ends
IDEINFOstruct
wGenConfig dw ?
wNumCyls dw ?;拄面数
wReserved dw ?
wNumHeads dw ?;磁头数
wBytesPerTrack dw ?;每道字节数
wBytesPerSector dw ?;每扇区字节数
wSectorsPerTrackdw ?;每道山区数
wVendorUnique dw 3 dup (?)
sSerialNumber db 20 dup (?);硬盘序列号
wBufferType dw ?;
wBufferSize dw ?; ;n * 512
wECCSize dw ?
sFirmwareRev db 8 dup (?);
sModelNumber db 40 dup (?)
wMoreVendorUniquedw ?
wDoubleWordIO dw ?
wCapabilities dw ?
wReserved1 dw ?
wPIOTiming dw ?;
wDMATiming dw ?;
wBS dw ?
wNumCurrentCyls dw ?;
wNumCurrentHeadsdw ?;
wNumCurrentSectorsPerTrack dw ?;
dwCurrentSectorCapacitydd ?;
wMultSectorStuffdw ?;
dwTotalAddressableSectors dd ?;
wSingleWordDMA dw ?;
wMultiWordDMA dw ?;
bReserved db 128 dup (?)
IDEINFOends
SetPhyscialMemorySectionCanBeWrited proto :dword
MiniMmGetPhysicalAddress proto :dword
ENTERRING0 macro
pushad
pushfd
cli
mov eax,cr0 ;get rid off readonly protect
and eax,0fffeffffh
mov cr0,eax
endm
LEAVERING0 macro
mov eax,cr0 ;restore readonly protect
or eax,10000h
mov cr0,eax
sti
popfd
popad
retf
endm
UNICODE_STR macro str
irpc _c,<str>
db '&_c'
db 0
endm
endm
.data?
GdtLimit dw ?
GdtAddr dd ?
mapAddr dd ?
OldEsp dd ?
readeddw ?
buffer db 512 dup(?)
ShowText db 512*3 dup (?)
szBuffer db 1024 dup (?)
szModelNumber db 41 dup (?)
szSerialNumber db 21 dup (?)
szFirmwareRev db 9 dup (?)
stIDEINFO IDEINFO <?>
.data
align 4
objname dw objnamestr_size,objnamestr_size+2
objnameptr dd 0
objnamestr equ this byte
UNICODE_STR <\Device\PhysicalMemory>
objnamestr_size equ $-objnamestr
szTitledb 'IDE 硬盘信息',0
szErrInfo db '无法读取硬盘信息',0
szIDEInfo db '柱面数 : %d',0dh,0ah
db '磁头数 : %d',0dh,0ah
db '每道扇区数 : %d',0dh,0ah
db '缓冲大小 : %d 扇区',0dh,0ah
db '硬盘型号 : %40s',0dh,0ah
db '序列号 : %20s',0dh,0ah
db '版本号 : %8s',0
align 4
ObjAttr db 24 dup (0)
Callgt dq 0 ;call gate's sel:off
Captiondb 'Windows XP绝对磁盘读写',0
Digitdb '0123456789ABCDEF',0
.code
_ShowBuffer proc ;显示所读出的信息
;把数据转换成16进制的形式
mov,512
movesi,offset buffer;数据
movedi,offset ShowText;转换后的数据
movebx,offset Digit
xorecx,ecx
xoreax,eax
computeAgain:
cmp,0
jz endCompute
dec
lodsb
push eax
shreax,4 ;高4位
xlatb
stosb
popeax
andeax,0fH ;低4位
xlatb
stosb
movbyte ptr[edi],' ';空格
incedi
incecx
cmpecx,16
jnzcomputeAgain
xorecx,ecx
movbyte ptr[edi-1],13;回车
jmpcomputeAgain
endCompute:
;显示
invokeMessageBoxA,NULL,offset ShowText,offset Caption,MB_OK
ret
_ShowBuffer endp
SetPhyscialMemorySectionCanBeWrited proc uses ebx esi edi hSection:HANDLE
local pDacl: PACL
local pNewDacl:PACL
local pSD :PSECURITY_DESCRIPTOR
local dwRes:DWORD ;
local ea:EXPLICIT_ACCESS ;
invoke GetSecurityInfo,hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION, NULL,NULL, addr pDacl,NULL, addr pSD
cmp eax,ERROR_SUCCESS
jz @f
jmp OutSet
@@:
mov dwRes,eax
mov ea.grfAccessPermissions ,SECTION_MAP_WRITE;2
mov ea.grfAccessMode ,GRANT_ACCESS;1
mov ea.grfInheritance,NO_INHERITANCE;0
mov ea.Trustee.pMultipleTrustee,0
mov ea.Trustee.MultipleTrusteeOperation,0
mov ea.Trustee.TrusteeForm,TRUSTEE_IS_NAME;1
mov ea.Trustee.TrusteeType,TRUSTEE_IS_USER;1
call @f
db "CURRENT_USER",0
@@:
pop edx
mov ea.Trustee.ptstrName,edx
invoke SetEntriesInAcl,1,addr ea,pDacl,addr pNewDacl
cmp eax,ERROR_SUCCESS
jz @f
jmp OutSet
@@:
invoke SetSecurityInfo,hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION, NULL,NULL,pNewDacl,NULL
OutSet:
cmp pSD,0
jz @f
invoke LocalFree,pSD
@@:
cmp pNewDacl,0
jz @f
invoke LocalFree,pNewDacl
@@:
ret
SetPhyscialMemorySectionCanBeWrited endp
MiniMmGetPhysicalAddress proc virtualaddress:dword
mov eax,virtualaddress
cmp eax,80000000h
jb @f
cmp eax,0a0000000h
jae @f
and eax,1FFFF000h
ret
@@:
mov eax,0
ret
MiniMmGetPhysicalAddress endp
ExecRing0Proc proc
local tmpSel:dword
local setcg:dword
local BaseAddress:dword
local NtdllMod :dword
local hSection:HANDLE
local status:NTSTATUS
local objectAttributes:OBJECT_ATTRIBUTES
local objName:UNICODE_STRING
mov status,STATUS_SUCCESS;
sgdt GdtLimit
invoke MiniMmGetPhysicalAddress,GdtAddr
mov mapAddr,eax
test eax,eax
jz Exit1
call @f
db "Ntdll.dll",0
@@:
call LoadLibraryA
mov NtdllMod,eax
lea edx,objnamestr
mov objnameptr,edx
lea edi,ObjAttr
and di,0fffch ;align to 4 bytes,or ZwOpenSection will fail
push edi ;edi->ObjAttr
push 24 ;length of <\Device\PhysicalMemory>
pop ecx
push ecx
xor eax,eax
rep stosb ;put ObjAttr with 0
pop ecx
pop edi
mov esi,edi
stosd
mov dword ptr[esi],ecx
stosd
lea eax,[edx-8] ;eax->objname
stosd ;ObjAddr(18h,00,00,00,00,00,00,00,offset objname,40,02,00,00,dd 2 dup(0)
mov dword ptr [edi],240h
call @f
db "ZwOpenSection",0
@@:
push NtdllMod
call GetProcAddress
mov ebx,eax ;ebx=ZwOpenSection
push esi ;esi->ObjAttr
push SECTION_MAP_READ or SECTION_MAP_WRITE
lea edi,hSection
push edi ;edi->hSection
call eax ;ZwOpenSection(&hSection,SECTION_MAP_READ or SECTION_MAP_WRITE,ObjAttr)
mov status,eax
cmp status,STATUS_ACCESS_DENIED
jnz AccessPermit
mov eax,ebx
push esi
push READ_CONTROL or WRITE_DAC
push edi
call eax
mov status,eax
invoke SetPhyscialMemorySectionCanBeWrited,hSection
call @f
db "ZwClose",0
@@:
push NtdllMod
call GetProcAddress
push hSection
call eax;zwClose hSection
mov eax,ebx
push esi
push SECTION_MAP_READ or SECTION_MAP_WRITE
lea edi,hSection
push edi
call eax
mov status ,eax
;status =ZwOpenSection(&hSection,SECTION_MAP_WRITE|SECTION_MAP_WRITE,&objectAttributes);
AccessPermit:
cmp status ,STATUS_SUCCESS
jz @f
;printf("Error Open PhysicalMemory Section Object,Status:%08X\n",status);
;return 0;
mov eax,0
ret
@@:
movzx eax,word ptr
inc eax
invoke MapViewOfFile,hSection, FILE_MAP_READ or FILE_MAP_WRITE, 0, mapAddr, eax
mov BaseAddress,eax
cmp BaseAddress,0
jnz @f
;printf("Error MapViewOffile:");
;PrintWin32Error(GetLastError()); return 0;
mov eax,0
ret
@@:
mov esi,eax ;esi->gdt base
mov ecx,3e0h
mov eax,GdtAddr
.if dword ptr [esi+ecx+2]!=0ec0003e8h
mov byte ptr [esi],0c3h
mov word ptr [esi+ecx],ax
shr eax,16
mov word ptr [esi+ecx+6],ax
mov dword ptr [esi+ecx+2],0ec0003e8h
mov dword ptr [esi+ecx+8],0000ffffh
mov dword ptr [esi+ecx+12],00cf9a00h
.endif
mov setcg,TRUE
cmp setcg,0
jnz ChangeOK
call @f
db "ZwClose",0
@@:
push NtdllMod
call GetProcAddress
push hSection
call eax
xor eax,eax
ret
ChangeOK:
and dword ptr Callgt,0
xor eax,eax
mov ax,3e0h
or al,3h
mov wordptr ,ax
;farcall=((short)((ULONG)cg-(ULONG)BaseAddress))|3; //Ring 3 callgate;
lea eax,_Ring0Proc
;invoke VirtualLock,eax,seglen
test eax,eax
jnz @f
xor eax,eax
ret
@@:
invoke GetCurrentThread
invoke SetThreadPriority,eax,THREAD_PRIORITY_TIME_CRITICAL
invoke Sleep,0
call fword ptr ;use callgate to Ring0!
;_asm call fword ptr
_Ring0Proc: ; Ring0 code here..
mov eax,esp ;save ring0 esp
mov esp,[esp+4];->ring3 esp
push eax
mov ebx,offset stIDEINFO
assume ebx:ptr IDEINFO
;********************************************************************
; 等待硬盘就绪
;********************************************************************
mov ecx,10000h
mov dx,01f7h
@@:
in al,dx
cmp al,50h
jz @F
loop @B
jmp _II_TimeOut
@@:
;********************************************************************
; 发送命令
; 如果向主控制发送命令,则端口为 1f0h-1f7h
; 如果向副控制发送命令,则端口为 170h-177h
; 1f6h 如果要检测的设备为该IDE接口的主(MASTER)设备,
; 那么发送 a0,如果为从那么发送 b0
; 1f7h 如果要检测的设备为 ATA 设备那么发送 ec
; 如果为 ATAPI 设备那么发送 a1
;********************************************************************
mov al,0a0h;Drive 0,Head 0
mov dx,01f6h ;Drive and head port
out dx,al
mov al,0ech
inc dx ;Command port
out dx,al
;********************************************************************
; 等待硬盘就绪
;********************************************************************
mov ecx,10000h
@@:
in al,dx;1f7 (r-status register)
cmp al,58h;(driver is ready ,and seek complete)
jz @F
loop @B
jmp _II_TimeOut
@@:
;********************************************************************
; 将返回信息读回
; 注意一定要读满 100h 个字长
;********************************************************************
cld
mov edx,01f0h;data port - data comes in and out here
mov edi,ebx
mov ecx,0100h
rep insw
;********************************************************************
; 返回的信息中,型号、序列号、版本号为字形式
; 需要整理到字符串的形式
;********************************************************************
lea esi,[ebx].sSerialNumber
mov edi,esi
mov ecx,10
@@:
lodsw
xchg ah,al
stosw
loop @B
lea esi,[ebx].sFirmwareRev
mov edi,esi
mov ecx,24
@@:
lodsw
xchg ah,al
stosw
loop @B
_II_TimeOut:
assume ebx:nothing
pop esp ;restore ring0 esp
push offset Ring3
retf
Ring0CodeLen=$-_Ring0Proc
Ring3:
invoke GetCurrentThread
invoke SetThreadPriority,eax,THREAD_PRIORITY_NORMAL
;invoke VirtualUnlock,Entry,seglen
call @f
db "ZwClose",0
@@:
push NtdllMod
call GetProcAddress
push hSection
call eax
mov eax,TRUE
ret
ExecRing0Proc endp
main:
assume fs:nothing
push offset MySEH
push fs:
mov fs:,esp
mov OldEsp,esp
mov ax,ds ;if Win9x?
test ax,4
jnz Exit1
invoke ExecRing0Proc
.if stIDEINFO.wNumCyls
lea esi,stIDEINFO.sModelNumber
mov edi,offset szModelNumber
mov ecx,sizeof stIDEINFO.sModelNumber
rep movsb
lea esi,stIDEINFO.sSerialNumber
mov edi,offset szSerialNumber
mov ecx,sizeof stIDEINFO.sSerialNumber
rep movsb
lea esi,stIDEINFO.sFirmwareRev
mov edi,offset szFirmwareRev
mov ecx,sizeof stIDEINFO.sFirmwareRev
rep movsb
movzx eax,stIDEINFO.wNumCyls
movzx ebx,stIDEINFO.wNumHeads
movzx ecx,stIDEINFO.wSectorsPerTrack
movzx edx,stIDEINFO.wBufferSize
invokewsprintf,addr szBuffer,addr szIDEInfo, eax,ebx,ecx,edx, addr szModelNumber, addr szSerialNumber, addr szFirmwareRev
mov eax,offset szBuffer
.else
mov eax,offset szErrInfo
.endif
@@:
invoke MessageBox,NULL,eax,addr szTitle,MB_ICONINFORMATION or MB_OK
Exit1:
pop fs:
add esp,4
invoke ExitProcess,0
MySEH :
mov esp,OldEsp
pop fs:
add esp,4
invoke ExitProcess,-1
end main
[此贴子已经被作者于2003-11-2 18:14:02编辑过]
呵呵,ExecRing0Proc 这段程序甚妙,先得到gdt,然后构造一个调用门call gate's ,使程序从用户模式(ring 3)进入内核模式(ring 0)。进入内核模式之后,就可以没有限制地对系统干任何勾当。这段程序确实为高手所为,在下佩服得紧。
至于读硬盘序列号之类,只不过是在内核模式下的一个I/O应用罢了。
其实在NT/2000下读取硬盘序列号只要打开\\.\PhysicalDriveX(X:设备号0~26)设备,然后用DeviceIoControl()就可以读取了,不需要绕ring0这么一个大圈子
这个程序也可以C语言实现,不过中间必须嵌入几条汇编的指令,如sgdt GdtLimit
但还是用c来写更方便,例如:
call @f
db "ZwOpenSection",0
@@:
push NtdllMod
call GetProcAddress
mov ebx,eax ;ebx=ZwOpenSection
push esi ;esi->ObjAttr
push SECTION_MAP_READ or SECTION_MAP_WRITE
lea edi,hSection
push edi ;edi->hSection
call eax ;
用c的话只要一句就可以了
ZwOpenSection(&hSection,SECTION_MAP_READ or SECTION_MAP_WRITE,ObjAttr);
因此懂汇编,然后用C/C++编程,是成为高手的捷径
[此贴子已经被作者于2003-11-3 16:46:50编辑过]
win32位汇编,真的很不错,业余的时间,全都投进去了 要能有台机器试一下多好,学汇编还从没想过去ring0,也感觉没哪个必要。
现在闲着真相试试。这片文章我在家保存了有快一年了。不用感觉可惜了。一直停着不用,我都快忘了那些曾经那些依稀的记忆了。水能给我一台电脑,我力马高喊:有你这么富的吗? 很久以前的一段代码 很久以前?
不是吧,这个是 轻描淡写 编程论坛的斑竹写的 看到过的。
页:
[1]