aboutsummaryrefslogtreecommitdiff
path: root/source/tests
diff options
context:
space:
mode:
authorToni Uhlig <matzeton@googlemail.com>2020-05-24 16:48:22 +0200
committerToni Uhlig <matzeton@googlemail.com>2020-05-25 21:57:14 +0200
commit31c69b6ca1b91e7fd9fd8e14082fd2584c5f538c (patch)
tree16e789c7d68608831b498f41f54d9482b82a711a /source/tests
first public release
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
Diffstat (limited to 'source/tests')
-rw-r--r--source/tests/run_tests.c106
-rw-r--r--source/tests/test_aes.c100
-rw-r--r--source/tests/test_asm.c51
-rw-r--r--source/tests/test_compat.c152
-rw-r--r--source/tests/test_crypt.c44
-rw-r--r--source/tests/test_http.c279
-rw-r--r--source/tests/test_mem.c17
-rw-r--r--source/tests/test_pe.c66
-rw-r--r--source/tests/test_utils.c226
-rw-r--r--source/tests/tests.h128
10 files changed, 1169 insertions, 0 deletions
diff --git a/source/tests/run_tests.c b/source/tests/run_tests.c
new file mode 100644
index 0000000..207347f
--- /dev/null
+++ b/source/tests/run_tests.c
@@ -0,0 +1,106 @@
+#include "compat.h"
+#include "tests.h"
+#include "utils.h"
+
+#include <unistd.h>
+#include <signal.h>
+
+
+int null_dev = -1;
+static FILE* null_file = NULL;
+MYASSERT_LOGDEF;
+unsigned test_count = 0;
+unsigned test_faild = 0;
+
+
+void sigsegv_handler(int signal)
+{
+ if (signal == SIGSEGV) {
+ ERRPRINT_BOTH("%s", "***** ACCESS VIOLATION *****");
+ fclose(null_file);
+ fclose(MYASSERT_LOGFILE);
+ exit(1);
+ }
+}
+
+int main(int argc, char** argv)
+{
+ fprintf(stderr, "Running TESTS ..\n\n");
+
+ (void)argc;
+ if (signal(SIGSEGV, sigsegv_handler) == SIG_ERR) {
+ fprintf(stderr, "Could not setup a signal handler for memory acces violations!\n");
+ }
+
+ if (bInitCompat( LoadLibraryA(TEXT("KERNEL32.dll")), GetProcAddress ) != TRUE) {
+ fprintf(stderr, "bInitCompat(...) failed!\n");
+ return 1;
+ }
+
+ const char* null_devname = "nul";
+ null_file = fopen (null_devname, "w");
+ if (null_file == NULL) {
+ fprintf(stderr, "Could not open windows NULL device: %s", null_devname);
+ } else null_dev = _fileno(null_file);
+
+ MYASSERT_INIT;
+ MYASSERT(test_math());
+ MYASSERT(test_utils())
+ MYASSERT(test_heap());
+ MYASSERT(test_mem());
+ MYASSERT(test_memalign());
+ MYASSERT(test_aes());
+ MYASSERT(test_crypt());
+ MYASSERT(test_distorm());
+ MYASSERT(test_stdio());
+ MYASSERT(test_pe(argv[0]));
+ MYASSERT(test_http());
+
+ MYASSERT_SILENT( (puts("puts(...)\n") == 0) );
+ MYASSERT_SILENT( (__xputs("__xputs(...)\n") > 0) );
+
+ static char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,.-#'?!";
+ char* rndstr = __randstring(4096, charset);
+ MYASSERT_SILENT( (__xprintf("---%s---\n", rndstr) > 0) );
+ COMPAT(free)(rndstr);
+
+ if (MYASSERT_RETVAL == 0) {
+ ERRPRINT_BOTH("SUCCESS | TESTS: %u", (unsigned)test_count);
+ } else {
+ ERRPRINT_BOTH("LAST FAILED with %d | FAILED/TESTS: %u/%u", MYASSERT_RETVAL, (unsigned)test_faild, (unsigned)test_count);
+ }
+
+ MYASSERT_RETURN;
+}
+
+char* test_randstring(size_t length)
+{
+
+ static char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,.-#'?!";
+ return __randstring(length, charset);;
+}
+
+char* test_randhexstring(size_t length)
+{
+ static char hcharset[] = "0123456789abcdef";
+ return __randstring(length, hcharset);
+}
+
+int fprintf_setw(FILE *stream, size_t s_maxlen, const char *format, ...)
+{
+ int ret;
+ static char tmp[BUFSIZ];
+ va_list va;
+ va_start(va, format);
+
+ ret = vsnprintf(tmp, BUFSIZ, format, va);
+ if (ret > 0 && (size_t)ret < s_maxlen && ret+s_maxlen < BUFSIZ)
+ {
+ for (size_t i = ret; i < s_maxlen; ++i)
+ tmp[i] = '.';
+ }
+ ret = fprintf(stream, "%s", tmp);
+
+ va_end(va);
+ return ret;
+}
diff --git a/source/tests/test_aes.c b/source/tests/test_aes.c
new file mode 100644
index 0000000..1040378
--- /dev/null
+++ b/source/tests/test_aes.c
@@ -0,0 +1,100 @@
+#include "tests.h"
+
+#include "compat.h"
+#include "aes.h"
+#include "pe_infect.h"
+
+#include "aes_strings_gen.h"
+#include "loader_x86_crypt.h"
+_AESDATA_(ldrdata, LOADER_SHELLCODE);
+
+
+BOOL test_aes(void)
+{
+ ERRETCP(bInitCompat(LoadLibraryA(TEXT("KERNEL32.dll")), GetProcAddress) == TRUE);
+
+ unsigned char key[KEY_256];
+ memset(&key[0], '\0', sizeof(unsigned char)*KEY_256);
+ aes_randomkey(&key[0], KEY_256);
+
+ unsigned char ptext[16] = "Attack at dawn!";
+ unsigned char ctext[16];
+ unsigned char decptext[16];
+ aes_ctx_t* ctx;
+
+ memset(&ctext[0], '\0', sizeof(ctext));
+ memset(&decptext[0], '\0', sizeof(decptext));
+
+ aes_init();
+ ctx = aes_alloc_ctx(key, sizeof(key));
+ if(!ctx) {
+ return FALSE;
+ }
+ aes_encrypt(ctx, ptext, ctext);
+ aes_decrypt(ctx, ctext, decptext);
+ ERRETCP( strlen((char*)decptext) == strlen((char*)ptext) );
+ ERRETCP( strcmp((char*)decptext, (char*)ptext) == 0 );
+
+ unsigned char qtext[16] = "blah";
+ unsigned char dtext[16];
+ unsigned char decqtext[16];
+
+ memset(&dtext[0], '\0', sizeof(dtext));
+ memset(&decqtext[0], '\0', sizeof(decqtext));
+
+ aes_encrypt(ctx, qtext, dtext);
+ aes_decrypt(ctx, dtext, decqtext);
+ ERRETCP( strlen((char*)decqtext) == strlen((char*)qtext) );
+ ERRETCP( strcmp((char*)decqtext, (char*)qtext) == 0 );
+
+ {
+ char inbuf[] = "This is a short short short short short text, but bigger than 16 bytes ...";
+ char *outbuf = NULL;
+ char *chkbuf = NULL;
+ size_t len = 0;
+ outbuf = aes_crypt_s(ctx, inbuf, sizeof(inbuf), &len, TRUE);
+ size_t chklen = 0;
+ chkbuf = aes_crypt_s(ctx, outbuf, len, &chklen, FALSE);
+ ERRETCP( strlen(inbuf) == strlen(chkbuf) );
+ ERRETCP( strcmp(inbuf, chkbuf) == 0 );
+ COMPAT(free)(outbuf);
+ COMPAT(free)(chkbuf);
+ }
+
+ aes_free_ctx(ctx);
+
+ {
+ unsigned char newkey[] = "\x08\xEE\xD4\xBA\xA0\x86\x6C\x52\x38\x1E\x04\xEA\xD0\xB6\x9C\x82\x68\x4E\x34\x1A\x00\xE6\xCC\xB2\x98\x7E\x64\x4A\x30\x16\xFC\xE2";
+ char newbuf[] = "\x3F\x65\xF3\xEC\xF2\xFD\x4D\x1B\xFE\xF5\x12\xE9\x66\x0D\x83\xD3\x1D\xB5\x64\xC1\x9F\x6D\xD2\x51\x51\x64\x89\x22\x94\xBE\x63\x11\x9E\xD7\x7A\x10\x9D\xDF\x22\x57\xB8\xD2\x76\x7E\x4E\x71\x1B\xCB";
+ char chkbuf[] = "This is a somewhat stupid test dude ..";
+ ctx = aes_alloc_ctx(newkey, sizeof(newkey)-1);
+ char* outbuf = aes_crypt_s(ctx, newbuf, sizeof(newbuf)-1, NULL, FALSE);
+ ERRETCP( strlen(chkbuf) == strlen(outbuf) );
+ ERRETCP( strcmp(outbuf, chkbuf) == 0 );
+ aes_free_ctx(ctx);
+ COMPAT(free)(outbuf);
+ }
+
+ {
+ unsigned char newkey[] = "\x81\x88\x8F\x96\x9D\xA4\xAB\xB2\xB9\xC0\xC7\xCE\xD5\xDC\xE3\xEA\xF1\xF8\xFF\x06\x0D\x14\x1B\x22\x29\x30\x37\x3E\x45\x4C\x53\x5A";
+ char chkbuf[] = "This is a somewhat stupid test dude ..";
+ ctx = aes_alloc_ctx(newkey, sizeof(newkey)-1);
+ size_t len = 0, newlen = 0;
+ char* outbuf = aes_crypt_s(ctx, chkbuf, sizeof(chkbuf)-1, &len, TRUE);
+ char* decbuf = aes_crypt_s(ctx, outbuf, len, &newlen, FALSE);
+ ERRETCP( strlen(chkbuf) == strlen(decbuf) );
+ ERRETCP( strcmp(decbuf, chkbuf) == 0 );
+ ERRETCP( newlen == len );
+ aes_free_ctx(ctx);
+ COMPAT(free)(outbuf);
+ }
+
+ SIZE_T lsiz = 0;
+ BYTE* l = getLoader(&lsiz);
+ ERRETCP( l != NULL );
+ ERRETCP( lsiz > 0 );
+ COMPAT(free)(l);
+
+ aes_cleanup();
+ return TRUE;
+}
diff --git a/source/tests/test_asm.c b/source/tests/test_asm.c
new file mode 100644
index 0000000..8f49f8f
--- /dev/null
+++ b/source/tests/test_asm.c
@@ -0,0 +1,51 @@
+#include "tests.h"
+
+#include "compat.h"
+#include "loader_x86.h"
+#include "distorm/distorm.h"
+
+
+static volatile unsigned char loader_bin[] = LOADER_SHELLCODE;
+#define MAX_INSTRUCTIONS (1000)
+static volatile _DecodedInst decodedInstructions[MAX_INSTRUCTIONS];
+
+
+BOOL test_distorm(void)
+{
+ ERRETCP(bInitCompat(LoadLibraryA(TEXT("KERNEL32.dll")), GetProcAddress) == TRUE);
+
+ _DecodeType dt = Decode32Bits;
+ _DecodeResult res;
+ _OffsetType offset = 0;
+ unsigned char* buf = (unsigned char*)&loader_bin[0];
+ size_t size = sizeof(loader_bin)/sizeof(loader_bin[0]);
+ unsigned int decodedInstructionsCount = 0, i, next;
+
+ COMPAT(memset)((unsigned char*)&decodedInstructions[0], '\0', sizeof(_DecodedInst)*MAX_INSTRUCTIONS);
+ while (1) {
+ res = distorm_decode(offset, buf, size, dt, (_DecodedInst*)&decodedInstructions[0], MAX_INSTRUCTIONS, &decodedInstructionsCount);
+ if (res == DECRES_INPUTERR)
+ break;
+
+ ERRETCP(res == DECRES_SUCCESS);
+ ERRETCP(decodedInstructionsCount > 0);
+ for (i = 0; i < decodedInstructionsCount; i++) {
+ ERRETCPDW_NOLOG( decodedInstructions[i].offset < size, decodedInstructions[i].offset );
+ ERRETCPDW_NOLOG( decodedInstructions[i].size > 0, decodedInstructions[i].size );
+ ERRETCPDW_NOLOG( decodedInstructions[i].size < 15, decodedInstructions[i].size );
+ ERRETCP_NOLOG( strnlen( (const char*)(&decodedInstructions[i])->mnemonic.p, MAX_TEXT_SIZE ) > 0 );
+ }
+
+ if (res == DECRES_SUCCESS) break; // All instructions were decoded.
+ else if (decodedInstructionsCount == 0) break;
+
+ // Synchronize:
+ next = (unsigned int)(decodedInstructions[decodedInstructionsCount-1].offset - offset);
+ next += decodedInstructions[decodedInstructionsCount-1].size;
+ // Advance ptr and recalc offset.
+ buf += next;
+ size -= next;
+ offset += next;
+ }
+ return TRUE;
+}
diff --git a/source/tests/test_compat.c b/source/tests/test_compat.c
new file mode 100644
index 0000000..f760a6e
--- /dev/null
+++ b/source/tests/test_compat.c
@@ -0,0 +1,152 @@
+#include "tests.h"
+
+#include "compat.h"
+
+
+BOOL test_heap(void)
+{
+ ERRETCP(bInitCompat(LoadLibraryA(TEXT("KERNEL32.dll")), GetProcAddress) == TRUE);
+ UINT64* hAlloc = __xcalloc(128, sizeof(UINT64));
+ ERRETCP(hAlloc != NULL);
+ memset(hAlloc, 'A', sizeof(UINT64)*128);
+ *(char*)((BYTE*)(hAlloc) + (sizeof(UINT64)*128)-1) = '\0';
+ ERRETCP( strlen((char*)hAlloc) == (sizeof(UINT64)*128)-1 );
+ __xfree(hAlloc);
+
+ BYTE* bAlloc = __xcalloc(BUFSIZ, sizeof(UINT64));
+ ERRETCP(bAlloc != NULL);
+ memset(bAlloc, 'A', sizeof(UINT64)*BUFSIZ);
+ *(char*)((BYTE*)(bAlloc) + (sizeof(UINT64)*BUFSIZ)-1) = '\0';
+ ERRETCP( strlen((char*)bAlloc) == (sizeof(UINT64)*BUFSIZ)-1 );
+ __xfree(bAlloc);
+
+ return TRUE;
+}
+
+BOOL test_mem(void)
+{
+ const size_t siz = 128;
+ char buf[65];
+
+ memset(buf, 'A', 64);
+ *(buf+64) = '\0';
+
+ ERRETCP(bInitCompat(LoadLibraryA(TEXT("KERNEL32.dll")), GetProcAddress) == TRUE);
+ char* hAllocOrg = calloc(siz+1, sizeof(char));
+ LPSTR hAlloc = __xcalloc(siz+1, sizeof(LPSTR));
+ ERRETCP(hAlloc != NULL && hAllocOrg != NULL);
+
+ /* memset */
+ ERRETCP(memset(hAllocOrg, 'A', siz) != NULL);
+ ERRETCP(strlen(hAllocOrg) == siz);
+ ERRETCP(__xmemset(hAlloc, 'A', siz) != NULL);
+ ERRETCP(strlen(hAlloc) == siz);
+ /* memcpy */
+ ERRETCP(memcpy(hAllocOrg, (const void*)buf, sizeof(buf)) != NULL);
+ ERRETCP(strlen(hAllocOrg) == sizeof(buf)-1);
+ ERRETCP(__xmemcpy(hAlloc, (LPCVOID)buf, sizeof(buf)) != NULL);
+ ERRETCP(strlen(hAlloc) == sizeof(buf)-1);
+ /* memmove */
+ ERRETCP( memset (hAllocOrg+ 8, 'B', 8) != NULL );
+ ERRETCP( memmove (hAllocOrg+16, hAllocOrg+4, 8) == (hAllocOrg+16) );
+ ERRETCP( memset (hAllocOrg+ 8, 'A', 8) != NULL );
+ ERRETCP( strstr (hAllocOrg, "BBBB") != NULL );
+ ERRETCP( __xmemset (hAlloc + 8, 'B', 8) != NULL );
+ ERRETCP( __xmemmove(hAlloc +16, hAlloc+4, 8) == (hAlloc+16) );
+ ERRETCP( __xmemset (hAlloc + 8, 'A', 8) != NULL );
+ ERRETCP( strstr (hAlloc, "BBBB") != NULL );
+
+ __xfree(hAlloc);
+ free(hAllocOrg);
+ return TRUE;
+}
+
+BOOL test_stdio(void)
+{
+ const char buf1[] = "AAAABBBBAAAACCCC*";
+ const size_t len1 = strlen(buf1);
+
+ ERRETCP(bInitCompat(LoadLibraryA(TEXT("KERNEL32.dll")), GetProcAddress) == TRUE);
+ ERRETCP( strcmp("BBBB", buf1) == __xstrcmp("BBBB", buf1) );
+ ERRETCP( strcmp("DDDD", buf1) == __xstrcmp("DDDD", buf1) );
+ ERRETCP( strcmp(buf1, "BBBB") == __xstrcmp(buf1, "BBBB") );
+ ERRETCP( strcmp(buf1, "DDDD") == __xstrcmp(buf1, "DDDD") );
+
+ ERRETCP( strncmp("BBBB", buf1, len1) == __xstrncmp("BBBB", buf1, len1) );
+ ERRETCP( strncmp("DDDD", buf1, len1) >= __xstrncmp("DDDD", buf1, len1) );
+ ERRETCP( strncmp(buf1, "BBBB", len1) == __xstrncmp(buf1, "BBBB", len1) );
+ ERRETCP( strncmp(buf1, "DDDD", len1) <= __xstrncmp(buf1, "DDDD", len1) );
+
+ ERRETCP( __xstrnicmp("BBBB", buf1, len1) != 0 );
+ ERRETCP( __xstrnicmp("bbbb", buf1, len1) != 0 );
+ ERRETCP( __xstrnicmp("dddd", buf1, len1) != 0 );
+ ERRETCP( __xstrnicmp("DDDD", buf1, len1) != 0 );
+ ERRETCP( __xstrnicmp("AAAA", buf1, len1) == 0 );
+ ERRETCP( __xstrnicmp("aaaa", buf1, len1) == 0 );
+
+ ERRETCP( strlen(buf1) == __xstrlen(buf1) );
+ ERRETCP( strnlen(buf1, 0xFF) == __xstrnlen(buf1, 0xFF) );
+ ERRETCP( strnlen(buf1, 8) == __xstrnlen(buf1, 8) );
+
+ char *tmp = COMPAT(strdup)(buf1);
+ ERRETCP( strlen(buf1) == strlen(tmp) );
+ ERRETCP( __xstrlen(buf1) == __xstrlen(tmp) );
+
+ ERRETCP( strchr(buf1, '*') == __xstrchr(buf1, '*') );
+ ERRETCP( strchr(buf1, '$') == __xstrchr(buf1, '$') );
+ COMPAT(free)(tmp);
+
+ char *buf2 = COMPAT(calloc)(128, sizeof(char*));
+ char buf3[] = "AAAA";
+ COMPAT(strcat)(buf2, buf3);
+ size_t len = strlen(buf2);
+ ERRETCP( len == strlen(buf3) );
+ ERRETCP( len+4 == strlen(__xstrcat(buf2, "BBBB")) );
+ ERRETCP( len+4 == strlen(__xstrcat(buf2, "")) );
+ ERRETCP( len+4 == strlen(__xstrcat(buf2, "\0\0\0\0")) );
+ ERRETCP( len+12 == strlen(__xstrcat(buf2, "CCCCCCCC")) );
+ COMPAT(free)(buf2);
+
+ char* buf4 = COMPAT(calloc)(PRINT_BUFSIZ, sizeof(char));
+ char* buf5 = COMPAT(calloc)(PRINT_BUFSIZ, sizeof(char));
+ int ret = COMPAT(snprintf)(buf4, PRINT_BUFSIZ, "---%d,%u---\n", 22, (UINT32)-1);
+ snprintf(buf5, PRINT_BUFSIZ, "---%d,%u---\n", 22, (UINT32)-1);
+ ERRETCP( ret > 0 && ret < PRINT_BUFSIZ );
+ ERRETCP( strncmp(buf4, buf5, PRINT_BUFSIZ) == 0);
+ COMPAT(free)(buf4);
+ COMPAT(free)(buf5);
+
+ buf4 = COMPAT(calloc)(PRINT_BUFSIZ, sizeof(char));
+ buf5 = COMPAT(calloc)(PRINT_BUFSIZ, sizeof(char));
+ ret = COMPAT(snprintf)(buf4, PRINT_BUFSIZ, "---%d,%u,%d,%d,%c,%p,%p---\n", 22, (UINT32)-1, (INT32)-1, INT_MIN, 'Z', (void*)0xAABBCCFF, (void*)NULL);
+ snprintf(buf5, PRINT_BUFSIZ, "---%d,%u,%d,%d,%c,%p,%p---\n", 22, (UINT32)-1, (INT32)-1, INT_MIN, 'Z', (void*)0xAABBCCFF, (void*)NULL);
+ ERRETCP( ret > 0 && ret < PRINT_BUFSIZ );
+ ERRETCP( strncmp(buf4, buf5, PRINT_BUFSIZ) == 0);
+ COMPAT(free)(buf4);
+ COMPAT(free)(buf5);
+
+ buf4 = COMPAT(calloc)(PRINT_BUFSIZ, sizeof(char));
+ buf5 = COMPAT(calloc)(PRINT_BUFSIZ, sizeof(char));
+ ret = COMPAT(snprintf)(buf4, PRINT_BUFSIZ, "---%p,%p,%X,%X---\n", 0x12345678, &buf2, 0x1234, 0x66667777);
+ snprintf(buf5, PRINT_BUFSIZ, "---%p,%p,%X,%X---\n", (void*)0x12345678, &buf2, 0x1234, 0x66667777);
+ ERRETCP( ret > 0 && ret < PRINT_BUFSIZ );
+ ERRETCP( strcmp(buf4, buf5) == 0);
+ COMPAT(free)(buf4);
+ COMPAT(free)(buf5);
+
+ char* randstr = test_randstring(65535);
+ buf5 = COMPAT(calloc)(strlen(randstr)+1, sizeof(char));
+ COMPAT(snprintf)(buf5, strlen(randstr)+1, "%s", randstr);
+ ERRETCP( strlen(randstr) == strlen(buf5) );
+ ERRETCP( strcmp(randstr, buf5) == 0 );
+ COMPAT(free)(buf5);
+
+ LPCSTR aStr = TEXT("This is a simple ANSI string if _UNICODE is not defined.");
+ int wLen = 0;
+ LPWSTR wStr = COMPAT(toWideChar)(aStr, strlen(aStr), &wLen);
+ ERRETCP( wLen > 0 );
+ ERRETCP( wStr != NULL );
+ COMPAT(free)(wStr);
+
+ return TRUE;
+}
diff --git a/source/tests/test_crypt.c b/source/tests/test_crypt.c
new file mode 100644
index 0000000..a2ebd49
--- /dev/null
+++ b/source/tests/test_crypt.c
@@ -0,0 +1,44 @@
+#include "tests.h"
+
+#include "utils.h"
+#include "crypt.h"
+
+
+#define MIN_BUFSIZ 8192
+#define MAX_BUFSIZ 65536
+
+
+BOOL test_crypt(void)
+{
+ uint32_t key[8], iv[8];
+ size_t ivkeysize = 0, maxsiz = 0;
+
+ maxsiz = MIN_BUFSIZ + (__rdtsc() % (MAX_BUFSIZ-MIN_BUFSIZ+1));
+ ivkeysize = 1 + (__rdtsc() % (sizeof(key)/sizeof(key[0])));
+
+ char* randstr = test_randstring(maxsiz);
+ ERRETCP( randstr != NULL );
+ size_t randlen = strlen(randstr);
+ ERRETCP( maxsiz == randlen );
+ ERRETCP( randlen >= MIN_BUFSIZ && MAX_BUFSIZ >= randlen );
+
+ for (size_t i = 0; i < ivkeysize; ++i) {
+ while(key[i] == 0) key[i] = xor32_randomkey();
+ while(iv[i] == 0) iv[i] = xor32_randomkey();
+ }
+
+ size_t encsiz = maxsiz + (ivkeysize*sizeof(key[0]));
+ char* encBuf = calloc(encsiz, sizeof(char));
+ for (size_t i = 0; i < encsiz; ++i)
+ ERRETCPDW_NOLOG( *(encBuf + i) == 0x0, *(encBuf + i) );
+ memcpy(encBuf, randstr, randlen);
+ size_t newsiz = xor32n_pcbc_crypt_buf((uint32_t*)encBuf, maxsiz, &iv[0], &key[0], ivkeysize);
+ ERRETCP( memcmp(encBuf, randstr, maxsiz) != 0 );
+ size_t oldsiz = xor32n_pcbc_crypt_buf((uint32_t*)encBuf, newsiz, &iv[0], &key[0], ivkeysize);
+ ERRETCP( oldsiz == newsiz );
+ ERRETCP( memcmp(encBuf, randstr, maxsiz) == 0 );
+ free(encBuf);
+
+ COMPAT(free)(randstr);
+ return TRUE;
+}
diff --git a/source/tests/test_http.c b/source/tests/test_http.c
new file mode 100644
index 0000000..e4882a4
--- /dev/null
+++ b/source/tests/test_http.c
@@ -0,0 +1,279 @@
+#include <unistd.h>
+#include <time.h>
+
+#include "tests.h"
+
+#include "http.h"
+#include "math.h"
+#include "utils.h"
+
+
+BOOL addPkg(SIZE_T sizA, SIZE_T sizB, struct http_resp* hresp, rrbuff* dst_buf, rrsize* dst_siz)
+{
+ ERRETCP( dst_buf != NULL && dst_siz != NULL && hresp != NULL );
+
+ rrsize new_siz = *dst_siz + sizA + sizeof(*hresp) + sizB;
+ *dst_buf = realloc(*dst_buf, new_siz*sizeof(**dst_buf));
+
+ rrbuff new_buf = *dst_buf + *dst_siz;
+ memset(new_buf, 'A', sizA);
+ memcpy(new_buf + sizA, hresp, sizeof(*hresp));
+ memset(new_buf + sizA + sizeof(*hresp), 'B', sizB);
+
+ *dst_siz = new_siz;
+ return TRUE;
+}
+
+#define PARSE_RESPONSE_CLEANUP(pkgbuf, pkgsiz, pkg_count, hresp) \
+ if (pkgbuf != NULL) free(pkgbuf); \
+ pkgbuf = NULL; \
+ pkgsiz = 0; \
+ pkg_count = 0; \
+ memset(&hresp, 0, sizeof(hresp)); \
+ memset(&hresp.startMarker[0], 'c', MARKER_SIZ);
+
+BOOL test_http(void)
+{
+ DWORD init_ret = ERR_HTTP_PRE;
+ ERRETCPDW( (init_ret = initHttp(LoadLibraryA, GetProcAddress)) == ERR_HTTP_OK, init_ret );
+
+ uint64_t sizA = __rdtsc() % 256;
+ uint64_t sizB = __rdtsc() % 512;
+ struct http_resp hresp = { {0}, 0, 0, 0 };
+ rrbuff pkgbuf = NULL;
+ rrsize pkgsiz = 0;
+ DWORD pkg_count = 0;
+
+ PARSE_RESPONSE_CLEANUP(pkgbuf, pkgsiz, pkg_count, hresp);
+
+ {
+ hresp.respCode = RC_REGISTER;
+ ERRETCP( addPkg(sizA, sizB, &hresp, &pkgbuf, &pkgsiz) == TRUE );
+ ERRETCP( addPkg(sizA, sizB, &hresp, &pkgbuf, &pkgsiz) == TRUE );
+ hresp.respCode = RC_PING;
+ ERRETCP( addPkg(sizA, sizB, &hresp, &pkgbuf, &pkgsiz) == TRUE );
+ pkg_count = 3;
+ }
+
+ {
+ int ret;
+ struct http_resp* tmp_hresp = NULL;
+ size_t pkgoff = 0;
+ while ((ret = parseResponse(pkgbuf, pkgsiz, &tmp_hresp, &pkgoff, &hresp.startMarker[0])) == RSP_OK ) {
+ ERRETCP( tmp_hresp != NULL );
+ pkg_count--;
+ }
+ if (pkg_count != 0)
+ ERRPRINT_BOTH("Last parseResponse returned: %d", ret);
+ ERRETCPLD( pkg_count == 0, pkg_count );
+ }
+
+ PARSE_RESPONSE_CLEANUP(pkgbuf, pkgsiz, pkg_count, hresp);
+
+ {
+ rflags all_flags[] = RF_ALL;
+ rrcode all_codes[] = RC_ALL;
+ for (DWORD i = 0; i < SIZEOF(all_codes); ++i) {
+ for (DWORD j = 0; j < SIZEOF(all_flags); ++j) {
+ hresp.respFlags = all_flags[j];
+ hresp.respCode = all_codes[i];
+ ERRETCP( addPkg(sizA, sizB, &hresp, &pkgbuf, &pkgsiz) == TRUE );
+ pkg_count++;
+ }
+ }
+ int ret;
+ struct http_resp* tmp_hresp = NULL;
+ size_t pkgoff = 0;
+ while ((ret = parseResponse(pkgbuf, pkgsiz, &tmp_hresp, &pkgoff, &hresp.startMarker[0])) == RSP_OK ) {
+ ERRETCP( tmp_hresp != NULL );
+ pkg_count--;
+ }
+ if (pkg_count != 0)
+ ERRPRINT_BOTH("Last parseResponse returned: %d", ret);
+ ERRETCPLD( pkg_count == 0, pkg_count );
+ }
+
+ PARSE_RESPONSE_CLEANUP(pkgbuf, pkgsiz, pkg_count, hresp);
+
+ {
+ DWORD maxPkgs = 64;
+ for (DWORD i = 0; i < maxPkgs; ++i) {
+ hresp.respCode = RC_PING;
+ ERRETCP( addPkg(sizA, sizB, &hresp, &pkgbuf, &pkgsiz) == TRUE );
+ pkg_count++;
+ }
+ ERRETCPLD( pkg_count == maxPkgs, pkg_count );
+ }
+
+ PARSE_RESPONSE_CLEANUP(pkgbuf, pkgsiz, pkg_count, hresp);
+
+ {
+ int abs_count = 0;
+ rrcode all_codes[] = RC_ALL;
+ DWORD maxPkgs = 64;
+ DWORD validPkgs = 0;
+ for (DWORD i = 0; i < maxPkgs; ++i) {
+ rrcode rc;
+ int rnd;
+ while ((rnd = __rdtsc()) == 0) {}
+ if (rnd % 2 == 0)
+ rc = all_codes[ __rdtsc() % SIZEOF(all_codes) ];
+ else
+ rc = (rrcode)__rdtsc();
+ for (DWORD j = 0; j < SIZEOF(all_codes); ++j) {
+ if (all_codes[j] == rc) {
+ pkg_count++;
+ validPkgs++;
+ break;
+ }
+ }
+ abs_count++;
+ hresp.respCode = rc;
+ ERRETCP( addPkg(0, 0, &hresp, &pkgbuf, &pkgsiz) == TRUE );
+ }
+ int ret;
+ struct http_resp* tmp_hresp = NULL;
+ size_t pkgoff = 0;
+ while (abs_count > 0) {
+ if ((ret = parseResponse(pkgbuf, pkgsiz, &tmp_hresp, &pkgoff, &hresp.startMarker[0])) == RSP_OK) {
+ pkg_count--;
+ }
+ abs_count--;
+ }
+ if (pkg_count != 0)
+ ERRPRINT_BOTH("Last parseResponse returned: %d (validPkgs/maxPkgs: %lu/%lu)", ret, validPkgs, maxPkgs);
+ ERRETCPLD( abs_count == 0, abs_count );
+ ERRETCPLD( pkg_count == 0, pkg_count );
+ }
+
+ PARSE_RESPONSE_CLEANUP(pkgbuf, pkgsiz, pkg_count, hresp);
+
+ {
+ DWORD maxPkgs = 64;
+ for (DWORD i = 0; i < maxPkgs; ++i) {
+ hresp.respCode = RC_PING;
+ ERRETCP( addPkg(0, 0, &hresp, &pkgbuf, &pkgsiz) == TRUE );
+ pkg_count++;
+ }
+ int ret;
+ struct http_resp* tmp_hresp = NULL;
+ size_t pkgoff = 0;
+ while ((ret = parseResponse(pkgbuf, pkgsiz, &tmp_hresp, &pkgoff, &hresp.startMarker[0])) == RSP_OK) {
+ pkg_count--;
+ }
+ if (pkg_count != 0)
+ ERRPRINT_BOTH("Last parseResponse returned: %d (maxPkgs: %lu)", ret, maxPkgs);
+ ERRETCPLD( pkg_count == 0, pkg_count );
+ }
+
+ PARSE_RESPONSE_CLEANUP(pkgbuf, pkgsiz, pkg_count, hresp);
+
+ {
+ hresp.respCode = RC_PING;
+ ERRETCP( addRequest(&pkgbuf, &pkgsiz, &hresp) == RSP_OK );
+ int ret = -1;
+ struct http_resp* tmp_hresp = NULL;
+ size_t pkgoff = 0;
+ ERRETCPLD( (ret = parseResponse(pkgbuf, pkgsiz, &tmp_hresp, &pkgoff, &hresp.startMarker[0])) == RSP_OK, ret );
+ }
+ PARSE_RESPONSE_CLEANUP(pkgbuf, pkgsiz, pkg_count, hresp);
+ {
+ hresp.respCode = 0;
+ ERRETCP( addRequest(&pkgbuf, &pkgsiz, &hresp) == RSP_OK );
+ int ret = -1;
+ struct http_resp* tmp_hresp = NULL;
+ size_t pkgoff = 0;
+ ERRETCPLD( (ret = parseResponse(pkgbuf, pkgsiz, &tmp_hresp, &pkgoff, &hresp.startMarker[0])) != RSP_OK, ret );
+ }
+ PARSE_RESPONSE_CLEANUP(pkgbuf, pkgsiz, pkg_count, hresp);
+
+ {
+ int abs_count = 0;
+ rrcode all_codes[] = RC_ALL;
+ DWORD maxPkgs = 64;
+ DWORD validPkgs = 0;
+ for (DWORD i = 0; i < maxPkgs; ++i) {
+ rrcode rc;
+ int rnd;
+ while ((rnd = __rdtsc()) == 0) {}
+ if (rnd % 2 == 0)
+ rc = all_codes[ __rdtsc() % SIZEOF(all_codes) ];
+ else
+ rc = (rrcode)__rdtsc();
+ for (DWORD j = 0; j < SIZEOF(all_codes); ++j) {
+ if (all_codes[j] == rc) {
+ pkg_count++;
+ validPkgs++;
+ break;
+ }
+ }
+ abs_count++;
+ hresp.respCode = rc;
+ ERRETCP( addRequest(&pkgbuf, &pkgsiz, &hresp) == RSP_OK );
+ }
+ int ret;
+ struct http_resp* tmp_hresp = NULL;
+ size_t pkgoff = 0;
+ while (abs_count > 0) {
+ if ((ret = parseResponse(pkgbuf, pkgsiz, &tmp_hresp, &pkgoff, &hresp.startMarker[0])) == RSP_OK) {
+ pkg_count--;
+ }
+ abs_count--;
+ }
+ if (pkg_count != 0)
+ ERRPRINT_BOTH("Last parseResponse returned: %d (validPkgs/maxPkgs: %lu/%lu)", ret, validPkgs, maxPkgs);
+ ERRETCPLD( abs_count == 0, abs_count );
+ ERRETCPLD( pkg_count == 0, pkg_count );
+ }
+
+ PARSE_RESPONSE_CLEANUP(pkgbuf, pkgsiz, pkg_count, hresp);
+
+ {
+ int abs_count = 0;
+ rrcode all_codes[] = RC_ALL;
+ DWORD maxPkgs = 64;
+ DWORD validPkgs = 0;
+ for (DWORD i = 0; i < maxPkgs; ++i) {
+ rrcode rc;
+ int rnd;
+ while ((rnd = __rdtsc()) == 0) {}
+ if (rnd % 2 == 0)
+ rc = all_codes[ __rdtsc() % SIZEOF(all_codes) ];
+ else
+ rc = (rrcode)__rdtsc();
+ for (DWORD j = 0; j < SIZEOF(all_codes); ++j) {
+ if (all_codes[j] == rc) {
+ pkg_count++;
+ validPkgs++;
+ break;
+ }
+ }
+ abs_count++;
+
+ rrsize psiz = __rdtsc() % 512;
+ struct http_resp* nresp = calloc(sizeof(*nresp) + pkgsiz, 1);
+ memcpy(&nresp->startMarker[0], &hresp.startMarker[0], MARKER_SIZ);
+ nresp->pkgsiz = psiz;
+ nresp->respCode = rc;
+ ERRETCP( addRequest(&pkgbuf, &pkgsiz, nresp) == RSP_OK );
+ free(nresp);
+ }
+
+ int ret;
+ struct http_resp* tmp_hresp = NULL;
+ size_t pkgoff = 0;
+ while (abs_count > 0) {
+ if ((ret = parseResponse(pkgbuf, pkgsiz, &tmp_hresp, &pkgoff, &hresp.startMarker[0])) == RSP_OK) {
+ pkg_count--;
+ }
+ abs_count--;
+ }
+ if (pkg_count != 0)
+ ERRPRINT_BOTH("Last parseResponse returned: %d (validPkgs/maxPkgs: %lu/%lu)", ret, validPkgs, maxPkgs);
+ ERRETCPLD( abs_count == 0, abs_count );
+ ERRETCPLD( pkg_count == 0, pkg_count );
+ }
+
+ PARSE_RESPONSE_CLEANUP(pkgbuf, pkgsiz, pkg_count, hresp);
+ return TRUE;
+}
diff --git a/source/tests/test_mem.c b/source/tests/test_mem.c
new file mode 100644
index 0000000..b16012e
--- /dev/null
+++ b/source/tests/test_mem.c
@@ -0,0 +1,17 @@
+#include "tests.h"
+
+#include "utils.h"
+
+
+BOOL test_memalign(void)
+{
+ DWORD addr = 0x41414141;
+ DWORD size = 512;
+ DWORD algn = 512;
+
+ ERRETCP( XMemAlign(size, algn, addr) == addr+size );
+ size++;
+ ERRETCP( XMemAlign(size, algn, 0) == 1024 );
+ ERRETCP( XMemAlign(size, algn, addr) == addr+1024 );
+ return TRUE;
+}
diff --git a/source/tests/test_pe.c b/source/tests/test_pe.c
new file mode 100644
index 0000000..bd77fce
--- /dev/null
+++ b/source/tests/test_pe.c
@@ -0,0 +1,66 @@
+#include "tests.h"
+
+#include "utils.h"
+#include "file.h"
+#include "pe_infect.h"
+#include "patch.h"
+#include "xor_strings.h"
+
+
+BOOL test_pe(char* filename)
+{
+ HANDLE hFile;
+ BYTE* buf;
+ SIZE_T szBuf;
+ struct ParsedPE ppe;
+
+ memset(&ppe, '\0', sizeof(struct ParsedPE));
+ ERRETCP( bOpenFile(filename, 0, &hFile) == TRUE );
+ ERRETCP( bFileToBuf(hFile, &buf, &szBuf) == TRUE );
+ ERRETCP( bParsePE(buf, szBuf, &ppe, FALSE) == TRUE );
+ ERRETCP( ppe.valid == TRUE );
+ ERRETCP( bIsInfected(&ppe) == FALSE );
+ ERRETCP( pGetSegmentAdr(".text", TRUE, &ppe, NULL) != NULL );
+ ERRETCP( pGetSegmentAdr(".data", TRUE, &ppe, NULL) != NULL );
+ ERRETCP( pGetSegmentAdr(".rdata", TRUE, &ppe, NULL) != NULL );
+ ERRETCP( pGetSegmentAdr(".idata", TRUE, &ppe, NULL) != NULL );
+ ERRETCP( pGetSegmentAdr(".CRT", TRUE, &ppe, NULL) != NULL );
+ ERRETCP( pGetSegmentAdr(LDRSECTION, TRUE, &ppe, NULL) == NULL );
+ ERRETCP( pGetSegmentAdr(DLLSECTION, TRUE, &ppe, NULL) == NULL );
+ ERRETCP( PtrToRva(&ppe, pGetSegmentAdr(".text", TRUE, &ppe, NULL)) != (DWORD)-1 );
+ ERRETCP( PtrToRva(&ppe, pGetSegmentAdr(".text", TRUE, &ppe, NULL)) > (DWORD)ppe.hdrOptional->ImageBase );
+ ERRETCP( OffsetToRva(&ppe, PtrToOffset(&ppe, pGetSegmentAdr(".text", TRUE, &ppe, NULL))) <
+ OffsetToRva(&ppe, PtrToOffset(&ppe, pGetSegmentAdr(".data", TRUE, &ppe, NULL))) );
+
+ free(buf);
+ CloseHandle(hFile);
+
+ BYTE jmp[5];
+ patchRelJMP(jmp, 0x44332211);
+ ERRETCP( strncmp((char*)jmp, "\xE9\x11\x22\x33\x44", 5) == 0 );
+
+ char* test_dir = dirname(filename);
+ char* loader_file = NULL;
+ asprintf(&loader_file, "%s\\loader_base.exe", test_dir);
+ if (bOpenFile(loader_file, 0, &hFile) == TRUE) {
+ ERRETCP( bFileToBuf(hFile, &buf, &szBuf) == TRUE );
+ ERRETCP( bParsePE(buf, szBuf, &ppe, FALSE) == TRUE );
+ ERRETCP( ppe.valid == TRUE );
+ ERRETCP( ppe.hasDLL == TRUE );
+ ERRETCP( ppe.hasLdr == TRUE );
+ ERRETCP( bIsInfected(&ppe) == TRUE );
+ ERRETCP( ppe.ptrToDLL != NULL );
+ ERRETCP( ppe.ptrToLdr != NULL );
+ ERRETCP( bCheckEndMarker(&ppe) == TRUE );
+ ERRETCP( ppe.loader86 != NULL );
+ ERRETCP( ppe.loader86->ptrToDLL != 0 );
+ ERRETCP( ppe.loader86->sizOfDLL != 0 );
+ size_t ldrstrsiz = sizeof(ppe.loader86->strVirtualAlloc)/sizeof(ppe.loader86->strVirtualAlloc[0]);
+ ERRETCP( ppe.loader86->strVirtualAlloc[ldrstrsiz-1] == '\0' );
+ ERRETCP( ppe.loader86->strIsBadReadPtr[ldrstrsiz-1] == '\0' );
+ DWORD dwImpLibs = dwCountNonSystemImportLibs(&ppe);
+ ERRETCPDW( dwImpLibs == 0, dwImpLibs );
+ } else ERRPRINT_STDERR("Could not OpenFile: %s\n", loader_file);
+ free(loader_file);
+ return TRUE;
+}
diff --git a/source/tests/test_utils.c b/source/tests/test_utils.c
new file mode 100644
index 0000000..b83fccc
--- /dev/null
+++ b/source/tests/test_utils.c
@@ -0,0 +1,226 @@
+#include <unistd.h>
+#include <time.h>
+
+#include "tests.h"
+
+#include "utils.h"
+#include "crypt.h"
+#include "math.h"
+#include "xor_strings_gen.h"
+
+
+BOOL test_math(void)
+{
+ ERRETCP( __moddi3 (100, 50) == 0 );
+ ERRETCP( __moddi3 (10000, 11) != 0 );
+ ERRETCP( __umoddi3(10000, 11) != 0 );
+ ERRETCP( __divdi3 (100, 2) == 50);
+ ERRETCP( __divdi3 (1, 1) == 1 );
+ ERRETCP( __divdi3 (100, 3) == 33);
+ ERRETCP( __divdi3 (1000,9000) == 0 );
+ ERRETCP( __moddi3 (LONG_LONG_MAX, LONG_LONG_MAX) == 0 );
+ ERRETCP( __moddi3 (LONG_LONG_MIN, LONG_LONG_MIN) == 0 );
+ ERRETCP( __umoddi3 (LONG_LONG_MAX, LONG_LONG_MAX) == 0 );
+ ERRETCP( __umoddi3 (ULONG_LONG_MAX,ULONG_LONG_MAX) == 0 );
+ ERRETCP( __divdi3 (LONG_LONG_MAX,LONG_LONG_MAX ) == 1 );
+ ERRETCP( __divdi3 (LONG_LONG_MIN,LONG_LONG_MIN ) == 1 );
+ ERRETCP( __udivdi3 (LONG_LONG_MAX,LONG_LONG_MAX ) == 1 );
+ ERRETCP( __udivdi3 (ULONG_LONG_MAX,ULONG_LONG_MAX) == 1 );
+ ERRETCP( __pow(2,0) == 1 );
+ ERRETCP( __pow(2,1) == 2 );
+ ERRETCP( __pow(2,10) == 1024 );
+ return TRUE;
+}
+
+BOOL test_utils(void)
+{
+ char buf1[64], buf2[64], buf3[64];
+
+ memset(buf1, '\0', 64);
+ memset(buf2, '\0', 64);
+ memset(buf3, '\0', 64);
+
+ __xultoa(0, (char*)buf1, 10);
+ __xultoa(ULONG_MAX, (char*)buf2, 10);
+ __xultoa(LONG_MAX, (char*)buf3, 10);
+ ERRETCP( strcmp(buf1, "0") == 0 );
+ ERRETCP( strcmp(buf2, "4294967295") == 0 );
+ ERRETCP( strcmp(buf3, "2147483647") == 0 );
+ ERRETCP( strlen(buf1) == strlen("0") );
+ ERRETCP( strlen(buf2) == strlen("4294967295") );
+ ERRETCP( strlen(buf3) == strlen("2147483647") );
+
+ memset(buf1, '\0', 64);
+ memset(buf2, '\0', 64);
+ memset(buf3, '\0', 64);
+
+ __xltoa(LONG_MAX, (char*)buf1, 10);
+ __xltoa(LONG_MIN, (char*)buf2, 10);
+ __xltoa(0, (char*)buf3, 10);
+ ERRETCP( strcmp(buf1, "2147483647") == 0 );
+ ERRETCP( strcmp(buf2, "-2147483648") == 0 );
+ ERRETCP( strcmp(buf3, "0") == 0 );
+ ERRETCP( strlen(buf1) == strlen("2147483647") );
+ ERRETCP( strlen(buf2) == strlen("-2147483648") );
+ ERRETCP( strlen(buf3) == strlen("0") );
+
+ char* buf4 = "AA1122334455667788990";
+ SIZE_T siz = 0;
+ char* result = __xbintostr((BYTE*)buf4, strlen(buf4), 2, &siz);
+ ERRETCP( siz == strlen("4141 3131 3232 3333 3434 3535 3636 3737 3838 3939 30") );
+ ERRETCP( strcmp(result, "4141 3131 3232 3333 3434 3535 3636 3737 3838 3939 30") == 0 );
+ __xfree(result);
+
+ BYTE* buf5 = COMPAT(calloc)(256, sizeof(char));
+ for (int i = 0; i < 256; ++i)
+ buf5[i] = i;
+ result = __xbintostr(buf5, 256, 0, NULL);
+ ERRETCP( strlen(result) == 256*2 );
+ ERRETCP( strcmp(result, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F" \
+ "202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F" \
+ "404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F" \
+ "606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F" \
+ "808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F" \
+ "A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF" \
+ "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF" \
+ "E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF") == 0 );
+ __xfree(result);
+
+
+ char* buf6 = strdup("This is a TOP SECRET message!");
+ char* buf7 = strdup(buf6);
+ unsigned int key = 0;
+
+ while(key == 0) key = xor32_randomkey();
+
+ xor32_byte_crypt((unsigned char*)buf7, strlen(buf6), key);
+ ERRETCP( strcmp(buf6, buf7) != 0 )
+
+ xor32_byte_crypt((unsigned char*)buf7, strlen(buf6), key);
+ ERRETCP( strlen(buf6) == strlen(buf7) );
+ ERRETCP( strcmp(buf6, buf7) == 0 );
+ free(buf7);
+
+ char buf9[COMPAT(strlen)(buf6)+1];
+ char buf10[COMPAT(strlen)(buf6)+1];
+
+ COMPAT(memcpy)(&buf9[0], buf6, strlen(buf6));
+ buf9[COMPAT(strlen)(buf6)] = '\0';
+ xor32_byte_crypt((unsigned char*)&buf9[0], COMPAT(strlen)(buf6), key);
+
+ memcpy(&buf10[0], &buf9[0], COMPAT(strlen)(buf6));
+ buf10[COMPAT(strlen)(buf6)] = '\0';
+ xor32_byte_crypt((unsigned char*)&buf10[0], COMPAT(strlen)(buf6), key);
+
+ ERRETCP( strlen(buf6) == strlen(buf10) );
+ ERRETCP( strcmp(buf6, buf9) != 0 );
+ ERRETCP( strcmp(buf6, buf10) == 0 );
+ free(buf6);
+
+ buf6 = strdup("We want to search a _substring_ in this _string_ !!");
+ ERRETCP( COMPAT(strnstr)(buf6, "_substring_", strlen(buf6)) != NULL );
+ ERRETCP( COMPAT(strnstr)(buf6, "_string_ !!", strlen(buf6)) != NULL );
+ ERRETCP( COMPAT(strnstr)(buf6, "_noonexistant_", strlen(buf6)) == NULL );
+ free(buf6);
+
+ buf6 = test_randstring(65535);
+ ERRETCP( COMPAT(strnstr)(buf6, "this string should not be found or you got bad luck", strlen(buf6)) == NULL );
+ COMPAT(free)(buf6);
+
+ buf6 = strdup("We test if _SubString_ works with strnistr(...)");
+ ERRETCP( COMPAT(strnistr)(buf6, "_substring_", strlen(buf6)) != NULL );
+ ERRETCP( COMPAT(strnistr)(buf6, "_sUBsTrinG_", strlen(buf6)) != NULL );
+ ERRETCP( COMPAT(strnistr)(buf6, "_NOTsubstring_", strlen(buf6)) == NULL );
+ ERRETCP( COMPAT(strnistr)(buf6, "STRNISTR(...)", strlen(buf6)) != NULL );
+ ERRETCP( COMPAT(strnistr)(buf6, "STRNISTR(...)!", strlen(buf6)) == NULL );
+ free(buf6);
+
+ buf6 = test_randstring(65535);
+ buf7 = test_randstring(4096);
+ ERRETCP( COMPAT(strnistr)(buf6, buf7, strlen(buf6)) == NULL );
+ ERRETCP( COMPAT(strnstr)(buf6, buf7, strlen(buf6)) == NULL );
+ COMPAT(free)(buf6);
+ COMPAT(free)(buf7);
+
+ char* garbage = __genGarbageFormatStr(512);
+ ERRETCP( garbage != NULL );
+ ERRETCP( strlen(garbage) > 500 );
+ COMPAT(free)(garbage);
+
+ struct LogicalDrives devs[32];
+ DWORD devnum = dwEnumDrives(&devs[0], sizeof(devs)/sizeof(devs[0]));
+ for (DWORD i = 0; i < devnum; ++i) {
+ ERRETCPDW( devs[i].devType > 0, devs[i].devType );
+ size_t len = strnlen(devs[i].name, MAX_PATH);
+ ERRETCP( len > 0 && len <= MAX_PATH );
+ if (devs[i].devType == 2 || devs[i].devType == 3) /* DRIVE_REMOVABLE || DRIVE_FIXED */
+ {
+ ERRETCP( devs[i].bytesPerSectorsPerCluster > 0 );
+ ERRETCP( devs[i].totalClusters > 0 );
+ }
+ }
+
+/*
+ // TODO: __pseudoRandom needs an update (not "Random" at all)
+ const unsigned max_rnd = 256;
+ const unsigned rnd_siz = 128;
+ unsigned char rnd[max_rnd][rnd_siz];
+ memset(&rnd[0][0], 0, sizeof(rnd));
+ for (unsigned i = 0; i < max_rnd; ++i) {
+ __pseudoRandom(rnd[i], rnd_siz);
+ }
+ for (unsigned i = 0; i < max_rnd; ++i) {
+ for (unsigned j = 0; j < max_rnd; ++j) {
+ if (i == j)
+ continue;
+ ERRETCP( memcmp(&rnd[i][0], &rnd[j][0], rnd_siz) != 0 );
+ }
+ }
+*/
+
+ char tok_str[] = "This is a sentence seperated with whitespaces without punctuation";
+ const unsigned tok_nmb = 9;
+ char* tok_next = tok_str;
+ char* tok_cur = NULL;
+ unsigned tok_n = 0;
+ while ((tok_cur = qtok(tok_next, &tok_next)) != NULL && *tok_cur) {
+ tok_n++;
+ }
+ ERRETCP( tok_n == tok_nmb );
+
+ char* str_numbers[] = { "32", "64", "128", "256", "512", "-1", "2700000", "-2700000", "1024e" };
+ for (unsigned i = 0; i < sizeof(str_numbers)/sizeof(str_numbers[0]); ++i) {
+ char* saveptr = NULL;
+ long nmb = COMPAT(strtol)(str_numbers[i], &saveptr, 10);
+ ERRETCPDW( nmb != 0, nmb );
+ long rnmb = strtol(str_numbers[i], &saveptr, 10);
+ ERRETCPDW( nmb == rnmb, rnmb );
+ }
+ char* str_not_numbers[] = { "abcdef", "abc1024", "a32b32", "a string" };
+ for (unsigned i = 0; i < sizeof(str_not_numbers)/sizeof(str_not_numbers[0]); ++i) {
+ char* saveptr = NULL;
+ long nmb = COMPAT(strtol)(str_not_numbers[i], &saveptr, 10);
+ ERRETCPDW( nmb == 0, nmb );
+ long rnmb = strtol(str_not_numbers[i], &saveptr, 10);
+ ERRETCPDW( nmb == rnmb, rnmb );
+ }
+ const unsigned max_hex = 64;
+ for (unsigned i = 0; i < max_hex; ++i) {
+ char* tmp_hex = test_randhexstring(6);
+ long nmb = COMPAT(strtol)(tmp_hex, NULL, 16);
+ long rnmb = strtol(tmp_hex, NULL, 16);
+ ERRETCPDW( nmb == rnmb, rnmb );
+ COMPAT(free)(tmp_hex);
+ }
+
+#if defined(i386) || defined(i686)
+ atomic_val aval = 0;
+ ERRETCPDW( aval == 0, aval );
+ atomic_inc(&aval);
+ ERRETCPDW( aval == 1, aval );
+ atomic_val retval = atomic_xchg(&aval, 2);
+ ERRETCPDW( aval == 2, aval );
+ ERRETCPDW( retval == 1, retval );
+#endif
+ return TRUE;
+}
diff --git a/source/tests/tests.h b/source/tests/tests.h
new file mode 100644
index 0000000..84135d8
--- /dev/null
+++ b/source/tests/tests.h
@@ -0,0 +1,128 @@
+#ifndef TESTS_H_INCLUDED
+#define TESTS_H_INCLUDED
+
+#ifndef _RUN_TESTS
+#error "_RUN_TESTS has to be defined"
+#endif
+#include "compat.h"
+
+#include <stdio.h>
+#include <libgen.h>
+
+
+#define MYASSERT_LOGFILE logfile
+extern FILE* MYASSERT_LOGFILE;
+
+extern unsigned test_count;
+extern unsigned test_faild;
+
+#define ERRPRINT(file, fmt, ...) { \
+ char* __erret_str = strdup(__FILE__); \
+ if (__erret_str != NULL) { \
+ char* __erret_base = basename(__erret_str); \
+ fprintf(file, "%s.%d: " fmt "\n", (__erret_base != NULL ? __erret_base : "NULL"), __LINE__, ##__VA_ARGS__); \
+ free(__erret_str); \
+ } \
+ }
+#define ERRPRINT_STDERR(fmt, ...) \
+ ERRPRINT(stderr, fmt, __VA_ARGS__)
+#define ERRPRINT_LOGFILE(fmt, ...) \
+ if (MYASSERT_LOGFILE != NULL) { ERRPRINT(MYASSERT_LOGFILE, fmt, __VA_ARGS__); fflush(MYASSERT_LOGFILE); }
+#define ERRPRINT_BOTH(fmt, ...) \
+ ERRPRINT(stderr, fmt, __VA_ARGS__) \
+ ERRPRINT_LOGFILE(fmt, __VA_ARGS__)
+
+#define MYASSERT_RETVAL retval
+#define MYASSERT_RETVAL_DEF int MYASSERT_RETVAL = 0;
+#define MYASSERT_LOG "tests.log"
+#define MYASSERT_LOGDEF FILE* MYASSERT_LOGFILE = NULL
+#define MYASSERT_INIT \
+ MYASSERT_RETVAL_DEF; \
+ if ((MYASSERT_LOGFILE = fopen(MYASSERT_LOG, "w")) == NULL) { \
+ ERRPRINT_BOTH("Could not open \"%s\" for writing.\n", MYASSERT_LOG); \
+ } else ERRPRINT_BOTH("Logfile-Init: %s", MYASSERT_LOG);
+
+#define MYASSERT_RETURN \
+ fclose(MYASSERT_LOGFILE); \
+ return MYASSERT_RETVAL;
+
+#define MYASSERT(expr) { \
+ ERRPRINT_LOGFILE("MYASSERT: %s", #expr); \
+ if ((expr) != TRUE) { \
+ fprintf_setw(stderr, 50, "%s", #expr); \
+ ERRPRINT_BOTH("FAILED with ERROR: %d", (int)GetLastError()); \
+ MYASSERT_RETVAL++; \
+ } else { \
+ fprintf_setw(stderr, 50, "%s", #expr); \
+ fprintf(stderr, "%s\n", "SUCCEEDED"); \
+ } \
+ }
+
+#define MYASSERT_SILENT(expr) { \
+ ERRPRINT_LOGFILE("MYASSERT_SILENT: %s", #expr); \
+ int outfd = dup(fileno(stdout)); \
+ int stdfd = fileno(stdout); \
+ close(stdfd); \
+ dup2(null_dev, stdfd); \
+ BOOL ret = (expr); \
+ close(stdfd); \
+ dup2(outfd, stdfd); \
+ close(outfd); \
+ if (ret != TRUE) { \
+ fprintf_setw(stderr, 50, "%s", #expr); \
+ ERRPRINT_BOTH("FAILED with ERROR: %d", (int)GetLastError()); \
+ } else { \
+ fprintf_setw(stderr, 50, "%s", #expr); \
+ fprintf(stderr, "%s\n", "SUCCEEDED"); \
+ } \
+ }
+
+
+#define _ERRETCP(expr) { test_count++; if ( (expr) != TRUE ) { test_faild++; ERRPRINT_BOTH("(%s) != TRUE", #expr); return FALSE; } }
+#define ERRETCP(expr) { ERRPRINT_LOGFILE("ERRETCP: %s", #expr); _ERRETCP(expr); }
+#define ERRETCP_NOLOG(expr) { _ERRETCP(expr); }
+
+#define _ERRETCPDW(expr, val) { test_count++; if ( (expr) != TRUE ) { test_faild++; ERRPRINT_BOTH("(%s) != TRUE , %s = %lu (0x%lX)", #expr, #val, (unsigned long)val, (unsigned long)val); return FALSE; } }
+#define ERRETCPDW(expr, val) { ERRPRINT_LOGFILE("ERRETCPDW: %s , %s = %lu (0x%lX) (", #expr, #val, (unsigned long)val, (unsigned long)val); _ERRETCPDW(expr, val); }
+#define ERRETCPDW_NOLOG(expr, val) { _ERRETCPDW(expr, val); }
+
+#define _ERRETCPLD(expr, val) { test_count++; if ( (expr) != TRUE ) { test_faild++; ERRPRINT_BOTH("(%s) != TRUE , %s = %ld (0x%lX)", #expr, #val, (long)val, (unsigned long)val); return FALSE; } }
+#define ERRETCPLD(expr, val) { ERRPRINT_LOGFILE("ERRETCPL: %s , %s = %ld (0x%lX) (", #expr, #val, (long)val, (unsigned long)val); _ERRETCPDW(expr, val); }
+#define ERRETCPLD_NOLOG(expr, val) { _ERRETCPDW(expr, val); }
+
+
+extern int null_dev;
+
+char* test_randstring(size_t length);
+
+char* test_randhexstring(size_t length);
+
+int fprintf_setw(FILE *stream, size_t s_maxlen, const char *format, ...);
+
+BOOL test_memmove(void);
+
+BOOL test_realloc(void);
+
+BOOL test_memalign(void);
+
+BOOL test_heap(void);
+
+BOOL test_mem(void);
+
+BOOL test_stdio(void);
+
+BOOL test_math(void);
+
+BOOL test_utils(void);
+
+BOOL test_distorm(void);
+
+BOOL test_aes(void);
+
+BOOL test_crypt(void);
+
+BOOL test_pe(char* filename);
+
+BOOL test_http(void);
+
+#endif // TESTS_H_INCLUDED