From 4bafbf79e8143941d744c9c47e6fc9216fcec47a Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Wed, 4 Nov 2015 22:02:31 +0000
Subject: Fixed some bugs and defined some first test cases.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@604 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                                 | 15 +++++
 plugins/pychrysa/analysis/contents/file.c |  4 +-
 plugins/pychrysa/format/elf/elf.c         |  9 ++-
 src/format/elf/section.c                  |  3 +
 tests/format/elf/Makefile                 | 16 ++++++
 tests/format/elf/non_existing_binary.py   | 26 +++++++++
 tests/format/elf/oob_section_name.asm     | 94 +++++++++++++++++++++++++++++++
 tests/format/elf/oob_section_name.py      | 24 ++++++++
 8 files changed, 189 insertions(+), 2 deletions(-)
 create mode 100644 tests/format/elf/Makefile
 create mode 100644 tests/format/elf/non_existing_binary.py
 create mode 100644 tests/format/elf/oob_section_name.asm
 create mode 100644 tests/format/elf/oob_section_name.py

diff --git a/ChangeLog b/ChangeLog
index 006f6ce..cf48cf0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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))
-- 
cgit v0.11.2-87-g4458