@@ -60,7 +60,6 @@ extern int sqfs_opt_proc(void* data, const char* arg, int key, struct fuse_args*
6060#include <sys/wait.h>
6161#include <fnmatch.h>
6262#include <sys/mman.h>
63-
6463#include <stdint.h>
6564
6665typedef struct {
@@ -313,6 +312,57 @@ ssize_t appimage_get_elf_size(const char* fname) {
313312 return size ;
314313}
315314
315+ /* Return the offset, and the length of an ELF section with a given name in a given ELF file */
316+ bool appimage_get_elf_section_offset_and_length (const char * fname , const char * section_name , unsigned long * offset , unsigned long * length ) {
317+ uint8_t * data ;
318+ int i ;
319+ int fd = open (fname , O_RDONLY );
320+ size_t map_size = (size_t ) lseek (fd , 0 , SEEK_END );
321+
322+ data = mmap (NULL , map_size , PROT_READ , MAP_SHARED , fd , 0 );
323+ close (fd );
324+
325+ // this trick works as both 32 and 64 bit ELF files start with the e_ident[EI_NINDENT] section
326+ unsigned char class = data [EI_CLASS ];
327+
328+ if (class == ELFCLASS32 ) {
329+ Elf32_Ehdr * elf ;
330+ Elf32_Shdr * shdr ;
331+
332+ elf = (Elf32_Ehdr * ) data ;
333+ shdr = (Elf32_Shdr * ) (data + ((Elf32_Ehdr * ) elf )-> e_shoff );
334+
335+ char * strTab = (char * ) (data + shdr [elf -> e_shstrndx ].sh_offset );
336+ for (i = 0 ; i < elf -> e_shnum ; i ++ ) {
337+ if (strcmp (& strTab [shdr [i ].sh_name ], section_name ) == 0 ) {
338+ * offset = shdr [i ].sh_offset ;
339+ * length = shdr [i ].sh_size ;
340+ }
341+ }
342+ } else if (class == ELFCLASS64 ) {
343+ Elf64_Ehdr * elf ;
344+ Elf64_Shdr * shdr ;
345+
346+ elf = (Elf64_Ehdr * ) data ;
347+ shdr = (Elf64_Shdr * ) (data + elf -> e_shoff );
348+
349+ char * strTab = (char * ) (data + shdr [elf -> e_shstrndx ].sh_offset );
350+ for (i = 0 ; i < elf -> e_shnum ; i ++ ) {
351+ if (strcmp (& strTab [shdr [i ].sh_name ], section_name ) == 0 ) {
352+ * offset = shdr [i ].sh_offset ;
353+ * length = shdr [i ].sh_size ;
354+ }
355+ }
356+ } else {
357+ fprintf (stderr , "Platforms other than 32-bit/64-bit are currently not supported!" );
358+ munmap (data , map_size );
359+ return false;
360+ }
361+
362+ munmap (data , map_size );
363+ return true;
364+ }
365+
316366/* Return the offset, and the length of an ELF section with a given name in a given ELF file */
317367char * read_file_offset_length (const char * fname , unsigned long offset , unsigned long length ) {
318368 FILE * f ;
@@ -330,6 +380,35 @@ char* read_file_offset_length(const char* fname, unsigned long offset, unsigned
330380 return buffer ;
331381}
332382
383+ int appimage_print_hex (char * fname , unsigned long offset , unsigned long length ) {
384+ char * data ;
385+ if ((data = read_file_offset_length (fname , offset , length )) == NULL ) {
386+ return 1 ;
387+ }
388+
389+ for (long long k = 0 ; k < length && data [k ] != '\0' ; k ++ ) {
390+ printf ("%x" , data [k ]);
391+ }
392+
393+ free (data );
394+
395+ printf ("\n" );
396+
397+ return 0 ;
398+ }
399+
400+ int appimage_print_binary (char * fname , unsigned long offset , unsigned long length ) {
401+ char * data ;
402+ if ((data = read_file_offset_length (fname , offset , length )) == NULL ) {
403+ return 1 ;
404+ }
405+
406+ printf ("%s\n" , data );
407+
408+ free (data );
409+
410+ return 0 ;
411+ }
333412
334413/* Exit status to use when launching an AppImage fails.
335414 * For applications that assign meanings to exit status codes (e.g. rsync),
@@ -523,6 +602,8 @@ void print_help(const char* appimage_path) {
523602 " https://github.com/vasi/squashfuse/blob/master/LICENSE\n"
524603 " * libzstd, licensed under the terms of\n"
525604 " https://github.com/facebook/zstd/blob/dev/LICENSE\n"
605+ " * zlib, licensed under the terms of\n"
606+ " https://zlib.net/zlib_license.html\n"
526607 "Please see https://github.com/probonopd/static-tools/\n"
527608 "for information on how to obtain and build the source code\n" , appimage_path );
528609}
@@ -1441,18 +1522,28 @@ int main(int argc, char* argv[]) {
14411522 exit (status );
14421523 }
14431524
1444- if (arg && (strcmp (arg , "appimage-updateinformation" ) == 0 || strcmp (arg , "appimage-updateinfo" ) == 0 )) {
1445- fprintf (stderr , "--%s is not yet implemented in version %s\n" , arg , GIT_COMMIT );
1446- // NOTE: Must be implemented in this .c file with no additional dependencies
1447- exit (1 );
1525+ if (arg && (strcmp (arg ,"appimage-updateinformation" )== 0 || strcmp (arg ,"appimage-updateinfo" )== 0 )) {
1526+ unsigned long offset = 0 ;
1527+ unsigned long length = 0 ;
1528+ appimage_get_elf_section_offset_and_length (appimage_path , ".upd_info" , & offset , & length );
1529+ // fprintf(stderr, "offset: %lu\n", offset);
1530+ // fprintf(stderr, "length: %lu\n", length);
1531+ // print_hex(appimage_path, offset, length);
1532+ appimage_print_binary (appimage_path , offset , length );
1533+ exit (0 );
14481534 }
14491535
1450- if (arg && strcmp (arg , "appimage-signature" ) == 0 ) {
1451- fprintf (stderr , "--%s is not yet implemented in version %s\n" , arg , GIT_COMMIT );
1452- // NOTE: Must be implemented in this .c file with no additional dependencies
1453- exit (1 );
1536+ if (arg && strcmp (arg ,"appimage-signature" )== 0 ) {
1537+ unsigned long offset = 0 ;
1538+ unsigned long length = 0 ;
1539+ appimage_get_elf_section_offset_and_length (appimage_path , ".sha256_sig" , & offset , & length );
1540+ // fprintf(stderr, "offset: %lu\n", offset);
1541+ // fprintf(stderr, "length: %lu\n", length);
1542+ // print_hex(appimage_path, offset, length);
1543+ appimage_print_binary (appimage_path , offset , length );
1544+ exit (0 );
14541545 }
1455-
1546+
14561547 portable_option (arg , appimage_path , "home" );
14571548 portable_option (arg , appimage_path , "config" );
14581549
0 commit comments