Thread: Why are my section headers receiving wrong text?

  1. #1
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    866

    Why are my section headers receiving wrong text?

    From compiling my app to checking the test.elf it creates here is the full ouput to display what I mean
    Code:
    misty alpha
    Writing ELF Header...
    Writing Symbols...
    Writing Segment Header/s...
    Writing Program Header/s...
    Writing Program Instructions...
    Flushing file...
    ./test.elf
    Segmentation fault
    readelf -all test.elf
    ELF Header:
      Magic:   7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00 
      Class:                             ELF64
      Data:                              2's complement, little endian
      Version:                           1 (current)
      OS/ABI:                            UNIX - GNU
      ABI Version:                       0
      Type:                              EXEC (Executable file)
      Machine:                           Advanced Micro Devices X86-64
      Version:                           0x1
      Entry point address:               0x19c
      Start of program headers:          356 (bytes into file)
      Start of section headers:          100 (bytes into file)
      Flags:                             0x0
      Size of this header:               64 (bytes)
      Size of program headers:           56 (bytes)
      Number of program headers:         1
      Size of section headers:           64 (bytes)
      Number of section headers:         4
      Section header string table index: 2
    readelf: Error: Section 2 has invalid sh_entsize of 0000000000000024
    readelf: Error: (Using the expected size of 24 for the rest of this dump)
    
    Section Headers:
      [Nr] Name              Type             Address           Offset
           Size              EntSize          Flags  Link  Info  Align
      [ 0] ^�ELF^B^A^A^C     NULL             0000000000000000  00000000
           0000000000000000  0000000000000000           0     0     0
      [ 1] ELF^B^A^A^C       PROGBITS         000000000000019c  00000000
           0000000000000006  0000000000000000 WXSLlp       0     0     0
      [ 2] LF^B^A^A^C        SYMTAB           0000000000000040  00000000
           0000000000000024  0000000000000018   S       3     3     1
      [ 3] F^B^A^A^C         STRTAB           0000000000000040  00000000
           0000000000000024  0000000000000001   S       0     0     1
    Key to Flags:
      W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
      L (link order), O (extra OS processing required), G (group), T (TLS),
      C (compressed), x (unknown), o (OS specific), E (exclude),
      l (large), p (processor specific)
    
    There are no section groups in this file.
    
    Program Headers:
      Type           Offset             VirtAddr           PhysAddr
                     FileSiz            MemSiz              Flags  Align
      LOAD           0x0000000000000000 0x000000000000019c 0x000000000000019c
                     0x0000000000000006 0x0000000000000006  RWE    0x0
    
     Section to Segment mapping:
      Segment Sections...
       00     
    
    There is no dynamic section in this file.
    
    There are no relocations in this file.
    
    The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.
    
    Symbol table 'LF^B^A^A^C' contains 1 entry:
       Num:    Value          Size Type    Bind   Vis      Ndx Name
         0: 0000000000000000 0x1003e0002 FUNC    LOCAL  INTERNAL bad section index[769] <corrupt>
    
    No version information found in this file.
    Exiting...
    
    
    ------------------
    (program exited with code: 0)
    Press return to continue
    The test.elf my app created (for hex editor only atm):
    test.elf - Google Drive
    The code I used to create the section header ".strtab"
    Code:
    elf64_t elf64 = {0};
    	segment_t e64 = {
    		0, "ELF Header",
    		{ sizeof(elf64_t), 1, 1, &elf64 }
    	};
    	segment_t stxt = Symbols();
    	segment_t es64 = {
    		stxt.pos + stxt.mem.size, "Segment Header/s",
    		{ sizeof(elsh64_t) * 4, 4, 4, calloc( 4, sizeof(elsh64_t) ) }
    	}; elsh64_t *es64v = (elsh64_t*)es64.mem.buff, *es64e = es64v;
    ...
    	/* Fill segment header .strtab */
    	es64e = &es64v[--s];
    	es64e->sh_name = s;
    	es64e->sh_type = ELSH_SHT_STRTAB;
    	es64e->sh_flags = 0x20;
    	es64e->sh_addr = stxt.pos;
    	es64e->sh_size = stxt.mem.size;
    	es64e->sh_offset = 0;
    	es64e->sh_link = 0;
    	es64e->sh_info = 0;
    	es64e->sh_adralign = 1;
    	es64e->sh_entsize = 1;

  2. #2
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    866
    I've now changed the code a bit to simplify the calculations a bit:
    Code:
    do {
    		segoffsetv[i] = es64->mem.size + s.mem.size;
    		s.mem.size += strlen(segmentv[i]) + 1;
    	} while ( segmentv[++i] );
    	s.mem.used = i;
    	s.mem.upto = i + 1;
    	segoffsetv[i] = es64->mem.size + s.mem.size;
    	++s.mem.size;
    ...
    #ifdef sh_name_index
    	es64e->sh_name = IndexOfSymbol(".symtab");
    #else
    	es64e->sh_name = segoffsetv[IndexOfSymbol(".symtab")] - (sizeof(elsh64_t) * s);
    #endif
    If you haven't realised it yet es64 is the segment header array (just buffer is written, not whole object) while es64e is an entry within that array

  3. #3
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    866
    Still can't figure it out, here's the methods I've tried:
    Code:
    //#define sh_name_index
    //#define sh_name_absolute
    //#define sh_name_from_self
    #define sh_name_from_pool
    //#define sh_name_from_header0
    void SegName( segment_t *array, elsh64_t *entry, u16 n, char const *txt ) {
    #ifdef sh_name_index
    	entry->sh_name = IndexOfSymbol(txt);
    #elif defined(sh_name_absolute)
    	entry->sh_name = segoffsetv[IndexOfSymbol(txt)] + array->pos;
    #elif defined(sh_name_from_self)
    	entry->sh_name = segoffsetv[IndexOfSymbol(txt)] - (sizeof(elsh64_t) * n);
    #elif defined(sh_name_from_header0)
    	entry->sh_name = segoffsetv[IndexOfSymbol(txt)];
    #elif defined(sh_name_from_pool)
    	entry->sh_name = segoffsetv[IndexOfSymbol(txt)] - array->mem.size;
    #else
    	entry->sh_name = 0;
    #endif
    }
    Last edited by awsdert; 04-02-2019 at 01:57 PM. Reason: Tried more

  4. #4
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    866
    So far based on the example.elf gcc compiled the sh_name_absolute appears to be the correct one but I still get incorrect text, goin' to sleep now so wil try again 2mw or whenever I next get motivation/an idea to try.

  5. #5
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    866
    Still waiting on suggestins bt in meantime I tidied up my code a bit to make reading it easier for me. Created structs for the symbols too but haven't finished reading up on how to use them yet, just filled in the st_name with same treatment as the segment header's sh_name. Gonna get ready for work now so will retry tomorrow probably
    Last edited by awsdert; 04-04-2019 at 04:45 AM. Reason: typo

  6. #6
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    866
    Alright I got a bit further, ie made symbol table but still getting corrupt text, I'm obviously misunderstanding something here. Can someone take a look at my readelf output then tell me what code they want to see to help me correct my understanding:
    Code:
    readelf -all test.elf
    ELF Header:
      Magic:   7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00 
      Class:                             ELF64
      Data:                              2's complement, little endian
      Version:                           1 (current)
      OS/ABI:                            UNIX - GNU
      ABI Version:                       0
      Type:                              EXEC (Executable file)
      Machine:                           Advanced Micro Devices X86-64
      Version:                           0x1
      Entry point address:               0x358
      Start of program headers:          744 (bytes into file)
      Start of section headers:          64 (bytes into file)
      Flags:                             0x0
      Size of this header:               64 (bytes)
      Size of program headers:           56 (bytes)
      Number of program headers:         2
      Size of section headers:           64 (bytes)
      Number of section headers:         6
      Section header string table index: 1
    readelf: Error: Section 3 has invalid sh_entsize of 000000000000001c
    readelf: Error: (Using the expected size of 24 for the rest of this dump)
    
    Section Headers:
      [Nr] Name              Type             Address           Offset
           Size              EntSize          Flags  Link  Info  Align
      [ 0] ^�ELF^B^A^A^C     NULL             0000000000000000  00000000
           0000000000000000  0000000000000000           0     0     0
      [ 1] <corrupt>         STRTAB           00000000000001c0  00000000
           000000000000002c  0000000000000001   S       0     0     0
      [ 2] <corrupt>         STRTAB           00000000000001c0  00000000
           000000000000002c  0000000000000001   S       0     0     0
      [ 3] <corrupt>         SYMTAB           00000000000001ec  00000000
           00000000000000fc  0000000000000018   S       1     1     0
      [ 4] <corrupt>         PROGBITS         0000000000000358  00000000
           0000000000000006  0000000000000000 WXSLlp       0     0     0
      [ 5] ^�ELF^B^A^A^C     NULL             0000000000000000  00000000
           0000000000000000  0000000000000000           0     0     0
    Key to Flags:
      W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
      L (link order), O (extra OS processing required), G (group), T (TLS),
      C (compressed), x (unknown), o (OS specific), E (exclude),
      l (large), p (processor specific)
    
    There are no section groups in this file.
    
    Program Headers:
      Type           Offset             VirtAddr           PhysAddr
                     FileSiz            MemSiz              Flags  Align
      NULL           0x0000000000000000 0x0000000000000000 0x0000000000000000
                     0x0000000000000000 0x0000000000000000         0x0
      LOAD           0x0000000000000000 0x0000000000000358 0x0000000000000358
                     0x0000000000000006 0x0000000000000006  RWE    0x0
    
     Section to Segment mapping:
      Segment Sections...
       00     ^�ELF^B^A^A^C 
       01     
    
    There is no dynamic section in this file.
    
    There are no relocations in this file.
    
    The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.
    
    Symbol table '<corrupt>' contains 10 entries:
       Num:    Value          Size Type    Bind   Vis      Ndx Name
         0: 0000000000000000 0x1003e0002 FUNC    LOCAL  INTERNAL bad section index[769] <corrupt>
         1: 00000000000002e8    64 NOTYPE  LOCAL  DEFAULT  UND <corrupt>
    readelf: Warning: local symbol 1 found at index >= <corrupt>'s sh_info value of 1
         2: 0001000600400002     0 NOTYPE  <unknown>: 4 DEFAULT bad section index[ 56] ^�ELF^B^A^A^C
         3: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND ^�ELF^B^A^A^C
    readelf: Warning: local symbol 3 found at index >= <corrupt>'s sh_info value of 1
         4: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND ^�ELF^B^A^A^C
    readelf: Warning: local symbol 4 found at index >= <corrupt>'s sh_info value of 1
         5: 00000003000001c0    32 NOTYPE  LOCAL  DEFAULT  UND ^�ELF^B^A^A^C
    readelf: Warning: local symbol 5 found at index >= <corrupt>'s sh_info value of 1
         6: 0000000000000000    44 NOTYPE  LOCAL  DEFAULT  UND <corrupt>
    readelf: Warning: local symbol 6 found at index >= <corrupt>'s sh_info value of 1
         7: 0000000000000000     1 NOTYPE  LOCAL  DEFAULT  UND ^�ELF^B^A^A^C
    readelf: Warning: local symbol 7 found at index >= <corrupt>'s sh_info value of 1
         8: 0000000000000020   448 SECTION LOCAL  DEFAULT  UND <corrupt>
    readelf: Warning: local symbol 8 found at index >= <corrupt>'s sh_info value of 1
         9: 000000000000002c     0 NOTYPE  LOCAL  DEFAULT  UND ^�ELF^B^A^A^C
    readelf: Warning: local symbol 9 found at index >= <corrupt>'s sh_info value of 1
    
    No version information found in this file.

  7. #7
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    866
    I condensed some of my code further and produced this function which is happy whatever side of the string pool the base address is:
    Code:
    //#define name_is_pointer
    //#define name_from_pool
    //#define name_from_top
    //#define name_from_self
    d32 Named( segment_t *this, segment_t *segv, d16 n, d16 Tsize, char const *txt ) {
    	segment_t *spool_seg = &segv[SEG_SHEAD];
    	shead64_t entry = {0};
    	u16 off = 0;
    	u16 pos = IndexOfSymbol(segv,txt,&off);
    	u16 abs = spool_seg->pos + off;
    	d32 top = (abs > this->pos) ? abs - this->pos :
    		-((d32)(this->pos - abs));
    	if ( n < 0 ) return 0;
    #if defined(name_is_pointer)
    	return abs;
    #elif defined(name_from_top)
    	return top;
    #elif defined(name_from_self)
    	return top - (Tsize * n);
    #elif defined(name_from_pool)
    	return off;
    #else
    	return pos;
    #endif
    }
    I'm still getting corrupt text whatever I try to use though

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Accessing .text section code pages of a running Windows process
    By coldthunder in forum Windows Programming
    Replies: 0
    Last Post: 04-05-2016, 05:08 AM
  2. Replies: 9
    Last Post: 03-07-2014, 09:36 PM
  3. Replies: 1
    Last Post: 03-21-2008, 08:15 PM
  4. glut text rendering in wrong color
    By ichijoji in forum Game Programming
    Replies: 1
    Last Post: 10-31-2005, 10:02 PM
  5. including headers inside headers
    By kromozom in forum C++ Programming
    Replies: 5
    Last Post: 04-18-2005, 10:56 AM

Tags for this Thread