From 99a30bc3dc5d9cd162977b27a50425f4ce297796 Mon Sep 17 00:00:00 2001 From: "Konychev, Valerii" Date: Fri, 15 Mar 2024 19:15:09 +0100 Subject: [PATCH] Refactor elf64Prase. --- .vscode/settings.json | 3 +- cTools/include/sys/elf64.h | 8 +- .../arch/aarch64/test/aarch64_code_move.c | 3 +- cTools/libs/binDynMod/test/binDynModTest.c | 2 +- cTools/libs/binParse/elfParse/elf64Parse.c | 514 ++++++------------ cTools/libs/binParse/elfParse/elf64Parse.h | 460 +++++++--------- cTools/libs/string/string.c | 16 +- cTools/libs/string/string.h | 30 +- 8 files changed, 420 insertions(+), 616 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index de395d0..8e8a371 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -129,7 +129,8 @@ "charconv": "cpp", "__locale": "c", "bindynmod.h": "c", - "windows.h": "c" + "windows.h": "c", + "stdint.h": "c" }, "C_Cpp.errorSquiggles": "enabled", diff --git a/cTools/include/sys/elf64.h b/cTools/include/sys/elf64.h index ad7e763..6ba06a1 100644 --- a/cTools/include/sys/elf64.h +++ b/cTools/include/sys/elf64.h @@ -149,9 +149,9 @@ typedef struct { /* Relocations that need an addend field. */ typedef struct { - Elf64_Addr r_offset; /* Location to be relocated. */ - Elf64_Xword r_info; /* Relocation type and symbol index. */ - Elf64_Sxword r_addend; /* Addend. */ + Elf64_Addr r_offset; /* Location to be relocated. */ + Elf64_Xword r_info; /* Relocation type and symbol index. */ + Elf64_Sxword r_addend; /* Addend. */ } Elf64_Rela; /* Macros for accessing the fields of r_info. */ @@ -176,7 +176,7 @@ typedef Elf_Note Elf64_Nhdr; */ typedef struct { Elf64_Lword m_value; /* symbol value */ - Elf64_Xword m_info; /* size + index */ + Elf64_Xword m_info; /* size + index */ Elf64_Xword m_poffset; /* symbol offset */ Elf64_Half m_repeat; /* repeat count */ Elf64_Half m_stride; /* stride info */ diff --git a/cTools/libs/arch/aarch64/test/aarch64_code_move.c b/cTools/libs/arch/aarch64/test/aarch64_code_move.c index 8b8e915..73eed04 100644 --- a/cTools/libs/arch/aarch64/test/aarch64_code_move.c +++ b/cTools/libs/arch/aarch64/test/aarch64_code_move.c @@ -102,8 +102,7 @@ void call_func6(uint32_t *n) } extern -void test_move_and_exec(void *func, const char *fn, void *arg);// __attribute__((section("__TEXT,__my_sect"))); - +void test_move_and_exec(void *func, const char *fn, void *arg); void test_move_and_exec(void *func, const char *fn, void *arg) { BinSymPtr sym = binParser.getSymByName(binParser.bin, fn); diff --git a/cTools/libs/binDynMod/test/binDynModTest.c b/cTools/libs/binDynMod/test/binDynModTest.c index 5492028..f2a214c 100644 --- a/cTools/libs/binDynMod/test/binDynModTest.c +++ b/cTools/libs/binDynMod/test/binDynModTest.c @@ -1,7 +1,7 @@ /*** * MIT License * - * Copyright (c) 2021-2023 Konychev Valerii + * Copyright (c) 2021-2024 Konychev Valerii * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/cTools/libs/binParse/elfParse/elf64Parse.c b/cTools/libs/binParse/elfParse/elf64Parse.c index 082643f..05e5fae 100755 --- a/cTools/libs/binParse/elfParse/elf64Parse.c +++ b/cTools/libs/binParse/elfParse/elf64Parse.c @@ -1,7 +1,7 @@ /*** * MIT License * - * Copyright (c) 2021-2023 Konychev Valerii + * Copyright (c) 2021-2024 Konychev Valerii * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -33,7 +33,12 @@ /* c standard headers */ #include -static ELF64_ERROR elf64ParseArch(Elf64File *elf64) +/*** + * @brief parse machine acritecture + * + * @param[in,out] elf64 elf64File descriptor + */ +static void elf64ParseArch(Elf64File *elf64) { switch (elf64->header->e_machine) { case EM_386: @@ -52,32 +57,19 @@ static ELF64_ERROR elf64ParseArch(Elf64File *elf64) elf64->arch = UNKNOWN_ARCH; break; } - - return ELF64_OK; } /*** - * Before: - * If you need a file position, you should to save it. - * Description: - * Function returns elf64 header, which is readed from file with descriptor @fd. - * Input: - * @fd - target elf64File descriptor. - * Output: - * Success: - * ELF64_OK - * Fail: - * ELF64_INV_ARG, ELF64_NO_MEM, ELF64_NO_HEADER - * After: - * need to free memory. + * @brief parse elf64 header + * + * @param[in,out] elf64 elf64File descriptor + * + * @return ELF64_OK or ELF64_NO_HEADER */ static ELF64_ERROR elf64ParseHeader(Elf64File *elf64) { - if (elf64 == NULL || IS_INV_FD(elf64->fd)) - return ELF64_INV_ARG; - uint64_t ehOff = 0; - Elf64Ehdr *header = (Elf64Ehdr*)((uint8_t*)elf64->faddr + ehOff); + Elf64Ehdr *header = (Elf64Ehdr*)(elf64->faddr + ehOff); unsigned char *eIdent = header->e_ident; if ( eIdent[EI_MAG0] == '\x7f' && eIdent[EI_MAG1] == 'E' && eIdent[EI_MAG2] == 'L' && eIdent[EI_MAG3] == 'F' @@ -91,29 +83,15 @@ static ELF64_ERROR elf64ParseHeader(Elf64File *elf64) } } - /*** - * Before: - * If you need a file position, you should to save it. - * Input: - * @elf64 - point to target elf64File structure with initialized fields: fd and - * elf64Header. - * Output: - * Success: - * ELF64_OK - * Fail: - * ELF64_INV_ARG, ELF64_NO_MEM, ELF64_NO_SECTIONS - * After all: - * need to free memory. + * @brief parse elf sections + * + * @param[in,out] elf64 pointer to Elf64File + * + * @return ELF64_OK or ELF64_NO_SECTIONS */ static ELF64_ERROR elf64ParseSections(Elf64File *elf64) { - /*** - * Sections are identified by an index into the section header table. - */ - if (elf64 == NULL || elf64->header == NULL || IS_INV_FD(elf64->fd)) - return ELF64_INV_ARG; - /*** * e_shoff - contains the file offset, in bytes, of the section header * table. @@ -128,65 +106,43 @@ static ELF64_ERROR elf64ParseSections(Elf64File *elf64) uint64_t eShOff = elf64->header->e_shoff; uint64_t shNum = elf64->header->e_shnum; if (shNum == SHN_UNDEF) { - Elf64Shdr *sect0 = (Elf64Shdr*)((uint8_t*)elf64->faddr + eShOff); + Elf64Shdr *sect0 = (Elf64Shdr*)(elf64->faddr + eShOff); if (sect0->sh_size == 0) { return ELF64_NO_SECTIONS; } } - elf64->sections = (Elf64Shdr*)((uint8_t*)elf64->faddr + eShOff); + elf64->sections = (Elf64Shdr*)(elf64->faddr + eShOff); return ELF64_OK; } - /*** - * Before: - * If you need a file position, you should to save it. - * Input: - * @elf64 - point to target elf64File structure with initialized fields: fd and - * elf64Header. - * Output: - * Success: - * ELF64_OK - * Fail: - * ELF64_INV_ARG, ELF64_NO_MEM, ELF64_NO_SEGMENTS - * After all: - * need to free memory. + * @brief parse segments + * + * @param[in,out] elf64 pointer to Elf64File + * + * @return ELF64_OK or ELF64_NO_SEGMENTS */ static ELF64_ERROR elf64ParseSegments(Elf64File *elf64) { - if (elf64 == NULL || IS_INV_FD(elf64->fd) || elf64->header == NULL) - return ELF64_INV_ARG; - uint64_t phoff = elf64->header->e_phoff; uint64_t phnum = elf64->header->e_phnum; if (phnum == 0) return ELF64_NO_SEGMENTS; - elf64->segments = (Elf64Phdr*)((uint8_t*)elf64->faddr + phoff); + elf64->segments = (Elf64Phdr*)(elf64->faddr + phoff); return ELF64_OK; } - /*** - * Before: - * If you need a file position, you should to save it. - * Input: - * @elf64 - Elf64File structer with initialized fields: fd, elf64Header and - * sectionHeaders. - * Output: - * Success: - * ELF64_OK - * Fail: - * ELF64_INV_ARG, ELF64_NO_MEM, ELF64_NO_SYMTAB - * After: - * need to free memory + * @brief parse symbol tab + * + * @param[in,out] elf64 pointer to Elf64File + * + * @return ELF64_OK or ELF64_NO_SYMTAB */ static ELF64_ERROR elf64ParseSymTab(Elf64File *elf64) { - if (elf64 == NULL) - return ELF64_INV_ARG; - /*** * SHT_SYMTAB - Contains a linker symbol table. */ @@ -194,30 +150,20 @@ static ELF64_ERROR elf64ParseSymTab(Elf64File *elf64) if (symtab == NULL) return ELF64_NO_SYMTAB; - elf64->symtab = (Elf64Sym*)((uint8_t*)elf64->faddr + symtab->sh_offset); + elf64->symtab = (Elf64Sym*)(elf64->faddr + symtab->sh_offset); elf64->symnum = symtab->sh_size/sizeof(Elf64Sym); return ELF64_OK; } /*** - * Before: - * If you need a file position, you should to save it. - * Input: - * elf64 - Elf64File structer with initialized fields: fd, elf64Header and - * sectionHeaders. - * Output: - * Success: - * ELF64_OK - * Fail: - * ELF64_INV_ARG, ELF64_NO_MEM, ELF64_NO_DYNSYM - * After all: - * need to free memory + * @brief parse dynamic symbol table + * + * @param[in,out] elf64 pointer to Elf64File + * + * @return ELF64_OK or ELF64_NO_DYNSYM */ static ELF64_ERROR elf64ParseDynSym(Elf64File *elf64) { - if (elf64 == NULL) - return ELF64_INV_ARG; - /*** * SHT_DYNSYM - Contains a dynamic loader symbol table. */ @@ -225,30 +171,20 @@ static ELF64_ERROR elf64ParseDynSym(Elf64File *elf64) if (dynsym == NULL) return ELF64_NO_DYNSYM; - elf64->dynsym = (Elf64Sym*)((uint8_t*)elf64->faddr + dynsym->sh_offset); + elf64->dynsym = (Elf64Sym*)(elf64->faddr + dynsym->sh_offset); elf64->dynsymnum = dynsym->sh_size/sizeof(Elf64Sym); return ELF64_OK; } /*** - * Before: - * If you need a file position, you should to save it. - * Input: - * @elf64 - Elf64File structer with initialized fields: fd, elf64Header and - * sectionHeaders. - * Output: - * Success: - * ELF64_OK - * Fail: - * ELF64_INV_ARG, ELF64_NO_MEM, ELF64_NO_SYMBOLS - * After all: - * need to free memory + * @brief parse symbols static and dynamic + * + * @param[in,out] elf64 pointer to Elf64File + * + * @return ELF64_OK or ELF64_NO_SYMBOLS */ static ELF64_ERROR elf64ParseSymbols(Elf64File *elf64) { - if (elf64 == NULL) - return ELF64_INV_ARG; - elf64ParseSymTab(elf64); elf64ParseDynSym(elf64); @@ -259,24 +195,14 @@ static ELF64_ERROR elf64ParseSymbols(Elf64File *elf64) } /*** - * Before: - * If you need a file position, you should to save it. - * Input: - * @elf64 - Elf64File structer with initialized fields: fd, elf64Header and - * sectionHeaders. - * Output: - * Success: - * ELF64_OK - * Fail: - * ELF64_INV_ARG, ELF64_NO_MEM, ELF64_NO_SH_NAME_TAB - * After: - * need to free memory. You should to be careful, see Symbols structure. + * @brief parse section name table + * + * @param[in,out] elf64 pointer to Elf64File + * + * @return ELF64_OK or ELF64_NO_SH_NAME_TAB */ static ELF64_ERROR elf64ParseSectNameTab(Elf64File *elf64) { - if (elf64 == NULL || elf64->header == NULL || elf64->sections == NULL) - return ELF64_INV_ARG; - /*** * e_shstrndx - contains the section header table index of the * section containing the section name string table. @@ -288,105 +214,67 @@ static ELF64_ERROR elf64ParseSectNameTab(Elf64File *elf64) return ELF64_NO_SH_NAME_TAB; Elf64Shdr *nameTab = &elf64->sections[shStrNdx]; - elf64->sectNameTab = (char*)((uint8_t*)elf64->faddr + nameTab->sh_offset); + elf64->sectNameTab = (char*)(elf64->faddr + nameTab->sh_offset); return ELF64_OK; } - /*** - * Before: - * If you need a file position, you should to save it. - * Input: - * @elf64 - Elf64File structer with initialized fields: fd, elf64Header and - * sectionHeaders. - * Output: - * Success: - * ELF64_OK - * Fail: - * ELF64_INV_ARG, ELF64_NO_MEM, ELF64_NO_SYM_NAME_TAB - * After: - * need to free memory + * @brief parse symbol name table + * + * @param[in,out] elf64 pointer to Elf64File + * + * @return ELF64_OK or ELF64_NO_SYM_NAME_TAB */ static ELF64_ERROR elf64ParseSymNameTab(Elf64File *elf64) { - if (elf64 == NULL) - return ELF64_INV_ARG; - Elf64Shdr *strtab = elf64GetSectByName(elf64, STRTAB); if (strtab == NULL) return ELF64_NO_SYM_NAME_TAB; - elf64->symNameTab = (char*)((uint8_t*)elf64->faddr + strtab->sh_offset); + elf64->symNameTab = (char*)(elf64->faddr + strtab->sh_offset); return ELF64_OK; } /*** - * Before: - * If you need a file position, you should to save it. - * Input: - * @elf64 - Elf64File structer with initialized fields: fd, elf64Header and - * sectionHeaders. - * Output: - * Success: - * ELF64_OK - * Fail: - * ELF64_INV_ARG, ELF64_NO_MEM, ELF64_NO_DYN_SYM_NAME_TAB - * After: - * need to free memory + * @brief parse dynamic symbol name table + * + * @param[in,out] elf64 pointer to Elf64File + * + * @return ELF64_OK or ELF64_NO_DYN_SYM_NAME_TAB */ static ELF64_ERROR elf64ParseDynSymNameTab(Elf64File *elf64) { - if (elf64 == NULL) - return ELF64_INV_ARG; - Elf64Shdr *dynSymTab = elf64GetSectByName(elf64, DYNSTR); if (dynSymTab == NULL) return ELF64_NO_DYN_SYM_NAME_TAB; - elf64->dynSymNameTab = (char*)((uint8_t*)elf64->faddr + dynSymTab->sh_offset); + elf64->dynSymNameTab = (char*)(elf64->faddr + dynSymTab->sh_offset); return ELF64_OK; } /*** - * Before: - * If you need a file position, you should to save it. - * Input: - * @elf64 - Elf64File structer with initialized fields: fd, elf64Header and - * sectionHeaders. - * Output: - * Success: - * ELF64_OK - * Fail: - * ELF64_INV_ARG, ELF64_NO_MEM, ELF64_NO_RELAPLT - * After: - * need to free memory + * @brief parse rela plt table + * + * @param[in,out] elf64 pointer to Elf64File + * + * @return ELF64_OK or ELF64_NO_RELAPLT */ static ELF64_ERROR elf64ParseRelaPlt(Elf64File *elf64) { - if (elf64 == NULL || elf64->fn == NULL) - return ELF64_INV_ARG; - Elf64Shdr *relaplt = elf64GetSectByName(elf64, RELAPLT); if (relaplt == NULL) return ELF64_NO_RELAPLT; - elf64->relaplt = (Elf64Rel*)((uint8_t*)elf64->faddr + relaplt->sh_offset); + elf64->relaplt = (Elf64Rel*)(elf64->faddr + relaplt->sh_offset); return ELF64_OK; } /*** - * Before: - * If you need a file position, you should to save it. - * Input: - * @elf64 - Elf64File structer with initialized fields: fd, elf64Header and - * sectionHeaders. - * Output: - * Success: - * ELF64_OK - * Fail: - * ELF64_INV_ARG, ELF64_NO_MEM, ELF64_NO_RELADYN - * After: - * need to free memory + * @brief parse rela dyn table + * + * @param[in,out] elf64 pointer to Elf64File + * + * @return ELF64_OK or ELF64_NO_RELADYN */ static ELF64_ERROR elf64ParseRelaDyn(Elf64File *elf64) { @@ -397,285 +285,245 @@ static ELF64_ERROR elf64ParseRelaDyn(Elf64File *elf64) if (reladyn == NULL) return ELF64_NO_RELADYN; - elf64->reladyn = (Elf64Rel*)((uint8_t*)elf64->faddr + reladyn->sh_offset); + elf64->reladyn = (Elf64Rel*)(elf64->faddr + reladyn->sh_offset); return ELF64_OK; } +/*** + * @brief parse dynamic section info + * + * @param[in,out] elf64 pointer to Elf64File + * + * @return ELF64_OK or ELF64_NO_DYNAMIC +*/ static ELF64_ERROR elf64ParseDynamic(Elf64File *elf64) { Elf64Shdr *dyn = elf64GetSectByType(elf64, SHT_DYNAMIC); if (dyn == NULL) return ELF64_NO_DYNAMIC; - elf64->dynamic = (Elf64Dyn*)((uint8_t*)elf64->faddr + dyn->sh_offset); + elf64->dynamic = (Elf64Dyn*)(elf64->faddr + dyn->sh_offset); int64_t i = -1; while (elf64->dynamic[++i].d_tag != DT_STRTAB); uint64_t vaddr = elf64->dynamic[i].d_un.d_val; - i = -1; - while (elf64->dynamic[++i].d_tag != DT_STRSZ); Elf64Shdr *sect = elf64GetSectByAddr(elf64, vaddr); if (sect == NULL) return ELF64_NO_DYNAMIC; size_t off = sect->sh_offset + vaddr - sect->sh_addr; - elf64->dtStrTab = (char*)((uint8_t*)elf64->faddr + off); + elf64->dtStrTab = (char*)(elf64->faddr + off); return ELF64_OK; } Elf64File *elf64Parse(const char *fn) { if (fn == NULL) { - LOG_ERROR("Invalid arguments"); - return NULL; + LOG_ERROR("Invalid file name"); + goto eexit0; } - LOG("start elf64Parse\n") - FileD fd = open(fn, O_RDONLY); - if (IS_INV_FD(fd)) { - PERROR("open()"); - return NULL; + Elf64File *elf64 = (Elf64File*) Calloc(1, sizeof(Elf64File)); + if (elf64 == NULL) { + LOG_ERROR("Cannot allocate %zu bytes", sizeof(Elf64File)); + goto eexit0; } - size_t fs = get_file_size(fd); - if (fs == (size_t) -1) { - close(fd); - return NULL; + elf64->fd = open(fn, O_RDONLY); + if (IS_INV_FD(elf64->fd)) { + PERROR("open()"); + goto eexit1; } - void *faddr = map_file(fd, fs, PROT_READ); - if (faddr == NULL) { - LOG_ERROR("Cannot map file"); - close(fd); - return NULL; + elf64->fs = get_file_size(elf64->fd); + if (elf64->fs == (size_t) -1) { + LOG_ERROR("Cannot get file size"); + goto eexit1; } - Elf64File *elf64 = (Elf64File*) Calloc(1, sizeof(Elf64File)); - if (elf64 == NULL) { - LOG_ERROR("Cannot allocate %zu bytes", sizeof(Elf64File)); - close(fd); - unmap_file(faddr, fs); - goto eexit_0; + elf64->faddr = (uint8_t*)map_file(elf64->fd, elf64->fs, PROT_READ); + if (elf64->faddr == NULL) { + LOG_ERROR("Cannot map file"); + goto eexit1; } - elf64->fs = fs; - elf64->faddr = faddr; - elf64->fd = fd; uint64_t nameSize = strlen(fn) * sizeof(char); if ((elf64->fn = (char*) Calloc(nameSize, sizeof(char))) == NULL) { LOG_ERROR("Cannot allocate %"PRIu64" bytes", nameSize); - goto eexit_1; + goto eexit1; } strncpy(elf64->fn, fn, nameSize); if (elf64ParseHeader(elf64)) { LOG_ERROR("Cannot parse elf64 header"); - goto eexit_1; + goto eexit1; } if (elf64ParseSections(elf64)) { if (IS_ELF64_FILE_OBJ(elf64)) { /* Object file must have sections for linker */ LOG_ERROR("There is no section headers table"); - goto eexit_1; - } else - WARNING("There is no section headers table"); + goto eexit1; + } } if (elf64ParseSegments(elf64)) { if (IS_ELF64_FILE_EXEC(elf64)) { /* Exec file must have segments for loader */ LOG_ERROR("There are no program headers"); - goto eexit_1; - } else - WARNING("There are no program headers"); + goto eexit1; + } } if (elf64ParseSymbols(elf64)) { if (IS_ELF64_FILE_OBJ(elf64)) { /* Object file must have symbols for linker */ LOG_ERROR("There is no symbols table"); - goto eexit_1; - } else - WARNING("There is no symbols table"); + goto eexit1; + } } if (elf64ParseSectNameTab(elf64)) { - if (elf64->symtab || elf64->dynsym) { + if (elf64->sections) { LOG_ERROR("There is no section name table"); - goto eexit_1; - } else - WARNING("There is no section name table"); + goto eexit1; + } } if (elf64ParseSymNameTab(elf64)) { if (elf64->symtab || elf64->dynsym) { LOG_ERROR("Cannot parse symbol name table."); - goto eexit_1; - } else - WARNING("Cannot parse symbol name table."); + goto eexit1; + } } if (elf64ParseDynSymNameTab(elf64)) { - if (elf64->dynsym != NULL) { + if (elf64->dynsym) { LOG_ERROR("Cannot parse dynamic symbol name table."); - goto eexit_1; - } else - WARNING("Cannot parse dynamic symbol name table."); + goto eexit1; + } } if (elf64ParseRelaPlt(elf64)) { if (elf64->dynsym) { LOG_ERROR("There is no " RELAPLT " table"); - goto eexit_1; - } else - WARNING("There is no " RELAPLT " table"); + goto eexit1; + } } if (elf64ParseRelaDyn(elf64)) { if (elf64->dynsym) { LOG_ERROR("There is no " RELADYN " table"); - goto eexit_1; - } else - WARNING("There is no " RELADYN " table"); + goto eexit1; + } } - elf64ParseDynamic(elf64); + if (elf64ParseDynamic(elf64)) { + if (elf64->dynsym) { + LOG_ERROR("There is no dynamic section"); + goto eexit1; + } + } return elf64; -eexit_1: +eexit1: elf64Free(elf64); - return NULL; -eexit_0: - close(fd); +eexit0: return NULL; } - void elf64Free(Elf64File *elf64) { if (elf64 == NULL) { - LOG_ERROR("Try to free NULL ptr stuct"); return; } - - LOG("start elf64Free"); - if (IS_VLD_FD(elf64->fd)) { - LOG("close file"); close(elf64->fd); - elf64->fd = 0; } - if (elf64->fn != NULL) { - LOG("free file name"); Free(elf64->fn); - elf64->fn = NULL; } - if (elf64->faddr) { unmap_file(elf64->faddr, elf64->fs); - elf64->faddr = NULL; - elf64->fs = (size_t)-1; } - LOG("end elf64Free"); + memset_s(elf64, sizeof(elf64), 0xFF, sizeof(elf64)); Free(elf64); } - ELF64_ERROR elf64Check(const Elf64File *elf64) { if (elf64 == NULL) { - LOG_ERROR("Invalid arguments"); return ELF64_INV_ARG; } if (elf64->header == NULL) { - LOG_ERROR("Uninitialized field elf64->header."); return ELF64_NO_HEADER; } if (elf64->segments == NULL) { if (IS_ELF64_FILE_EXEC(elf64)) { - LOG_ERROR("Uninitialized field elf64->segments."); return ELF64_NO_SEGMENTS; - } else - WARNING("Uninitialized field elf64->segments."); + } } if (elf64->sections == NULL) { if (IS_ELF64_FILE_OBJ(elf64)) { - LOG_ERROR("Uninitialized field elf64->sections."); return ELF64_NO_SECTIONS; - } else - WARNING("Uninitialized field elf64->sections."); + } } if (elf64->symtab == NULL) { if (IS_ELF64_FILE_OBJ(elf64)) { - LOG_ERROR("Uninitialized field elf64->symtab."); return ELF64_NO_SYMTAB; - } else - WARNING("Uninitialized field elf64->symtab."); + } } - if (elf64->dynsym == NULL) - WARNING("Uninitialized field elf64->dynsym.\n"); - if (elf64->relaplt == NULL) { if (elf64->dynsym != NULL) { - LOG_ERROR("Uninitialized field elf64->relTabs.relaplt."); return ELF64_NO_RELAPLT; - } else - WARNING("Uninitialized field elf64->relTabs.relaplt.\n"); + } } if (elf64->reladyn == NULL) { if (elf64->dynsym != NULL) { - LOG_ERROR("Uninitialized field elf64->relTabs.reladyn."); return ELF64_NO_RELADYN; - } else - WARNING("Uninitialized field elf64->relTabs.reladyn.\n"); + } } if (elf64->sectNameTab == NULL) { if (elf64->symtab) { - LOG_ERROR("Uninitialized field elf64->sectNameTab."); return ELF64_NO_SH_NAME_TAB; - } else - WARNING("Uninitialized field elf64->sectNameTab."); + } } - if (elf64->symNameTab == NULL) { + if (elf64->symNameTab == NULL) { if (elf64->symtab != NULL) { - LOG_ERROR("Uninitialized field elf64->symNameTab."); return ELF64_NO_SYM_NAME_TAB; - } else { - WARNING("Uninitialized field elf64->symNameTab.\n"); } } - if (elf64->dynSymNameTab == NULL) { + if (elf64->dynSymNameTab == NULL) { if (elf64->dynsym != NULL) { - LOG_ERROR("Uninitialized field elf64->dynSymNameTab."); return ELF64_NO_DYN_SYM_NAME_TAB; - } else { - WARNING("Uninitialized field elf64->dynSymNameTab.\n"); + } + } + + if (elf64->dynamic == NULL) { + if (elf64->dynsym) { + return ELF64_NO_DYNAMIC; } } return ELF64_OK; } - Elf64Sym *elf64GetSymByName(const Elf64File *elf64, const char *name) { if (elf64Check(elf64) || name == NULL) { - LOG_ERROR("Invalid arguments"); return NULL; } @@ -700,31 +548,32 @@ Elf64Sym *elf64GetSymByName(const Elf64File *elf64, const char *name) return (Elf64Sym*) &elf64->symtab[i]; } - WARNING("There is no symbol %s.", name); return NULL; } - char *elf64GetSymName(const Elf64File *elf64, const Elf64Sym *sym) { if (elf64Check(elf64) || sym == NULL) { - LOG_ERROR("Invalid arguments"); return NULL; } return (char*)((uint64_t)elf64->symNameTab + sym->st_name); } - char *elf64GetDSymName(const Elf64File *elf64, const Elf64Sym *sym) { + if (elf64Check(elf64) || sym == NULL) { + return NULL; + } + return (char*)((uint64_t)elf64->dynSymNameTab + sym->st_name); } - int elf64CmpSym(const void *a, const void *b) { - int64_t distance = (int64_t)(((const Elf64Sym*)a)->st_value - ((const Elf64Sym*)b)->st_value); + const Elf64Sym *sym_a = (const Elf64Sym*)a; + const Elf64Sym *sym_b = (const Elf64Sym*)b; + int64_t distance = (int64_t)(sym_a->st_value - sym_b->st_value); if (distance > 0) return 1; else if (distance < 0) @@ -733,31 +582,27 @@ int elf64CmpSym(const void *a, const void *b) return 0; } - Elf64Sym *elf64GetSSymTab(const Elf64File *elf64) { if (elf64 == NULL) { - LOG_ERROR("Invalid arguments"); return NULL; } return elf64->symtab; } -Elf64Sym *elf64GetDSymTab(const Elf64File *elf) +Elf64Sym *elf64GetDSymTab(const Elf64File *elf64) { - if (elf == NULL || elf->dynsym == NULL) { - LOG_ERROR("Invalid arguments"); + if (elf64 == NULL) { return NULL; } - return elf->dynsym; + return elf64->dynsym; } uint64_t elf64GetAmountSSym(const Elf64File *elf64) { if (elf64 == NULL) { - LOG_ERROR("Invalid arguments"); return ELF64_INV_ARG; } @@ -767,7 +612,6 @@ uint64_t elf64GetAmountSSym(const Elf64File *elf64) uint64_t elf64GetAmountDSym(const Elf64File *elf) { if (elf == NULL) { - LOG_ERROR("Invalid arguments"); return ELF64_INV_ARG; } @@ -777,18 +621,15 @@ uint64_t elf64GetAmountDSym(const Elf64File *elf) uint64_t elf64GetSSymAddr(const Elf64Sym *sym) { if (sym == NULL) { - LOG_ERROR("Invalid arguments"); return ELF64_INV_ARG; } return sym->st_value; } - uint64_t elf64GetAddrSymByName(const Elf64File *elf64, const char *name) { if (elf64Check(elf64) || name == NULL) { - LOG_ERROR("Invalid arguments"); return ELF64_INV_ARG; } @@ -796,22 +637,18 @@ uint64_t elf64GetAddrSymByName(const Elf64File *elf64, const char *name) return elf64GetSymByName(elf64, name)->st_value; } - uint64_t elf64GetSSymSize(const Elf64File *elf64, const Elf64Sym *sym) { if (elf64 == NULL || sym == NULL) { - LOG_ERROR("Invalid arguments"); return ELF64_INV_ARG; } return sym->st_size; } - uint64_t elf64GetSSymFileoff(const Elf64File *elf64, const Elf64Sym *sym) { if (elf64Check(elf64) || sym == NULL) { - LOG_ERROR("Invalid arguments"); return ELF64_INV_ARG; } @@ -821,11 +658,9 @@ uint64_t elf64GetSSymFileoff(const Elf64File *elf64, const Elf64Sym *sym) return sym->st_value - diff; } - uint64_t elf64GetDSymIndxByName(const Elf64File *elf64, const char *name) { if (elf64Check(elf64) || name == NULL) { - LOG_ERROR("Invalid arguments"); return ELF64_INV_ARG; } @@ -843,25 +678,22 @@ uint64_t elf64GetDSymIndxByName(const Elf64File *elf64, const char *name) return ELF64_NO_SYMBOL; } - uint64_t elf64GetAmountSeg(const Elf64File *elf64) { if (elf64Check(elf64)) { - LOG_ERROR("Invalid argument"); return ELF64_INV_ARG; } return elf64->header->e_phnum; } - Elf64Shdr *elf64GetSectByType(const Elf64File *elf64, const Elf64Word shType) { if ( elf64 == NULL || elf64->header == NULL || elf64->sections == NULL - ) { - LOG_ERROR("Invalid arguments"); + ) + { return NULL; } @@ -878,15 +710,14 @@ Elf64Shdr *elf64GetSectByType(const Elf64File *elf64, const Elf64Word shType) return NULL; } - Elf64Shdr *elf64GetSectByName(const Elf64File *elf64, const char* name) { if ( elf64 == NULL || elf64->header == NULL || elf64->sections == NULL || name == NULL - ) { - LOG_ERROR("Invalid arguments"); + ) + { return NULL; } @@ -911,6 +742,10 @@ Elf64Shdr *elf64GetSectByName(const Elf64File *elf64, const char* name) Elf64Shdr *elf64GetSectByAddr(const Elf64File *elf64, uint64_t addr) { + if (elf64Check(elf64)) { + return NULL; + } + uint64_t i = 0; uint64_t shnum = elf64->header->e_shnum; for (i = 0; i < shnum; ++i) { @@ -926,27 +761,24 @@ Elf64Shdr *elf64GetSectByAddr(const Elf64File *elf64, uint64_t addr) Elf64Shdr *elf64GetLastLoadableSect(const Elf64File *elf64) { if (elf64Check(elf64)) { - LOG_ERROR("Invalid argument"); return NULL; } uint64_t i = elf64GetAmountSect(elf64) - 1; if (i == (uint64_t)-1) { - WARNING("Can not get section amount."); return NULL; } + for (;i != (uint64_t)-1; --i) if (elf64->sections[i].sh_addr) return &elf64->sections[i]; - WARNING("There are no loadable sections."); return NULL; } void *elf64ReadSect(const Elf64File *elf64, const Elf64Shdr *sectionHeader) { if (elf64 == NULL || IS_INV_FD(elf64->fd) || sectionHeader == NULL) { - LOG_ERROR("Invalid arguments"); return NULL; } @@ -961,18 +793,15 @@ void *elf64ReadSect(const Elf64File *elf64, const Elf64Shdr *sectionHeader) void *section = readFromFile(fd, (size_t*)&shOffset, shSize); if (section == NULL) { - LOG_ERROR("Cannot read from file."); return NULL; } return section; } - uint64_t elf64GetAmountSect(const Elf64File *elf64) { if (elf64Check(elf64)) { - LOG_ERROR("Invalid argument"); return ELF64_INV_ARG; } @@ -983,7 +812,6 @@ uint64_t elf64GetAmountSect(const Elf64File *elf64) const char* elf64GetSectName(const Elf64File *elf64, const Elf64Shdr *sect) { if (elf64Check(elf64) || sect == NULL) { - LOG_ERROR("Invalid argument"); return NULL; } @@ -995,7 +823,6 @@ const char* elf64GetSectName(const Elf64File *elf64, const Elf64Shdr *sect) uint64_t elf64GetSectSize(const Elf64Shdr *elf64Sect) { if (elf64Sect == NULL) { - LOG_ERROR("Invalid arguments"); return ELF64_INV_ARG; } @@ -1006,7 +833,6 @@ uint64_t elf64GetSectSize(const Elf64Shdr *elf64Sect) uint64_t elf64GetSectAddr(const Elf64Shdr *elf64Sect) { if (elf64Sect == NULL) { - LOG_ERROR("Invalid arguments"); return ELF64_INV_ARG; } @@ -1017,7 +843,6 @@ uint64_t elf64GetSectAddr(const Elf64Shdr *elf64Sect) uint64_t elf64GetSectFileoff(const Elf64Shdr *elf64Sect) { if (elf64Sect == NULL) { - LOG_ERROR("Invalid arguments"); return ELF64_INV_ARG; } @@ -1033,14 +858,13 @@ uint64_t elf64GetRelocForAddr( const Elf64File *elf64 if ( elf64Check(elf64) || sect == NULL || addr == (uint64_t)-1 - ) { - LOG_ERROR("Invalid arguments"); + ) + { return ELF64_INV_ARG; } const char *sectName = elf64GetSectName(elf64, sect); if (sectName == NULL) { - LOG_ERROR("getSectName()."); return ELF64_NO_SECTION; } @@ -1048,7 +872,6 @@ uint64_t elf64GetRelocForAddr( const Elf64File *elf64 size += strlen(sectName); char *relaSectName = (char*)Malloc(size); if (relaSectName == NULL) { - LOG_ERROR("Cannot alloc %"PRIu64" bytes.", size); return ELF64_NO_MEM; } @@ -1057,7 +880,6 @@ uint64_t elf64GetRelocForAddr( const Elf64File *elf64 Elf64Shdr *relaSect = elf64GetSectByName(elf64, relaSectName); if (relaSect == NULL) { - LOG_ERROR("Cannot get the section %s.", relaSectName); return ELF64_NO_SECTION; } @@ -1080,36 +902,30 @@ uint64_t elf64GetRelocForAddr( const Elf64File *elf64 if ( IS_ELF64_FILE_OBJ(elf64) && rela[i].r_offset + sect->sh_addr == addr ) { - LOG("find addr %"PRIu64"\n", addr); break; } if ( IS_ELF64_FILE_EXEC(elf64) && rela[i].r_offset == addr ) { - LOG("find addr %"PRIu64"\n", addr); break; } } if (i == relaAmount) { - LOG_ERROR("There is no relocation info"); return ELF64_NO_RELOCATION; } if (ELF64_R_TYPE(rela[i].r_info) == R_X86_64_64) { return (uint64_t)rela[i].r_addend; } else { - LOG_ERROR("Unknown relocation type."); return ELF64_NO_RELOCATION; } } - void *elf64GetRelocDataAddr(const Elf64File *elf64, const char *func) { if (elf64Check(elf64) || func == NULL) { - LOG_ERROR("Invalid arguments"); return NULL; } @@ -1118,7 +934,6 @@ void *elf64GetRelocDataAddr(const Elf64File *elf64, const char *func) */ uint64_t symbolIndex = elf64GetDSymIndxByName(elf64, func); if (symbolIndex == (uint64_t)-1) { - LOG_ERROR("Cannot get an index of a dynamic symbol %s.", func); return NULL; } @@ -1128,7 +943,6 @@ void *elf64GetRelocDataAddr(const Elf64File *elf64, const char *func) */ Elf64Shdr *relplt = elf64GetSectByName(elf64, RELAPLT); if (relplt == NULL) { - LOG_ERROR("Cannot get the section " RELAPLT "."); return NULL; } diff --git a/cTools/libs/binParse/elfParse/elf64Parse.h b/cTools/libs/binParse/elfParse/elf64Parse.h index dd2b618..25d91c4 100755 --- a/cTools/libs/binParse/elfParse/elf64Parse.h +++ b/cTools/libs/binParse/elfParse/elf64Parse.h @@ -1,7 +1,7 @@ /*** * MIT License * - * Copyright (c) 2021 Konychev Valerii + * Copyright (c) 2021-2024 Konychev Valerii * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -42,6 +42,7 @@ * alignment - 4 bytes */ typedef Elf64_Word Elf64Word; + /*** * typedef struct * { @@ -51,17 +52,18 @@ typedef Elf64_Word Elf64Word; * Elf64_Word e_version; * Elf64_Addr e_entry; * Elf64_Off e_phoff; - * Elf64_Off e_shoff; // Sect header offset + * Elf64_Off e_shoff; // Sect header offset * Elf64_Word e_flags; * Elf64_Half e_ehsize; * Elf64_Half e_phentsize; * Elf64_Half e_phnum; * Elf64_Half e_shentsize; - * Elf64_Half e_shnum; // Number of section header entries - * Elf64_Half e_shstrndx; // Sect name string table index + * Elf64_Half e_shnum; // Number of section header entries + * Elf64_Half e_shstrndx; // Sect name string table index * } Elf64_Ehdr; */ -typedef Elf64_Ehdr Elf64Ehdr; +typedef Elf64_Ehdr Elf64Ehdr; + /*** * typedef struct * { @@ -75,15 +77,16 @@ typedef Elf64_Ehdr Elf64Ehdr; * Elf64_Xword p_align; // Segment alignment * } Elf64_Phdr; */ -typedef Elf64_Phdr Elf64Phdr; +typedef Elf64_Phdr Elf64Phdr; + /*** * typedef struct { - * Elf64_Word sh_name; // Sect name - * Elf64_Word sh_type; // Sect type + * Elf64_Word sh_name; // Sect name + * Elf64_Word sh_type; // Sect type * Elf64_Xword sh_flags; * Elf64_Addr sh_addr; - * Elf64_Off sh_offset; // Offset in file - * Elf64_Xword sh_size; // Size of section + * Elf64_Off sh_offset; // Offset in file + * Elf64_Xword sh_size; // Size of section * Elf64_Word sh_link; * Elf64_Word sh_info; * Elf64_Xword sh_addralign; @@ -91,6 +94,7 @@ typedef Elf64_Phdr Elf64Phdr; * } Elf64_Shdr; */ typedef Elf64_Shdr Elf64Shdr; + /*** * typedef struct { * Elf64_Word st_name; @@ -102,6 +106,7 @@ typedef Elf64_Shdr Elf64Shdr; * } Elf64_Sym; */ typedef Elf64_Sym Elf64Sym; + /*** * typedef struct { * Elf64_Addr r_offset; @@ -181,7 +186,7 @@ typedef struct { char *fn; FileD fd; size_t fs; - void *faddr; + uint8_t *faddr; uint32_t type; Arch arch; Elf64Ehdr *header; @@ -231,376 +236,327 @@ static_assert(sizeof(ELF64_ERROR) == 8, "ELF64_ERROR must be 64 bit"); static_assert(((int64_t)ELF64_INV_ARG) < 0, "ERRORS must be negative"); /*** - * Input: - * @fn - binary file name. C string with terminal null. - * Output: - * Success: - * point to Elf64File structer. - * Fail: - * Null point. - * After: - * need to call function void elf64Free(Elf64File *elf64). + * @brief Parse elf64 binary file + * + * @param[in] fn Binary file name. C string with terminal null + * + * @return Pointer to Elf64File structer or NULL if fail */ EXPORT_FUNC Elf64File *elf64Parse(const char *fn); - /*** - * Before: - * You must completed all jobs with this elf64, otherwise you will free all - * information about this file including sections, symbols etc. - * Input: - * @elf64 - point to Elf64File structer, that is necessary to free. - * After: - * you should to assigned elf64 = NULL. + * @brief You must complete all jobs with this elf64, otherwise you will free + * all information about this file including sections, symbols etc + * @param[in] elf64 pointer to Elf64File structer */ EXPORT_FUNC void elf64Free(Elf64File *elf64); - /*** - * Input: - * @elf64 - Elf64File structure, that is nedded to check. - * Output: - * Success: - * If all fields are initialized, function will return 0. - * Fail: - * -1. + * @brief Check if elf64 points to a valid structure + * + * @param[in] elf64 pointer to Elf64File structure to check + * + * @return ELF64_OK or number of error (see ELF64ERROR) */ EXPORT_FUNC ELF64_ERROR elf64Check(const Elf64File *elf64); - /*** - * Before: - * If you need a file position, you should to save it. - * Description: - * Function returns pointer to the symbol with @name. - * Input: - * @elf64 - Elf64File structer with initialized fields: fd, elf64Header, - * sectionHeaders and symbols. - * @name - target section name. - * Output: - * Success: - * point to elf64 symbols(maybe dynamic) from Elf64File structer. - * Fail: - * NULL point. + * @brief Function returns pointer to the symbol with name + * + * @param[in] elf64 pointer to Elf64File structer + * @param[in] name symbol name needed to find + * + * @return pointer to Elf64Sym or NULL if fail */ EXPORT_FUNC Elf64Sym *elf64GetSymByName(const Elf64File *elf64, const char *name); - /*** - * Description: - * Function returns name of the symbol @sym. - * Input: - * @elf64 - point to the targer elf64File. - * @sym - point to symbol structure. - * Output: - * Success: - * point to name of symbol. - * Fail: - * NULL point. + * @brief Function returns name of the symbol + * + * @param[in] elf64 pointer to the target elf64File + * @param[in] sym pointer to symbol structure + * + * @return pointer to name of symbol or NULL if fail */ EXPORT_FUNC char *elf64GetSymName(const Elf64File *elf64, const Elf64Sym *sym); + +/*** + * @brief Function returns name of dynamic symbol + * + * @param[in] elf64 pointer to the target elf64File + * @param[in] sym pointer to symbol structure + * + * @return pointer to name of symbol or NULL if fail + */ EXPORT_FUNC char *elf64GetDSymName(const Elf64File *elf64, const Elf64Sym *sym); /*** - * Description: - * Function for work with qsort. Functions compare addresses of symbols and - * returns 1/-1/0 if a->addr >/addr. + * @brief Function for work with qsort. Functions compare addresses of symbols + * and returns 1/-1/0 if @a->addr >/addr. + * + * @param[in] a pointer to a fist symbol + * @param[in] b pointer to a second symbol */ EXPORT_FUNC int elf64CmpSym(const void *a, const void *b); - /*** - * Description: - * Function returns pointer to the static symbols table. - * Input: - * @elf64 - point to the targer elf64File. - * Output: - * Success: - * point to table of static symbols from elf64File structer. - * Fail: - * NULL point. + * @brief Function returns pointer to the static symbols table + * + * @param[in] elf64 pointer to the target Elf64File + * + * @return pointer to static symbol table or NULL if fail */ EXPORT_FUNC Elf64Sym *elf64GetSSymTab(const Elf64File *elf64); -EXPORT_FUNC -Elf64Sym *elf64GetSSymSortTab(const Elf64File *elf64); + +/*** + * @brief Function returns pointer to the dynamic symbols table + * + * @param[in] elf64 pointer to the target Elf64File + * + * @return pointer to dynamic symbol table or NULL if fail + */ EXPORT_FUNC Elf64Sym *elf64GetDSymTab(const Elf64File *elf64); /*** - * Description: - * Function returns amount of static symbols. - * Input: - * @elf64 - point to the targer elf64File. - * Output: - * Success: - * amount of static symbols from the elf64 structer. - * Fail: - * -1. + * @brief Function returns amount of static symbols + * + * @param[in] elf64 pointer to the target Elf64File + * + * @return amount of static symbols or -1 */ EXPORT_FUNC uint64_t elf64GetAmountSSym(const Elf64File *elf64); + +/*** + * @brief Function returns amount of dynamic symbols + * + * @param[in] elf64 pointer to the target Elf64File + * + * @return amount of dynamic symbols or -1 + */ EXPORT_FUNC uint64_t elf64GetAmountDSym(const Elf64File *elf64); /*** - * Description: - * Function returns addr of static symbol without randomization address space. - * Input: - * @sym - point to the targer static Elf64Sym. - * Output: - * Success: - * addr of the static symbol sym. - * Fail: - * -1. + * @brief returns addr of static symbol without ASLR + * + * @param[in] sym pointer to the target static Elf64Sym. + * + * @return address of -1 */ EXPORT_FUNC uint64_t elf64GetSSymAddr(const Elf64Sym *sym); - /*** - * Before: - * If you need a file position, you should to save it. - * Input: - * @elf64 - Elf64File structer with initialized fields: fd, elf64Header, - * sectionHeaders and symbols. - * @name - target section name. - * Output: - * Success: - * virtual addres of elf64 symbols from Elf64File structer. - * Fail: - * -1. + * @brief Return addr of static symbol with name + * + * @param[in] elf64 pointer to Elf64File structer + * @param[in] name name of static symbol + * + * @return static symbol address of -1 */ EXPORT_FUNC uint64_t elf64GetAddrSymByName(const Elf64File *elf64, const char *name); - /*** - * Description: - * Function returns size of static symbol without randomization address space. - * Input: - * @sym - point to the targer static Elf64Sym. - * Output: - * Success: - * size of the static symbol sym. - * Fail: - * -1. + * @brief returns size of static symbol + * + * @param[in] sym pointer to the target static Elf64Sym + * + * @return size of static symbol or -1 */ EXPORT_FUNC uint64_t elf64GetSSymSize(const Elf64File *elf64, const Elf64Sym *sym); - /*** - * Description: - * Function returns file position for the static symbol @sym. - * Input: - * @elf64 - point to the targer Elf64File. - * @sym - point to symbol structure. - * Output: - * Success: - * file position of the static symbol. - * Fail: - * -1. + * @brief returns file position for the static symbol + * + * @param[in] elf64 pointer to the target Elf64File + * @param[in] sym pointer to symbol + * + * @return file offset to start of symbol or -1 */ EXPORT_FUNC uint64_t elf64GetSSymFileoff(const Elf64File *elf64, const Elf64Sym *sym); - /*** - * Before: - * If you need a file position, you should to save it. - * Input: - * elf64 - Elf64File structer with initialized fields: fd, elf64Header, - * sectionHeaders and symbols. - * name - target symbol name. - * Output: - * Success: - * index of dynamic symbol from Symbols structer in Elf64File structer. - * Fail: - * -1. + * @brief returns index of symbol with name in dynamic table + * + * @param[in] elf64 pointer to Elf64File + * @param[in] name target dynamic symbol name + * + * @return Index of symbol with name in dynamic table or -1 */ EXPORT_FUNC uint64_t elf64GetDSymIndxByName(const Elf64File *elf64, const char *name); - /*** - * Function returns an amount of segments in the binary file. - * Input: - * @elf64 - point to the targer Elf64File. - * Output: - * Success: - * amount of segments in the binary file. - * Fail: - * -1. + * @brief returns an amount of segments + * + * @param[in] elf64 pointer to the target Elf64File + * + * @return amount of segments */ EXPORT_FUNC uint64_t elf64GetAmountSeg(const Elf64File *elf64); - /*** - * Input: - * sh_type - this member categorizes the section’s contents and semantics. - * Output: - * Success: - * point to elf64 section header from Elf64File structer - * Fail: - * NULL point. + * @brief returns pointer to the fist section with type + * + * @param[in] elf64 pointer to the target Elf64File + * @param[in] sh_type section type + * + * @return pointer to section of NULL */ EXPORT_FUNC -Elf64Shdr *elf64GetSectByType(const Elf64File *elf64, const Elf64Word sh_type); - +Elf64Shdr *elf64GetSectByType(const Elf64File *elf64, const Elf64Word type); /*** - * Description: - * Function returns a descriptor of a section with @name. - * Input: - * @elf64 - Elf64File structer with initialized fields: fd, elf64Header and - * sectionHeaders. - * @name - target section name. - * Output: - * Success: - * point to elf64 section header from Elf64File structer - * Fail: - * NULL point. + * @brief returns a descriptor of a section with name + * + * @param[in] elf64 pointer to the target Elf64File + * @param[in] name section name + * + * @return pointer to a section of NULL */ EXPORT_FUNC Elf64Shdr *elf64GetSectByName(const Elf64File *elf64, const char* name); + +/*** + * @brief returns a descriptor of a section contains addr + * + * @param[in] elf64 pointer to the target Elf64File + * @param[in] addr address without ASLR + * + * @return pointer to a section of NULL + */ EXPORT_FUNC Elf64Shdr *elf64GetSectByAddr(const Elf64File *elf64, uint64_t addr); + +/*** + * @brief returns last loadable section in binary file + * + * @param[in] elf64 pointer to the target Elf64File + * + * @return pointer to a section of NULL + */ EXPORT_FUNC Elf64Shdr *elf64GetLastLoadableSect(const Elf64File *elf64); - /*** - * Before: - * If you need a file position, you should to save it. - * Input: - * elf64 - Elf64File structer with initialized field fd. - * sectionHeader - header of section is related with elf64 file. - * Output: - * Success: - * point to elf64 section data. - * Fail: - * NULL point. - * After: - * need to free memory + * @brief Reads section contents + * + * @param[in] elf64 pointer to the target Elf64File + * @param[in] sect section descriptor + * + * @return pointer to a content or NULL + * @warning need to free memory */ EXPORT_FUNC -void *elf64ReadSect(const Elf64File *elf64, const Elf64Shdr *sectionHeader); - +void *elf64ReadSect(const Elf64File *elf64, const Elf64Shdr *sect); /*** - * Description: - * Function returns an amount of sections in the binary file. + * @brief returns an amount of sections + * + * @param[in] elf64 pointer to the target Elf64File + * + * @return amount of sections */ EXPORT_FUNC uint64_t elf64GetAmountSect(const Elf64File *elf64); - /*** - * Description: - * Function returns name of the section @sect. - * Input: - * @elf64 - point to the targer Elf64File. - * @sect - point to section descriptor. - * Output: - * Success: - * point to name of section. - * Fail: - * NULL. + * @brief returns name of the section + * + * @param[in] elf64 pointer to the target Elf64File + * @param[in] sect section descriptor + * + * @return pointer of NULL */ EXPORT_FUNC const char* elf64GetSectName(const Elf64File *elf64, const Elf64Shdr *sect); - /*** - * Description: - * Function returns a size of a section. - * Input: - * @sect - point to section descriptor. - * Output: - * Success: - * section size. - * Fail: - * -1. + * @brief returns a size of a section + * + * @param[in] sect pointer to section descriptor + * + * @return section size or -1 */ EXPORT_FUNC -uint64_t elf64GetSectSize(const Elf64Shdr *elf64Sect); - +uint64_t elf64GetSectSize(const Elf64Shdr *sect); /*** - * Description: - * Function returns a virtual address of a section. - * Input: - * @sect - point to section descriptor. - * Output: - * Success: - * section virtual addr without randomization of an address space. - * Fail: - * -1. + * @brief returns a virtual address of a section start + * + * @param[in] sect pointer to section descriptor + * + * @return addr or -1 */ EXPORT_FUNC uint64_t elf64GetSectAddr(const Elf64Shdr *sect); - /*** - * Description: - * Function returns a file offset of a section. - * Input: - * @sect - point to section descriptor. - * Output: - * Success: - * position of section in an executable file. - * Fail: - * -1. + * @brief returns a file offset of a section. + * + * @param[in] sect pointer to section descriptor. + * + * @return file offset to a section start */ EXPORT_FUNC uint64_t elf64GetSectFileoff(const Elf64Shdr *sect); - /*** - * Description: - * Function returns a relocation number for data, that is located at @addr in - * section @sect. - * Input: - * @elf64 - binary file descriptor. - * @sect - point to section descriptor. - * @addr - address of relocatable data. - * Output: - * Success: - * relocation offset. - * Fail: - * NULL. + * @brief returns addend for addr in section + * + * @param[in] elf64 binary file descriptor + * @param[in] sect pointer to section descriptor + * @param[in] addr address of relocatable data + * + * @return addend or -1 */ EXPORT_FUNC uint64_t elf64GetRelocForAddr(const Elf64File *elf64, const Elf64Shdr *sect, uint64_t addr); - /*** - * Before: - * If you need a file position, you should to save it. - * Input: - * elf64 - Elf64File structer with initialized field fd. - * func - name of function, that is nedded. - * Output: - * Success: - * Relocation addr. - * Fail: - * NULL point. + * @brief returns memory space position of actual dynamic func address + * + * @param[in] elf64 Elf64File structer + * @param[in] func function name + * + * @return vaddr or NULL */ EXPORT_FUNC void *elf64GetRelocDataAddr(const Elf64File *elf64, const char *func); +/*** + * @brief returns symbol version info + * + * @param[in] elf64 elf file descriptor + * @param[in] inds index of dynamic symbol in dynamic table + * + * @return symbol version info +*/ EXPORT_FUNC uint16_t elf64GetSymVersionByIndx(const Elf64File *elf64, uint64_t indx); +/*** + * @brief returns version name by varsion info + * + * @param[in] elf64 elf file descriptor + * @param[in] ver version info + * + * @return pointer to version name or NULL +*/ EXPORT_FUNC const char *elf64GetVerNameBySymVersion(const Elf64File *elf, uint16_t ver); diff --git a/cTools/libs/string/string.c b/cTools/libs/string/string.c index d36ab2b..b119eaf 100644 --- a/cTools/libs/string/string.c +++ b/cTools/libs/string/string.c @@ -30,11 +30,6 @@ size_t strlen(const char *addr) { - if (addr == NULL) { - STDERROR_PRINT_DEBUG("Invalid arguments."); - return (size_t)-1; - } - size_t len = 0; while (addr[len] != '\0') ++len; @@ -86,3 +81,14 @@ char *copyString(const char *src, char* dest) return &dest[i]; } +void *memset(void *dst, int c, size_t n) +{ + uint8_t *p = (uint8_t*)dst; + + while (n--) { + *p++ = c; + } + + return dst; +} + diff --git a/cTools/libs/string/string.h b/cTools/libs/string/string.h index a342e1b..eee23a0 100644 --- a/cTools/libs/string/string.h +++ b/cTools/libs/string/string.h @@ -1,7 +1,7 @@ /*** * MIT License * - * Copyright (c) 2021-2023 Konychev Valerii + * Copyright (c) 2021-2024 Konychev Valerii * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,8 +28,10 @@ #include "os.h" /* C standard headers */ +#include #include #include +#include /* * Description: @@ -97,5 +99,31 @@ void *memcpy(void *dest, const void *src, size_t n); EXPORT_FUNC char *copyString(const char *src, char* dest); +/*** + * @brief The memset() function fills the first n bytes of the memory area + * pointed to by dst with the constant byte c. + * + * @param[in,out] dst pointer to a memory needed to update + * @param[in] c fill byte + * @param[in] n number of bytes + * + * @return pointer to dst +*/ +EXPORT_FUNC +void *memset(void *dst, int c, size_t n); + +static inline +errno_t memset_s(void *dst, rsize_t dstsz, int c, rsize_t n) +{ + volatile uint8_t *s = dst; + + if (s == NULL || dstsz > RSIZE_MAX || n > dstsz) { + return errno = EINVAL; + } + + memset(dst, c, n); + return 0; +} + #endif