.386 .model flat,stdcall .code q: db 16- .... db 16- end q
; @echo off ; ml /c /coff quine.cmd ; pause ; if errorlevel 1 goto exit ; link /subsystem:windows /section:.text,RW quine.obj ; pause ; del quine.obj ; goto exit .386 .model flat,stdcall option casemap:none include \masm32\include\windows.inc bStr = 25 ; - , qLen = len * 5 + (len / bStr + 1) * 4 + len1 + 10 ; stLen = (qLen / 1000h + 1) * 1000h ; .code ; *** 1 - *** start: cld mov edx,[esp] ; kernel32.dll - 2 sub esp,stLen ; mov edi,esp mov stAddr,edi lea esi,text xor ecx,ecx mov cl,len1 rep movsb ; '.386 .model flat ...' lea esi,start mov bl,bStr cycl: mov eax,ecx ; . ? div bl or ah,ah jnz comma mov ax,0A0Dh ; - db stosw mov eax,' bd' stosd dec edi jmp j1 comma: mov al,',' ; - , stosb j1: mov al,'h' ; 16- - h shl eax,16 lodsb mov ah,al and al,0Fh cmp al,10 sbb al,69h das ; xchg al,ah shr al,4 cmp al,10 sbb al,69h das ; shl eax,8 mov al,'0' ; 0 stosd inc ecx cmp ecx,len jb cycl mov ax,0A0Dh ; 'end q' stosw mov eax,' dne' stosd mov eax,'q' stosd ; *** 2 - API *** xor dx,dx c2: cmp word ptr [edx],'ZM' ; MZ- kernel32? je c1 c3: sub edx,10000h jmp c2 c1: mov ecx,[edx+3Ch] cmp dword ptr [edx+ecx],'EP' ; PE-? jne c3 mov ecx,[edx+ecx+78h] add ecx,edx ; kernel32 push ecx mov eax,[ecx+20h] add eax,edx ; xor ebx,ebx xor ecx,ecx cycl2: mov esi,[eax+4*ebx] add esi,edx lea edi,GPAname mov cl,len2 repe cmpsb ; GetProcAddress je found inc ebx jmp cycl2 found: pop ecx mov eax,[ecx+24h] add eax,edx mov bx,[eax+2*ebx] ; GetProcAddress mov eax,[ecx+1ch] add eax,edx mov ebx,[eax+4*ebx] add ebx,edx mov edi,edx ; EBX - GetProcAddress ; EDI - kernel32 ( - user32) xor ecx,ecx ; mov cl,tlen lea esi,tbl cycl3: cmp cl,tlen-tlen2 jne j2 push ecx push offset DLLname call eax ; user32.dll LoadLibrary pop ecx mov edi,eax j2: dec cl push ecx push [esi+4*ecx] push edi call ebx ; GetProcAddress pop ecx mov [esi+4*ecx],eax or cl,cl jnz cycl3 ; *** 3 - MessageBox *** push NULL call dword ptr _GetModuleHandle mov hInst,eax call dword ptr _GetCurrentThreadId push eax push NULL push offset hProc push WH_CBT ; call dword ptr _SetWindowsHookEx mov hook,eax push MB_OK push offset capt push stAddr push 0 call dword ptr _MessageBox ; push 0 call dword ptr _ExitProcess ; *** hProc proc code:dword,wParam:dword,lParam:dword ; local coord:RECT pusha cmp code,HCBT_ACTIVATE ; ? jne exit push 0FFFFh push wParam call dword ptr _GetDlgItem mov ebx,eax ; lea eax,coord push eax push ebx call dword ptr _GetClientRect ; add coord.right,20 push NULL push NULL push WM_GETFONT push ebx mov edi,_SendMessage call edi ; mov esi,eax push SW_HIDE push ebx call dword ptr _ShowWindow ; push NULL push hInst push 0FFFFh push wParam push coord.bottom push coord.right push coord.top push coord.left push WS_CHILD+WS_VISIBLE+ES_MULTILINE+ES_READONLY push stAddr push offset cname push WS_EX_WINDOWEDGE call dword ptr _CreateWindowEx ; EDIT STATIC ; , push NULL push esi push WM_SETFONT push eax call edi ; push hook call dword ptr _UnhookWindowsHookEx ; popa xor eax,eax ret exit: popa push lParam push wParam push code push hook call dword ptr _CallNextHookEx ; ret hProc endp ; *** capt db 'Quine',0 ; GPAname db 'GetProcAddress',0 len2 equ $ - GPAname GDIname db 'GetDlgItem',0 ; GCRname db 'GetClientRect',0 SMname db 'SendMessageA',0 SWname db 'ShowWindow',0 CWEname db 'CreateWindowExA',0 UWHEname db 'UnhookWindowsHookEx',0 CNHEname db 'CallNextHookEx',0 SWHEname db 'SetWindowsHookExA',0 MBname db 'MessageBoxA',0 LLname db 'LoadLibraryA',0 GMHname db 'GetModuleHandleA',0 GCTIname db 'GetCurrentThreadId',0 EPname db 'ExitProcess',0 DLLname db 'user32.dll',0 cname db 'EDIT',0 ; text db '.386',13,10,'.model flat,stdcall',13,10,'.code',13,10,'q:' ; len1 equ $ - text tbl label dword ; , _GetDlgItem dd offset GDIname ; user32.dll _GetClientRect dd offset GCRname _SendMessage dd offset SMname _ShowWindow dd offset SWname _CreateWindowEx dd offset CWEname _UnhookWindowsHookEx dd offset UWHEname _CallNextHookEx dd offset CNHEname _SetWindowsHookEx dd offset SWHEname _MessageBox dd offset MBname tbl2 label dword _LoadLibrary dd offset LLname ; kernel32.dll _GetModuleHandle dd offset GMHname _GetCurrentThreadId dd offset GCTIname _ExitProcess dd offset EPname tlen2 equ ($-tbl2) / 4 tlen equ ($-tbl) / 4 ; len equ $ - start ; ; *** , hInst dd ? ; hook dd ? ; stAddr dd ? ; end start :exit
Source: https://habr.com/ru/post/217375/
All Articles