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

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 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 PostQuitMessage,0
        xor eax,eax

.finish:
        ret

endp


callConsoleApp:
        invoke AllocConsole
        invoke GetConsoleWindow
        mov [consoleHandle],eax
        invoke ShowWindow, [consoleHandle], SW_HIDE

        invoke GetStdHandle, STD_OUTPUT_HANDLE
        mov [stdOutput],eax
        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:
        invoke FreeConsole
        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
_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

msg MSG
client RECT

sinfo   STARTUPINFO
pinfo   PROCESS_INFORMATION


edithwnd dd ?
editfont dd ?


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

textLine      rb 80+2

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'
