summaryrefslogtreecommitdiff
path: root/src/format/elf/section.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/format/elf/section.c')
-rw-r--r--src/format/elf/section.c153
1 files changed, 83 insertions, 70 deletions
diff --git a/src/format/elf/section.c b/src/format/elf/section.c
index c619293..940acdf 100644
--- a/src/format/elf/section.c
+++ b/src/format/elf/section.c
@@ -34,9 +34,11 @@
/******************************************************************************
* *
-* Paramètres : format = description de l'exécutable à compléter. *
+* Paramètres : format = description de l'exécutable à consulter. *
+* index = indice de la section recherchée. *
+* section = ensemble d'informations à faire remonter. [OUT] *
* *
-* Description : Charge en mémoire la liste humaine des sections. *
+* Description : Recherche une section donnée au sein de binaire par indice. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -44,25 +46,15 @@
* *
******************************************************************************/
-bool read_elf_section_names(elf_format *format)
+bool find_elf_section_by_index(const GElfFormat *format, uint16_t index, elf_shdr *section)
{
- off_t offset; /* Position des données */
- Elf32_Shdr section; /* Section visée */
-
- offset = format->header.e_shoff + format->header.e_shentsize * format->header.e_shstrndx;
-
- if ((offset + sizeof(Elf32_Shdr)) > EXE_FORMAT(format)->length) return false;
-
- memcpy(&section, &EXE_FORMAT(format)->content[offset], sizeof(Elf32_Shdr));
-
- if ((section.sh_offset + section.sh_size) > EXE_FORMAT(format)->length) return false;
+ off_t offset; /* Emplacement à venir lire */
- format->sec_names = (char *)calloc(section.sh_size + 1, sizeof(char));
- format->sec_size = section.sh_size;
+ if (index >= format->header.e_shnum) return false;
- memcpy(format->sec_names, &EXE_FORMAT(format)->content[section.sh_offset], section.sh_size);
+ offset = ELF_OFF(format, format->header.e_shoff) + format->header.e_shentsize * index;
- return true;
+ return read_elf_section_header(format, offset, section);
}
@@ -81,13 +73,15 @@ bool read_elf_section_names(elf_format *format)
* *
******************************************************************************/
-bool find_elf_section_by_name(const elf_format *format, const char *name, Elf_Shdr *section)
+bool find_elf_section_by_name(const GElfFormat *format, const char *name, elf_shdr *section)
{
- bool result; /* Bilan à retourner */
+ bool result; /* Bilan à faire remonter */
+ elf_shdr strings; /* Section des descriptions */
uint16_t i; /* Boucle de parcours */
+ const char *secname; /* Nom d'une section analysée */
- /* Si on perd notre temps... */
- if (format->sec_size == 0) return false;
+ if (!find_elf_section_by_index(format, format->header.e_shstrndx, &strings))
+ return false;
result = false;
@@ -95,7 +89,10 @@ bool find_elf_section_by_name(const elf_format *format, const char *name, Elf_Sh
{
find_elf_section_by_index(format, i, section);
- result = (strcmp(name, &format->sec_names[ELF_SHDR(format, section, sh_name)]) == 0);
+ secname = extract_name_from_elf_string_section(format, &strings,
+ ELF_SHDR(format, *section, sh_name));
+
+ result = (strcmp(name, secname) == 0);
}
@@ -106,10 +103,9 @@ bool find_elf_section_by_name(const elf_format *format, const char *name, Elf_Sh
/******************************************************************************
* *
-* Paramètres : format = description de l'exécutable à consulter. *
-* type = type de la section recherchée. *
-* sections = tableau d'informations à faire remonter. [OUT] *
-* count = nombre d'éléments présents dans le tableau. [OUT] *
+* Paramètres : format = description de l'exécutable à consulter. *
+* addr = adresse de la section recherchée. (32 bits) *
+* section = ensemble d'informations à faire remonter. [OUT] *
* *
* Description : Recherche une section donnée au sein de binaire par type. *
* *
@@ -119,38 +115,34 @@ bool find_elf_section_by_name(const elf_format *format, const char *name, Elf_Sh
* *
******************************************************************************/
-bool find_elf_section_by_type(const elf_format *format, uint16_t type, Elf_Shdr **sections, size_t *count)
+bool find_elf_section_by_virtual_address(const GElfFormat *format, uint32_t addr, elf_shdr *section)
{
+ bool result; /* Bilan à faire remonter */
uint16_t i; /* Boucle de parcours */
- Elf_Shdr section; /* Section à analyser */
- *sections = NULL;
- *count = 0;
+ result = false;
- for (i = 0; i < format->header.e_shnum; i++)
+ for (i = 0; i < format->header.e_shnum && !result; i++)
{
- find_elf_section_by_index(format, i, &section);
+ find_elf_section_by_index(format, i, section);
- if (type == ELF_SHDR(format, &section, sh_type))
- {
- *sections = (Elf_Shdr *)realloc(*sections, ++(*count) * sizeof(Elf_Shdr));
- (*sections)[*count - 1] = section;
- }
+ result = (addr == ELF_SHDR(format, *section, sh_addr));
}
- return (*count > 0);
+ return result;
}
/******************************************************************************
* *
-* Paramètres : format = description de l'exécutable à consulter. *
-* index = indice de la section recherchée. *
-* section = ensemble d'informations à faire remonter. [OUT] *
+* Paramètres : format = description de l'exécutable à consulter. *
+* type = type de la section recherchée. *
+* sections = tableau d'informations à faire remonter. [OUT] *
+* count = nombre d'éléments présents dans le tableau. [OUT] *
* *
-* Description : Recherche une section donnée au sein de binaire par indice. *
+* Description : Recherche une section donnée au sein de binaire par type. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -158,17 +150,27 @@ bool find_elf_section_by_type(const elf_format *format, uint16_t type, Elf_Shdr
* *
******************************************************************************/
-bool find_elf_section_by_index(const elf_format *format, uint16_t index, Elf_Shdr *section)
+bool find_elf_sections_by_type(const GElfFormat *format, uint32_t type, elf_shdr **sections, size_t *count)
{
- off_t offset; /* Emplacement à venir lire */
+ uint16_t i; /* Boucle de parcours */
+ elf_shdr section; /* Section à analyser */
- if (index >= format->header.e_shnum) return false;
+ *sections = NULL;
+ *count = 0;
- offset = format->header.e_shoff + format->header.e_shentsize * index;
+ for (i = 0; i < format->header.e_shnum; i++)
+ {
+ find_elf_section_by_index(format, i, &section);
- memcpy(section, &EXE_FORMAT(format)->content[offset], ELF_SIZEOF_SHDR(format));
+ if (type == ELF_SHDR(format, section, sh_type))
+ {
+ *sections = (elf_shdr *)realloc(*sections, ++(*count) * sizeof(elf_shdr));
+ (*sections)[*count - 1] = section;
+ }
+
+ }
- return true;
+ return (*count > 0);
}
@@ -179,7 +181,7 @@ bool find_elf_section_by_index(const elf_format *format, uint16_t index, Elf_Shd
* section = section à consulter. *
* offset = position de la section trouvée. [OUT] *
* size = taille de la section trouvée. [OUT] *
-* voffset = adresse virtuelle de la section trouvée. [OUT] *
+* addr = adresse virtuelle de la section trouvée. [OUT] *
* *
* Description : Fournit les adresses et taille contenues dans une section. *
* *
@@ -189,13 +191,13 @@ bool find_elf_section_by_index(const elf_format *format, uint16_t index, Elf_Shd
* *
******************************************************************************/
-void get_elf_section_content(const elf_format *format, const Elf_Shdr *section, off_t *offset, off_t *size, uint64_t *voffset)
+void get_elf_section_content(const GElfFormat *format, const elf_shdr *section, off_t *offset, off_t *size, vmpa_t *addr)
{
- *offset = ELF_SHDR(format, section, sh_offset);
- *size = ELF_SHDR(format, section, sh_size);
+ *offset = ELF_SHDR(format, *section, sh_offset);
+ *size = ELF_SHDR(format, *section, sh_size);
- if (voffset != NULL)
- *voffset = ELF_SHDR(format, section, sh_addr);
+ if (addr != NULL)
+ *addr = ELF_SHDR(format, *section, sh_addr);
}
@@ -206,7 +208,7 @@ void get_elf_section_content(const elf_format *format, const Elf_Shdr *section,
* name = nom de la section recherchée. *
* offset = position de la section trouvée. [OUT] *
* size = taille de la section trouvée. [OUT] *
-* voffset = adresse virtuelle de la section trouvée. [OUT] *
+* address = adresse virtuelle de la section trouvée. [OUT] *
* *
* Description : Recherche une zone donnée au sein de binaire par nom. *
* *
@@ -216,15 +218,15 @@ void get_elf_section_content(const elf_format *format, const Elf_Shdr *section,
* *
******************************************************************************/
-bool find_elf_section_content_by_name(const elf_format *format, const char *name, off_t *offset, off_t *size, uint64_t *voffset)
+bool find_elf_section_content_by_name(const GElfFormat *format, const char *name, off_t *offset, off_t *size, vmpa_t *address)
{
bool result; /* Bilan à retourner */
- Elf_Shdr section; /* Section trouvée ou non */
+ elf_shdr section; /* Section trouvée ou non */
result = find_elf_section_by_name(format, name, &section);
if (result)
- get_elf_section_content(format, &section, offset, size, voffset);
+ get_elf_section_content(format, &section, offset, size, address);
return result;
@@ -234,28 +236,39 @@ bool find_elf_section_content_by_name(const elf_format *format, const char *name
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à consulter. *
-* index = indice de la section recherchée. *
-* offset = position de la section trouvée. [OUT] *
-* size = taille de la section trouvée. [OUT] *
-* voffset = adresse virtuelle de la section trouvée. [OUT] *
+* section = section contenant des chaînes terminées par '\0'. *
+* index = indice du premier caractères à cerner. *
* *
-* Description : Recherche une zone donnée au sein de binaire par indice. *
+* Description : Identifie une chaîne de caractères dans une section adéquate.*
* *
-* Retour : Bilan de l'opération. *
+* Retour : Pointeur vers la chaîne recherchée ou NULL en cas d'échec. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool find_elf_section_content_by_index(const elf_format *format, uint16_t index, off_t *offset, off_t *size, uint64_t *voffset)
+const char *extract_name_from_elf_string_section(const GElfFormat *format, const elf_shdr *section, uint16_t index)
{
- bool result; /* Bilan à retourner */
- Elf_Shdr section; /* Section trouvée ou non */
+ const char *result; /* Nom trouvé à renvoyer */
+ const bin_t *content; /* Contenu binaire à lire */
+ off_t length; /* Taille totale du contenu */
+ off_t last; /* Dernier '\0' possible */
+ off_t pos; /* Point de lecture */
- result = find_elf_section_by_index(format, index, &section);
+ content = G_BIN_FORMAT(format)->content;
+ length = G_BIN_FORMAT(format)->length;
- if (result)
- get_elf_section_content(format, &section, offset, size, voffset);
+ last = ELF_SHDR(format, *section, sh_offset) + ELF_SHDR(format, *section, sh_size);
+
+ pos = ELF_SHDR(format, *section, sh_offset) + index;
+
+ if ((pos + 1) >= MIN(length, last))
+ return NULL;
+
+ result = (const char *)&content[pos];
+
+ if ((pos + strlen(result)) > last)
+ return NULL;
return result;