NASM - falsches binär Format

jkallup

Erfahrenes Mitglied
Hallo,

ich habe folgenden Code.
der wird auch compiliert mittels
nasm -f bin -o test test.asm

aber das erzeugte programm lässt
sich nicht ausführen.

ich erhalte bei "file test":
ELF 64-bit LSB executable, x86-64, version 1 (SYSV), too many program (312)

kann da jemand bitte sachdienliche
infos und fixes geben?
danke
Jens

Code:
  BITS 64

  %define ET_EXEC  2
  %define EM_386  3
  %define EM_X8664  62
  %define EV_CURRENT  1

  %define PT_LOAD  1
  %define PT_DYNAMIC  2
  %define PT_INTERP  3

  %define PF_X  1
  %define PF_W  2
  %define PF_R  4

  %define STT_FUNC  2

  %define STB_GLOBAL  1

  %define R_386_PC32  2
  %define R_AMD64_PC64  24

  %define DT_NULL  0
  %define DT_NEEDED  1
  %define DT_HASH  4
  %define DT_STRTAB  5
  %define DT_SYMTAB  6
  %define DT_STRSZ  10
  %define DT_SYMENT  11
  %define DT_REL  17
  %define DT_RELSZ  18
  %define DT_RELENT  19

  %define ST_INFO(b, t) (((b) << 4) | (t))
  %define R_INFO(s, t)  (((s) << 8) | (t))

  shentsz  equ  0x28

  ;  org  0x08048000

  ;; The ELF header

  ehdr:  ; Elf32_Ehdr
  db  0x7F, "ELF",2,1,1  ;  e_ident
  times 9 db  0

  ;db 4

  dw  ET_EXEC  ;  e_type
  dw  EM_X8664  ;  e_machine
  dd  EV_CURRENT  ;  e_version
  dd  _start  ;  e_entry
  dd  phdr - $$  ;  e_phoff
  dd  0  ;  e_shoff
  dd  0  ;  e_flags
  dw  ehdrsz  ;  e_ehsize
  dw  phentsz  ;  e_phentsize
  dw  3  ;  e_phnum
  dw  shentsz  ;  e_shentsize
  dw  0  ;  e_shnum
  dw  0  ;  e_shstrndx
  ehdrsz  equ  $ - ehdr

  ;; The program segment header table

  phdr:  ; Elf32_Phdr
  dd  PT_INTERP  ;  p_type
  dd  interp - $$  ;  p_offset
  dd  interp  ;  p_vaddr
  dd  interp  ;  p_paddr
  dd  interpsz  ;  p_filesz
  dd  interpsz  ;  p_memsz
  dd  PF_R  ;  p_flags
  dd  0  ;  p_align
  phentsz  equ  $ - phdr
  dd  PT_LOAD  ;  p_type
  dd  0  ;  p_offset
  dd  $$  ;  p_vaddr
  dd  $$  ;  p_paddr
  dd  filesz  ;  p_filesz
  dd  memsz  ;  p_memsz
  dd  PF_R | PF_W | PF_X  ;  p_flags
  dd  0x1000  ;  p_align

  dd  PT_DYNAMIC  ;  p_type
  dd  dyntab - $$  ;  p_offset
  dd  dyntab  ;  p_vaddr
  dd  dyntab  ;  p_paddr
  dd  dyntabsz  ;  p_filesz
  dd  dyntabsz  ;  p_memsz
  dd  PF_R | PF_W  ;  p_flags
  dd  4  ;  p_align

  ;; The hash table

  hashtab:
  dd  1  ; no. of buckets
  dd  2  ; no. of symbols
  dd  1  ; the bucket: symbol #1
  dd  0, 0  ; two links, both zero

  ;; The symbol table

  symtab:  ; Elf32_Sym
  dd  0  ;  st_name
  dd  0  ;  st_value
  dd  0  ;  st_size
  db  0  ;  st_info
  db  0  ;  st_other
  dw  0  ;  st_shndx

  dd  exit_name  ;  st_name
  dd  0  ;  st_value
  dd  0  ;  st_size
  db  ST_INFO(STB_GLOBAL, STT_FUNC)  ;  st_info
  db  0  ;  st_other
  dw  0  ;  st_shndx


  dd  test_name  ;  st_name
  dd  0  ;  st_value
  dd  0  ;  st_size
  db  ST_INFO(STB_GLOBAL, STT_FUNC)  ;  st_info
  db  0  ;  st_other
  dw  0  ;  st_shndx
symentsz  equ  $ - symtab

  ;; The relocation table

  reltab:  ; Elf32_Rel
  dd  exit_call  ;  r_offset
  dd  R_INFO(1, R_AMD64_PC64)  ;  r_info
  relentsz  equ  $ - reltab

  reltab2:
  dd  test_call  ;  r_offset
  dd  R_INFO(1, R_AMD64_PC64)  ;  r_info

  relentsz2  equ  $ - reltab
  reltabsz  equ  $ - reltab

  ;; The dynamic section

  dyntab:
  dd  DT_STRTAB, strtab
  dd  DT_STRSZ,  strtabsz
  dd  DT_SYMTAB, symtab
  dd  DT_SYMENT, symentsz
  dd  DT_REL,  reltab
  dd  DT_RELSZ,  reltabsz
  dd  DT_RELENT, relentsz
  dd  DT_HASH,  hashtab
  dd  DT_NEEDED, libc_name
  dd  DT_NULL,  0

  dyntabsz  equ  $ - dyntab

  ;; The interpreter segment

  interp:
  db  '/lib64/ld-linux-x86-64.so.2', 0
  interpsz  equ  $ - interp

  ;; The string table

  strtab:
  db  0
  libc_name  equ  $ - strtab
  db  'libkbase.so', 0

  exit_name  equ  $ - strtab
  db  '_exit', 0

  test_name  equ  $ - strtab
  db  "_test_func", 0

  strtabsz  equ  $ - strtab

  ;; Our program

  _start:

  mov rax, 21
  call test_call

  push  byte 42
  call  exit_call


  exit_call  equ  $ - 4
  test_call  equ  $ - 4

  ;; End of the file image.

  filesz  equ  $ - $$
  memsz  equ  filesz
 

jkallup

Erfahrenes Mitglied
Hallo,

hat sich erstmal erledigt.
habe soeben mein eigenes binär format entworfen.
es könnte ganz einfach in linux eingeklingt werden, ohne den kernel neu zu übersetzen.

du fragst nach dem grund?
ich versuche so platform unabhängig wie möglich zu arbeiten,
und dabei bit und bytes zu sparen.
so ist zum beispiel eine test executable 170 bytes groß.
elf64 würde >= 2048 bytes ausmachen.

irgendwie mag ich linux :)