LCF-AT Posted August 7, 2017 Posted August 7, 2017 Hi guys, today I would like to ask something about CMD / console windows so I have again a little problem and need some help. Problem: I am trying to create a new GUI app and using a library from a commandline app.So everything ok so far so I can normaly use the functions of that library for my GUI app.Only problem I have now is that the original commandline app does also LOG informations into the console window and I just use a GUI without console window yet.I also see that the library still does LOG everything but I dont have a console window to see that infos into etc you know. My question is how to start a simple console window and what to use to see that LOG infos inside? In the library I can see at the LOG API that it used fprintf API with a streamhandle like that.. /CALL to fprintf |stream = msvcrt.75E62940 |format = "%s: %s" |<%s> = "DEBUG" \<%s> = "Parsing..." So what can I do now?Starting a new console window anyhow (by button press in GUI) and then I should get / have a handle of console window and should I then just change the used stream handle with my started console window handle to get then the LOG infos to see inside?I am not really sure about that so maybe you have some ideas how it could work etc.Or are there better / easier ways like starting a console window + giving then the handle above etc?As I said the library does LOG already everything and I just need to start a console + xy to see that logs then in that console anyhow. Thank you
atom0s Posted August 7, 2017 Posted August 7, 2017 AllocConsole API will allow you to create a console window for a UI application. 2
LCF-AT Posted August 8, 2017 Author Posted August 8, 2017 Hi, ok but how to get now the LOG datas inside the window now by the called APIs like fputs / fprintf?So somehow I have to set the window to get the Log datas inside.Any idea? greetz
LCF-AT Posted August 8, 2017 Author Posted August 8, 2017 Hi again, I found something like that... #include<stdio.h> #include<windows.h> #include<fcntl.h> #include<io.h> int __stdcall WinMain(HINSTANCE,HINSTANCE,LPSTR,int) { AllocConsole(); *stdout = *_fdopen(_open_osfhandle((long) GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT), "w"); printf("aaa"); FreeConsole(); return 0; } I tried this in my code.... invoke AllocConsole invoke GetStdHandle,STD_OUTPUT_HANDLE mov edi,eax invoke crt__open_osfhandle,edi,4000h ;_O_TEXT invoke crt__fdopen,eax,chr$("w") printf("aaa"); invoke FreeConsole ....but I get nothing into the window. Only thing I could do is hooking the output APIs like fputs / fprintf etc to catch the logged datas and to send them via WriteConsole into my allocconsole window but thats just a stupid idea.So somehow it should work else but how is the question. PS: Main goal is it to start a CMD window and to get the APIs like fputs / fprintf working with that CMD window = text should shown then in that CMD window I did started. greetz
LCF-AT Posted August 8, 2017 Author Posted August 8, 2017 Hi, so for the moment I tried to hook fprintf API to my code where I do make a wsprintfA call and send then the datas via WriteConsole into CMD window.Seems to work so far but the problem is if I close the CMD window via mouse then it also close my GUI app too!?Why this now?So the CMD window should get closed by user itself without using freeconsole in that case.Has anyone some more hints for me? greetz
atom0s Posted August 8, 2017 Posted August 8, 2017 There is also 'AttachConsole' API you can use by passing it the current process id of itself. The other std handles you can use to change the output to the console are: freopen("CONIN$", "r", stdin); freopen("CONOUT$", "w", stdout); freopen("CONOUT$", "w", stderr); 1
VirtualPuppet Posted August 8, 2017 Posted August 8, 2017 1 hour ago, LCF-AT said: Hi, so for the moment I tried to hook fprintf API to my code where I do make a wsprintfA call and send then the datas via WriteConsole into CMD window.Seems to work so far but the problem is if I close the CMD window via mouse then it also close my GUI app too!?Why this now?So the CMD window should get closed by user itself without using freeconsole in that case.Has anyone some more hints for me? greetz You want to use the following for Windows (example taken from one of my old HackShield bypasses): AllocConsole(); SetConsoleTitle("HackShield Bypass"); AttachConsole(GetCurrentProcessId()); FILE* file = nullptr; freopen_s(&file, "CON", "r", stdin); freopen_s(&file, "CON", "w", stdout); freopen_s(&file, "CON", "w", stderr); Now all io-functionality will be printed/parsed through CON (file descriptor for console), instead of stdin, stdout and stderr. However, when doing this (AllocConsole in general), you're binding the console to the lifetime of the current process, and manually closing the console will also terminate the process. I haven't looked for a way to circumvent this, as I haven't had the need to, but I don't think Windows intended for such functionality. 1
LCF-AT Posted August 8, 2017 Author Posted August 8, 2017 Hi again, AttachConsole dosent work with process ID and get ERROR_ACCESS_DENIED. As I said,I dont want that my main app does terminate if I close the console window via mouse.Is there not a way to let call just freeconsole API if I press close in the console app? Ok,so if it dosent work using console window as I want then I need to show any own window the user can see & close without closing the main app.The problem in that case is I dont what I should use for that (similar control as console).Only control I could use is a listbox where I can send data into which also keeps inside.For edit control I can not add new lines into etc you know what I mean.So what for a control could I use then? greetz
VirtualPuppet Posted August 8, 2017 Posted August 8, 2017 8 minutes ago, LCF-AT said: Hi again, AttachConsole dosent work with process ID and get ERROR_ACCESS_DENIED. As I said,I dont want that my main app does terminate if I close the console window via mouse.Is there not a way to let call just freeconsole API if I press close in the console app? Ok,so if it dosent work using console window as I want then I need to show any own window the user can see & close without closing the main app.The problem in that case is I dont what I should use for that (similar control as console).Only control I could use is a listbox where I can send data into which also keeps inside.For edit control I can not add new lines into etc you know what I mean.So what for a control could I use then? greetz You should use a listbox or listview depending on the data you output. If it has specific format, you would use a listview with columns, if it's just formatted strings, you should use a listbox (with custom-draw/owner-draw if you want it to look like a console). 1
LCF-AT Posted August 9, 2017 Author Posted August 9, 2017 Hi, so the data output is already done by the library I do use for console window and I just need to output same data to any control what should look same as in console.The datas to output also using CLRF I cant just use with a listview.For listbox I dont know it yet whether I could send such datas directly into it.So I also just wanna send same datas to any control to let show it without to reformat the datas etc.Also I dont wanna have that single selection of a LB and the scrolling of LBs is also bad (dont wanna disable Win option). Do you have any example code / file to check that out? greetz
VirtualPuppet Posted August 9, 2017 Posted August 9, 2017 20 minutes ago, LCF-AT said: Hi, so the data output is already done by the library I do use for console window and I just need to output same data to any control what should look same as in console.The datas to output also using CLRF I cant just use with a listview.For listbox I dont know it yet whether I could send such datas directly into it.So I also just wanna send same datas to any control to let show it without to reformat the datas etc.Also I dont wanna have that single selection of a LB and the scrolling of LBs is also bad (dont wanna disable Win option). Do you have any example code / file to check that out? greetz Well, it wouldn't be very nice to immitate that on a Listbox, as it is also row-divided like a listview (has independent rows). If you want to use CLRF like a Console, you'd need to either use a modified RICH EDIT control, with some kind of "append"-function or something that emulates the input/output functions. You could probably even force the input/output of printf, etc. to some custom hook that adds the data to an edit-control. You can look at this page for inspiration or help: https://www.codeproject.com/Articles/335909/Embedding-a-Console-in-a-C-Application Alternatively, you can disable the close-button for the console alltogether: HWND hWndConsole = GetConsoleWindow(); if (hWndConsole != NULL) { HMENU hMenu = GetSystemMenu(hWndConsole, FALSE); if (hMenu != NULL) DeleteMenu(hMenu, SC_CLOSE, MF_BYCOMMAND); } 1
LCF-AT Posted August 9, 2017 Author Posted August 9, 2017 Hi again, so I found that DeleteMenu also now on internet and tried it.So exit button is disabled now in console window.Seems to be good so far.Now I have created 2 test buttons in a test GUI.One does create the console with disabled close button and one button does free console = working.Now I checked that issue using Handler routine for the CTRL commands and the handler routine works too to get the commands and I can also catch CTRL_CLOSE_EVENT if I press close on console window but here I cant disable closing process.Also it happens automatically after few seconds.My question now is whether I could also stop the close event anyhow if I catch it in my handler routine?If yes then I dont need to disable the close function in console window and the user could also close the console without closing my GUI too. .elseif uMsg == WM_COMMAND .if wParam == IDB_EXIT invoke SendMessage, hWnd, WM_CLOSE, 0, 0 ;.................. .elseif wParam == 1030 invoke AllocConsole invoke GetStdHandle,STD_OUTPUT_HANDLE mov edi,eax invoke GetConsoleWindow mov esi,eax invoke GetSystemMenu,esi,FALSE mov ebx,eax invoke DeleteMenu,ebx,SC_CLOSE,MF_BYCOMMAND invoke WriteConsole, edi, chr$("TEST ETS"), 8, addr FREE2, NULL invoke SetConsoleCtrlHandler, ADDR HandlerRoutine, TRUE .elseif wParam == 1031 invoke FreeConsole ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; HandlerRoutine proc dwCtrlType:DWORD .IF dwCtrlType == CTRL_CLOSE_EVENT invoke MessageBox,0,chr$("CTRL_CLOSE_EVENT!"),chr$("Problem!"),MB_ICONWARNING invoke FreeConsole mov eax,TRUE ret .elseif dwCtrlType == CTRL_C_EVENT invoke MessageBox,0,chr$("CTRL_C_EVENT!"),chr$("Problem!"),MB_ICONWARNING invoke FreeConsole mov eax,TRUE ret .elseif dwCtrlType == CTRL_BREAK_EVENT invoke MessageBox,0,chr$("CTRL_BREAK_EVENT!"),chr$("Problem!"),MB_ICONWARNING .elseif dwCtrlType == CTRL_LOGOFF_EVENT invoke MessageBox,0,chr$("CTRL_LOGOFF_EVENT!"),chr$("Problem!"),MB_ICONWARNING .elseif dwCtrlType == CTRL_SHUTDOWN_EVENT invoke MessageBox,0,chr$("CTRL_SHUTDOWN_EVENT!"),chr$("Problem!"),MB_ICONWARNING .endif xor eax,eax Ret HandlerRoutine endp So on the other hand the user can press Strg+C to close console and GUI keeps running. AddOn question: Can I also set a new entry or context menu in that console window where I could choose "close window" ?Then I could do a freeconsole call after user did choose it etc you know. greetz
VirtualPuppet Posted August 9, 2017 Posted August 9, 2017 18 minutes ago, LCF-AT said: < long quote > Sadly, there's no actual way of intercepting or intervening with the closing-process. According to some information by Microsoft, that I googled my way to, the data used internally by the Console is already freed and deallocated before the event routine is being called, so the window is already partially destroyed when you are notified of the event, and as such there's no way to stop it half-way through (as it would be dangerous to keep the window while much of the data has been deallocated). If you want to intercept the contextmenu, you're gonna have to do API hooks, cause the console window runs in a sub-system to your current process. 1
LCF-AT Posted August 9, 2017 Author Posted August 9, 2017 Ah ok thanks for the infos so far.So I think at the moment I can live with that solution to disable close in console and using Strg+c & or extra button in GUI itself to free console.So I did some tests with that in my main project and it seems to work all good so far. Just bad that I need to hook the msvcrt APIs which do send datas to output to output them via WriteConsole.Anyway,so long the detour does work its also ok. One more question: So I see if I create a console window then my mouse scroller wheel isnt working in that console window.On internet I found that... Try SetConsoleMode and disable ENABLE_MOUSE_INPUT and use ENABLE_PROCESSED_INPUT. something like GetConsoleMode(hConsoleHandle, &lpMode); SetConsoleMode(hConsoleHandle, lpMode & ~ENABLE_MOUSE_INPUT | ENABLE_PROCESSED_INPUT); ...but isnt working anyhow.So I use AllocConsole / GetStdHandle STD_OUTPUT_HANDLE.Have I to use that handle I get from GetStdHandle?I tried and I get 3 back (ENABLE_PROCESSED_INPUT & ENABLE_LINE_INPUT) but if I use SetConsoleMode for that handle then it fails. invoke AllocConsole invoke GetStdHandle,STD_OUTPUT_HANDLE mov edi,eax invoke GetConsoleMode,edi,addr FREE2 invoke SetConsoleMode,edi,ENABLE_MOUSE_INPUT or ENABLE_PROCESSED_INPUT Some invalid Paramter I get in lasterror register and eax 0.So whats wrong here?Just dont wanna change anything etc just enabling the mouse wheel to scroll up / down in console you know. Thanks again
VirtualPuppet Posted August 9, 2017 Posted August 9, 2017 16 minutes ago, LCF-AT said: Ah ok thanks for the infos so far.So I think at the moment I can live with that solution to disable close in console and using Strg+c & or extra button in GUI itself to free console.So I did some tests with that in my main project and it seems to work all good so far. Just bad that I need to hook the msvcrt APIs which do send datas to output to output them via WriteConsole.Anyway,so long the detour does work its also ok. One more question: So I see if I create a console window then my mouse scroller wheel isnt working in that console window.On internet I found that... Try SetConsoleMode and disable ENABLE_MOUSE_INPUT and use ENABLE_PROCESSED_INPUT. something like GetConsoleMode(hConsoleHandle, &lpMode); SetConsoleMode(hConsoleHandle, lpMode & ~ENABLE_MOUSE_INPUT | ENABLE_PROCESSED_INPUT); ...but isnt working anyhow.So I use AllocConsole / GetStdHandle STD_OUTPUT_HANDLE.Have I to use that handle I get from GetStdHandle?I tried and I get 3 back (ENABLE_PROCESSED_INPUT & ENABLE_LINE_INPUT) but if I use SetConsoleMode for that handle then it fails. invoke AllocConsole invoke GetStdHandle,STD_OUTPUT_HANDLE mov edi,eax invoke GetConsoleMode,edi,addr FREE2 invoke SetConsoleMode,edi,ENABLE_MOUSE_INPUT or ENABLE_PROCESSED_INPUT Some invalid Paramter I get in lasterror register and eax 0.So whats wrong here?Just dont wanna change anything etc just enabling the mouse wheel to scroll up / down in console you know. Thanks again I've never tried altering the input-types for Console windows, so I can't help you there
LCF-AT Posted August 10, 2017 Author Posted August 10, 2017 Hi, anyway,so I checked CMD file what it does set for STD_INPUT_HANDLE.Just need these (ENABLE_PROCESSED_INPUT or ENABLE_LINE_INPUT or ENABLE_ECHO_INPUT) to get scrolling working. Now it works. greetz 1
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now