Remote Shell
-
mrBROWN schrieb:
Ich denke sowieso, dass bei dem Server jedes Virenprogramm alarm schlagen würde!
Wieso das? Bis jetzt hast Du nur telnet beschrieben.
-
Naja FTP evtl für Datenübertragung...
Gibt es denn eine Dokumentation, wie ich in dem Programm (also beim Server) die cmd starte?
bzw direkt Befehle an die cmd weitergebe?
-
Wenn Du den Server und den Client selbst schreibst, bestimmst Du doch selbst das Protokoll. Du sendest und empfängst einfach Strings und mußt sie beim jeweiligen Empfänger interpretieren.
No need für FTP.Zum cmd-Handling bieten sich Pipes an. Ich glaube, in der MSDN gibt es ein schönes Beispiel zu Anonymous Pipes.
-
Ich hab mir mal sowas selbst gestrickt. Per Winsock die Befehle an den Server uebergeben, der hat die string einfach an System uebergeben. Dumm war nur, ich hatte niemals irgendwelche Rueckmeldungen (Fehlermeldungen usw) bekommen. Also musste der Syntax schon 100% stimmen.
Irgendwo gibts hier einen Link zum winsock Tutorial, das hab ich nur etwas modifiziert...Ivo
-
Ivo schrieb:
Dumm war nur, ich hatte niemals irgendwelche Rueckmeldungen (Fehlermeldungen usw) bekommen.
Deswegen hab ich ja geschrieben, er soll Pipes einsetzen.
-
Abend
ja, da sag ich gleich mal vielen herzlichen Dank für die guten Tips. Werde mir besagte msdn Seiten zu den Pipes durchlesen. Mit FTP habt ihr natürlich recht. Kleiner Denkfehler meinerseits... Naja finde Netzwerkprogrammierung eben unheimlich spannend und bin mich grad noch im Reinfuchsen, obwohl die Programmierung mit Winsock schon ganz gut hinhaut, obwohl ich jetzt noch nicht soo viel Erfahrung in C/C++ habe. Mein Problem ist, dass ich C und Cpp Code gerne mische. Das ganze soll eben ein kleines (großes ;)) Projekt werden und Netzwerke interessieren mich eben am meisten.
Also nochmal vielen Dank für die Tips und ich werde euch bestimmt mal wieder nerven
Sorry schonmal dafür.
Beste Grüße,
brownie
-
hi!
Hab mich jetzt bisschen informiert und so wie ich das Verstanden habe, kann eine unbenannte Pipe entweder nur Lesen oder Schreiben. Aber ich brauche doch beides. Der Server soll ja die Info die vom Client kommt an die cmd weitergeben und dann die Antwort von cmd wieder auslesen. Also brauch ich doch wohl eine benannte Pipe oder? Oder heißt das nur, dass man das nicht gleichzeitig machen kann (Read und Write).
Grüße
-
Wenn es Dir gelingt die Standardausgabe des Servers auf einen string umzuleiten, sollte es gehen. Dann hast Du alle Meldungen der cmd auf Deinen Remoterechner.
Musst du nur richtig implementieren.Ivo
-
hmmm. habe jetzt die msdn seiten ein bisschen überflogen. ich denke ein gutes tutorial bezüglich dem Einsatz von Pipes wäre nicht schlecht
Wenn ihr was habt, lasst es mich bitte wissen...
Bisher habe ich es so verstanden, dass man die der cmd die Befehle nicht direkt übergibt (bräucht ich übrigens auch infos, wie man eigentlich die Befehle an die CMD bekommt, also wie man sie "öffnet"), sondern die Pipe mit der CMD verknüpft und die Befehle im Programm an die Pipe weitergibt. die Pipe macht dann das eigentliche weiterleiten. Aber wie man Die CMD jetzt mit der Pipe verknüpft? Keine Ahnung, und konnte auch nicht die Lösung aus der msdn hilfe entnehmen...
-
Die einfachste und schlechteste Moeglichkeit ist sicher
system(string.c_str());
Ivo
-
Ok, das ist also ein Befehl direkt an die cmd. Das heißt ja aber, dass ich den direkten Weg gehe und nicht über Pipes. D.h. ich habe keine Fehlermeldungen...
Pipes währen da schon eleganter denke ich. Aber hab leider immer noch kein gutes Tut zu den anonymen gefunden.
Grüße
-
Sodala. Hab es jedenfalls schonmal geschafft die cmd zu starten und eine Pipe zu erstellen. Aber wie verknüpfe ich Pipe mit CMD und root.exe(mein Server)??
Hier mein Code:
#include <windows.h> #include <tchar.h> #include <stdio.h> int main(void) { //PIPE HANDLE hReadPipe; HANDLE hWritePipe; SECURITY_ATTRIBUTES sa; //Sicherheitshinweise der Pipe sa.nLength= sizeof(SECURITY_ATTRIBUTES); //Wie groß die Struktur SEC_ATR ist sa.lpSecurityDescriptor = NULL; //Zugriffsrechte für jeden sa.bInheritHandle = TRUE; //PROCESS STARTUPINFO si; //Infos über Größe,Ort usw der Child App. PROCESS_INFORMATION pi; //Gibt Infos über Process ID, Handle, Thread usw. Für Child App. ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); //Größe der Struktur in Bytes wird hier ermittelt. ZeroMemory( &pi, sizeof(pi) ); //PROZESS ERSTELLEN if(!CreateProcess(NULL, "C:\\WINDOWS\\system32\\cmd.exe", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { printf("CreateProcess failed (%d)\n", GetLastError()); return 0; } else printf("CreateProcess started...\n"); //PIPE ERSTELLEN if(!CreatePipe(&hReadPipe, &hWritePipe, &sa, 0)) printf("Problem :%d",GetLastError); else printf("Pipe started...\n"); //Warten bis die cmd geschlossen wird WaitForSingleObject( pi.hProcess, INFINITE ); //Die Shell Wieder aufräumen CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); return 1; }
Grüße
-
Mit dem system uebergibst Du einfach eine Zeichenkette an die root.exe.
Oder besser gesagt, die Daten die root.exe ueber TCP/IP empfaengt uebergibst Du so an die CMD.
Nun muss es Dir nur noch gelingen die Standardausgabe der CMD (auf der Serverseite) in einen String oder aehnliches zu packen. Wenn du das geschaft hast, schickt Du die auf die Reise. Oder sieh dir einfach mal den Code von Telnet bzw. OpenSSH an. So geht es richtig und es ist kein Gefrickel. Gefrickel ist immer etwas "mai dai"Ivo
-
du meinst ich soll meine Befehle gar nicht per Pipe an die Cmd weiterleiten? Und CreateProcess brauch ich auch nicht? Aber wie kann ich die Ausgabe der Cmd mit meinem server Programm auslesen? Da brauch ich doch eine Pipe oder gibt es eine einfache andere Möglichkeit?
Grüße
-
Ja, diese Ausgabe der cmd bekomme ich ja nur über eine Pipe... Ich versteh noch nicht wirklich wie ich die Pipe mit dem Prozess in Verbindung bekomme.
Jedenfalls muss ich doch den Output von meinem Prozess, also von der cmd auf den Input meiner Pipe "routen" d.h. auf hReadPipe.Wenn das Funktioniert müsste ich ja theoretisch nur noch das Programm starten und prallel dazu eine cmd aufmachen und da zb "DIR" eingeben. Dann müsste doch bei meinem eigenen Programm das Ergebnis ausgespuckt werden oder nicht?
Grüße
-
Du hast das schon richtig erkannt: Du brauchst eine Pipe zum Schreiben an den aufgerufenen Prozess und eine zum Lesen dessen, was der aufgerufene Prozess in seine Standardausgabe schreibt.
Das Schreibende der einen Pipe behält der Aufrufer, das Leseende vererbt er an STDIN des aufgerufenen Prozesses.
Von der zweiten Pipe behält der Aufrufer das Leseende und vererbt das Schreibende an STDOUT des aufgerufenen Prozesses.
Der Aufrufer hat also zwei Pipes, von denen er jeweils nur ein Ende benutzt.Hier ist ein ganz gutes Beispiel:
http://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx
-
Tja mein Denkansatz ist vielleicht richtig, aber irgendwie steig ich nicht so dahinter. Vielleicht ist das Thema auch einfach noch zu komplex für mich. Hab mir das etwas einfacher vorgestellt. Allerdings hab ich schon verstanden wie die Pipe geroutet werden muss. Habe mal folgendes gemacht, aber irgendwie gibt das Programm nur die anzahl meines Feldes in kryptischer Form aus:
#include <windows.h> #include <tchar.h> #include <stdio.h> int main(void) { //PIPE HANDLE hReadPipe; HANDLE hWritePipe; SECURITY_ATTRIBUTES sa; //Sicherheitshinweise der Pipe sa.nLength= sizeof(SECURITY_ATTRIBUTES); //Wie groß die Struktur SEC_ATR ist sa.lpSecurityDescriptor = NULL; //Zugriffsrechte für jeden sa.bInheritHandle = TRUE; //PIPE ERSTELLEN if(!CreatePipe(&hReadPipe, &hWritePipe, &sa, 0)) printf("Problem :%d",GetLastError); else printf("Pipe started...\n"); //PROCESS STARTUPINFO si; //Infos über Größe,Ort usw der Child App. PROCESS_INFORMATION pi; //Gibt Infos über Process ID, Handle, Thread usw. Für Child App. ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); //Größe der Struktur in Bytes wird hier ermittelt. ZeroMemory( &pi, sizeof(pi) ); si.hStdInput=NULL; si.hStdOutput=hWritePipe; si.hStdError=hWritePipe; si.dwFlags=STARTF_USESTDHANDLES; CloseHandle(hWritePipe); //PROZESS ERSTELLEN if(!CreateProcess(NULL, "C:\\WINDOWS\\system32\\cmd.exe", NULL, NULL, NULL, 0, NULL, NULL, &si, &pi)) { printf("CreateProcess failed (%d)\n", GetLastError()); return 0; } else printf("CreateProcess started...\n"); char buf[100]; DWORD reDword; ReadFile(hReadPipe,buf,99,&reDword,0); printf(buf); //Warten bis die cmd geschlossen wird WaitForSingleObject( pi.hProcess, INFINITE ); //Die Shell Wieder aufräumen CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); return 1; }
-
Erstens bin ich mir nicht sicher, ob Du das Pipe-Handle, daß Du weitergibst, beim Aufrufer erst NACH dem CreateProcess schließen solltest, zweitens mußt Du beim CreateProcess als fünften Parameter true übergeben.
-
Jo dann funktioniert es auch. Wenn ich das Programm starte bekomme ich die ersten Zeilen von der cmd... Cool
Aber ich glaube irgendwie es ist nicht so optimal direkt den buf in printf zu übergeben.....
Wie dem auch sei. Wie kann ich jetzt "lauschen", also warten ob die cmd was zu sagen hat?
-
Hab es so gelöst:
[cpp]
while(true)
{
if(ReadFile(hReadPipe,buf,99,&reDword,0)!=0)
printf(buf,"\n");
}[code]Allerdings nicht sehr performant... Wenn ich das Fenster rumziehe, dann zieht es schlieren nach sich. Gibts da evtl. was besseres, als so eine Endloschleife?
Achja, und wenn ich ne andre CMD starte und befehle eingebe, dann kommt nichts an bei meinem Programm. Liegt das daran, dass die cmd die ich öffne ein ganz neues Handle bekommt und keinen Einfluss haben kann auf mein per CreateProcess geöffnetes cmd?