tag mp3tag kid3 editar easytag linux unix embedded

linux - kid3 - mp3tag



Encabezados de archivo ELF (9)

Una pregunta rápida sobre los encabezados de archivos elf, parece que no encuentro nada útil sobre cómo agregar / cambiar campos en el encabezado de duela. Me gustaría poder cambiar los números mágicos y agregar una fecha de compilación al encabezado, y probablemente algunas otras cosas más.

Según tengo entendido, el vinculador crea la información del encabezado, pero no veo nada en el script LD que se refiera a él (aunque soy nuevo en los scripts ld).

Estoy usando gcc y compilando para ARM.

¡Gracias!

Actualizaciones:

  • ok tal vez mi primera pregunta debería ser: ¿es posible crear / editar el archivo de encabezado en el momento del enlace?

Estoy bastante seguro de que una secuencia de comandos ld lo suficientemente compleja puede hacer lo que quieras. Sin embargo, no tengo idea de cómo.

Por otro lado, elfsh puede hacer todo tipo de manipulaciones a los objetos elfos, así que dale un giro.


No he hecho esto por un tiempo, pero no puedes agregar datos arbitrarios a un ejecutable. Si siempre anexa datos de tamaño fijo, sería trivial recuperar todo lo que agregue. El tamaño variable no sería mucho más difícil. Probablemente sea más fácil que jugar con encabezados de w / elf y potencialmente arruinar tus ejecutables.


No sé de los comandos de secuencia de comandos del enlazador que pueden hacer esto, pero puede hacerlo post-link usando el comando objcopy . La opción --add-section se puede usar para agregar una sección que contenga datos arbitrarios al archivo ELF. Si el encabezado ELF no contiene los campos que desea, solo haga una nueva sección y agréguela allí.


No terminé el libro, pero iirc Linkers and Loaders de John Levine tenía los detalles sangrientos que necesitaría para poder hacer esto.



En consola Linux:

$ hombre ld

$ ld --verbose

HTH


En Solaris puede usar elfedit, pero creo que realmente está pidiendo soluciones para Linux. Linux no es UniX: P


Puede crear un archivo de objeto con campos informativos, como un número de versión, y vincular ese archivo para que se incluyan en el binario ELF resultante.

Ident

Por ejemplo, como parte de su proceso de compilación, puede generar, por ejemplo, info.c que contenga una o más directivas #ident :

#ident "Build: 1.2.3 (Halloween)" #ident "Environment: example.org"

Compilarlo:

$ gcc -c info.c

Verifique si la información está incluida:

$ readelf -p .comment info.o String dump of section ''.comment'': [ 1] Build: 1.2.3 (Halloween) [ 1a] Environment: example.org [ 33] GCC: (GNU) 7.2.1 20170915 (Red Hat 7.2.1-2)

Alternativamente, puede usar objdump -s --section .comment info.o Tenga en cuenta que GCC también escribe su propio comentario, por defecto.

Verifique la información después de vincular un ejecutable ELF:

$ gcc -o main main.o info.o $ readelf -p .comment main String dump of section ''.comment'': [ 0] GCC: (GNU) 7.2.1 20170915 (Red Hat 7.2.1-2) [ 2c] Build: 1.2.3 (Halloween) [ 45] Environment: example.org

Sección de comentarios

Usar #ident en una unidad de traducción C es básicamente equivalente a crear una sección .comment en un archivo de ensamblador. Ejemplo:

$ cat info.s .section .comment .string "Build: 1.2.3 (Halloween)" .string "Environment: example.org" $ gcc -c info.s String dump of section ''.comment'': [ 0] Build: 1.2.3 (Halloween) [ 19] Environment: example.org

El uso de un nombre de sección poco común también funciona (p .section .blahblah ., .section .blahblah ). Pero .comment es usado y entendido por otras herramientas. GNU también entiende la directiva .ident , y esto es a lo que GCC traduce #ident a.

Con símbolos

Para los datos a los que también desea acceder desde el ejecutable ELF, debe crear símbolos.

Objcopy

Supongamos que desea incluir algunos bytes mágicos almacenados en un archivo de datos:

$ cat magic.bin 2342

Convierte en un archivo de objeto con objcopy de GNU :

$ objcopy -I binary -O elf64-x86-64 -B i386 / --rename-section .data=.rodata,alloc,load,readonly,data,contents / magic.bin magic.o

Compruebe los símbolos:

$ nm magic.o 0000000000000005 R _binary_magic_bin_end 0000000000000005 A _binary_magic_bin_size 0000000000000000 R _binary_magic_bin_start

Ejemplo de uso:

#include <stdio.h> #include <string.h> #include <inttypes.h> extern const char _binary_magic_bin_start[]; extern const char _binary_magic_bin_end[]; extern const unsigned char _binary_magic_bin_size; static const size_t magic_bin_size = (uintptr_t) &_binary_magic_bin_size; int main() { char s[23]; memcpy(s, _binary_magic_bin_start, _binary_magic_bin_end - _binary_magic_bin_start); s[magic_bin_size] = 0; puts(s); return 0; }

Enlace todo junto:

$ gcc -g -o main_magic main_magic.c magic.o

GNU ld

GNU ld también puede convertir archivos de datos en archivos de objetos usando un esquema de nombres compatible con objcopy:

$ ld -r -b binary magic.bin -o magic-ld.o

A diferencia de objcopy, coloca los símbolos en .data lugar de la sección .rodata , sin embargo (ver objdump -h magic.o ).

incbin

En caso de que GNU objcopy no esté disponible, se puede usar GNU como directiva .incbin para crear el archivo objeto (ensamblar con gcc -c incbin.s ):

.section .rodata .global _binary_magic_bin_start .type _binary_magic_bin_start, @object _binary_magic_bin_start: .incbin "magic.bin" .size _binary_magic_bin_start, . - _binary_magic_bin_start .global _binary_magic_bin_size .type _binary_magic_bin_size, @object .set _binary_magic_bin_size, . - _binary_magic_bin_start .global _binary_magic_bin_end .type _binary_magic_bin_end, @object .set _binary_magic_bin_end, _binary_magic_bin_start + _binary_magic_bin_size ; an alternate way to include the size .global _binary_magic_bin_len .type _binary_magic_bin_len, @object .size _binary_magic_bin_len, 8 _binary_magic_bin_len: .quad _binary_magic_bin_size

xxd

Una alternativa más portátil que no requiere GNU objcopy ni GNU ya que es crear un archivo C intermedio y compilar y vincular eso. Por ejemplo, con xxd :

$ xxd -i magic.bin | sed ''s//(unsigned/)/const /1/'' > magic.c $ gcc -c magic.c $ nm magic.o 0000000000000000 R magic_bin 0000000000000008 R magic_bin_len $ cat magic.c const unsigned char magic_bin[] = { 0x32, 0x33, 0x34, 0x32, 0x0a }; const unsigned int magic_bin_len = 5;


Es posible que pueda usar libmelf, un proyecto inactivo en carne fresca, pero disponible en LOPI - http://www.ipd.bth.se/ska/lopi.html

De lo contrario, puede obtener la especificación y (sobre) escribir el encabezado usted mismo.