diff --git a/include/perk/perk.h b/include/perk/perk.h index f34f7c1..3f9f890 100644 --- a/include/perk/perk.h +++ b/include/perk/perk.h @@ -154,6 +154,7 @@ perk_api void pe_free_unit_ctx (struct pe_unit_ctx *); /* utility api */ perk_api int pe_output_export_symbols (const struct pe_image_meta *, const struct pe_common_ctx *, FILE *); +perk_api int pe_output_import_libraries(const struct pe_image_meta *, const struct pe_common_ctx *, FILE *); /* high-level api */ perk_api int pe_map_raw_image (int fd, const char * path, int prot, struct pe_raw_image *); diff --git a/include/perk/perk_output.h b/include/perk/perk_output.h index 18ec373..d7e3b9a 100644 --- a/include/perk/perk_output.h +++ b/include/perk/perk_output.h @@ -7,6 +7,8 @@ /* output actions */ #define PERK_OUTPUT_EXPORT_SYMS 0x00000001 +#define PERK_OUTPUT_IMPORT_LIBS 0x00000002 +#define PERK_OUTPUT_IMPORT_SYMS 0x00000004 /* pretty-printer flags */ diff --git a/project/common.mk b/project/common.mk index d28c6a2..c925124 100644 --- a/project/common.mk +++ b/project/common.mk @@ -4,6 +4,7 @@ COMMON_SRCS = \ src/logic/pe_get_image_meta.c \ src/logic/pe_map_raw_image.c \ src/output/pe_output_export_symbols.c \ + src/output/pe_output_import_libraries.c \ src/reader/pe_read_coff_header.c \ src/reader/pe_read_dos_header.c \ src/reader/pe_read_export_header.c \ diff --git a/src/driver/pe_driver_ctx.c b/src/driver/pe_driver_ctx.c index a463e9a..990738b 100644 --- a/src/driver/pe_driver_ctx.c +++ b/src/driver/pe_driver_ctx.c @@ -9,6 +9,8 @@ enum app_tags { TAG_VERSION, TAG_OUTPUT, TAG_EXPSYMS, + TAG_IMPLIBS, + TAG_IMPSYMS, }; static const struct argv_option options[] = { @@ -24,6 +26,13 @@ static const struct argv_option options[] = { {"expsyms", 'e',TAG_EXPSYMS,ARGV_OPTARG_NONE, 0,0, "print exported symbols" }, + + {"implibs", 'i',TAG_IMPLIBS,ARGV_OPTARG_NONE, 0,0, + "list direct dependency libraries"}, + + {"impsyms", 'I',TAG_IMPSYMS,ARGV_OPTARG_NONE, 0,0, + "list direct dependency libraries " + "along with required symbols"}, {0} }; @@ -139,6 +148,14 @@ int pe_get_driver_ctx( case TAG_EXPSYMS: fflags |= PERK_OUTPUT_EXPORT_SYMS; break; + + case TAG_IMPLIBS: + fflags |= PERK_OUTPUT_IMPORT_LIBS; + break; + + case TAG_IMPSYMS: + fflags |= PERK_OUTPUT_IMPORT_SYMS; + break; } } else nunits++; diff --git a/src/logic/pe_get_image_meta.c b/src/logic/pe_get_image_meta.c index ea76a92..b5bca34 100644 --- a/src/logic/pe_get_image_meta.c +++ b/src/logic/pe_get_image_meta.c @@ -138,10 +138,6 @@ int pe_get_image_meta(const struct pe_raw_image * image, struct pe_image_meta ** 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) { @@ -175,9 +171,6 @@ int pe_get_image_meta(const struct pe_raw_image * image, struct pe_image_meta ** + 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 } } } diff --git a/src/output/pe_output_import_libraries.c b/src/output/pe_output_import_libraries.c new file mode 100644 index 0000000..1e47d81 --- /dev/null +++ b/src/output/pe_output_import_libraries.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include + +#include +#include +#include "perk_output_impl.h" + +int pe_output_import_libraries( + const struct pe_image_meta * m, + const struct pe_common_ctx * cctx, + FILE * fout) +{ + FILE * ftmp; + int i,j; + + if (!m->summary.num_of_implibs) + return 0; + + if (!(fout = pe_output_prolog(cctx,fout,&ftmp))) + return -1; + + for (i=0; isummary.num_of_implibs; i++) { + if (cctx->fmtflags & PERK_OUTPUT_IMPORT_SYMS) + fprintf(fout,"%s:\n",m->idata[i].name); + else + fprintf(fout,"%s\n",m->idata[i].name); + + if (cctx->fmtflags & PERK_OUTPUT_IMPORT_SYMS) + for (j=0; jidata[i].count; j++) + if (m->idata[i].items[j].name) + fprintf(fout,"==> %s\n", + m->idata[i].items[j].name); + } + + return pe_output_epilog(0,ftmp); +} diff --git a/src/perk.c b/src/perk.c index 17872a2..72cfa37 100644 --- a/src/perk.c +++ b/src/perk.c @@ -1,4 +1,5 @@ #include +#include #include #include @@ -6,12 +7,32 @@ #define PERK_DRIVER_FLAGS PERK_DRIVER_VERBOSITY_ERRORS|PERK_DRIVER_VERBOSITY_USAGE #endif +static void perk_paragraph_break(struct pe_unit_ctx * uctx, int * fpara) +{ + if (*fpara) { + if (uctx->cctx.fdout >= 0) + write(uctx->cctx.fdout,"\n",1); + else + fputc('\n',stdout); + *fpara = 0; + } +} + static void perk_perform_unit_actions(struct pe_unit_ctx * uctx) { + int fpara = 0; uint64_t flags = uctx->cctx.fmtflags; - if (flags & PERK_OUTPUT_EXPORT_SYMS) + if (flags & PERK_OUTPUT_EXPORT_SYMS) { uctx->cctx.status = pe_output_export_symbols(uctx->meta,&uctx->cctx,0); + fpara += uctx->meta->summary.num_of_export_syms; + } + + if ((flags & PERK_OUTPUT_IMPORT_LIBS) || (flags & PERK_OUTPUT_IMPORT_SYMS)) { + perk_paragraph_break(uctx,&fpara); + uctx->cctx.status = pe_output_import_libraries(uctx->meta,&uctx->cctx,0); + fpara += (uctx->meta->summary.num_of_implibs > 0); + } } static int perk_exit(struct pe_driver_ctx * dctx, int status)