flat assembler
Message board for the users of flat assembler.

Index > Windows > get the console output

Author
Thread Post new topic Reply to topic
edfed



Joined: 20 Feb 2006
Posts: 4354
Location: Now
edfed 14 Jun 2019, 09:08
How can i get the content of console from an external .exe?

i createprocess a .exe console that will close itself at the end.

i need to get the content of this console to parse the text.

the console app cannot be modified and don't use pipes.

thanks


[edit]

here is the solution

in this code, the console is allocated at startup, then hidden.
each time a command is executed (createprocess), the console content is reset to get only the last result.

in the previous version, the console was created and hidden each time a command is executed, inducing a ugly window to sparkle on the screen.

Code:
format PE GUI 4.0
entry start

include 'win32a.inc'

struct COORD
      X dw 0
      Y dw 0
ends

struct SMALL_RECT
      left dw 0
      top dw 0
      right dw 0
      bottom dw 0
ends

struct CHAR
      AsciiChar db ?,?
ends

struct CHAR_INFO
       Char CHAR
       Attributes dw ?
ends

struct CONSOLE_SCREEN_BUFFER_INFO
       dwSize COORD
       dwCursorPosition COORD
       wAttributes dw ?
       srWindow SMALL_RECT
       dwMaximumWindowSize COORD
ends

section '.text' code readable writable executable

start:
        invoke GetModuleHandle,0
        mov [wc.hInstance],eax
        invoke RegisterClass,wc
        test eax,eax
        jz error
        invoke LoadMenu,[wc.hInstance],IDR_MENU
        invoke CreateWindowEx,\
                        WS_EX_TOPMOST,_class,_title,\
                        WS_VISIBLE+WS_OVERLAPPEDWINDOW,\
                        20,32,300,512,\
                        NULL,eax,[wc.hInstance],NULL
        test eax,eax
        jz error

msg_loop:
        invoke GetMessage,msg,NULL,0,0
        cmp eax,1
        jb end_loop
        jne msg_loop
        invoke TranslateMessage,msg
        invoke DispatchMessage,msg
        jmp msg_loop

error:
        invoke MessageBox,NULL,_error,NULL,MB_ICONERROR+MB_OK

end_loop:
        invoke ExitProcess,[msg.wParam]

proc WindowProc uses ebx esi edi ,hwnd,wmsg,wparam,lparam
        mov eax,[wmsg]
        cmp eax,WM_DESTROY
        je .wmdestroy
        cmp eax,WM_COMMAND
        je .wmcommand
        cmp eax,WM_CREATE
        je .wmcreate
        cmp eax,WM_SIZE
        je .wmsize
        cmp eax,WM_SETFOCUS
        je .wmsetfocus

.default:
        invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
        jmp .finish

.wmcreate:
        invoke AllocConsole
        invoke GetConsoleWindow
        mov [consoleHandle],eax
        invoke ShowWindow, [consoleHandle], SW_HIDE

        invoke GetStdHandle, STD_OUTPUT_HANDLE
        mov [stdOutput],eax

        invoke GetConsoleScreenBufferInfo,[stdOutput],consoleBuffer


        invoke GetClientRect,[hwnd],client
        invoke CreateWindowEx,\
                        WS_EX_CLIENTEDGE,_edit,0,\
                        WS_VISIBLE+WS_CHILD+WS_HSCROLL+WS_VSCROLL+ES_AUTOHSCROLL+ES_AUTOVSCROLL+ES_MULTILINE,\
                        [client.left],[client.top],[client.right],[client.bottom],\
                        [hwnd],0,[wc.hInstance],NULL
        or eax,eax
        jz .failed
        mov [edithwnd],eax
        invoke CreateFont,\
                        14,0,0,0,0,FALSE,FALSE,FALSE,\
                        ANSI_CHARSET,OUT_RASTER_PRECIS,CLIP_DEFAULT_PRECIS,DRAFT_QUALITY,FIXED_PITCH+FF_DONTCARE,NULL
        or eax,eax
        jz .failed
        mov [editfont],eax
        invoke SendMessage,[edithwnd],WM_SETFONT,eax,FALSE
        xor eax,eax
        jmp .finish

.failed:
        or eax,-1
        jmp .finish

.wmsize:
        invoke GetClientRect,[hwnd],client
        invoke MoveWindow,[edithwnd],[client.left],[client.top],[client.right],[client.bottom],TRUE
        xor eax,eax
        jmp .finish

.wmsetfocus:
        invoke SetFocus,[edithwnd]
        xor eax,eax
        jmp .finish

.wmcommand:
        movzx eax,word[wparam]
        cmp eax,IDM_EXIT
        je .wmdestroy
        cmp eax,IDM_LOAD
        je .load
        cmp eax,IDM_ABOUT
        je .about
        jmp .default

.new:
        jmp .finish

.load:
        call callConsoleApp
        jmp .finish

.about:
        invoke MessageBox,[hwnd],_aboutTxt,_title,MB_OK
        jmp .finish

.wmdestroy:
        invoke FreeConsole
        invoke PostQuitMessage,0
        xor eax,eax

.finish:
        ret

endp


callConsoleApp:

        movzx eax,[consoleBuffer.dwSize.X]
        movzx ebx,[consoleBuffer.dwSize.Y]
        imul ebx

        invoke FillConsoleOutputCharacter,[stdOutput],' ',eax,0,return
        invoke SetConsoleCursorPosition,[stdOutput],0

        mov [startupInfo.cb], sizeof.STARTUPINFO
        mov [startupInfo.dwFlags], STARTF_USESHOWWINDOW;
        mov [startupInfo.wShowWindow], SW_HIDE;
        invoke CreateProcess, NULL, commandLine, NULL, NULL, FALSE, 0, NULL, NULL, startupInfo, processInfo
        or eax,eax
        jne @f
        invoke GetLastError
        jmp .end
@@:
        invoke WaitForSingleObject, [processInfo.hProcess], 100000
        invoke ReadConsoleOutput,[stdOutput], cinfo, dword[bsize], dword[bstart], bzone
        mov ch,100
        mov ebx,0
.line:
        mov cl,80
        mov edx,0
        mov ah,0
.char:
        mov al,byte[cinfo+ebx*4+CHAR_INFO.Char.AsciiChar]
        inc ebx
        cmp ax,'  '
        je @f
        mov [textLine+edx],al
        inc edx
@@:
        mov ah,al
        dec cl
        jne .char
        cmp edx,1
        jle @f
        mov [textLine+edx],13
        mov [textLine+edx+1],10
        mov [textLine+edx+2],0
        mov eax,textLine
        call printf
@@:
        dec ch
        jne .line
.end:
        ret

printf:
;eax = pointer to string null terminated to put at the end of the text field
        push ebx ecx edx
        mov ebx,[edithwnd]
        push eax
        invoke  SendMessage,ebx,EM_SETSEL,-1,-1
        pop eax
        invoke  SendMessage,ebx,EM_REPLACESEL,FALSE,eax
        pop edx ecx ebx
        ret

section '.rdata' data readable writeable

wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class

msg MSG
client RECT

sinfo   STARTUPINFO
pinfo   PROCESS_INFORMATION

edithwnd dd ?
editfont dd ?

consoleBuffer CONSOLE_SCREEN_BUFFER_INFO

startupInfo   STARTUPINFO
processInfo   PROCESS_INFORMATION
consoleHandle dd 0
stdOutput     dd 0

cinfo         rd 80*100 ;CHAR_INFO
bsize         COORD 80,100
bstart        COORD 0,0
bzone         SMALL_RECT 0,0,80,100

return        dd ?
textLine      rb 80+2

_class  db 'edfed',0
_title  db 'console interception',0
_aboutTxt db 'This tool get the console output from a console executable',0
_error  db 'Startup failed.',0
_edit   db 'EDIT',0
commandLine db 'fasm.exe try.asm',0
commandCls db 'cls',0

section '.rsrc' resource data readable

IDR_ICON = 17
IDR_MENU = 37

IDM_NEW   = 101
IDM_EXIT  = 102
IDM_ABOUT = 901
IDM_CRV   = 201
IDM_LOAD  = 202
IDM_PARENT = 203

IDL_READY = 301
IDL_KEYS  = 302
IDL_MEDIA = 303
IDL_CP1A = 304

directory RT_MENU,menus,\
          RT_VERSION,versions

resource menus,\
         IDR_MENU,LANG_ENGLISH+SUBLANG_DEFAULT,main_menu

resource versions,\
         1,LANG_NEUTRAL,version

menu main_menu
     menuitem '&File',0,MFR_POPUP
              menuitem '&Load',IDM_LOAD
              menuseparator
              menuitem 'E&xit',IDM_EXIT,MFR_END
     menuitem '&Help',0,MFR_POPUP + MFR_END
              menuitem '&About...',IDM_ABOUT,MFR_END

versioninfo version,VOS__WINDOWS32,VFT_APP,VFT2_UNKNOWN,LANG_ENGLISH+SUBLANG_DEFAULT,0,\
            'FileDescription','console interception',\
            'LegalCopyright','edfed 2019',\
            'FileVersion','0.1',\
            'ProductVersion','0.1',\
            'OriginalFilename','consoleInterception.exe'

section '.idata' import data readable writeable

library kernel32,'KERNEL32.DLL',\
        user32,'USER32.DLL',\
        shell32,'SHELL32.DLL',\
        gdi32,'GDI32.DLL',\
        comdlg32,'COMDLG32.DLL'

include 'api\kernel32.inc'
include 'api\user32.inc'
include 'api\shell32.inc'
include 'api\gdi32.inc'
include 'api\comdlg32.inc'
    


Description:
Download
Filename: consoleInterception.asm
Filesize: 7.47 KB
Downloaded: 543 Time(s)



Last edited by edfed on 11 Jul 2019, 08:55; edited 1 time in total
Post 14 Jun 2019, 09:08
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20519
Location: In your JS exploiting you and your system
revolution 14 Jun 2019, 09:37
You can create a child process and specify the handle for the child process to output stdout into your app.

That is actually what the normal Windows console does anyway. It just takes the output and draws a window showing the text. But for you instead of drawing a window you can process the text for your needs.
Post 14 Jun 2019, 09:37
View user's profile Send private message Visit poster's website Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4354
Location: Now
edfed 14 Jun 2019, 12:43
thanks. got it Smile
Post 14 Jun 2019, 12:43
View user's profile Send private message Visit poster's website Reply with quote
guignol



Joined: 06 Dec 2008
Posts: 763
guignol 14 Jun 2019, 20:12
can you please show in functions
Post 14 Jun 2019, 20:12
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4354
Location: Now
edfed 15 Jun 2019, 13:58
i code it in c++, it uses:

AllocConsole
GetStdHandle
CreateProcess
WaitForSingleObject
ReadConsoleOutput
FreeConsole

ones i got the console output in the lpBuffer argument of ReadConsoleOutput, i just scan each character and append to a string for each line, and store each string in an array.

monday i'll make a asm version and post it Wink
Post 15 Jun 2019, 13:58
View user's profile Send private message Visit poster's website Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4354
Location: Now
edfed 17 Jun 2019, 12:17
see first post for the last version


Description:
Download
Filename: consoleInterception.asm
Filesize: 6.93 KB
Downloaded: 592 Time(s)



Last edited by edfed on 15 Jul 2019, 07:48; edited 1 time in total
Post 17 Jun 2019, 12:17
View user's profile Send private message Visit poster's website Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4354
Location: Now
edfed 05 Jul 2019, 08:25
now, i wonder how i can avoid the brief display of the console window.
Post 05 Jul 2019, 08:25
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20519
Location: In your JS exploiting you and your system
revolution 05 Jul 2019, 13:01
edfed wrote:
now, i wonder how i can avoid the brief display of the console window.
If you make it a GUI application then there is no console window. But then you can't later attach to an existing console to get events.
Post 05 Jul 2019, 13:01
View user's profile Send private message Visit poster's website Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4354
Location: Now
edfed 05 Jul 2019, 15:36
i say, the console of the child process
Post 05 Jul 2019, 15:36
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20519
Location: In your JS exploiting you and your system
revolution 06 Jul 2019, 14:00
It is the same for a child process and a parent process. The behaviour of GUI vs console is like that.

Windows doesn't make it so easy to work with console apps.
Post 06 Jul 2019, 14:00
View user's profile Send private message Visit poster's website Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4354
Location: Now
edfed 08 Jul 2019, 09:20
yep, and microsoft provide a pseudo console functions to work with since win10.
https://docs.microsoft.com/en-us/windows/console/createpseudoconsole

https://docs.microsoft.com/en-us/windows/console/creating-a-pseudoconsole-session

problem is ...win10 only
Post 08 Jul 2019, 09:20
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.