mirror of
https://github.com/CPunch/Laika.git
synced 2024-11-22 04:50:06 +00:00
Box: added LAIKA_BOX_SKID, vmTest now uses the LAIKA_BOX_SKID box
- updated CONTRIB
This commit is contained in:
parent
f90c99ce64
commit
a4239282b2
@ -15,6 +15,7 @@ Looking for some simple tasks that need to get done for that sweet 'contributor'
|
|||||||
- Change `lib/lin/linshell.c` to use openpty() instead of forkpty() for BSD support
|
- Change `lib/lin/linshell.c` to use openpty() instead of forkpty() for BSD support
|
||||||
- Fix address sanitizer for CMake DEBUG builds
|
- Fix address sanitizer for CMake DEBUG builds
|
||||||
- Change laikaT_getTime in `lib/src/ltask.c` to not use C11 features.
|
- Change laikaT_getTime in `lib/src/ltask.c` to not use C11 features.
|
||||||
|
- Implement more LAIKA_BOX_* VMs in `lib/include/lbox.h`
|
||||||
|
|
||||||
## Lib: Error Handling
|
## Lib: Error Handling
|
||||||
Error handling in Laika is done via the 'lerror.h' header library. It's a small and simple error handling solution written for laika, however can be stripped and used as a simple error handling library. Error handling in Laika is used similarly to other languages, implementing a try & catch block and is achieved using setjmp(). The LAIKA_ERROR(...) is used to throw errors.
|
Error handling in Laika is done via the 'lerror.h' header library. It's a small and simple error handling solution written for laika, however can be stripped and used as a simple error handling library. Error handling in Laika is used similarly to other languages, implementing a try & catch block and is achieved using setjmp(). The LAIKA_ERROR(...) is used to throw errors.
|
||||||
@ -44,6 +45,9 @@ Laika has a simple binary protocol & a small backend (see `lib/src/lpeer.c`) to
|
|||||||
## Lib: Task Service
|
## Lib: Task Service
|
||||||
Tasks can be scheduled on a delta-period (call X function every approximate N seconds). laikaT_pollTasks() is used to check & run any currently queued tasks. This is useful for sending keep-alive packets, polling shell pipes, or other repeatably scheduled tasks. Most laikaT_pollTasks() calls are done in the peerHandler for each client/server.
|
Tasks can be scheduled on a delta-period (call X function every approximate N seconds). laikaT_pollTasks() is used to check & run any currently queued tasks. This is useful for sending keep-alive packets, polling shell pipes, or other repeatably scheduled tasks. Most laikaT_pollTasks() calls are done in the peerHandler for each client/server.
|
||||||
|
|
||||||
|
## Lib: VM Boxes
|
||||||
|
Laika has a tiny VM for decrypting sensitive information (currently unused, but functional). For details on the ISA read `lib/include/lvm.h`, for information on how to use them read `lib/include/lbox.h`. Feel free to write your own boxes and contribute them :D
|
||||||
|
|
||||||
## Bot: Platform-specific backends
|
## Bot: Platform-specific backends
|
||||||
|
|
||||||
`bot/win` and `bot/lin` include code for platform-specific code that can't be quickly "ifdef"d away. These mainly include stuff like persistence or opening pseudo-ttys.
|
`bot/win` and `bot/lin` include code for platform-specific code that can't be quickly "ifdef"d away. These mainly include stuff like persistence or opening pseudo-ttys.
|
@ -18,7 +18,7 @@
|
|||||||
2 main APIs are exposed here, laikaB_unlock() & laikaB_lock(). Both of which are inlined to make it more painful
|
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.
|
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
|
Each box has its own VM, with it's own deobfuscation routine. This makes static analysis a painful route for string
|
||||||
dumping.
|
dumping. Some predefined boxes are made for you to use.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct sLaikaB_box {
|
struct sLaikaB_box {
|
||||||
@ -26,6 +26,29 @@ struct sLaikaB_box {
|
|||||||
uint8_t code[LAIKA_VM_CODESIZE];
|
uint8_t code[LAIKA_VM_CODESIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* BOX_SKID decodes null-terminated strings using a provided xor _key. aptly named lol [SEE tools/vmtest/src/main.c] */
|
||||||
|
#define LAIKA_BOX_SKID(_key) { \
|
||||||
|
.unlockedData = {0}, /* reserved */ \
|
||||||
|
.code = { /* stack layout: \
|
||||||
|
[0] - unlockedData (ptr) \
|
||||||
|
[1] - data (ptr) \
|
||||||
|
[2] - key (uint8_t) \
|
||||||
|
[3] - working data (uint8_t) \
|
||||||
|
*/ \
|
||||||
|
LAIKA_MAKE_VM_IAB(OP_LOADCONST, 0, 0), \
|
||||||
|
LAIKA_MAKE_VM_IAB(OP_LOADCONST, 1, 1), \
|
||||||
|
LAIKA_MAKE_VM_IAB(OP_PUSHLIT, 2, _key), \
|
||||||
|
/* LOOP_START */ \
|
||||||
|
LAIKA_MAKE_VM_IAB(OP_READ, 3, 1), /* load data into working data */ \
|
||||||
|
LAIKA_MAKE_VM_IABC(OP_XOR, 3, 3, 2), /* xor data with key */ \
|
||||||
|
LAIKA_MAKE_VM_IAB(OP_WRITE, 0, 3), /* write data to unlockedData */ \
|
||||||
|
LAIKA_MAKE_VM_IA(OP_INCPTR, 0), \
|
||||||
|
LAIKA_MAKE_VM_IA(OP_INCPTR, 1), \
|
||||||
|
LAIKA_MAKE_VM_IAB(OP_TESTJMP, 3, -17), /* exit loop on null terminator */ \
|
||||||
|
OP_EXIT \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
LAIKA_FORCEINLINE void* laikaB_unlock(struct sLaikaB_box *box, void *data) {
|
LAIKA_FORCEINLINE void* laikaB_unlock(struct sLaikaB_box *box, void *data) {
|
||||||
struct sLaikaV_vm vm = {
|
struct sLaikaV_vm vm = {
|
||||||
/* boxes have 2 reserved constants, [0] for the output, [1] for the input */
|
/* boxes have 2 reserved constants, [0] for the output, [1] for the input */
|
||||||
|
@ -5,39 +5,17 @@
|
|||||||
#include "lbox.h"
|
#include "lbox.h"
|
||||||
|
|
||||||
/* VM BOX Demo:
|
/* VM BOX Demo:
|
||||||
A secret message has been xor'd, this tiny bytecode chunk decodes 'data' into
|
A secret message has been xor'd, the BOX_SKID is used to decode the message.
|
||||||
'unlockedData'. Obviously you wouldn't want a key this simple, more obfuscation
|
|
||||||
would be good (byte swapping, revolving xor key, etc.)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int main(int argv, char **argc) {
|
int main(int argv, char **argc) {
|
||||||
uint8_t data[] = {
|
uint8_t data[] = {
|
||||||
0x96, 0xBB, 0xB2, 0xB2, 0xB1, 0xFE, 0x89, 0xB1,
|
0x96, 0xBB, 0xB2, 0xB2, 0xB1, 0xFE, 0x89, 0xB1,
|
||||||
0xAC, 0xB2, 0xBA, 0xFF, 0xDE, 0x20, 0xEA, 0xBA,
|
0xAC, 0xB2, 0xBA, 0xFF, 0xDE, 0x20, 0xEA, 0xBA, /* you can see the key here, 0xDE ^ 0xDE is the NULL terminator lol */
|
||||||
0xCE, 0xEA, 0xFC, 0x01, 0x9C, 0x23, 0x4D, 0xEE
|
0xCE, 0xEA, 0xFC, 0x01, 0x9C, 0x23, 0x4D, 0xEE
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sLaikaB_box box = {
|
struct sLaikaB_box box = LAIKA_BOX_SKID(0xDE);
|
||||||
.unlockedData = {0}, /* reserved */
|
|
||||||
.code = { /* stack layout:
|
|
||||||
[0] - unlockedData (ptr)
|
|
||||||
[1] - data (ptr)
|
|
||||||
[2] - key (uint8_t)
|
|
||||||
[3] - working data (uint8_t)
|
|
||||||
*/
|
|
||||||
LAIKA_MAKE_VM_IAB(OP_LOADCONST, 0, 0),
|
|
||||||
LAIKA_MAKE_VM_IAB(OP_LOADCONST, 1, 1),
|
|
||||||
LAIKA_MAKE_VM_IAB(OP_PUSHLIT, 2, 0xDE),
|
|
||||||
/* LOOP_START */
|
|
||||||
LAIKA_MAKE_VM_IAB(OP_READ, 3, 1), /* load data into working data */
|
|
||||||
LAIKA_MAKE_VM_IABC(OP_XOR, 3, 3, 2), /* xor data with key */
|
|
||||||
LAIKA_MAKE_VM_IAB(OP_WRITE, 0, 3), /* write data to unlockedData */
|
|
||||||
LAIKA_MAKE_VM_IA(OP_INCPTR, 0),
|
|
||||||
LAIKA_MAKE_VM_IA(OP_INCPTR, 1),
|
|
||||||
LAIKA_MAKE_VM_IAB(OP_TESTJMP, 3, -17), /* exit loop on null terminator */
|
|
||||||
OP_EXIT
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
laikaB_unlock(&box, data);
|
laikaB_unlock(&box, data);
|
||||||
printf("%s\n", box.unlockedData);
|
printf("%s\n", box.unlockedData);
|
||||||
|
Loading…
Reference in New Issue
Block a user