By a "filter", I mean a program that takes a file for input, and outputs another ("filtered") file.
;DUMP.EXE for the Win32 console, illustrative standard-IO filter.
;Also illustrates buffered file input and output.
comment~ Sample build file:
@echo off
\masm32\bin\ml /c /coff dump.asm
if errorlevel 1 goto end
\masm32\bin\polink /SUBSYSTEM:CONSOLE /STACK:4096,4096 /HEAP:4096,4096 dump.obj
del dump.obj
dir dump.exe
:end
~
comment~ When it's assembled, enter e.g.
dump<sometextfile
or
echo some text|dump
or
type sometextfile|dump
and you will see a hex dump of the input. The output may be redirected
to a file or device, just as in DOS.
Filters of this kind can be chained together, as in:
type sometextfile | caps.exe | ltrim.exe
where "caps" and "ltrim" are st-IO filters.
~
.586
.model flat, stdcall
option casemap:none
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
ReadBuff_ equ 200h ;buffer sizes
WriteBuff_ equ 200h
.data
ExitAddress dd ?
hRead dd ? ;file handle
ReadBuff dd ? ;address of a buffer in the stack
amtReadBuff dd 0 ;number of bytes of data remaining in the buffer
ptrReadBuff dd ? ;address of the next byte to get
hWrite dd ? ;file handle
WriteBuff dd ? ;address of a buffer in the stack
amtWriteBuff dd WriteBuff_ ;number of bytes of space remaining in the buffer
ptrWriteBuff dd ? ;address to which to put the next byte
bytesperline equ 16
countdown dd bytesperline
.code
Start:
pop ExitAddress ;an alternative to ExitProcess or ExitThread
sub esp,ReadBuff_ ;heap instead of stack could be used for these buffers
mov ReadBuff,esp
sub esp,WriteBuff_
mov WriteBuff,esp
mov ptrWriteBuff,esp
invoke GetStdHandle,-10 ; -10 = STD_INPUT_HANDLE
mov hRead,eax
invoke GetStdHandle,-11 ; -11 = STD_OUTPUT_HANDLE
mov hWrite,eax
MainLoop:
call GetByte
js InputExhausted
push eax
mov al," "
call PutByte
pop eax
call AL2hexAX
push eax
call PutByte
pop eax
mov al,ah
call PutByte
dec countdown
jnz MainLoop
mov countdown,bytesperline
call PutCRLF
jmp MainLoop
InputExhausted:
cmp countdown,bytesperline
je short @F
call PutCRLF
@@: call FlushWrite
xor eax,eax
jmp ExitAddress
GetByte: ;returns a byte in AL, from the read handle, or SF if end-of-file.
mov esi,offset amtReadBuff
dec dword ptr[esi]
jns short @F ;if read buffer is empty, read more of the input
invoke ReadFile,hRead,ReadBuff,ReadBuff_,esi,0
mov eax,[esi]
dec eax
js short AnyRet
mov [esi],eax
mov eax,ReadBuff
mov ptrReadBuff,eax
@@: mov esi,ptrReadBuff
lodsb
mov ptrReadBuff,esi
AnyRet: ret
PutCRLF:
mov al,13
call PutByte
mov al,10
PutByte: ;input is al
mov edi,ptrWriteBuff
stosb
mov ptrWriteBuff,edi
dec amtWriteBuff
jnz short AnyRet ;if write buffer is now full, write what is there
FlushWrite:
mov eax,ptrWriteBuff
mov edx,WriteBuff
sub eax,edx
invoke WriteFile,hWrite,edx,eax,addr amtWriteBuff,0
mov amtWriteBuff,WriteBuff_
mov eax,WriteBuff
mov ptrWriteBuff,eax
ret
AL2hexAX:
mov ah,al
shr ah,4
call nibble2hexAL
xchg al,ah
nibble2hexAL:
and al,0Fh
cmp al,0Ah
sbb al,69h
das
ret
end Start
very cool
Mike (Slugsnack) was playing with this a while back
he was using piping to run one app under another in GUI mode - you might find it interesting
Lol, why on earth do you save the calling address from the CreateProcess api and jmp to that ? Weirdness.
I thought people using RET instead of exitprocess was weird, but this ... :green
I like to be different. Who else would use POP as the very first instruction in a program? :eek But really now, jumping to ExitAddress is available from anywhere in the program, whereas RET isn't, and it makes for one fewer symbol in the import table.
Quote from: Larry Hammick on November 10, 2009, 05:15:42 AM
Who else would use POP as the very first instruction in a program?
malware/virus writers? (
no accusations here, just an observation :bg)
A small subroutine may well start with a pop instruction, e.g.
sz_copy@8: ;(lpDest,lpSrc) returns eax pointing at the terminator in the destination
pop eax
pop edx ;dest
pop ecx ;src
push eax
sub edx,ecx
@@: mov al,[ecx]
mov [ecx+edx],al
inc ecx
test al,al
jnz short @B
lea eax,[ecx+edx-1]
ret ;stack is clean
For sure, but that's a subroutine, not the first instruction. I've also seen it in exe packers and 'no import' win32 exe's.
So you aren't so different after all :P
Quote from: sinsi on November 10, 2009, 05:32:29 AM
Quote from: Larry Hammick on November 10, 2009, 05:15:42 AM
Who else would use POP as the very first instruction in a program?
malware/virus writers? (no accusations here, just an observation :bg)
I use it a lot of times inside procs and i never write a malware or virus :bg
Rui
A "varargs" routine that cleans its own stack is likely to be begin by popping the return address. Simple illustration:
add_em_all: ;takes a zero-terminated list of dwords on the stack
pop edx
xor eax,eax
@@: pop ecx
add eax,ecx
test ecx,ecx
jnz short @B
jmp edx
I've written my own partial substitute for wsprintf that cleans its own stack. Not very hard.