diff options
-rw-r--r-- | ChangeLog | 15 | ||||
-rw-r--r-- | plugins/pychrysa/analysis/contents/file.c | 4 | ||||
-rw-r--r-- | plugins/pychrysa/format/elf/elf.c | 9 | ||||
-rw-r--r-- | src/format/elf/section.c | 3 | ||||
-rw-r--r-- | tests/format/elf/Makefile | 16 | ||||
-rw-r--r-- | tests/format/elf/non_existing_binary.py | 26 | ||||
-rw-r--r-- | tests/format/elf/oob_section_name.asm | 94 | ||||
-rw-r--r-- | tests/format/elf/oob_section_name.py | 24 |
8 files changed, 189 insertions, 2 deletions
@@ -1,3 +1,18 @@ +15-11-04 Cyrille Bagard <nocbos@gmail.com> + + * plugins/pychrysa/analysis/contents/file.c: + * plugins/pychrysa/format/elf/elf.c: + Improve the Python support code. + + * src/format/elf/section.c: + Better handle invalid strings for section names. + + * tests/format/elf/Makefile: + * tests/format/elf/non_existing_binary.py: + * tests/format/elf/oob_section_name.asm: + * tests/format/elf/oob_section_name.py: + New entries: define some first test cases. + 15-11-03 Cyrille Bagard <nocbos@gmail.com> * configure.ac: diff --git a/plugins/pychrysa/analysis/contents/file.c b/plugins/pychrysa/analysis/contents/file.c index d356197..897561e 100644 --- a/plugins/pychrysa/analysis/contents/file.c +++ b/plugins/pychrysa/analysis/contents/file.c @@ -64,7 +64,9 @@ static PyObject *py_file_content_new(PyTypeObject *type, PyObject *args, PyObjec content = g_file_content_new(filename); result = pygobject_new(G_OBJECT(content)); - g_object_unref(content); + + if (content != NULL) + g_object_unref(content); return result; diff --git a/plugins/pychrysa/format/elf/elf.c b/plugins/pychrysa/format/elf/elf.c index 07e5130..72a9647 100644 --- a/plugins/pychrysa/format/elf/elf.c +++ b/plugins/pychrysa/format/elf/elf.c @@ -28,6 +28,9 @@ #include <pygobject.h> +#include <i18n.h> + + #include <format/elf/elf.h> @@ -67,7 +70,11 @@ static PyObject *py_elf_format_new(PyTypeObject *type, PyObject *args, PyObject if (!ret) return NULL; ret = PyObject_IsInstance(content_obj, (PyObject *)get_python_binary_content_type()); - if (!ret) return NULL; + if (!ret) + { + PyErr_SetString(PyExc_TypeError, _("The argument must be an instance of BinContent.")); + return NULL; + } content = G_BIN_CONTENT(pygobject_get(content_obj)); format = g_elf_format_new(content, NULL); diff --git a/src/format/elf/section.c b/src/format/elf/section.c index 60bd67a..5307928 100644 --- a/src/format/elf/section.c +++ b/src/format/elf/section.c @@ -270,6 +270,9 @@ const char *extract_name_from_elf_string_section(const GElfFormat *format, const result = (const char *)g_binary_content_get_raw_access(content, &pos, 1); + if (result == NULL) + return NULL; + if ((phys + strlen(result)) > last) return NULL; diff --git a/tests/format/elf/Makefile b/tests/format/elf/Makefile new file mode 100644 index 0000000..b14ff47 --- /dev/null +++ b/tests/format/elf/Makefile @@ -0,0 +1,16 @@ + +EXECUTABLES=tiny oob_section_name + +all: $(EXECUTABLES) + +tiny: tiny.o + $(ARM_CROSS)objcopy $< -O binary $@ + +oob_section_name: oob_section_name.o + $(ARM_CROSS)objcopy $< -O binary $@ + +%.o: %.asm + $(ARM_CROSS)as -c $< -o $@ + +clean: + rm -f *.o $(EXECUTABLES) diff --git a/tests/format/elf/non_existing_binary.py b/tests/format/elf/non_existing_binary.py new file mode 100644 index 0000000..47c9028 --- /dev/null +++ b/tests/format/elf/non_existing_binary.py @@ -0,0 +1,26 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + + +# Eprouve quelques mécanismes de construction côté Python. + + +import pychrysalide + +from pychrysalide.analysis.contents import FileContent +from pychrysalide.format.elf import ElfFormat + +cnt = FileContent("non_existing_binary") + +print(cnt) + +print(cnt == None) + +try: + fmt = ElfFormat(cnt) +except TypeError as e: + fmt = None + +print(fmt) + +print(fmt == None) diff --git a/tests/format/elf/oob_section_name.asm b/tests/format/elf/oob_section_name.asm new file mode 100644 index 0000000..ad5b599 --- /dev/null +++ b/tests/format/elf/oob_section_name.asm @@ -0,0 +1,94 @@ + +.macro bump addr + .word \addr + 0x200000 +.endm + +.macro label_offset lbl + .word \lbl - str_table +.endm + + +elf_header: + + .byte 0x7F, 'E', 'L', 'F' @ e_ident + .byte 1 @ EI_CLASS => ELFCLASS32 + .byte 1 @ EI_DATA => ELFDATA2LSB + .byte 1 @ EI_VERSION => EV_CURRENT + .byte 0 @ EI_OSABI => ELFOSABI_SYSV + .byte 0 @ EI_ABIVERSION + + .word 0 + .short 0 + .byte 0 + + .short 2 @ e_type => ET_EXEC + .short 40 @ e_machine => EM_ARM + .word 1 @ e_version => EV_CURRENT + bump main @ e_entry + + .word program_headers @ e_phoff + .word section_headers @ e_shoff + + .word 0x80 @ e_flags => EF_ARM_NEW_ABI + + .short 52 @ e_ehsize + .short 32 @ e_phentsize + .short 1 @ e_phnum + .short 40 @ e_shentsize + .short 2 @ e_shnum + .short 1 @ e_shstrndx + + +program_headers: + + .word 1 @ p_type => PT_LOAD + .word O @ p_offset + .word 0x200000 @ p_vaddr + .word 0x200000 @ p_paddr + .word file_size @ p_filesz + .word file_size @ p_memsz + .word 0x5 @ p_flags => PF_X | PF_R + .word 0x1000 @ p_align + + +section_headers: + + .word 0xa0000000 @ label_offset text_lbl @ sh_name + .word 1 @ sh_type => SHT_PROGBITS + .word 0x6 @ sh_flags => SHF_ALLOC | SHF_EXECINSTR + bump main @ sh_addr + .word main @ sh_offset + .word file_size - main @ sh_size + .word 0 @ sh_link + .word 0 @ sh_info + .word 4 @ sh_addralign + .word 0 @ sh_entsize + + label_offset strtab_lbl @ sh_name + .word 3 @ sh_type => SHT_STRTAB + .word 0x0 @ sh_flags + .word 0x0 @ sh_addr + .word str_table @ sh_offset + .word 0xb0000000 @ sh_size + .word 0 @ sh_link + .word 0 @ sh_info + .word 1 @ sh_addralign + .word 0 @ sh_entsize + + +str_table: + + .byte 0, 0 +text_lbl: + .byte '.', 't', 'e', 'x', 't', 0 +strtab_lbl: + .byte '.', 's', 't', 'r', 't', 'a', 'b', 0 + + +main: + mov r7, #1 @ __NR_exit + mov r0, #42 @ $? + svc 0 + + +file_size: diff --git a/tests/format/elf/oob_section_name.py b/tests/format/elf/oob_section_name.py new file mode 100644 index 0000000..da58e29 --- /dev/null +++ b/tests/format/elf/oob_section_name.py @@ -0,0 +1,24 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + + +# Une section peut avoir un index pour son nom démesurément grand (et invalide). +# +# Si la section des chaînes de caractères est toute aussi grande et invalide, +# l'index invalide reste suffisamment cohérent pour passer les premiers tests +# de extract_name_from_elf_string_section() et conduire ensuite à un plantage +# lors de l'accès concret, au moment de l'appel à strlen(). + + +import pychrysalide + +from pychrysalide.analysis.contents import FileContent +from pychrysalide.format.elf import ElfFormat + +cnt = FileContent("oob_section_name") + +fmt = ElfFormat(cnt) + +print(fmt) + +print(isinstance(fmt, ElfFormat)) |