Beispiel #1
0
Datei: pe.cpp Projekt: haofree/rp
CPU::E_CPU PE::extract_information_from_binary(std::ifstream &file)
{
    RP_IMAGE_DOS_HEADER imgDosHeader = {0};
    RP_IMAGE_NT_HEADERS32 imgNtHeaders32 = {0};
    CPU::E_CPU cpu = CPU::CPU_UNKNOWN;

    std::cout << "Loading PE information.." << std::endl;

    /* Remember where the caller was in the file */
    std::streampos off = file.tellg();

    file.seekg(0, std::ios::beg);
    file.read((char*)&imgDosHeader, sizeof(RP_IMAGE_DOS_HEADER));

    file.seekg(imgDosHeader.e_lfanew, std::ios::beg);
    /* 
     * Yeah, in fact, we don't know yet if it is a x86/x64 PE ; 
     * so just we grab the signature field, FILE_HEADER and the field Magic 
     */
    file.read((char*)&imgNtHeaders32, sizeof(unsigned int) + sizeof(RP_IMAGE_FILE_HEADER) + sizeof(unsigned int));
    
    if(imgNtHeaders32.Signature != RP_IMAGE_NT_SIGNATURE)
        RAISE_EXCEPTION("This file doesn't seem to be a correct PE (bad IMAGE_NT_SIGNATURE)");

    switch(imgNtHeaders32.OptionalHeader.Magic)
    {
        case RP_IMAGE_NT_OPTIONAL_HDR32_MAGIC:
        {
            cpu = CPU::CPU_x86;
            /* Ok, now we can allocate the good version of the PE Layout */
            /* The 32bits version there! */
            init_properly_PELayout<x86Version>();
            break;
        }

        case RP_IMAGE_NT_OPTIONAL_HDR64_MAGIC:
        {
            cpu = CPU::CPU_x64;
            init_properly_PELayout<x64Version>();
            break;
        }

        default:
            RAISE_EXCEPTION("Cannot determine the CPU type");
    }
    
    /* Now we can fill the structure */
    std::memcpy(&m_pPELayout->imgDosHeader, &imgDosHeader, m_pPELayout->get_image_dos_header_size());

    m_pPELayout->fill_nt_structures(file);

    file.seekg(off);
    return cpu;
}
Beispiel #2
0
    std::vector<Section*> get_executable_section(std::ifstream &file)
    {
        std::vector<Section*> exc_sect;

        for(iter_rp_section it = sections.begin(); it != sections.end(); ++it)
        {
            if((*it)->flags & S_ATTR_PURE_INSTRUCTIONS || (*it)->flags & S_ATTR_SOME_INSTRUCTIONS)
            {
                Section *s = new Section(
                    (char*)(*it)->sectname,
                    (*it)->offset,
                    (*it)->addr,
                    (*it)->size
                );

                if(s == NULL)
                    RAISE_EXCEPTION("Cannot allocate s");
                
                s->dump(file);

                s->set_props(Section::Executable);

                exc_sect.push_back(s);
            }
        }
        return exc_sect;
    }
Beispiel #3
0
Datei: pe.cpp Projekt: haofree/rp
std::vector<Section*> PE::get_executables_section(std::ifstream & file)
{
    std::vector<Section*> exec_sections;

    for(std::vector<RP_IMAGE_SECTION_HEADER*>::iterator it = m_pPELayout->imgSectionHeaders.begin();
        it != m_pPELayout->imgSectionHeaders.end();
        ++it)
    {
        if((*it)->Characteristics & RP_IMAGE_SCN_MEM_EXECUTE)
        {
            Section *tmp = new (std::nothrow) Section(
                (*it)->get_name().c_str(),
                (*it)->PointerToRawData,
                /* in the PE, this field is a RVA, so we need to add it the image base to have a VA */
                m_pPELayout->get_image_base() + (*it)->VirtualAddress,
                (*it)->SizeOfRawData
            );

            if(tmp == NULL)
                RAISE_EXCEPTION("Cannot allocate a section");
            
            tmp->dump(file);

            tmp->set_props(Section::Executable);

            exec_sections.push_back(tmp);
        }
    }
    return exec_sections;
}
Beispiel #4
0
Datei: pe.cpp Projekt: haofree/rp
CPU* PE::get_cpu(std::ifstream &file)
{
    CPU* cpu(NULL);
    CPU::E_CPU cpu_type = CPU::CPU_UNKNOWN;

    cpu_type = extract_information_from_binary(file);

    switch(cpu_type)
    {
        case CPU::CPU_x86:
        {
            cpu = new (std::nothrow) x86();
            break;
        }

        case CPU::CPU_x64:
        {
            cpu = new (std::nothrow) x64();
            break;
        }

        default:
            RAISE_EXCEPTION("Cannot determine the CPU type");
    }
    
    return cpu;
}
Beispiel #5
0
Datei: pe.cpp Projekt: Ge0/rp
std::shared_ptr<CPU> PE::get_cpu(std::ifstream &file)
{
    std::shared_ptr<CPU> cpu;
    CPU::E_CPU cpu_type = CPU::CPU_UNKNOWN;

    cpu_type = extract_information_from_binary(file);

    switch(cpu_type)
    {
        case CPU::CPU_x86:
        {
            cpu = std::make_shared<x86>();
            break;
        }

        case CPU::CPU_x64:
        {
            cpu = std::make_shared<x64>();
            break;
        }

		case CPU::CPU_ARM:
		{
			cpu = std::make_shared<ARM>();
			break;
		}

        default:
            RAISE_EXCEPTION("Cannot determine the CPU type");
    }
    
    return cpu;
}
Beispiel #6
0
    std::vector<Section*> get_executable_section(std::ifstream &file) const
    {
        std::vector<Section*> exec_sections;

        for(iter_elf_phdr it = elfProgramHeaders.begin(); it != elfProgramHeaders.end(); ++it)
        {
            if((*it)->p_flags & 1)
            {
                Section *sec = new (std::nothrow) Section(
                    type_to_str((*it)->p_type).c_str(),
                    (*it)->p_offset,
                    (*it)->p_vaddr,
                    (*it)->p_filesz
                );

                if(sec == NULL)
                    RAISE_EXCEPTION("Cannot alocate a section");
                
                sec->dump(file);
                sec->set_props(Section::Executable);

                exec_sections.push_back(sec);
            }
        }

        return exec_sections;
    }
Beispiel #7
0
std::multiset<Gadget*> BeaRopGadgetFinder::find_rop_gadgets(const unsigned char* data, unsigned long long size, unsigned long long vaddr)
{
    std::multiset<Gadget*> merged_gadgets;
    DISASM dis;

    init_disasm_struct(&dis);

    for(unsigned long long offset = 0; offset < size; ++offset)
    {
        dis.EIP = (UIntPtr)(data + offset);
        dis.VirtualAddr = SafeAddU64(vaddr, offset);
        dis.SecurityBlock = (UInt32)(size - offset + 1);
        
        int len = Disasm(&dis);
        /* I guess we're done ! */
        if(len == OUT_OF_BLOCK)
            break;

        /* OK this one is an unknow opcode, goto the next one */
        if(len == UNKNOWN_OPCODE)
            continue;

        if(is_valid_ending_instruction(&dis))
        {
            DISASM ret_instr;

            /* Okay I found a RET ; now I can build the gadget */
            memcpy(&ret_instr, &dis, sizeof(DISASM));
            
            /* Do not forget to add the ending instruction only -- we give to the user all gadget with < depth instruction */
            std::list<Instruction> only_ending_instr;

            only_ending_instr.push_back(Instruction(
                std::string(ret_instr.CompleteInstr),
                std::string(ret_instr.Instruction.Mnemonic),
                offset,
                len
            ));

            Gadget *gadget_with_one_instr = new (std::nothrow) Gadget();
            if(gadget_with_one_instr == NULL)
                RAISE_EXCEPTION("Cannot allocate gadget_with_one_instr");

            /* the gadget will only have 1 ending instruction */
            gadget_with_one_instr->add_instructions(only_ending_instr, vaddr);
            merged_gadgets.insert(gadget_with_one_instr);

            /* if we want to see gadget with more instructions */
            if(m_depth > 0)
            {
                std::multiset<Gadget*> gadgets = find_all_gadget_from_ret(data, vaddr, &ret_instr, len);
                for(std::multiset<Gadget*>::iterator it = gadgets.begin(); it != gadgets.end(); ++it)
                    merged_gadgets.insert(*it);
            }
        }
    }

    return merged_gadgets;
}
Beispiel #8
0
    static inline T Add(const T a, const T b)
    {
        T result = a + b;
        if(result < a)
            RAISE_EXCEPTION("Integer overflow detected.");

        return result;
    }
Beispiel #9
0
void Section::dump(std::ifstream &file)
{
    /* NB: std::streampos performs unsigned check */
    unsigned long long fsize = get_file_size(file);
    if(SafeAddU64(m_offset, m_size) > fsize)
        RAISE_EXCEPTION("Your file seems to be f****d up");

    std::streampos backup = file.tellg();

    file.seekg((unsigned int)m_offset, std::ios::beg);
    m_section = new (std::nothrow) unsigned char[(unsigned int)m_size];
    if(m_section == NULL)
        RAISE_EXCEPTION("Cannote allocate a section.");

    file.read((char*)m_section, (unsigned int)m_size);

    file.seekg(backup);
}
Beispiel #10
0
CPU* Macho::get_cpu(std::ifstream &file)
{
    CPU *cpu(NULL);
    RP_MACH_HEADER<x86Version> header32;

    std::cout << "Loading Mach-O information.." << std::endl;

    /* Remember where the caller was in the file */
    std::streampos off = file.tellg();

    file.seekg(0, std::ios::beg);
    file.read((char*)&header32, sizeof(RP_MACH_HEADER<x86Version>));

    switch(header32.cputype)
    {
        case CPU_TYPE_x86_64:
        {
            cpu = new (std::nothrow) Ia64();
            init_properly_macho_layout<x64Version>();
            break;
        }

        case CPU_TYPE_I386:
        {
            cpu = new (std::nothrow) Ia32();
            init_properly_macho_layout<x86Version>();
            break;
        }

        default:
            RAISE_EXCEPTION("Cannot determine which architecture is used in this Mach-O file");
    }

    file.seekg(off);

    if(cpu == NULL)
        RAISE_EXCEPTION("Cannot allocate cpu");

    /* Now we can fill the structure */
    m_MachoLayout->fill_structures(file);

    return cpu;
}
Beispiel #11
0
ExecutableFormat* ExecutableFormat::GetExecutableFormat(unsigned int magic_dword)
{
    ExecutableFormat *exe_format = NULL;

    /* Yeah, I told you it was basic. */
    switch(magic_dword)
    {
        case 0x00905A4D:
        {
            exe_format = new (std::nothrow) PE();
            break;
        }

        case 0x464C457F:
        {
            exe_format = new (std::nothrow) Elf();
            break;
        }
        
        /* this is for x64 */
        case 0xFEEDFACF:
        /* this one for x86 */
        case 0xFEEDFACE:
        {
            exe_format = new (std::nothrow) Macho();
            break;
        }

        case 0xBEBAFECA:
        {
            RAISE_EXCEPTION("Hmm, actually I don't handle OSX Universal binaries. You must extract them manually.");
            break;
        }

        default:
            RAISE_EXCEPTION("Cannot determine the executable format used");
    }

    if(exe_format == NULL)
        RAISE_EXCEPTION("Cannot allocate exe_format");

    return exe_format;
}
Beispiel #12
0
ArmCapstone::ArmCapstone(unsigned int thumb_mode)
: is_thumb(true)
{
	cs_mode mode = CS_MODE_THUMB;
	if(thumb_mode == 0)
	{
		mode = CS_MODE_ARM;
		is_thumb = false;
	}

	if(cs_open(CS_ARCH_ARM, mode, &m_handle) != CS_ERR_OK)
		RAISE_EXCEPTION("Apparently no support for ARM in capstone.lib");

	cs_option(m_handle, CS_OPT_DETAIL, CS_OPT_ON);
}
Beispiel #13
0
Program::Program(const std::string & program_path, CPU::E_CPU arch)
: m_cpu(NULL), m_exformat(NULL)
{
    unsigned int magic_dword = 0;

    std::cout << "Trying to open '" << program_path << "'.." << std::endl;
    m_file.open(program_path.c_str(), std::ios::binary);
    if(m_file.is_open() == false)
        RAISE_EXCEPTION("Cannot open the file");

    /* If we know the CPU in the constructor, it is a raw file */
    if(arch != CPU::CPU_UNKNOWN)
    {
        m_exformat = new (std::nothrow) Raw();
        if(m_exformat == NULL)
            RAISE_EXCEPTION("Cannot allocate raw");
        
        switch(arch)
        {
            case CPU::CPU_IA32:
                m_cpu = new (std::nothrow) Ia32();
                break;

            case CPU::CPU_IA64:
                m_cpu = new (std::nothrow) Ia64();
                break;

            default:
                RAISE_EXCEPTION("Don't know your architecture");
        }

        if(m_cpu == NULL)
            RAISE_EXCEPTION("Cannot allocate m_cpu");
 
    }
    /* This isn't a raw file, we have to determine the executable format and the cpu */
    else
    {
        m_file.read((char*)&magic_dword, sizeof(magic_dword));

        m_exformat = ExecutableFormat::GetExecutableFormat(magic_dword);
        if(m_exformat == NULL)
            RAISE_EXCEPTION("GetExecutableFormat fails");

        m_cpu = m_exformat->get_cpu(m_file);
        if(m_cpu == NULL)
            RAISE_EXCEPTION("get_cpu fails");
    }


    std::cout << "FileFormat: " << m_exformat->get_class_name() << ", Arch: " << m_cpu->get_class_name() << std::endl;
}
Beispiel #14
0
/**
 * \fn static void disable_color(const Colors colo)
 * \brief Unset the color you have previously set
 */
static void disable_color(void)
{
#ifdef COLORS_ENABLED
#ifdef WINDOWS
    HANDLE hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    if(hStdOutput == INVALID_HANDLE_VALUE)
        RAISE_EXCEPTION("Cannot find a STD_OUTPUT_HANDLE valid value");

    SetConsoleTextAttribute(
        hStdOutput,
        COLO_DEFAULT
        );
#else
    const char *colors[] = {
        "\x1b[91m", "\x1b[92m",
        "\x1b[93m", "\x1b[0m"
    };
    std::cout << colors[COLO_DEFAULT];
#endif
#else
#endif
}
Beispiel #15
0
    void fill_nt_structures(std::ifstream &file)
    {
        /* Remember where the caller was in the file */
        std::streampos off = file.tellg();

        file.seekg(imgDosHeader.e_lfanew, std::ios::beg);
        file.read((char*)&imgNtHeaders, get_nt_headers_size());

        file.seekg(imgDosHeader.e_lfanew, std::ios::beg);
        /* This offset is relative to the NT Header, do not forget to move the file pointer on it */
        file.seekg(imgNtHeaders.get_offset_first_section(), std::ios::cur);

        for(unsigned int i = 0; i < imgNtHeaders.FileHeader.NumberOfSections; ++i)
        {
            RP_IMAGE_SECTION_HEADER* pImgSectionHeader = new (std::nothrow) RP_IMAGE_SECTION_HEADER;
            if(pImgSectionHeader == NULL)
                RAISE_EXCEPTION("Cannot allocate memory for pImgSectionHeader");

            file.read((char*)pImgSectionHeader, get_image_section_header_size());
            imgSectionHeaders.push_back(pImgSectionHeader);
        }

        file.seekg(off);
    }
Beispiel #16
0
std::vector<Section*> Raw::get_executables_section(std::ifstream & file)
{
    std::vector<Section*> executable_sections;

    unsigned long long raw_file_size = get_file_size(file);
    
    /* It is a raw file -> we have only one "virtual" section */
    Section *sect = new (std::nothrow) Section(
        ".raw",
        0,
        0,
        raw_file_size
    );

    if(sect == NULL)
        RAISE_EXCEPTION("Cannot allocate sect");
    
    sect->dump(file);
    sect->set_props(Section::Executable);

    executable_sections.push_back(sect);
    
    return executable_sections;
}
Beispiel #17
0
Datei: pe.hpp Projekt: Ge0/rp
 void init_properly_PELayout()
 {
     m_pPELayout = std::make_shared<PELayout<T>>();
     if(m_pPELayout == NULL)
         RAISE_EXCEPTION("m_PELayout allocation failed");
 }
Beispiel #18
0
std::multiset<Gadget*> BeaRopGadgetFinder::find_all_gadget_from_ret(const unsigned char* data, unsigned long long vaddr, const DISASM* ending_instr_disasm, unsigned int len_ending_instr)
{
    std::multiset<Gadget*> gadgets;
    DISASM dis;

    init_disasm_struct(&dis);

    /*
        We go back, trying to create the longuest gadget possible with the longuest instructions
        "On INTEL processors, (in IA-32 or intel 64 modes), instruction never exceeds 15 bytes." -- beaengine.org
    */
    dis.EIP         = (UIntPtr)(ending_instr_disasm->EIP - m_depth*15); // /!\ Warning to pointer arith
    dis.VirtualAddr = ending_instr_disasm->VirtualAddr - m_depth*15;

    /* going back yeah, but not too much :)) */
    if(dis.EIP < (UIntPtr)data)
    {
        dis.EIP = (UIntPtr)data;
        dis.VirtualAddr = vaddr;
    }

    while(dis.EIP < ending_instr_disasm->EIP)
    {
        std::list<Instruction> list_of_instr;

        /* save where we were in memory */
        UIntPtr saved_eip  = dis.EIP;
        UInt64 saved_vaddr = dis.VirtualAddr;

        bool is_a_valid_gadget = false;

        /* now we'll try to find suitable sequence */
        for(unsigned int nb_ins = 0; nb_ins < m_depth; nb_ins++)
        {
            int len_instr = Disasm(&dis);

            /* if the instruction isn't valid, let's try the process one byte after */
            if(len_instr == UNKNOWN_OPCODE || is_valid_instruction(&dis) == false)
                break;

            list_of_instr.push_back(Instruction(
                std::string(dis.CompleteInstr),
                std::string(dis.Instruction.Mnemonic),
                dis.EIP - (UIntPtr)data,
                len_instr
            ));
            
            dis.EIP += len_instr;
            dis.VirtualAddr += len_instr;

            /* if the address of the latest instruction found points on the ending one, we have a winner */
            if(dis.EIP == ending_instr_disasm->EIP)
            {
                is_a_valid_gadget = true;
                /* NB: I reach the ending instruction without depth instruction */
                break;
            }

            /* if we point after the ending one, it's not a valid sequence */
            if(dis.EIP > ending_instr_disasm->EIP)
                break;
        }

        if(is_a_valid_gadget)
        {
            /* we have a valid gadget, time to build it ; add the instructions found & finally add the ending instruction */
            
            /* Don't forget to include the ending instruction in the chain of instruction */
            list_of_instr.push_back(Instruction(
                std::string(ending_instr_disasm->CompleteInstr),
                std::string(ending_instr_disasm->Instruction.Mnemonic),
                ending_instr_disasm->EIP - (UIntPtr)data,
                len_ending_instr
            ));


            Gadget *gadget = new (std::nothrow) Gadget();
            if(gadget == NULL)
                RAISE_EXCEPTION("Cannot allocate gadget");

            /* Now we populate our gadget with the instructions previously found.. */
            gadget->add_instructions(list_of_instr, vaddr);

            gadgets.insert(gadget);
        }

        /* goto the next byte */
        dis.EIP = saved_eip + 1;
        dis.VirtualAddr = saved_vaddr + 1;
    }

    return gadgets;
}
Beispiel #19
0
    void fill_structures(std::ifstream &file)
    {
        bool is_all_section_walked = false;
        std::streampos off = file.tellg();

        if (off == -1)
            RAISE_EXCEPTION("Error while using file.tellg().");

        /* 1] Fill the header structure */
        file.seekg(0, std::ios::beg);
        file.read((char*)&header, sizeof(RP_MACH_HEADER<T>));

        /* 2] The load commands now */
        for(unsigned int i = 0; i < header.ncmds; ++i)
        {
            RP_LOAD_COMMAND loadcmd = {0, 0};

            file.read((char*)&loadcmd, sizeof(RP_LOAD_COMMAND));
            switch(loadcmd.cmd)
            {
                case LC_SEGMENT:
                case LC_SEGMENT_64:
                {
                    RP_SEGMENT_COMMAND<T>* seg_cmd = new (std::nothrow) RP_SEGMENT_COMMAND<T>;
                    if(seg_cmd == NULL)
                        RAISE_EXCEPTION("Cannot allocate seg_cmd");

                    file.read((char*)seg_cmd, sizeof(RP_SEGMENT_COMMAND<T>));
                    seg_commands.push_back(seg_cmd);

                    /* 
                       Directly following a segment_command data structure is an array of section data 
                       structures, with the exact count determined by the nsects field of the segment_command
                       structure.
                    */
                    for(unsigned int j = 0; j < seg_cmd->nsects; ++j)
                    {
                        RP_SECTION<T>* sect = new (std::nothrow) RP_SECTION<T>;
                        if(sect == NULL)
                            RAISE_EXCEPTION("Cannot allocate sect");

                        file.read((char*)sect, sizeof(RP_SECTION<T>));
                        sections.push_back(sect);
                    }

                    break;
                }

                default:
                {
                    /* 
                        XXX: We assume that all SEGMENT_HEADER[_64] are in first, and they are all contiguous
                        The proper way should be add cases for each COMMAND possible, and increment the file pointer of the size of the COMMAND read
                    */ 
                    is_all_section_walked = true;
                    break;
                }
            }

            if(is_all_section_walked)
                break;
        }
    }
Beispiel #20
0
 /*!
  *  \brief Fill the structures you need, parse your executable format to extract the useful information 
  *
  *  \param file: It is your binary file
  *
  *  \return The CPU type used in your binary file
  */
 virtual CPU::E_CPU extract_information_from_binary(std::ifstream &file)
 {
     RAISE_EXCEPTION("This method should not be called ; you're doing it wrong!");
     return CPU::CPU_UNKNOWN;
 }
Beispiel #21
0
 void init_properly_ELFLayout(void)
 {
     m_ELFLayout = new (std::nothrow) ELFLayout<T>;
     if(m_ELFLayout == NULL)
         RAISE_EXCEPTION("m_ELFLayout allocation failed");
 }
Beispiel #22
0
    void fill_structures(std::ifstream &file)
    {
        /* Remember where the caller was in the file */
        std::streampos off = file.tellg();
        std::streampos fsize = 0;

        /* 1] Dump the Elf Header */
        file.seekg(0, std::ios::end);
        fsize = file.tellg();
        file.seekg(0, std::ios::beg);
        file.read((char*)&elfHeader, sizeof(Elf_Ehdr<T>));

        /* 2] Goto the first Program Header, and dump them */
        file.seekg((std::streamoff)elfHeader.e_phoff, std::ios::beg);
        for(unsigned int i = 0; i < elfHeader.e_phnum; ++i)
        {
            Elf_Phdr<T>* pElfProgramHeader = new (std::nothrow) Elf_Phdr<T>;
            if(pElfProgramHeader == NULL)
                RAISE_EXCEPTION("Cannot allocate pElfProgramHeader");

            file.read((char*)pElfProgramHeader, sizeof(Elf_Phdr<T>));
            elfProgramHeaders.push_back(pElfProgramHeader);
        }

        /* 3.1] If we want to know the name of the different section, 
         *    we need to find the string table section 
         */
        find_string_table(file);

        /* 3.2] Keep the string table in memory */
        file.seekg((std::streamoff)offset_string_table, std::ios::beg);

        if ((unsigned long long)size_string_table > fsize)
            size_string_table = (unsigned long long)fsize - elfHeader.e_shoff;

        char* string_table_section = new (std::nothrow) char[(unsigned int)size_string_table];
        if(string_table_section == NULL)
            RAISE_EXCEPTION("Cannot allocate string_table_section");


        file.read(string_table_section, (std::streamsize)size_string_table);
        if (!file)
            RAISE_EXCEPTION("Cannot read string_table_section");

        /* 3.3] Goto the first Section Header, and dump them !*/
        file.seekg((std::streamoff)elfHeader.e_shoff, std::ios::beg);
        for(unsigned int i = 0; i < elfHeader.e_shnum; ++i)
        {
            Elf_Shdr_Abstraction<T>* pElfSectionHeader = new (std::nothrow) Elf_Shdr_Abstraction<T>;
            if(pElfSectionHeader == NULL)
                RAISE_EXCEPTION("Cannot allocate pElfSectionHeader");

            file.read((char*)&pElfSectionHeader->header, sizeof(Elf_Shdr<T>));

            /* 3.4] Resolve the name of the section */
            if(pElfSectionHeader->header.sh_name < size_string_table)
            {
                /* Yeah we know where is the string */
                char *name_section = string_table_section + pElfSectionHeader->header.sh_name;
                std::string s(name_section, std::strlen(name_section));
                pElfSectionHeader->name = (s == "") ? std::string("unknown section") : s;
            }

            elfSectionHeaders.push_back(pElfSectionHeader);
        }

        /* Set correctly the pointer */
        file.seekg(off);

        delete[] string_table_section;
    }