![]() |
|
|
#1 |
![]() |
C/C++/C# Console Redirection with Sockets - Win32
Here's another interesting thing that you can do with sockets in C or C++. If any of you are familiar with the concepts of SSH or Telnet you'll get this straight away. Every console application has three IO paths...
1. stdIn is the standard input - aka when you type something into the console and it goes to your program. 2. stdOut is the standard output - aka when your program outputs feedback the data is written to stdOut, then its contents are written to the console you are working in. 3. stdErr is the standard error - aka if your program crashes and burns you can tell the OS roughly what happened (in an ideal world...) Well with C or C++ in Windows you can redirect stdIn and stdOut of any console application to go through a network socket. To write to stdIn you simply send data over the socket. To read from stdOut you simply read data off of the socket. Pretty cool, eh? The most obvious use of something like this is for remote access to your computer - create a host program that sits around waiting for you to connect to it and redirect output to, say, cmd.exe so you have "complete" control over your PC remotely. "Complete" because cmd.exe sucks ![]() Code:
#using <windows.h> //sorry not entirely sure where inside there the specific headers are :(
//The socket to use
Socket thisSocket;
//Information about the process we are redirecting.
PROCESS_INFORMATION pi;
//Information about where the IO goes ;)
STARTUPINFO si;
/* Initialise the socket somewhere here */
//cb is the size of the STARTUPINFO structure
si.cb = sizeof( si );
//Tell it we do not want to see the application we are redirecting to/from
si.wShowWindow = SW_HIDE;
//Tell it we want to be able to use .wShowWinwow, .hStdInput, .hstdOutput, .hstdError members.
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
//Tell it we want the standard input to come from thisSocket
si.hStdInput = (HANDLE)thisSocket;
//Tell it we want the standard output to go to thisSocket
si.hStdOutput = (HANDLE)thisSocket;
//Tell it we want the stardard error to appear on thisSocket
si.hStdError = (HANDLE)thisSocket;
//Spawn the process we want to redirect using the information we just declared.
CreateProcess( NULL, "cmd.exe", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi );
/* From now everything is set up and ticking over. */
//Wait until the process we started ends - then we can quit.
WaitForSingleObject( pi.hProcess, INFINITE );
//Close the process handles before exiting.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
MSDN on STARTUPINFO - http://msdn.microsoft.com/en-us/libr...31(VS.85).aspx The same effect can be done using C#. The code is easier to read and follow in C# but also it's trickier because you have to transfer the data between the socket yourself... At least that's what i'm assuming when i attempted it... Code:
using System.Diagnostics; process = new Process(); process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardInput = true; process.StartInfo.UseShellExecute = false; process.StartInfo.FileName = "cmd.exe"; process.Start(); //use process.StandardInput.WriteLine(); to write to the applications stdIn //use process.StandardOutput.ReadLine(); to read from the applications stdOut |
|
|
|
| The Following User Says Thank You to Oliver_FF For This Useful Post: |
|
|
#2 |
|
Seņor Moderator
Join Date: May 2004
Location: Utrecht, Utrecht, The kingdom of the Netherlands
Posts: 8,498 (2.58/day)
Thanks: 41
Thanked 1,453 Times in 1,077 Posts
|
I've been looking for simple code to send data over a network to build upon. This seems relatively simple. The examples I found were huge and didn't even work out of the box.
The downside is that I don't use C, I'll be looking into this though. |
|
|
|
|
|
#3 |
![]() |
If you just want to send data over the network you might want to check my basic sockets tutorial thing here:
http://forums.techpowerup.com/showthread.php?t=56901 The syntax may vary between programming languages, but the method of using the Windows API is usually fairly similar. It's all pretty well documented over at MSDN too
|
|
|
|
|
|
#4 |
|
Hardcore Monkey Moderator
Join Date: Feb 2007
Location: Cheeseland (Wisconsin, USA)
Posts: 12,114 (5.27/day)
Thanks: 591
Thanked 5,492 Times in 2,936 Posts
|
What language are you using Dan?
__________________
Cloud (noun, singular): A dynamic arrangement of multiple potential single points of failure, with a user at one end and their data at the other. Get more tech news on a wide variety of topics at NextPowerUp
|
|
|
|
|
|
#5 |
|
Seņor Moderator
Join Date: May 2004
Location: Utrecht, Utrecht, The kingdom of the Netherlands
Posts: 8,498 (2.58/day)
Thanks: 41
Thanked 1,453 Times in 1,077 Posts
|
|
|
|
|
|
|
#6 |
![]() |
Well I guess it's lucky for you that the structures and function calls are all in VB
![]() Code:
Dim pInfo As PROCESS_INFORMATION = New PROCESS_INFORMATION()
Dim sInfo As STARTUPINFO = New STARTUPINFO()
...[options here]...
CreateProcess("cmd.exe", Nothing, IntPtr.Zero, IntPtr.Zero, True, 0, IntPtr.Zero, Nothing, sInfo, pInfo)
Last edited by Oliver_FF; Jun 8, 2008 at 10:08 PM. |
|
|
|
|
|
#7 |
![]() Join Date: Jan 2009
Posts: 6 (0.00/day)
Thanks: 0
Thanked 0 Times in 0 Posts
|
Could you please explain how i would use the send and recv functions in order to send commands to cmd.exe and how to retrieve output?
Thanks alot! Lo0ney |
|
|
|
|
|
#8 |
|
"I go fast!1!11!1!"
Join Date: Oct 2008
Location: IA, USA
Posts: 10,575 (6.28/day)
Thanks: 1,755
Thanked 2,596 Times in 1,960 Posts
|
If you want to use cmd on the local machine to do something, you're better off just using System.Diagnostics.ProcessStartInfo, System.Diagnostics.Process, and a System.IO.StreamReader. Simply make ProcessStartInfo point to command.exe on Windows 9x and cmd.exe on Windows NT. In the arguments, do:
/C "your commands > file to save output in" Use the StreamReader to parse the file. Also, there is Process.StandardOutput, Process.StandardInput, and Process.StandardError that you could use for redirection.
__________________
Golden Rule of Programming: Never assume. try { SteamDownload(); } catch (Steamception ex) { RageQuit(); } |
|
|
|
|
|
#9 |
![]() Join Date: Jan 2009
Posts: 6 (0.00/day)
Thanks: 0
Thanked 0 Times in 0 Posts
|
Well im using C and im trying to send commands to cmd.exe remotely. IE: Client/Server
So i would need the client to send commands to the server which would then pass the cmd to cmd.exe then return output to the client |
|
|
|
|
|
#10 |
|
"I go fast!1!11!1!"
Join Date: Oct 2008
Location: IA, USA
Posts: 10,575 (6.28/day)
Thanks: 1,755
Thanked 2,596 Times in 1,960 Posts
|
What kind of commands?
__________________
Golden Rule of Programming: Never assume. try { SteamDownload(); } catch (Steamception ex) { RageQuit(); } |
|
|
|
|
|
#11 |
![]() Join Date: Jan 2009
Posts: 6 (0.00/day)
Thanks: 0
Thanked 0 Times in 0 Posts
|
Any command that can be executed in cmd.exe. For example: "dir", "ipconfig", "cd C:\"
I have an edit box on the client where the user will type a command to be executed 'remotely' from the server, which launced cmd.exe, then returns the output of the command back to the client. |
|
|
|
|
|
#12 |
|
"I go fast!1!11!1!"
Join Date: Oct 2008
Location: IA, USA
Posts: 10,575 (6.28/day)
Thanks: 1,755
Thanked 2,596 Times in 1,960 Posts
|
I would advise against doing that as there is nothing to stop a user from completely destroying a computer. Additionally, some commands return a massive stack of data so you'd have to use TCP instead of the preferred UDP. Have you already got the network layers sorted because that will take the most work.
__________________
Golden Rule of Programming: Never assume. try { SteamDownload(); } catch (Steamception ex) { RageQuit(); } |
|
|
|
|
|
#13 |
![]() Join Date: Jan 2009
Posts: 6 (0.00/day)
Thanks: 0
Thanked 0 Times in 0 Posts
|
I can set cmd restrictions and filters later, but for now its just for testing purposes. And I am using TCP sockets, but could i not just use the source posted by Oliver FF to do this?
I have the source (first post) basically as my server, and then i have a client which connects to the server. |
|
|
|
|
|
#14 |
|
Join Date: Aug 2010
Posts: 1 (0.00/day)
Thanks: 0
Thanked 0 Times in 0 Posts
|
I had the error 87 problem and it turned out to be not using a protocol that supported
IFS handles. Here is how I created a socket that uses IFS handles: // Load version 2.2 of Winsock if (WSAStartup(MAKEWORD(2, 2), &wsda)) { fprintf(stderr, (char *)"WSAStartup failed error=%d\n", WSAGetLastError()); exit(1); } // Find a protocol where socket descriptors returned by the provider // are operating system Installable File System (IFS) handles. // First, have WSAEnumProtocols tell you how big a buffer you need. bool bProtocolFound = false; LPWSAPROTOCOL_INFO lpProtocolBuf = NULL; DWORD dwBufLen, dwErr; int nRet = WSAEnumProtocolsA(NULL, lpProtocolBuf, &dwBufLen); if (SOCKET_ERROR != nRet) { die((char *)"WSAEnumProtocols: should not have succeeded"); } else if (WSAENOBUFS != (dwErr = WSAGetLastError())) { // WSAEnumProtocols failed for some reason not relating to buffer size. die((char *)"WSAEnumProtocols"); } else { // WSAEnumProtocols failed for the "expected" reason. Therefore, // you need to allocate a buffer of the appropriate size. lpProtocolBuf = (WSAPROTOCOL_INFO *)malloc(dwBufLen); if (lpProtocolBuf) { // Now call WSAEnumProtocols again with the expectation // that it will succeed because you have allocated a big enough // buffer. nRet = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen); if (SOCKET_ERROR == nRet) { die((char *)"WSAEnumProtocols"); } else { // Loop through protocols, looking for the first service // provider that meets the matching criteria. for (i = 0; i < nRet; i++) { if ((IPPROTO_TCP == lpProtocolBuf[i].iProtocol) && (XP1_IFS_HANDLES == (XP1_IFS_HANDLES & lpProtocolBuf[i].dwServiceFlags1))) { bProtocolFound = true; // Create socket. sock = WSASocket( FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, &lpProtocolBuf[i], 0, 0); if (INVALID_SOCKET == sock) { die((char *)"WSASocket"); } break; } } } } } |
|
|
|
![]() |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
|
|