diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..8ebac96 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,115 @@ +name: CI + +on: + push: + branches: [ main ] + pull_request: + +jobs: + build: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + autoconf \ + automake \ + libtool \ + pkg-config \ + build-essential \ + libcunit1 \ + libcunit1-dev \ + wget \ + zlib1g-dev \ + libssl-dev \ + libsqlite3-dev \ + libreadline-dev \ + libncurses5-dev \ + libbz2-dev \ + libffi-dev \ + nasm \ + gdb + + - name: Enable core dumps + run: | + ulimit -c unlimited + sudo mkdir -p /cores + sudo chmod 777 /cores + echo "/cores/core.%e.%p" | sudo tee /proc/sys/kernel/core_pattern + sudo sysctl -w kernel.core_pattern=/cores/core.%e.%p + + - name: Cache Python 2.7 + uses: actions/cache@v3 + id: python-cache + with: + path: /opt/python2.7 + key: ${{ runner.os }}-python2.7-v1 + + - name: Build Python 2.7 + if: steps.python-cache.outputs.cache-hit != 'true' + run: | + wget https://www.python.org/ftp/python/2.7.18/Python-2.7.18.tgz + tar xzf Python-2.7.18.tgz + cd Python-2.7.18 + ./configure --prefix=/opt/python2.7 --without-test-modules + make -j$(nproc) + sudo make install + cd .. + + - name: Save Python 2.7 cache + if: steps.python-cache.outputs.cache-hit != 'true' + uses: actions/cache/save@v3 + with: + path: /opt/python2.7 + key: ${{ runner.os }}-python2.7-v1 + + - name: Download and build udis86 with -fPIC + run: | + wget https://github.com/vmt/udis86/archive/refs/tags/v1.7.2.tar.gz -O udis86-1.7.2.tar.gz + tar xzf udis86-1.7.2.tar.gz + cd udis86-1.7.2 + autoreconf -i + CFLAGS="-fPIC" ./configure + make PYTHON=/opt/python2.7/bin/python2 + sudo make install + cd .. + + - name: Configure and build project + run: | + ./autogen.sh + CFLAGS="-Wno-stringop-truncation -g" ./configure --enable-tests + make + + - name: Run tests + run: | + cd test + make check + cd .. + + - name: Display test logs + if: always() + run: | + echo "=== Test Suite Log ===" + cat test/test-suite.log + echo "=====================" + + - name: Analyze core dumps + if: always() + run: | + echo "=== Core Dumps Analysis ===" + echo "Current directory: $(pwd)" + echo "Core dump directory contents:" + ls -la /cores/ + for core in /cores/core.*; do + if [ -f "$core" ]; then + echo "Analyzing core dump: $core" + executable=$(echo $core | cut -d. -f2) + echo "Looking for executable: $executable" + find . -name "$executable" -type f + gdb -batch -ex "bt full" -ex "info threads" -ex "thread apply all bt" "./test/.libs/$executable" "$core" + fi + done + echo "========================" \ No newline at end of file diff --git a/configure.ac b/configure.ac index 0f3b5cf..5edc967 100644 --- a/configure.ac +++ b/configure.ac @@ -11,6 +11,9 @@ AC_CONFIG_SRCDIR([src/binary.c]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) +# Add compiler flags +CFLAGS="$CFLAGS -Wpedantic" + HAVE_TESTS="yes" dnl Enable unit-tests AC_ARG_ENABLE([tests], diff --git a/src/Makefile.am b/src/Makefile.am index eed69ed..f3e2654 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ CFLAGS_LANGUAGE=-std=c99 -pedantic -D_POSIX_C_SOURCE \ - -D_SVID_SOURCE + -D_DEFAULT_SOURCE CFLAGS_WARNS=-Wall -Wextra -Werror CFLAGS_INCLUDES=-Iinclude -I$(LIBXML_INCLUDES) -I$(LIBUDIS_INCLUDES) diff --git a/src/binary.c b/src/binary.c index b133b04..582a291 100644 --- a/src/binary.c +++ b/src/binary.c @@ -598,19 +598,17 @@ static _u32 _malelf_binary_get_segment_32(MalelfBinary *bin, _u32 segment_idx, MalelfSegment *segment) { - MalelfPhdr stphdr; Elf32_Phdr *phdr32; int error = MALELF_SUCCESS; - assert(bin != NULL && bin->mem != NULL); + assert(bin != NULL && bin->mem != NULL && segment != NULL && segment->phdr != NULL); - error = malelf_binary_get_phdr(bin, &stphdr); + error = malelf_binary_get_phdr(bin, segment->phdr); if (error != MALELF_SUCCESS) { return error; } - phdr32 = stphdr.uhdr.h32; - + phdr32 = segment->phdr->uhdr.h32; phdr32 += segment_idx; segment->type = phdr32->p_type; @@ -619,7 +617,6 @@ static _u32 _malelf_binary_get_segment_32(MalelfBinary *bin, segment->size = phdr32->p_filesz; segment->offset = phdr32->p_offset; segment->mem = bin->mem + phdr32->p_offset; - segment->phdr = &stphdr; return MALELF_SUCCESS; } @@ -628,17 +625,16 @@ static _u32 _malelf_binary_get_segment_64(MalelfBinary *bin, _u32 segment_idx, MalelfSegment *segment) { - MalelfPhdr stphdr; Elf64_Phdr *phdr64; int error = MALELF_SUCCESS; - assert(bin != NULL && bin->mem != NULL); - error = malelf_binary_get_phdr(bin, &stphdr); + assert(bin != NULL && bin->mem != NULL && segment != NULL && segment->phdr != NULL); + error = malelf_binary_get_phdr(bin, segment->phdr); if (error != MALELF_SUCCESS) { return error; } - phdr64 = stphdr.uhdr.h64; + phdr64 = segment->phdr->uhdr.h64; phdr64 += segment_idx; @@ -648,7 +644,6 @@ static _u32 _malelf_binary_get_segment_64(MalelfBinary *bin, segment->offset = phdr64->p_offset; segment->size = phdr64->p_filesz; segment->mem = bin->mem + phdr64->p_offset; - segment->phdr = &stphdr; return MALELF_SUCCESS; } @@ -778,15 +773,15 @@ static _u32 _malelf_binary_get_section32(_u32 section_idx, _u32 error = MALELF_SUCCESS; Elf32_Shdr *shdr32; - MalelfShdr ushdr; + assert(bin != NULL && bin->mem != NULL && section != NULL && section->shdr != NULL); - error = malelf_binary_get_shdr(bin, &ushdr); + error = malelf_binary_get_shdr(bin, section->shdr); if (error != MALELF_SUCCESS) { return error; } - shdr32 = ushdr.uhdr.h32; + shdr32 = section->shdr->uhdr.h32; shdr32 += section_idx; error = malelf_binary_get_section_name(bin, @@ -800,7 +795,6 @@ static _u32 _malelf_binary_get_section32(_u32 section_idx, section->offset = shdr32->sh_offset; section->addr = shdr32->sh_addr; section->size = shdr32->sh_size; - section->shdr = &ushdr; return MALELF_SUCCESS; } @@ -810,15 +804,15 @@ static _u32 _malelf_binary_get_section64(_u32 section_idx, { int error = MALELF_SUCCESS; Elf64_Shdr *shdr64; - MalelfShdr ushdr; + assert(bin != NULL && bin->mem != NULL && section != NULL && section->shdr != NULL); - error = malelf_binary_get_shdr(bin, &ushdr); + error = malelf_binary_get_shdr(bin, section->shdr); if (error != MALELF_SUCCESS) { return error; } - shdr64 = ushdr.uhdr.h64; + shdr64 = section->shdr->uhdr.h64; shdr64 += section_idx; error = malelf_binary_get_section_name(bin, @@ -956,12 +950,13 @@ _u32 _malelf_binary_get_section_by_name64(MalelfBinary *bin, return error; } +// section->shdr must be initialized before calling this function. _u32 malelf_binary_get_section_by_name(MalelfBinary *bin, const char *name, MalelfSection *section) { int error = MALELF_SUCCESS; - assert(NULL != name && NULL != bin && NULL != bin->mem); + assert(NULL != name && NULL != bin && NULL != bin->mem && NULL != section && NULL != section->shdr); switch (bin->class) { @@ -1278,21 +1273,31 @@ _u32 _malelf_binary_write_elf(MalelfBinary *bin) _u32 last_size = 0; /* writing binary content using the program headers */ for (i = 0; i < ehdr_phnum; i++) { - MalelfSegment segment; + MalelfSegment *segment; + + segment = malelf_malloc(sizeof(MalelfSegment) + sizeof(MalelfPhdr)); + if (!segment) { + return MALELF_EALLOC; + } - error = malelf_binary_get_segment(bin, i, &segment); + segment->phdr = (MalelfPhdr *)(segment + sizeof(MalelfSegment)); - if (segment.type == PT_NULL) + error = malelf_binary_get_segment(bin, i, segment); + + if (segment->type == PT_NULL) { + free(segment); continue; + } - last_offset = segment.offset; - last_size = segment.size; + last_offset = segment->offset; + last_size = segment->size; - lseek(bin->fd, segment.offset, SEEK_SET); + lseek(bin->fd, segment->offset, SEEK_SET); error = malelf_write(bin->fd, - bin->mem + segment.offset, - segment.size); + bin->mem + segment->offset, + segment->size); + free(segment); if (MALELF_SUCCESS != error) { return error; } diff --git a/src/debug.c b/src/debug.c index cc77635..ec2c65f 100644 --- a/src/debug.c +++ b/src/debug.c @@ -98,7 +98,6 @@ int __malelf_debug(_u8 logcode, char temp[256]; char fmt_out[LOG_BUFSIZE]; char stime[26]; - int timelen; char *prefix; if (!_malelf_debug_ok) { @@ -115,11 +114,8 @@ int __malelf_debug(_u8 logcode, localtime_r(<ime, &result); asctime_r(&result, stime); - timelen = strlen(stime); - strcat(temp, "["); - strncat(temp, stime, timelen); - temp[timelen] = 0; + strncat(temp, stime, 255); strcat(temp, "]"); strcat(temp, "[%s][%s:%s] %s"); diff --git a/src/ehdr.c b/src/ehdr.c index 32ee842..d570ccd 100644 --- a/src/ehdr.c +++ b/src/ehdr.c @@ -62,6 +62,7 @@ static MalelfEhdrTable _me_machine[] = { {"EM_88K", 5, "Motorola 88000"}, {"EM_860", 7, "Intel 80860"}, {"EM_MIPS", 8, "MIPS RS3000"}, + {"EM_X86_64", 64, "x86-64"}, {"UNKNOWN", 0, "UNKNOWN"} }; @@ -185,7 +186,7 @@ _u32 malelf_ehdr_get_machine(MalelfEhdr *ehdr, } switch(machine) { - case EM_NONE: + case EM_NONE: *me_machine = _me_machine[0]; break; case EM_M32: @@ -209,6 +210,9 @@ _u32 malelf_ehdr_get_machine(MalelfEhdr *ehdr, case EM_MIPS: *me_machine = _me_machine[7]; break; + case EM_X86_64: + *me_machine = _me_machine[8]; + break; default: *me_machine = _me_machine[8]; me_machine->value = machine; diff --git a/src/include/malelf/binary.h b/src/include/malelf/binary.h index a1daadf..8f03d69 100644 --- a/src/include/malelf/binary.h +++ b/src/include/malelf/binary.h @@ -34,6 +34,8 @@ MALELF_BEGIN_DECLS +#define pointer_to(p, offset) \ + ((void *) ((char *) (p) + (offset))) typedef struct { char *fname; /* Binary filename */ diff --git a/src/include/malelf/debug.h b/src/include/malelf/debug.h index da70000..69e8d1a 100644 --- a/src/include/malelf/debug.h +++ b/src/include/malelf/debug.h @@ -35,7 +35,7 @@ #define _MALELF_DEBUG_TEST(code, ...) \ __malelf_debug(code, \ - __FUNCTION__, \ + __func__, \ __FILE__, \ TOSTRING(__LINE__), \ __VA_ARGS__) diff --git a/src/include/malelf/error.h b/src/include/malelf/error.h index e88fa52..151d288 100644 --- a/src/include/malelf/error.h +++ b/src/include/malelf/error.h @@ -95,7 +95,7 @@ typedef enum { #define MALELF_PERROR(code)\ - __malelf_perror(code, __FUNCTION__, __FILE__, __LINE__) + __malelf_perror(code, __func__, __FILE__, __LINE__) #define MALELF_FATAL(code)\ do {\ diff --git a/src/infect.c b/src/infect.c index d531025..b824860 100644 --- a/src/infect.c +++ b/src/infect.c @@ -207,6 +207,8 @@ _u32 _malelf_infect_prepare_silvio_padding32(MalelfInfect *infector) host_ehdr = (Elf32_Ehdr *) MALELF_ELF_DATA(&host->ehdr); host_phdr = (Elf32_Phdr *) MALELF_ELF_DATA(&host->phdr); + assert(host_ehdr->e_phnum > 0); + for (phdr = host_phdr, i = host_ehdr->e_phnum; i-- > 0; phdr++) { diff --git a/src/malware/lib/inc/errno-base.inc.asm b/src/malware/lib/inc32/errno-base.inc.asm similarity index 100% rename from src/malware/lib/inc/errno-base.inc.asm rename to src/malware/lib/inc32/errno-base.inc.asm diff --git a/src/malware/lib/inc/net.inc.asm b/src/malware/lib/inc32/net.inc.asm similarity index 100% rename from src/malware/lib/inc/net.inc.asm rename to src/malware/lib/inc32/net.inc.asm diff --git a/src/malware/lib/inc/socket.inc.asm b/src/malware/lib/inc32/socket.inc.asm similarity index 100% rename from src/malware/lib/inc/socket.inc.asm rename to src/malware/lib/inc32/socket.inc.asm diff --git a/src/malware/lib/inc/syscall.inc.asm b/src/malware/lib/inc32/syscall.inc.asm similarity index 100% rename from src/malware/lib/inc/syscall.inc.asm rename to src/malware/lib/inc32/syscall.inc.asm diff --git a/src/malware/lib/inc/util.inc.asm b/src/malware/lib/inc32/util.inc.asm similarity index 98% rename from src/malware/lib/inc/util.inc.asm rename to src/malware/lib/inc32/util.inc.asm index 767fe22..7f7d105 100644 --- a/src/malware/lib/inc/util.inc.asm +++ b/src/malware/lib/inc32/util.inc.asm @@ -1,4 +1,4 @@ -%include "inc/syscall.inc.asm" +%include "inc32/syscall.inc.asm" %macro prologue 0 push ebp diff --git a/src/malware/lib/itoa.asm b/src/malware/lib/itoa32.asm similarity index 100% rename from src/malware/lib/itoa.asm rename to src/malware/lib/itoa32.asm diff --git a/src/malware/lib/itoa64.asm b/src/malware/lib/itoa64.asm new file mode 100644 index 0000000..6a8fbd7 --- /dev/null +++ b/src/malware/lib/itoa64.asm @@ -0,0 +1,100 @@ +; itoa64 tests +; by i4k + +BITS 64 + +%macro prologue 0 + push rbp + mov rbp, rsp +%endmacro + +%macro prologue 1 + push rbp + mov rbp, rsp + sub rsp, %1 +%endmacro + +%macro epilogue 0 + mov rsp, rbp + pop rbp +%endmacro + + global _start + section .text +_start: + prologue + mov rdi, 1337 + call itoa64 + + ; Write the number string + mov rdx, rax ; length + mov rsi, rdi ; string pointer + mov rdi, 1 ; stdout + mov rax, 1 ; sys_write + syscall + + ; Exit + mov rdi, 0 + mov rax, 60 ; sys_exit + syscall + + epilogue + +; rdi: number to convert +; returns: rdi: pointer to string, rax: length +itoa64: + prologue 32 ; Allocate space for string buffer + + mov rax, rdi ; number to convert + mov rdi, rbp ; use stack space for string + sub rdi, 32 ; point to buffer start + mov rcx, 0 ; counter for digits + + test rax, rax + jns .convert ; if positive, start converting + + ; Handle negative number + neg rax ; make number positive + mov byte [rdi], '-' ; add minus sign + inc rdi + inc rcx + +.convert: + mov rbx, 10 ; divisor + xor rdx, rdx ; clear rdx for division + div rbx ; rax = rax/10, rdx = remainder + + add dl, '0' ; convert to ASCII + mov [rdi], dl ; store digit + inc rdi + inc rcx + + test rax, rax ; check if we're done + jnz .convert + + ; Reverse the string + mov rsi, rbp + sub rsi, 32 ; start of buffer + mov rdi, rsi + add rdi, rcx + dec rdi ; end of string + +.reverse_loop: + cmp rsi, rdi + jge .done + + mov al, [rsi] + mov bl, [rdi] + mov [rsi], bl + mov [rdi], al + + inc rsi + dec rdi + jmp .reverse_loop + +.done: + mov rax, rcx ; return length + mov rdi, rbp + sub rdi, 32 ; return string pointer + epilogue + ret \ No newline at end of file diff --git a/src/table.c b/src/table.c index bd1bf2d..7f41862 100644 --- a/src/table.c +++ b/src/table.c @@ -68,7 +68,7 @@ _u32 malelf_table_add_str_value(MalelfTable *obj, const char *value) } if (obj->element < (obj->nrows * obj->ncolumns)) { - strncpy(obj->content[obj->element], value, strlen(value)); + strncpy(obj->content[obj->element], value, MALELF_TABLE_CONTENT_LEN); obj->element++; } @@ -92,7 +92,7 @@ _u32 malelf_table_add_row(MalelfTable *obj, char **row) if (obj->element < (obj->nrows * obj->ncolumns)) { strncpy(obj->content[obj->element], row[i], - strlen(row[i])); + MALELF_TABLE_CONTENT_LEN); obj->element++; } } diff --git a/test/binary_test.c b/test/binary_test.c index 7b835bd..18dc8a2 100644 --- a/test/binary_test.c +++ b/test/binary_test.c @@ -186,17 +186,20 @@ static void malelf_binary_open_TEST() _malelf_binary_open_success_TEST("hosts/uninfected", MALELF_ALLOC_MALLOC); _malelf_binary_open_success_TEST("hosts/uninfected_asm", MALELF_ALLOC_MALLOC); _malelf_binary_open_fail_TEST("/wrong/path/uninfected", MALELF_ALLOC_MALLOC); - _malelf_binary_open_shellcode_success_TEST("malwares/write_message.o", MALELF_ALLOC_MMAP); - _malelf_binary_open_shellcode_fail_TEST("/wrong/path/write_message.o", MALELF_ALLOC_MMAP); - _malelf_binary_open_shellcode_success_TEST("malwares/write_message.o", MALELF_ALLOC_MALLOC); - _malelf_binary_open_shellcode_fail_TEST("/wrong/path/write_message.o", MALELF_ALLOC_MALLOC); + _malelf_binary_open_shellcode_success_TEST("malwares/write_message32.o", MALELF_ALLOC_MMAP); + _malelf_binary_open_shellcode_fail_TEST("/wrong/path/write_message32.o", MALELF_ALLOC_MMAP); + _malelf_binary_open_shellcode_success_TEST("malwares/write_message32.o", MALELF_ALLOC_MALLOC); + _malelf_binary_open_shellcode_fail_TEST("/wrong/path/write_message32.o", MALELF_ALLOC_MALLOC); } static void malelf_binary_get_section_name_TEST() { MalelfBinary bin; _i32 result; - char *name = NULL; + char *name1 = NULL; + char *name2 = NULL; + char *expect1 = NULL; + char *expect2 = NULL; malelf_binary_init(&bin); @@ -205,43 +208,37 @@ static void malelf_binary_get_section_name_TEST() CU_ASSERT(result == MALELF_SUCCESS); CU_ASSERT(NULL != bin.fname); - if (bin.class == MALELF_ELF32) { - result = malelf_binary_get_section_name(&bin, 1, &name); - CU_ASSERT(MALELF_SUCCESS == result); + result = malelf_binary_get_section_name(&bin, 1, &name1); + CU_ASSERT(MALELF_SUCCESS == result); - CU_ASSERT_STRING_EQUAL(".text", name); - - result = malelf_binary_get_section_name(&bin, 2, &name); - CU_ASSERT(MALELF_SUCCESS == result); - CU_ASSERT_STRING_EQUAL(".data", name); - - result = malelf_binary_get_section_name(&bin, 3, &name); - CU_ASSERT(MALELF_SUCCESS == result); - CU_ASSERT_STRING_EQUAL(".shstrtab", name); + if (strcmp(name1, ".text") == 0) { + // text comes first + expect1 = ".text"; + expect2 = ".data"; } else { - /* 64bit machine .data is before .text */ - result = malelf_binary_get_section_name(&bin, 1, &name); - CU_ASSERT(MALELF_SUCCESS == result); - - CU_ASSERT_STRING_EQUAL(".data", name); - - result = malelf_binary_get_section_name(&bin, 2, &name); - CU_ASSERT(MALELF_SUCCESS == result); - CU_ASSERT_STRING_EQUAL(".text", name); - - result = malelf_binary_get_section_name(&bin, 3, &name); - CU_ASSERT(MALELF_SUCCESS == result); - CU_ASSERT_STRING_EQUAL(".shstrtab", name); + // data comes first + expect1 = ".data"; + expect2 = ".text"; } + CU_ASSERT_STRING_EQUAL(expect1, name1); + result = malelf_binary_get_section_name(&bin, 2, &name2); + CU_ASSERT(MALELF_SUCCESS == result); + CU_ASSERT_STRING_EQUAL(expect2, name2); + malelf_binary_close(&bin); } static void malelf_binary_get_section_TEST() { + char *expect1 = NULL; + char *expect2 = NULL; + _i32 result; MalelfBinary bin; - _i32 result; - MalelfSection section; + MalelfSection *section; + + section = (MalelfSection *)malloc(sizeof(MalelfSection) + sizeof(MalelfShdr)); + section->shdr = pointer_to(section, sizeof(MalelfSection)); malelf_binary_init(&bin); @@ -250,50 +247,24 @@ static void malelf_binary_get_section_TEST() CU_ASSERT(result == MALELF_SUCCESS); CU_ASSERT(NULL != bin.fname); - if (bin.class == MALELF_ELF32) { - result = malelf_binary_get_section(&bin, 1, §ion); - CU_ASSERT(MALELF_SUCCESS == result); - CU_ASSERT_STRING_EQUAL(section.name, ".text"); - CU_ASSERT(section.offset == 0x80); - CU_ASSERT(section.size == 0x1d); - CU_ASSERT(section.shdr != NULL); - - result = malelf_binary_get_section(&bin, 2, §ion); - CU_ASSERT(MALELF_SUCCESS == result); - CU_ASSERT_STRING_EQUAL(section.name, ".data"); - CU_ASSERT(section.offset == 0xa0); - CU_ASSERT(section.size == 0x12); - CU_ASSERT(section.shdr != NULL); - - result = malelf_binary_get_section(&bin, 3, §ion); - CU_ASSERT(MALELF_SUCCESS == result); - CU_ASSERT_STRING_EQUAL(section.name, ".shstrtab"); - CU_ASSERT(section.offset == 0xb2); - CU_ASSERT(section.size == 0x27); - CU_ASSERT(section.shdr != NULL); - } else if (bin.class == MALELF_ELF64) { - result = malelf_binary_get_section(&bin, 1, §ion); - CU_ASSERT(MALELF_SUCCESS == result); - CU_ASSERT_STRING_EQUAL(section.name, ".data"); - CU_ASSERT(section.offset == 0x200); - CU_ASSERT(section.size == 0x12); - CU_ASSERT(section.shdr != NULL); - - result = malelf_binary_get_section(&bin, 2, §ion); - CU_ASSERT(MALELF_SUCCESS == result); - CU_ASSERT_STRING_EQUAL(section.name, ".text"); - CU_ASSERT(section.offset == 0x220); - CU_ASSERT(section.size == 0x1d); - CU_ASSERT(section.shdr != NULL); - - result = malelf_binary_get_section(&bin, 3, §ion); - CU_ASSERT(MALELF_SUCCESS == result); - CU_ASSERT_STRING_EQUAL(section.name, ".shstrtab"); - CU_ASSERT(section.offset == 0x240); - CU_ASSERT(section.size == 0x32); - CU_ASSERT(section.shdr != NULL); + result = malelf_binary_get_section(&bin, 1, section); + CU_ASSERT(MALELF_SUCCESS == result); + if (strcmp(section->name, ".text") == 0) { + expect1 = ".text"; + expect2 = ".data"; + } else { + expect1 = ".data"; + expect2 = ".text"; } + CU_ASSERT_STRING_EQUAL(expect1, section->name); + CU_ASSERT(section->shdr != NULL); + + result = malelf_binary_get_section(&bin, 2, section); + CU_ASSERT(MALELF_SUCCESS == result); + CU_ASSERT_STRING_EQUAL(expect2, section->name); + CU_ASSERT(section->shdr != NULL); + free(section); malelf_binary_close(&bin); } diff --git a/test/debug_test.c b/test/debug_test.c index 8ce0de9..5588be6 100644 --- a/test/debug_test.c +++ b/test/debug_test.c @@ -49,9 +49,9 @@ void malelf_debug_init_TEST() setenv("MALELF_DEBUG_FILE", "tmp/check.log", 1); malelf_debug_init(); - CU_ASSERT(MALELF_DEBUG_TEST("1") == 70); - CU_ASSERT(MALELF_DEBUG_TEST("12") == 71) - CU_ASSERT(MALELF_DEBUG_TEST("1234567890") == 79); // time + msg + CU_ASSERT(MALELF_DEBUG_TEST("1") == 71); + CU_ASSERT(MALELF_DEBUG_TEST("12") == 72) + CU_ASSERT(MALELF_DEBUG_TEST("1234567890") == 80); // time + msg CU_ASSERT(MALELF_DEBUG_TEST( "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" @@ -90,10 +90,10 @@ void malelf_debug_init_TEST() "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" ) == 1023); /* trying to overflow */ - CU_ASSERT(MALELF_DEBUG_TEST("testing") == 76); + CU_ASSERT(MALELF_DEBUG_TEST("testing") == 77); setenv("MALELF_DEBUG", "4", 1); - CU_ASSERT(MALELF_DEBUG_TEST_ERROR("testing") == 76); + CU_ASSERT(MALELF_DEBUG_TEST_ERROR("testing") == 77); } void malelf_debug_cleanup() diff --git a/test/infect_test.c b/test/infect_test.c index 2bd30dc..7f33f1c 100644 --- a/test/infect_test.c +++ b/test/infect_test.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -131,29 +132,36 @@ void test_malelf_infect_silvio_padding(char* malware_path, for (i = 0; i < sizeof(uninfected_files)/256; i++) { //Preparing strings for the tests - strncpy(uninfected_path, uninfected_files[i], 255); + strncpy(uninfected_path, uninfected_files[i], sizeof(uninfected_path) - 1); + uninfected_path[sizeof(uninfected_path) - 1] = '\0'; - strncpy(infected_path, infected_dir, 255); - strncat(infected_path, basename(uninfected_path), 255); + strncpy(infected_path, infected_dir, sizeof(infected_path) - 1); + infected_path[sizeof(infected_path) - 1] = '\0'; + strncat(infected_path, basename(uninfected_path), sizeof(infected_path) - strlen(infected_path) - 1); - strncpy(infected_output_file, infected_path, 255); - strncat(infected_output_file, ".out", 255); + strncpy(infected_output_file, infected_path, sizeof(infected_output_file) - 1); + infected_output_file[sizeof(infected_output_file) - 1] = '\0'; + strncat(infected_output_file, ".out", sizeof(infected_output_file) - strlen(infected_output_file) - 1); - strncpy(uninfected_output_file, uninfected_dir, 255); - strncat(uninfected_output_file, basename(uninfected_path), 255); - strncat(uninfected_output_file, ".out", 255); + strncpy(uninfected_output_file, uninfected_dir, sizeof(uninfected_output_file) - 1); + uninfected_output_file[sizeof(uninfected_output_file) - 1] = '\0'; + strncat(uninfected_output_file, basename(uninfected_path), sizeof(uninfected_output_file) - strlen(uninfected_output_file) - 1); + strncat(uninfected_output_file, ".out", sizeof(uninfected_output_file) - strlen(uninfected_output_file) - 1); - strncpy(uninfected_exec, uninfected_path, 255); - strncat(uninfected_exec, redir, 255); - strncat(uninfected_exec, uninfected_output_file, 255); + strncpy(uninfected_exec, uninfected_path, sizeof(uninfected_exec) - 1); + uninfected_exec[sizeof(uninfected_exec) - 1] = '\0'; + strncat(uninfected_exec, redir, sizeof(uninfected_exec) - strlen(uninfected_exec) - 1); + strncat(uninfected_exec, uninfected_output_file, sizeof(uninfected_exec) - strlen(uninfected_exec) - 1); - strncpy(infected_exec, "./", 255); - strncat(infected_exec, infected_path, 255); - strncat(infected_exec, redir, 255); - strncat(infected_exec, infected_output_file, 255); + strncpy(infected_exec, "./", sizeof(infected_exec) - 1); + infected_exec[sizeof(infected_exec) - 1] = '\0'; + strncat(infected_exec, infected_path, sizeof(infected_exec) - strlen(infected_exec) - 1); + strncat(infected_exec, redir, sizeof(infected_exec) - strlen(infected_exec) - 1); + strncat(infected_exec, infected_output_file, sizeof(infected_exec) - strlen(infected_exec) - 1); - strncpy(chmod_str, "chmod +x ", 255); - strncat(chmod_str, infected_path, 255); + strncpy(chmod_str, "chmod +x ", sizeof(chmod_str) - 1); + chmod_str[sizeof(chmod_str) - 1] = '\0'; + strncat(chmod_str, infected_path, sizeof(chmod_str) - strlen(chmod_str) - 1); malelf_binary_init(&input); malelf_binary_init(&output); @@ -163,13 +171,18 @@ void test_malelf_infect_silvio_padding(char* malware_path, //Preparing files for the tests input.fname = uninfected_path; output.fname = infected_path; - malware.fname = malware_path_gen; - malware.class = MALELF_FLAT32; - malware_in.class = MALELF_FLAT32; error = malelf_binary_open(&input, uninfected_path); CU_ASSERT(MALELF_SUCCESS == error); + malware.fname = malware_path_gen; + if (input.class == MALELF_ELF32) { + malware.class = MALELF_FLAT32; + } else { + malware.class = MALELF_FLAT64; + } + malware_in.class = malware.class; + error = malelf_binary_open(&malware_in, malware_path); CU_ASSERT(MALELF_SUCCESS == error); @@ -190,12 +203,19 @@ void test_malelf_infect_silvio_padding(char* malware_path, CU_ASSERT(error == MALELF_SUCCESS); //Testing ... - error = malelf_infect_silvio_padding32(&input, - &output, - &malware, - 0, - magic_bytes); - CU_ASSERT(error == MALELF_SUCCESS); + if (input.class == MALELF_ELF32) { + error = malelf_infect_silvio_padding32(&input, + &output, + &malware, + 0, + magic_bytes); + } else { + error = malelf_infect_silvio_padding64(&input, + &output, + &malware, + 0, + magic_bytes); + } if (error != MALELF_SUCCESS) { MALELF_PERROR(error); @@ -238,7 +258,11 @@ void test_malelf_infect_silvio_padding(char* malware_path, void malelf_infect_silvio_padding_TEST(void) { - test_malelf_infect_silvio_padding("malwares/write_message.o", "OWNED BY I4K"); + if ((int)(CHAR_BIT * sizeof(void *)) == 32) { + test_malelf_infect_silvio_padding("malwares/write_message32.o", "OWNED BY I4K"); + } else { + test_malelf_infect_silvio_padding("malwares/write_message64.o", "OWNED BY I4K"); + } } CU_ErrorCode infect_get_test_suite(CU_pSuite *rsuite) diff --git a/test/malwares/Makefile.am b/test/malwares/Makefile.am index 4ec63d3..a393380 100644 --- a/test/malwares/Makefile.am +++ b/test/malwares/Makefile.am @@ -1,9 +1,9 @@ -bin_PROGRAMS = write_message -write_message_SOURCES = write_message.asm +bin_PROGRAMS = write_message32 write_message64 +write_message32_SOURCES = write_message32.asm +write_message64_SOURCES = write_message64.asm + LINK=echo .asm.o: nasm -f bin -I../../src/malware/lib/ -o $@ $< - - diff --git a/test/malwares/list-files.asm b/test/malwares/list-files.asm index b41bdd5..b8aabd0 100644 --- a/test/malwares/list-files.asm +++ b/test/malwares/list-files.asm @@ -3,7 +3,7 @@ ; -%include "inc/syscall.inc.asm" +%include "inc32/syscall.inc.asm" %define PT_LOAD 01 %define O_RDWR 2 diff --git a/test/malwares/write_message.asm b/test/malwares/write_message32.asm similarity index 88% rename from test/malwares/write_message.asm rename to test/malwares/write_message32.asm index 045d8f0..1973c4b 100644 --- a/test/malwares/write_message.asm +++ b/test/malwares/write_message32.asm @@ -1,5 +1,5 @@ BITS 32 - %include "inc/util.inc.asm" + %include "inc32/util.inc.asm" call get_msg db "OWNED BY I4K",0x0a diff --git a/test/malwares/write_message64.asm b/test/malwares/write_message64.asm new file mode 100644 index 0000000..5312e0b --- /dev/null +++ b/test/malwares/write_message64.asm @@ -0,0 +1,20 @@ + BITS 64 + + call get_msg +db "OWNED BY I4K",0x0a +msg: + pop rsi + mov rdx, 13 + mov rdi, 1 + mov rax, 1 + syscall + + xor rax, rax + xor rdi, rdi + xor rsi, rsi + xor rdx, rdx + + jmp exit + +get_msg: jmp msg +exit: