From bbf9e9debd761b5c5024d8417ad38e1cadc70d5b Mon Sep 17 00:00:00 2001 From: midipix Date: Sat, 21 Nov 2015 21:17:19 -0500 Subject: driver integration 1/9: remove old (ad-hoc) driver, prepare source tree. --- project/common.mk | 6 +- project/tree.mk | 2 +- src/internal/perk_impl.h | 14 --- src/logic/pe_get_image_meta.c | 196 ++++++++++++++++++++++++++++++++++++++++++ src/logic/pe_map_raw_image.c | 40 +++++++++ src/main/pe_get_image_meta.c | 196 ------------------------------------------ src/main/pe_map_raw_image.c | 40 --------- src/main/perk.c | 116 ------------------------- src/perk.c | 11 +++ 9 files changed, 251 insertions(+), 370 deletions(-) create mode 100644 src/logic/pe_get_image_meta.c create mode 100644 src/logic/pe_map_raw_image.c delete mode 100644 src/main/pe_get_image_meta.c delete mode 100644 src/main/pe_map_raw_image.c delete mode 100644 src/main/perk.c create mode 100644 src/perk.c diff --git a/project/common.mk b/project/common.mk index d1839f1..012bcb6 100644 --- a/project/common.mk +++ b/project/common.mk @@ -1,6 +1,6 @@ COMMON_SRCS = \ - src/main/pe_get_image_meta.c \ - src/main/pe_map_raw_image.c \ + src/logic/pe_get_image_meta.c \ + src/logic/pe_map_raw_image.c \ src/output/pe_output_export_symbols.c \ src/reader/pe_read_coff_header.c \ src/reader/pe_read_dos_header.c \ @@ -10,4 +10,4 @@ COMMON_SRCS = \ src/reader/pe_read_section_header.c \ APP_SRCS = \ - src/main/perk.c + src/perk.c diff --git a/project/tree.mk b/project/tree.mk index 0c5a1cc..74bcb9b 100644 --- a/project/tree.mk +++ b/project/tree.mk @@ -1,7 +1,7 @@ tree.tag: mkdir -p src mkdir -p src/internal - mkdir -p src/main + mkdir -p src/logic mkdir -p src/output mkdir -p src/reader touch tree.tag diff --git a/src/internal/perk_impl.h b/src/internal/perk_impl.h index a47391c..bda7581 100644 --- a/src/internal/perk_impl.h +++ b/src/internal/perk_impl.h @@ -4,20 +4,6 @@ #include #include -/* internal structures */ -struct perk_ctx { - int argc; - char ** argv; - char ** envp; - const char * fname; - int status; - int flags; - int fd; - FILE * fout; - FILE * tmp; - struct pe_raw_image map; -}; - #if (BYTE_ORDER == LITTLE_ENDIAN) static inline uint16_t pe_read_short(const unsigned char * raw) diff --git a/src/logic/pe_get_image_meta.c b/src/logic/pe_get_image_meta.c new file mode 100644 index 0000000..350abe3 --- /dev/null +++ b/src/logic/pe_get_image_meta.c @@ -0,0 +1,196 @@ +#include +#include +#include +#include +#include + +#include +#include "perk_impl.h" + +static int pe_free_image_meta_impl (struct pe_image_meta * meta, int status) +{ + unsigned i; + + if (!meta) return 0; + + for (i=0; isummary.num_of_implibs; i++) + free(meta->idata[i].items); + + free(meta->idata); + free(meta->sectbl); + free(meta); + + return status; +} + +int pe_free_image_meta (struct pe_image_meta * meta) +{ + return pe_free_image_meta_impl(meta,0); +} + +int pe_get_named_section_index (const struct pe_image_meta * m, const char * name) +{ + int i; for (i=0; icoff.num_of_sections; i++) + if (!(strcmp(name,m->sectbl[i].name))) + return i; + + return -1; +} + +int pe_get_block_section_index (const struct pe_image_meta * m, const struct pe_block * block) +{ + int i; + uint32_t low,high; + + for (i=0; icoff.num_of_sections; i++) { + low = m->sectbl[i].virtual_addr; + high = low + m->sectbl[i].virtual_size; + + if ((block->rva >= low) && (block->rva + block->size <= high)) + return i; + } + + return -1; +} + +int pe_get_image_meta (const struct pe_raw_image * image, struct pe_image_meta ** meta) +{ + int i,j,s,status; + struct pe_image_meta * m; + char * base = image->addr; + + if (!(m = calloc(1,sizeof(*m)))) + return errno; + + m->ados = (struct pe_image_dos_hdr *)base; + + if ((status = (pe_read_dos_header(m->ados,&m->dos)))) + return pe_free_image_meta_impl(m,status); + + m->acoff = (struct pe_coff_file_hdr *)(base + m->dos.dos_lfanew); + + if ((status = (pe_read_coff_header(m->acoff,&m->coff)))) + return pe_free_image_meta_impl(m,status); + + m->aopt = (union pe_opt_hdr *)((char *)m->acoff + sizeof(m->coff)); + + if ((status = (pe_read_optional_header(m->aopt,&m->opt)))) + return pe_free_image_meta_impl(m,status); + + m->asectbl = (struct pe_sec_hdr *)((char *)m->aopt + m->coff.size_of_opt_hdr); + + if (!(m->sectbl = calloc(m->coff.num_of_sections,sizeof(*(m->sectbl))))) + return pe_free_image_meta_impl(m,status); + + for (i=0; icoff.num_of_sections; i++) + pe_read_section_header(&m->asectbl[i],&m->sectbl[i]); + + /* .edata */ + i = pe_get_named_section_index(m,".edata"); + s = pe_get_block_section_index(m,&m->opt.dirs.export_tbl); + + if ((i >= 0) && (i != s)) + return pe_free_image_meta_impl(m,PERK_MALFORMED_IMAGE); + + if (s >= 0) { + m->hedata = &m->sectbl[s]; + m->aedata = (struct pe_export_hdr *)(base + m->sectbl[s].ptr_to_raw_data + + m->opt.dirs.export_tbl.rva - m->sectbl[s].virtual_addr); + } else if (i >= 0) { + m->hedata = &m->sectbl[i]; + m->aedata = (struct pe_export_hdr *)(base + m->sectbl[i].ptr_to_raw_data); + } + + if (m->aedata) + pe_read_export_header(m->aedata,&m->edata); + + /* .idata */ + struct pe_import_hdr * pidata; + struct pe_import_lookup_item * pitem; + + i = pe_get_named_section_index(m,".idata"); + s = pe_get_block_section_index(m,&m->opt.dirs.import_tbl); + + if ((i >= 0) && (i != s)) + return pe_free_image_meta_impl(m,PERK_MALFORMED_IMAGE); + + if (s >= 0) { + m->hidata = &m->sectbl[s]; + m->aidata = (struct pe_import_hdr *)(base + m->sectbl[s].ptr_to_raw_data + + m->opt.dirs.import_tbl.rva - m->sectbl[s].virtual_addr); + } else if (i >= 0) { + m->hidata = &m->sectbl[i]; + m->aidata = (struct pe_import_hdr *)(base + m->sectbl[i].ptr_to_raw_data); + } + + if (m->aidata) { + /* num of implibs */ + for (pidata=m->aidata; pidata->name_rva[0]; pidata++,m->summary.num_of_implibs++); + + /* import headers */ + if (!(m->idata = calloc(m->summary.num_of_implibs,sizeof(*(m->idata))))) + return pe_free_image_meta_impl(m,status); + + for (i=0; isummary.num_of_implibs; i++) { + pe_read_import_header(&m->aidata[i],&m->idata[i]); + + m->idata[i].name = base + m->hidata->ptr_to_raw_data + + m->idata[i].name_rva - m->hidata->virtual_addr; + + if (m->idata[i].import_lookup_tbl_rva) + m->idata[i].aitems = (struct pe_import_lookup_item *)(base + m->hidata->ptr_to_raw_data + + m->idata[i].import_lookup_tbl_rva - m->hidata->virtual_addr); + + #ifdef PERK_DEVEL + printf("%s\n",m->idata[i].name); + #endif + + /* items */ + m->idata[i].count = 0; + if (m->idata[i].import_lookup_tbl_rva) { + for (pitem=m->idata[i].aitems; *(uint32_t *)pitem->u.hint_name_tbl_rva; pitem++) + m->idata[i].count++; + + if (!(m->idata[i].items = calloc(m->idata[i].count,sizeof(*(m->idata[i].items))))) + return pe_free_image_meta_impl(m,status); + } + + for (j=0; jidata[i].count; j++) { + if ((status = pe_read_import_lookup_item( + &(m->idata[i].aitems[j]), + &(m->idata[i].items[j]), + m->opt.std.magic))) + return pe_free_image_meta_impl(m,status); + + switch (m->opt.std.magic) { + case PE_MAGIC_PE32: + m->idata[i].items[j].flags = m->idata[i].items[j].u.import_lookup_entry_32; + break; + + case PE_MAGIC_PE32_PLUS: + m->idata[i].items[j].flags = (m->idata[i].items[j].u.import_lookup_entry_64 >> 32); + break; + } + + if (!m->idata[i].items[j].flags) { + struct pe_hint_name_entry * pentry = + (struct pe_hint_name_entry *)(base + m->hidata->ptr_to_raw_data + + m->idata[i].items[j].u.hint_name_tbl_rva - m->hidata->virtual_addr); + + m->idata[i].items[j].name = (char *)pentry->name; + #ifdef PERK_DEVEL + printf("%s\n",m->idata[i].items[j].name); + #endif + } + } + } + } + + /* image */ + m->image.addr = image->addr; + m->image.size = image->size; + + /* all done */ + *meta = m; + return 0; +} diff --git a/src/logic/pe_map_raw_image.c b/src/logic/pe_map_raw_image.c new file mode 100644 index 0000000..caf14b9 --- /dev/null +++ b/src/logic/pe_map_raw_image.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int pe_map_raw_image (int fd, const char * fname, int prot, struct pe_raw_image * map) +{ + struct stat stat; + int nfd, ret; + + if ((nfd = !fd)) + fd = open(fname,O_RDONLY | O_CLOEXEC); + + if ((fd < 0) || (fstat(fd,&stat) < 0)) + return errno; + + map->size = stat.st_size; + map->addr = mmap(0,map->size,prot,MAP_PRIVATE,fd,0); + + if (map->addr == MAP_FAILED) { + map->addr = 0; + ret = PERK_MAP_ERROR; + } else + ret = 0; + + if (nfd) close(fd); + + return ret; +} + +int pe_unmap_raw_image (struct pe_raw_image * map) +{ + return munmap(map->addr, map->size); +} diff --git a/src/main/pe_get_image_meta.c b/src/main/pe_get_image_meta.c deleted file mode 100644 index 350abe3..0000000 --- a/src/main/pe_get_image_meta.c +++ /dev/null @@ -1,196 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include "perk_impl.h" - -static int pe_free_image_meta_impl (struct pe_image_meta * meta, int status) -{ - unsigned i; - - if (!meta) return 0; - - for (i=0; isummary.num_of_implibs; i++) - free(meta->idata[i].items); - - free(meta->idata); - free(meta->sectbl); - free(meta); - - return status; -} - -int pe_free_image_meta (struct pe_image_meta * meta) -{ - return pe_free_image_meta_impl(meta,0); -} - -int pe_get_named_section_index (const struct pe_image_meta * m, const char * name) -{ - int i; for (i=0; icoff.num_of_sections; i++) - if (!(strcmp(name,m->sectbl[i].name))) - return i; - - return -1; -} - -int pe_get_block_section_index (const struct pe_image_meta * m, const struct pe_block * block) -{ - int i; - uint32_t low,high; - - for (i=0; icoff.num_of_sections; i++) { - low = m->sectbl[i].virtual_addr; - high = low + m->sectbl[i].virtual_size; - - if ((block->rva >= low) && (block->rva + block->size <= high)) - return i; - } - - return -1; -} - -int pe_get_image_meta (const struct pe_raw_image * image, struct pe_image_meta ** meta) -{ - int i,j,s,status; - struct pe_image_meta * m; - char * base = image->addr; - - if (!(m = calloc(1,sizeof(*m)))) - return errno; - - m->ados = (struct pe_image_dos_hdr *)base; - - if ((status = (pe_read_dos_header(m->ados,&m->dos)))) - return pe_free_image_meta_impl(m,status); - - m->acoff = (struct pe_coff_file_hdr *)(base + m->dos.dos_lfanew); - - if ((status = (pe_read_coff_header(m->acoff,&m->coff)))) - return pe_free_image_meta_impl(m,status); - - m->aopt = (union pe_opt_hdr *)((char *)m->acoff + sizeof(m->coff)); - - if ((status = (pe_read_optional_header(m->aopt,&m->opt)))) - return pe_free_image_meta_impl(m,status); - - m->asectbl = (struct pe_sec_hdr *)((char *)m->aopt + m->coff.size_of_opt_hdr); - - if (!(m->sectbl = calloc(m->coff.num_of_sections,sizeof(*(m->sectbl))))) - return pe_free_image_meta_impl(m,status); - - for (i=0; icoff.num_of_sections; i++) - pe_read_section_header(&m->asectbl[i],&m->sectbl[i]); - - /* .edata */ - i = pe_get_named_section_index(m,".edata"); - s = pe_get_block_section_index(m,&m->opt.dirs.export_tbl); - - if ((i >= 0) && (i != s)) - return pe_free_image_meta_impl(m,PERK_MALFORMED_IMAGE); - - if (s >= 0) { - m->hedata = &m->sectbl[s]; - m->aedata = (struct pe_export_hdr *)(base + m->sectbl[s].ptr_to_raw_data - + m->opt.dirs.export_tbl.rva - m->sectbl[s].virtual_addr); - } else if (i >= 0) { - m->hedata = &m->sectbl[i]; - m->aedata = (struct pe_export_hdr *)(base + m->sectbl[i].ptr_to_raw_data); - } - - if (m->aedata) - pe_read_export_header(m->aedata,&m->edata); - - /* .idata */ - struct pe_import_hdr * pidata; - struct pe_import_lookup_item * pitem; - - i = pe_get_named_section_index(m,".idata"); - s = pe_get_block_section_index(m,&m->opt.dirs.import_tbl); - - if ((i >= 0) && (i != s)) - return pe_free_image_meta_impl(m,PERK_MALFORMED_IMAGE); - - if (s >= 0) { - m->hidata = &m->sectbl[s]; - m->aidata = (struct pe_import_hdr *)(base + m->sectbl[s].ptr_to_raw_data - + m->opt.dirs.import_tbl.rva - m->sectbl[s].virtual_addr); - } else if (i >= 0) { - m->hidata = &m->sectbl[i]; - m->aidata = (struct pe_import_hdr *)(base + m->sectbl[i].ptr_to_raw_data); - } - - if (m->aidata) { - /* num of implibs */ - for (pidata=m->aidata; pidata->name_rva[0]; pidata++,m->summary.num_of_implibs++); - - /* import headers */ - if (!(m->idata = calloc(m->summary.num_of_implibs,sizeof(*(m->idata))))) - return pe_free_image_meta_impl(m,status); - - for (i=0; isummary.num_of_implibs; i++) { - pe_read_import_header(&m->aidata[i],&m->idata[i]); - - m->idata[i].name = base + m->hidata->ptr_to_raw_data - + m->idata[i].name_rva - m->hidata->virtual_addr; - - if (m->idata[i].import_lookup_tbl_rva) - m->idata[i].aitems = (struct pe_import_lookup_item *)(base + m->hidata->ptr_to_raw_data - + m->idata[i].import_lookup_tbl_rva - m->hidata->virtual_addr); - - #ifdef PERK_DEVEL - printf("%s\n",m->idata[i].name); - #endif - - /* items */ - m->idata[i].count = 0; - if (m->idata[i].import_lookup_tbl_rva) { - for (pitem=m->idata[i].aitems; *(uint32_t *)pitem->u.hint_name_tbl_rva; pitem++) - m->idata[i].count++; - - if (!(m->idata[i].items = calloc(m->idata[i].count,sizeof(*(m->idata[i].items))))) - return pe_free_image_meta_impl(m,status); - } - - for (j=0; jidata[i].count; j++) { - if ((status = pe_read_import_lookup_item( - &(m->idata[i].aitems[j]), - &(m->idata[i].items[j]), - m->opt.std.magic))) - return pe_free_image_meta_impl(m,status); - - switch (m->opt.std.magic) { - case PE_MAGIC_PE32: - m->idata[i].items[j].flags = m->idata[i].items[j].u.import_lookup_entry_32; - break; - - case PE_MAGIC_PE32_PLUS: - m->idata[i].items[j].flags = (m->idata[i].items[j].u.import_lookup_entry_64 >> 32); - break; - } - - if (!m->idata[i].items[j].flags) { - struct pe_hint_name_entry * pentry = - (struct pe_hint_name_entry *)(base + m->hidata->ptr_to_raw_data - + m->idata[i].items[j].u.hint_name_tbl_rva - m->hidata->virtual_addr); - - m->idata[i].items[j].name = (char *)pentry->name; - #ifdef PERK_DEVEL - printf("%s\n",m->idata[i].items[j].name); - #endif - } - } - } - } - - /* image */ - m->image.addr = image->addr; - m->image.size = image->size; - - /* all done */ - *meta = m; - return 0; -} diff --git a/src/main/pe_map_raw_image.c b/src/main/pe_map_raw_image.c deleted file mode 100644 index caf14b9..0000000 --- a/src/main/pe_map_raw_image.c +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -int pe_map_raw_image (int fd, const char * fname, int prot, struct pe_raw_image * map) -{ - struct stat stat; - int nfd, ret; - - if ((nfd = !fd)) - fd = open(fname,O_RDONLY | O_CLOEXEC); - - if ((fd < 0) || (fstat(fd,&stat) < 0)) - return errno; - - map->size = stat.st_size; - map->addr = mmap(0,map->size,prot,MAP_PRIVATE,fd,0); - - if (map->addr == MAP_FAILED) { - map->addr = 0; - ret = PERK_MAP_ERROR; - } else - ret = 0; - - if (nfd) close(fd); - - return ret; -} - -int pe_unmap_raw_image (struct pe_raw_image * map) -{ - return munmap(map->addr, map->size); -} diff --git a/src/main/perk.c b/src/main/perk.c deleted file mode 100644 index 0382186..0000000 --- a/src/main/perk.c +++ /dev/null @@ -1,116 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "perk_impl.h" - -static int perk_parse_opts(struct perk_ctx * ctx) -{ - int i; - char * ch; - const char ** popt; - - for (i=1; iargc; i++) { - ch = ctx->argv[i]; - - if (*ch == '-') { - switch (*++ch) { - case 'i': - popt = &ctx->fname; - break; - case 'h': - ctx->flags = PERK_HELP; - return 0; - default: - ctx->status = PERK_BAD_OPT; - return ctx->status; - } - - while ((*++ch == '\t') || (*ch == ' ')); - - if (!*ch) { - if (++i < ctx->argc) - *popt = ctx->argv[i]; - else - ctx->status = PERK_BAD_OPT_VAL; - } else - *popt = ch; - } else if (!ctx->fname) - ctx->fname = ch; - else - ctx->status = PERK_BAD_OPT; - - } - - return ctx->status; -} - - -static int perk_map_input(struct perk_ctx * ctx) -{ - ctx->fd = open(ctx->fname,O_RDONLY | O_CLOEXEC); - - if (ctx->fd < 0) { - ctx->status = PERK_IO_ERROR; - return ctx->status; - } - - ctx->status = pe_map_raw_image(ctx->fd,0,PROT_READ,&ctx->map); - - return ctx->status; -} - - -static int perk_exit(struct perk_ctx * ctx) -{ - if (ctx->map.addr) - pe_unmap_raw_image(&ctx->map); - - return ctx->status; -} - - -static int perk_run(struct perk_ctx * ctx) -{ - struct pe_image_meta * meta; - - if (perk_map_input(ctx)) - return perk_exit(ctx); - - if ((ctx->status = pe_get_image_meta(&ctx->map,&meta))) - return perk_exit(ctx); - - /* pre-alpha default output */ - pe_output_export_symbols( - meta, - PERK_OUTPUT_FORMAT_LIST | PERK_OUTPUT_FIELD_NAME, - stdout); - - ctx->status = pe_free_image_meta(meta); - - return perk_exit(ctx); -} - -static int perk_main(int argc, char ** argv, char ** envp) -{ - struct perk_ctx ctx = {argc,argv,envp}; - - if (perk_parse_opts(&ctx)) - return ctx.status; - else - return perk_run(&ctx); -} - -int main(int argc, char ** argv, char ** envp) -{ - return perk_main(argc,argv,envp); -} diff --git a/src/perk.c b/src/perk.c new file mode 100644 index 0000000..983c130 --- /dev/null +++ b/src/perk.c @@ -0,0 +1,11 @@ +#include + +static int perk_main(int argc, char ** argv, char ** envp) +{ + return -1; +} + +int main(int argc, char ** argv, char ** envp) +{ + return perk_main(argc,argv,envp); +} -- cgit v1.2.3