RElicAnalysis/tests/bfd_file.c
2026-04-29 13:56:33 +02:00

122 lines
3.3 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <bfd.h>
#include <dis-asm.h>
// apt install binutils binutils-dev
// https://sourceware.org/binutils/docs/bfd/BFD-Index.html
// gcc bfd_file.c -o bfd_file -lopcodes -lbfd && ./bfd_file
// https://ftp.gnu.org/old-gnu/Manuals/bfd-2.9.1/html_chapter/bfd_1.html
static bfd_boolean disassemble;
struct data {
char *data;
};
static int dump_asm(void *stream, const char *fmt, ...){
struct data *sData = (struct data*)stream;
va_list args;
va_start(args, fmt);
char str[64];
vsprintf(str, fmt, args);
//vsnprintf(str, sizeof(str), fmt, args);
//asprintf(str, "%s\n", args);
va_end(args);
char tmp[64];
memset(tmp, 0, 64);
//printf("%d\n", sData->offset);
if (strlen(sData->data) > 0){
memcpy(tmp, sData->data, 64);
//printf("TMP: %s %d\n", tmp, strlen(tmp));
strcat(tmp, str);
}
else
memcpy(tmp, str, strlen(str));
memcpy(sData->data, tmp, 64);
}
static int disass(){
struct disassemble_info disasm_info;
struct data *sData = (struct data*)malloc(sizeof(struct data));
sData->data = (char*)malloc(64);
//char filename[256] = "/home/geoffrey/Documents/GIT/cybersecurity/forensic/disassembly/call_function";
char filename[256];
bfd *abfd = NULL;
struct stat s_stat;
int fd_r;
pid_t pid = getpid();
sprintf(filename, "/proc/%d/exe", pid);
printf("%s\n", filename);
if ((fd_r = open(filename, O_RDONLY)) < 0){
printf("Failed to read file\n");
return -1;
}
fstat(fd_r, &s_stat);
printf("Len: %d\n", s_stat.st_size);
close(fd_r);
bfd_init();
abfd = bfd_openr(filename, NULL);
//set_default_bfd_target();
if (abfd == NULL){
printf("Cannot read bfd file\n");
free(sData->data);
free(sData);
return -1;
}
// Defined in https://github.com/redox-os/binutils-gdb/blob/master/include/dis-asm.h
//init_disassemble_info (&disasm_info, stdout, (fprintf_ftype) fprintf);
init_disassemble_info (&disasm_info, sData, dump_asm);
disasm_info.arch = bfd_get_arch(abfd);
disasm_info.mach = bfd_get_mach(abfd);
/*disasm_info.arch = bfd_arch_i386;
disasm_info.mach = bfd_mach_x86_64;
disasm_info.read_memory_func = buffer_read_memory;
disasm_info.buffer = code;
disasm_info.buffer_vma = 0;
disasm_info.buffer_length = length;*/
disassemble_init_for_target(&disasm_info);
printf("%d\n", bfd_get_arch(abfd));
printf("%d\n", bfd_get_mach(abfd));
printf("%s\n", bfd_printable_arch_mach(
bfd_get_arch(abfd),
bfd_get_mach(abfd)));
//disassembler_ftype disas = disassembler(abfd);
disassembler_ftype disas = disassembler(bfd_arch_i386, false, bfd_mach_x86_64, NULL);
if (!disas){
printf("Can't disassemble\n");
perror("disassembler()");
return -1;
}
size_t i = 0;
size_t length = s_stat.st_size;
while (i < length){
size_t octets = disas(i, &disasm_info);
printf("%s\n", sData->data);
i += octets;
memset(sData->data, 0, 64);
};
free(sData->data);
free(sData);
bfd_close(abfd);
return 0;
}
int main(void){
disass();
return 0;
}