Permalink
Browse files

Function to read ELF sections

  • Loading branch information...
1 parent 86a0ba2 commit 2824afc9e662fd6858fb5f1fa1f6d95a06bc8008 @probonopd committed Sep 25, 2016
Showing with 102 additions and 65 deletions.
  1. +5 −34 appimagetool.c
  2. +2 −2 build.sh
  3. +7 −29 digest.c
  4. +77 −0 getsection.c
  5. +11 −0 getsection.h
View
@@ -23,6 +23,7 @@
#include <string.h>
#include "elf.h"
+#include "getsection.h"
extern int _binary_runtime_start;
extern int _binary_runtime_size;
@@ -228,8 +229,6 @@ main (int argc, char *argv[])
/* Check for dependencies here. Better fail early if they are not present. */
if(! g_find_program_in_path ("mksquashfs"))
die("mksquashfs is missing but required, please install it");
- if(! g_find_program_in_path ("objdump"))
- die("objdump is missing but required, please install it");
if(! g_find_program_in_path ("zsyncmake"))
g_print("WARNING: zsyncmake is missing, will not be able to generate zsync files, please install it if you want to use binary delta updates\n");
if(! g_find_program_in_path ("appstreamcli"))
@@ -471,45 +470,17 @@ main (int argc, char *argv[])
if (fp == NULL)
die("Failed to run zsyncmake command");
}
-
- gchar *objdump_path = g_find_program_in_path ("objdump");
-
- sprintf (command, "%s -h %s", objdump_path, destination);
-
- fp = popen(command, "r");
- if (fp == NULL)
- die("Failed to run objdump command");
-
- long ui_offset = 0;
- /* TODO: replace with more robust code parsing the ELF like in elf_elf_size */
- while(fgets(line, sizeof(line), fp) != NULL ){
- if(strstr(line, ".upd_info") != NULL)
- {
- if(verbose)
- printf("%s", line);
-
- char *token = strtok(line, " \t"); // Split the line in tokens
- token = strtok(NULL, " \t"); // We are not interested in this token
- token = strtok(NULL, " \t"); // We are not interested in this token
- token = strtok(NULL, " \t"); // We are not interested in this token
- token = strtok(NULL, " \t"); // We are not interested in this token
- token = strtok(NULL, " \t"); // We are not interested in this token
- if(verbose)
- printf("token parsed from objdump: %s\n", token);
- ui_offset = (int)strtol(token, NULL, 16) + 0;
- if(verbose)
- printf("ui_offset: %lu\n", ui_offset);
- }
- }
- fclose(fp);
+ unsigned long ui_offset = 0;
+ unsigned long ui_length = 0;
+ get_elf_section_offset_and_lenghth(destination, ".upd_info", &ui_offset, &ui_length);
if(ui_offset == 0)
die("Could not determine offset for updateinformation");
fseek(fpdst, ui_offset, SEEK_SET);
// fwrite(0x00, 1, 1024, fpdst); // FIXME: Segfaults; why?
fseek(fpdst, ui_offset, SEEK_SET);
- fwrite(updateinformation, strlen(updateinformation), 1, fpdst);
+ fwrite(updateinformation, strlen(updateinformation), 1, fpdst); // TODO: Use ui_length which is the maximum length the segment has available
}
fclose(fpdst);
fprintf (stderr, "Success\n");
View
@@ -34,7 +34,7 @@ cd build
# Compile and link digest tool
-cc -o digest ../digest.c -lssl -lcrypto
+cc -o digest ../getsection.c ../digest.c -lssl -lcrypto
# cc -o digest -Wl,-Bdynamic ../digest.c -Wl,-Bstatic -static -lcrypto -Wl,-Bdynamic -ldl # 1.4 MB
strip digest
@@ -76,7 +76,7 @@ ld -r -b binary -o data.o runtime
# Compile appimagetool but do not link - glib version
-cc -DVERSION_NUMBER=\"$(git describe --tags --always --abbrev=7)\" -D_FILE_OFFSET_BITS=64 -I ../squashfuse $(pkg-config --cflags glib-2.0) -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -g -Os -c ../appimagetool.c
+cc -DVERSION_NUMBER=\"$(git describe --tags --always --abbrev=7)\" -D_FILE_OFFSET_BITS=64 -I ../squashfuse $(pkg-config --cflags glib-2.0) -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -g -Os -c ../appimagetool.c ../getsection.c
# Now statically link against libsquashfuse and liblzma - glib version
View
@@ -1,5 +1,5 @@
/*
- cc -o digest digest.c -lssl -lcrypto
+ cc -o digest getsection.c digest.c -lssl -lcrypto
*/
#include <stdio.h>
@@ -10,6 +10,8 @@
#include <sys/stat.h>
#include <linux/limits.h>
+#include "getsection.h"
+
typedef unsigned char byte;
char segment_name[] = ".sha256_sig";
@@ -100,38 +102,14 @@ int main(int argc,char **argv) {
exit(1);
}
- int skip_offset;
- int skip_length;
+ unsigned long skip_offset = 0;
+ unsigned long skip_length = 0;
char *filename = argv[1];
if(argc < 4){
- /* TODO: replace with more robust code parsing the ELF like in elf_elf_size */
- char line[PATH_MAX];
- char command[PATH_MAX];
- sprintf (command, "/usr/bin/objdump -h %s", filename);
- FILE *fp;
- fp = popen(command, "r");
- if (fp == NULL){
- fprintf(stderr, "Failed to run objdump command\n");
- exit(1);
- }
- long ui_offset = 0;
- while(fgets(line, sizeof(line), fp) != NULL ){
- if(strstr(line, segment_name) != NULL)
- {
- char *token = strtok(line, " \t"); // Split the line in tokens
- token = strtok(NULL, " \t"); // We are not interested in this token
- token = strtok(NULL, " \t");
- skip_length = (int)strtol(token, NULL, 16);
- token = strtok(NULL, " \t"); // We are not interested in this token
- token = strtok(NULL, " \t"); // We are not interested in this token
- token = strtok(NULL, " \t"); // We are not interested in this token
- skip_offset = (int)strtol(token, NULL, 16);
- }
- }
- fclose(fp);
+ get_elf_section_offset_and_lenghth(filename, ".sha256_sig", &skip_offset, &skip_length);
if(skip_length > 0)
- fprintf(stderr, "Skipping ELF section %s with offset %i, length %i\n", segment_name, skip_offset, skip_length);
+ fprintf(stderr, "Skipping ELF section %s with offset %lu, length %lu\n", segment_name, skip_offset, skip_length);
} else if(argc == 4) {
skip_offset = atoi(argv[2]);
skip_length = atoi(argv[3]);
View
@@ -0,0 +1,77 @@
+#include <elf.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <string.h>
+#include <unistd.h>
+
+/* Return the offset, and the length of an ELF section with a given name in a given ELF file */
+int get_elf_section_offset_and_lenghth(char* fname, char* section_name, unsigned long *offset, unsigned long *length)
+{
+ uint8_t *data;
+ int i;
+ Elf64_Ehdr *elf;
+ Elf64_Shdr *shdr;
+ int fd = open(fname, O_RDONLY);
+ data = mmap(NULL, lseek(fd, 0, SEEK_END), PROT_READ, MAP_SHARED, fd, 0);
+ close(fd);
+ elf = (Elf64_Ehdr *) data;
+ shdr = (Elf64_Shdr *) (data + elf->e_shoff);
+ char *strTab = (char *)(data + shdr[elf->e_shstrndx].sh_offset);
+ for(i = 0; i < elf->e_shnum; i++) {
+ if(strcmp(&strTab[shdr[i].sh_name], section_name) == 0) {
+ *offset = shdr[i].sh_offset;
+ *length = shdr[i].sh_size;
+ }
+ }
+ return(0);
+}
+
+void print_hex(char* fname, unsigned long offset, unsigned long length){
+ uint8_t *data;
+ unsigned long k;
+ int fd = open(fname, O_RDONLY);
+ data = mmap(NULL, lseek(fd, 0, SEEK_END), PROT_READ, MAP_SHARED, fd, 0);
+ close(fd);
+ for (k = offset; k < offset + length; k++) {
+ printf("%x", data[k]);
+ }
+ printf("\n");
+}
+
+void print_binary(char* fname, unsigned long offset, unsigned long length){
+ uint8_t *data;
+ unsigned long k;
+ int fd = open(fname, O_RDONLY);
+ data = mmap(NULL, lseek(fd, 0, SEEK_END), PROT_READ, MAP_SHARED, fd, 0);
+ close(fd);
+ for (k = offset; k < offset + length; k++) {
+ printf("%c", data[k]);
+ }
+ printf("\n");
+}
+
+/*
+int main(int ac, char **av)
+{
+ unsigned long offset = 0;
+ unsigned long length = 0; // Where the function will store the result
+ char* segment_name;
+ segment_name = ".upd_info";
+ int res = get_elf_section_offset_and_lenghth(av[1], segment_name, &offset, &length);
+ printf("segment_name: %s\n", segment_name);
+ printf("offset: %lu\n", offset);
+ printf("length: %lu\n", length);
+ print_hex(av[1], offset, length);
+ print_binary(av[1], offset, length);
+ segment_name = ".sha256_sig";
+ printf("segment_name: %s\n", segment_name);
+ res = get_elf_section_offset_and_lenghth(av[1], segment_name, &offset, &length);
+ printf("offset: %lu\n", offset);
+ printf("length: %lu\n", length);
+ print_hex(av[1], offset, length);
+ print_binary(av[1], offset, length);
+ return res;
+}
+*/
View
@@ -0,0 +1,11 @@
+#ifndef __GETSECTION_H__
+#define __GETSECTION_H__
+
+/* Return the offset, and the length of an ELF section with a given name in a given ELF file */
+int get_elf_section_offset_and_lenghth(char* fname, char* section_name, unsigned long *offset, unsigned long *length);
+
+void print_hex(char* fname, unsigned long offset, unsigned long length);
+
+void print_binary(char* fname, unsigned long offset, unsigned long length);
+
+#endif /* __GETSECTION_H__ */

0 comments on commit 2824afc

Please sign in to comment.