GNU/Linux >> Linux Esercitazione >  >> Linux

Esempi di comandi Linux Objcopy per copiare e tradurre file oggetto

Ci sono momenti in cui è necessario trasferire un file oggetto disponibile per un tipo di piattaforma (come ARM o x86) su un altro tipo di piattaforma. Le cose sono relativamente facili se il codice sorgente è disponibile in quanto può essere ricompilato sulla piattaforma di destinazione. Ma cosa succede se il codice sorgente non è disponibile ed è comunque necessario trasferire un file oggetto da un tipo di piattaforma a un altro? Bene, se stai usando Linux, il comando objcopy fa esattamente il necessario. In questo articolo impareremo l'utilizzo di base di questo comando attraverso alcuni esempi.

Dato che lavoro solo su tipo di piattaforma x86_64, cercherò di coprire alcune funzionalità neutre della piattaforma di questo comando in questo tutorial.

La sintassi di questo comando è:

objcopy [options] infile [outfile]...

Nota che le "opzioni" e "outfile" non sono argomenti obbligatori ma hanno un significato proprio.

Esempi

1. Copia semplicemente il file oggetto dall'origine alla destinazione

Considera il seguente esempio:

$ objcopy test new_test
$

Quindi il comando sopra copierà "test" in un nuovo file "new_test". Si noti che poiché in questo caso "test" è stato compilato sulla stessa piattaforma, quindi l'output "new_test" non sarà diverso.

Inoltre, se ti piace disassemblare un file binario e ottenere maggiori dettagli sui tuoi file oggetto, dovresti usare il comando objdump come spiegato in precedenza.

2. Copia il file oggetto senza fornire il nuovo nome file

Nell'esempio precedente, il file copiato è stato denominato "new_test" poiché è stato fornito insieme alle opzioni del comando. Tuttavia, se non viene fornito alcun nome file di destinazione, il comando objcopy sostituisce il file originale con il file copiato.

Considera il seguente esempio:

$ stat test
  File: `test'
  Size: 8498      	Blocks: 24         IO Block: 4096   regular file
Device: 805h/2053d	Inode: 1442357     Links: 1
Access: (0755/-rwxr-xr-x)  Uid: ( 1000/himanshu)   Gid: ( 1001/  family)
Access: 2012-08-31 21:25:54.828808055 +0530
Modify: 2012-08-31 21:25:50.498614487 +0530
Change: 2012-08-31 21:25:50.498614487 +0530

$ objcopy test

$ stat test
  File: `test'
  Size: 8498      	Blocks: 24         IO Block: 4096   regular file
Device: 805h/2053d	Inode: 1459714     Links: 1
Access: (0755/-rwxr-xr-x)  Uid: ( 1000/himanshu)   Gid: ( 1001/  family)
Access: 2012-08-31 21:30:04.108833244 +0530
Modify: 2012-08-31 21:30:04.108833244 +0530
Change: 2012-08-31 21:30:04.108833244 +0530

Quindi vediamo che le statistiche del file oggetto "test" sono state completamente modificate poiché objcopy lo ha creato come un file completamente nuovo.

3. Copia solo una sezione particolare usando l'opzione -j

Se desideri copiare solo una sezione dal file oggetto di origine al file oggetto di destinazione, in questo caso viene utilizzata l'opzione -j.

Considera il seguente esempio:

$ objcopy -j.interp test new_test
$

Il comando precedente copierà effettivamente solo la sezione .interp nel file new_test vuoto.

Se lo confermiamo :

$ objdump -s new_test 

new_test:     file format elf64-x86-64

Contents of section .interp:
 400238 2f6c6962 36342f6c 642d6c69 6e75782d  /lib64/ld-linux-
 400248 7838362d 36342e73 6f2e3200           x86-64.so.2.

Quindi vediamo che questo file contiene solo la sezione .interp (che abbiamo copiato da 'test' ).

4. Rimuovi solo una sezione particolare dal file copiato usando l'opzione -R

Questa opzione consente al comando objdump di copiare il file sorgente completo eccetto le sezioni specificate insieme a questa opzione.

Considera il seguente esempio:

$ objcopy -R.interp test new_test

Se confermiamo :

$ objdump -s -j.interp new_test 

new_test:     file format elf64-x86-64

Quindi vediamo che nessuna sezione .interp è nel nuovo file "new_test".

5. Conserva le date di accesso e modifica usando l'opzione -p

Le date di accesso e modifica del file copiato possono essere conservate (possono essere mantenute uguali alla fonte) usando l'opzione -p insieme a questo comando.

Considera il seguente esempio:

$ objcopy -p test new_tst

Il comando sopra conserverà la data/ora di accesso e modifica.

Se confermiamo :

$ $ stat test
  File: `test'
  Size: 8498      	Blocks: 24         IO Block: 4096   regular file
Device: 805h/2053d	Inode: 1459714     Links: 1
Access: (0755/-rwxr-xr-x)  Uid: ( 1000/himanshu)   Gid: ( 1001/  family)
Access: 2012-08-31 21:32:32.458629723 +0530
Modify: 2012-08-31 21:30:04.108833244 +0530
Change: 2012-08-31 21:30:04.108833244 +0530

$ stat new_tst
  File: `new_tst'
  Size: 8498      	Blocks: 24         IO Block: 4096   regular file
Device: 805h/2053d	Inode: 1442650     Links: 1
Access: (0755/-rwxr-xr-x)  Uid: ( 1000/himanshu)   Gid: ( 1001/  family)
Access: 2012-08-31 21:32:32.000000000 +0530
Modify: 2012-08-31 21:30:04.000000000 +0530
Change: 2012-08-31 21:42:25.938657423 +0530

Quindi vediamo che sia l'ora/data di modifica sia quella di accesso sono state mantenute.

6. Cambia tutti i simboli globali in deboli usando l'opzione –weaken

Questo può essere utile durante la creazione di un file oggetto che può essere collegato ad altri file oggetto utilizzando l'opzione -R al linker.

Considera il seguente esempio:

$ readelf -s new_test

Symbol table '.dynsym' contains 4 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.2.5 (2)
     2: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)

Symbol table '.symtab' contains 65 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000400238     0 SECTION LOCAL  DEFAULT    1
     2: 0000000000400254     0 SECTION LOCAL  DEFAULT    2
     3: 0000000000400274     0 SECTION LOCAL  DEFAULT    3
     4: 0000000000400298     0 SECTION LOCAL  DEFAULT    4
     ..
    27: 0000000000000000     0 SECTION LOCAL  DEFAULT   27
    28: 000000000040046c     0 FUNC    LOCAL  DEFAULT   14 call_gmon_start
    29: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    ..
    49: 0000000000400550     2 FUNC    GLOBAL DEFAULT   14 __libc_csu_fini
    50: 0000000000400440     0 FUNC    GLOBAL DEFAULT   14 _start
    51: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
    52: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _Jv_RegisterClasses
    53: 0000000000400628     0 FUNC    GLOBAL DEFAULT   15 _fini
    54: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@@GLIBC_
    55: 0000000000400638     4 OBJECT  GLOBAL DEFAULT   16 _IO_stdin_used
    ..
$ objcopy --weaken test new_test

$ readelf -s new_test

Symbol table '.dynsym' contains 4 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.2.5 (2)
     2: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)

Symbol table '.symtab' contains 65 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000400238     0 SECTION LOCAL  DEFAULT    1
     2: 0000000000400254     0 SECTION LOCAL  DEFAULT    2
     3: 0000000000400274     0 SECTION LOCAL  DEFAULT    3
     4: 0000000000400298     0 SECTION LOCAL  DEFAULT    4
     ..
    28: 000000000040046c     0 FUNC    LOCAL  DEFAULT   14 call_gmon_start
    29: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    30: 0000000000600e18     0 OBJECT  LOCAL  DEFAULT   19 __CTOR_LIST__
    31: 0000000000600e28     0 OBJECT  LOCAL  DEFAULT   20 __DTOR_LIST__
    32: 0000000000600e38     0 OBJECT  LOCAL  DEFAULT   21 __JCR_LIST__
    ...
    49: 0000000000400550     2 FUNC    WEAK   DEFAULT   14 __libc_csu_fini
    50: 0000000000400440     0 FUNC    WEAK   DEFAULT   14 _start
    51: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
    52: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _Jv_RegisterClasses
    53: 0000000000400628     0 FUNC    WEAK   DEFAULT   15 _fini
    54: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@@GLIBC_
    55: 0000000000400638     4 OBJECT  WEAK   DEFAULT   16 _IO_stdin_used
    56: 0000000000601010     0 NOTYPE  WEAK   DEFAULT   25 __data_start
    ..
$

Quindi vediamo che dopo aver eseguito il comando objcopy con il flag –weaken, tutti i simboli GLOBAL sono stati convertiti in DEBOLE.

7. Prefissare i simboli con una stringa usando l'opzione –prefix-symbols

Considera il seguente esempio in cui si desidera che una stringa "TGS" sia preceduta dai nomi dei simboli:

$ objcopy --prefix-symbols="TGS" test new_test
$ readelf -s new_test

Symbol table '.dynsym' contains 4 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.2.5 (2)
     2: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)

Symbol table '.symtab' contains 65 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000400238     0 SECTION LOCAL  DEFAULT    1
     2: 0000000000400254     0 SECTION LOCAL  DEFAULT    2
     3: 0000000000400274     0 SECTION LOCAL  DEFAULT    3
     4: 0000000000400298     0 SECTION LOCAL  DEFAULT    4
     ...
    28: 000000000040046c     0 FUNC    LOCAL  DEFAULT   14 TGScall_gmon_start
    29: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS TGScrtstuff.c
    30: 0000000000600e18     0 OBJECT  LOCAL  DEFAULT   19 TGS__CTOR_LIST__
    31: 0000000000600e28     0 OBJECT  LOCAL  DEFAULT   20 TGS__DTOR_LIST__
    32: 0000000000600e38     0 OBJECT  LOCAL  DEFAULT   21 TGS__JCR_LIST__
    33: 0000000000400490     0 FUNC    LOCAL  DEFAULT   14 TGS__do_global_dtors_aux
    ...

Quindi vediamo che "TGS" era preceduto dai nomi dei simboli.

8. Elimina un particolare simbolo usando l'opzione –strip-symbols

Nel caso in cui alcuni simboli debbano essere rimossi, è possibile utilizzare l'opzione –strip-symbols insieme al nome di un file. Questo nome file contiene i nomi dei simboli da rimuovere (uno in ogni riga).

Si consideri il seguente esempio in cui il nome del simbolo "call_gmon_start" verrà rimosso come specificato in un file (symbolname).

 $ readelf -s new_test

Symbol table '.dynsym' contains 4 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.2.5 (2)
     2: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)

Symbol table '.symtab' contains 65 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000400238     0 SECTION LOCAL  DEFAULT    1
     2: 0000000000400254     0 SECTION LOCAL  DEFAULT    2
     3: 0000000000400274     0 SECTION LOCAL  DEFAULT    3
     4: 0000000000400298     0 SECTION LOCAL  DEFAULT    4
     .....
    28: 000000000040046c 0 FUNC LOCAL DEFAULT 14 call_gmon_start
    29: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    30: 0000000000600e18     0 OBJECT  LOCAL  DEFAULT   19 __CTOR_LIST__
    31: 0000000000600e28     0 OBJECT  LOCAL  DEFAULT   20 __DTOR_LIST__
    32: 0000000000600e38     0 OBJECT  LOCAL  DEFAULT   21 __JCR_LIST__
    33: 0000000000400490     0 FUNC    LOCAL  DEFAULT   14 __do_global_dtors_aux
    ...

$ objcopy --strip-symbols=symbolname test new_test

$ readelf -s new_test

Symbol table '.dynsym' contains 4 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.2.5 (2)
     2: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)

Symbol table '.symtab' contains 64 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000400238     0 SECTION LOCAL  DEFAULT    1
     2: 0000000000400254     0 SECTION LOCAL  DEFAULT    2
     3: 0000000000400274     0 SECTION LOCAL  DEFAULT    3
     4: 0000000000400298     0 SECTION LOCAL  DEFAULT    4
     ...
    26: 0000000000601020     0 SECTION LOCAL  DEFAULT   26
    27: 0000000000000000     0 SECTION LOCAL  DEFAULT   27
    28: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    29: 0000000000600e18     0 OBJECT  LOCAL  DEFAULT   19 __CTOR_LIST__
    30: 0000000000600e28     0 OBJECT  LOCAL  DEFAULT   20 __DTOR_LIST__
    31: 0000000000600e38     0 OBJECT  LOCAL  DEFAULT   21 __JCR_LIST__
    32: 0000000000400490     0 FUNC    LOCAL  DEFAULT   14 __do_global_dtors_aux
    ...

Quindi vediamo che il simbolo "call_gmon_start" è stato rimosso con successo.

9. Prefissare i nomi delle sezioni con una stringa usando l'opzione –prefix-sections

Considera il seguente esempio:

$ objcopy --prefix-sections="TGS" test new_test
$ readelf -s new_test
readelf: Error: no .dynamic section in the dynamic segment

Symbol table 'TGS.dynsym' contains 4 entries:
Num: Value          Size Type    Bind  Vis     Ndx Name
0: 0000000000000000 0    NOTYPE  LOCAL DEFAULT UND
...
...
...

Quindi vediamo che il nome della sezione era preceduto dalla nostra stringa TGS fornita.

10. Mantieni il simbolo del nome del file sorgente usando l'opzione –keep-file-symbols

Ogni volta che si utilizza il simbolo –strip-debug (che rimuove molti simboli relativi al debug insieme al simbolo che specifica il nome del file), se è necessario mantenere il simbolo del nome del file di origine, è possibile utilizzare –keep-file-symbols.

Considera il seguente esempio:

$ objcopy --strip-debug test new_test
$ readelf -s new_test

Symbol table '.dynsym' contains 4 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.2.5 (2)
     2: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)

Symbol table '.symtab' contains 62 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 000000000040046c     0 FUNC    LOCAL  DEFAULT   14 call_gmon_start
     2: 0000000000600e18     0 OBJECT  LOCAL  DEFAULT   19 __CTOR_LIST__
     3: 0000000000600e28     0 OBJECT  LOCAL  DEFAULT   20 __DTOR_LIST__
     4: 0000000000600e38     0 OBJECT  LOCAL  DEFAULT   21 __JCR_LIST__
     ...
    10: 00000000004006e8     0 OBJECT  LOCAL  DEFAULT   18 __FRAME_END__
    11: 0000000000600e38     0 OBJECT  LOCAL  DEFAULT   21 __JCR_END__
    12: 00000000004005f0     0 FUNC    LOCAL  DEFAULT   14 __do_global_ctors_aux
    13: 0000000000600fe8     0 OBJECT  LOCAL  HIDDEN   24 _GLOBAL_OFFSET_TABLE_
    14: 0000000000600e14     0 NOTYPE  LOCAL  HIDDEN   19 __init_array_end
    15: 0000000000600e14     0 NOTYPE  LOCAL  HIDDEN   19 __init_array_start
    ...

$ objcopy --strip-debug --keep-file-symbols test new_test

$ readelf -s new_test

Symbol table '.dynsym' contains 4 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.2.5 (2)
     2: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)

Symbol table '.symtab' contains 65 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 000000000040046c     0 FUNC    LOCAL  DEFAULT   14 call_gmon_start
     2: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
     3: 0000000000600e18     0 OBJECT  LOCAL  DEFAULT   19 __CTOR_LIST__
     4: 0000000000600e28     0 OBJECT  LOCAL  DEFAULT   20 __DTOR_LIST__
     ...
    12: 00000000004006e8     0 OBJECT  LOCAL  DEFAULT   18 __FRAME_END__
    13: 0000000000600e38     0 OBJECT  LOCAL  DEFAULT   21 __JCR_END__
    14: 00000000004005f0     0 FUNC    LOCAL  DEFAULT   14 __do_global_ctors_aux
    15: 0000000000000000 0 FILE LOCAL DEFAULT ABS test.c
    16: 0000000000600fe8     0 OBJECT  LOCAL  HIDDEN   24 _GLOBAL_OFFSET_TABLE_
    17: 0000000000600e14     0 NOTYPE  LOCAL  HIDDEN   19 __init_array_end
    18: 0000000000600e14     0 NOTYPE  LOCAL  HIDDEN   19 __init_array_start
    ...

Nell'esempio sopra, in primo luogo objcopy è stato eseguito con l'opzione –strip-debug che (insieme a molti altri simboli) ha rimosso il simbolo che menzionava il nome del file sorgente (test.c). Quindi eseguiamo nuovamente il comando objcopy insieme all'opzione –keep-file-symbols e osserviamo (in grassetto) che il simbolo per il nome del file sorgente non è stato rimosso.


Linux
  1. 5 Esempi di comandi Wget per scaricare file in Linux.

  2. 6 Esempi di comandi mv per spostare o rinominare file e directory Linux

  3. Come copiare file in Linux e Unix? 10 cp Esempi di comandi

  4. 10 esempi di comandi Cat per gestire i file in Linux / UNIX

  5. ln Esempi di comandi in Linux

Come spostare file e directory in Linux (comando mv)

Comando Cp in Linux (copia file)

lsof Command in Linux (10 esempi)

Come copiare file e directory nel terminale Linux

Cat Command in Linux:esempi essenziali e avanzati

Comando tar di Linux per comprimere ed estrarre file