summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/perk/perk.h7
-rw-r--r--include/perk/perk_meta.h16
-rw-r--r--project/common.mk1
-rw-r--r--src/logic/pe_get_image_framework.c104
4 files changed, 128 insertions, 0 deletions
diff --git a/include/perk/perk.h b/include/perk/perk.h
index 8c6711e..02d3275 100644
--- a/include/perk/perk.h
+++ b/include/perk/perk.h
@@ -154,6 +154,10 @@ struct pe_unit_ctx {
void * any;
};
+struct pe_info_string {
+ char buffer[128];
+};
+
/* package info */
perk_api const struct pe_source_version * pe_source_version(void);
@@ -188,6 +192,9 @@ perk_api int pe_get_rva_from_roffset (const struct pe_image_meta *, uint32_t ro
perk_api int pe_get_expsym_by_name (const struct pe_image_meta *, const char * name, struct pe_expsym * optional);
perk_api int pe_get_expsym_by_index (const struct pe_image_meta *, unsigned index, struct pe_expsym * optional);
+/* info api */
+perk_api int pe_get_image_framework (const struct pe_image_meta *, struct pe_info_string * optional);
+
/* low-level api */
perk_api int pe_read_dos_header (const struct pe_image_dos_hdr *, struct pe_meta_image_dos_hdr *);
perk_api int pe_read_coff_header (const struct pe_coff_file_hdr *, struct pe_meta_coff_file_hdr *);
diff --git a/include/perk/perk_meta.h b/include/perk/perk_meta.h
index e3dfab7..fc8c268 100644
--- a/include/perk/perk_meta.h
+++ b/include/perk/perk_meta.h
@@ -7,6 +7,22 @@ extern "C" {
#include <stdint.h>
+enum pe_framework {
+ PE_FRAMEWORK_UNKNOWN,
+ PE_FRAMEWORK_FREESTD,
+ PE_FRAMEWORK_PSXSCL,
+ PE_FRAMEWORK_MIDIPIX,
+ PE_FRAMEWORK_CYGONE,
+ PE_FRAMEWORK_CYGWIN,
+ PE_FRAMEWORK_MINGW,
+ PE_FRAMEWORK_MSYS,
+ PE_FRAMEWORK_SUACON,
+ PE_FRAMEWORK_WINCON,
+ PE_FRAMEWORK_WINCLI,
+ PE_FRAMEWORK_WIN32,
+ PE_FRAMEWORK_CAP
+};
+
/* generic block info / image directory header */
struct pe_block {
uint32_t rva;
diff --git a/project/common.mk b/project/common.mk
index 453a374..b71e972 100644
--- a/project/common.mk
+++ b/project/common.mk
@@ -2,6 +2,7 @@ API_SRCS = \
src/driver/pe_amain.c \
src/driver/pe_driver_ctx.c \
src/driver/pe_unit_ctx.c \
+ src/logic/pe_get_image_framework.c \
src/logic/pe_get_image_meta.c \
src/logic/pe_map_raw_image.c \
src/output/pe_output_error.c \
diff --git a/src/logic/pe_get_image_framework.c b/src/logic/pe_get_image_framework.c
new file mode 100644
index 0000000..ba44d2f
--- /dev/null
+++ b/src/logic/pe_get_image_framework.c
@@ -0,0 +1,104 @@
+/***************************************************************/
+/* perk: PE Resource Kit */
+/* Copyright (C) 2015--2016 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.PERK. */
+/***************************************************************/
+
+#include <string.h>
+#include <stdbool.h>
+
+#include <perk/perk.h>
+#include <perk/perk_meta.h>
+
+static const char const * pe_framework_str[PE_FRAMEWORK_CAP] = {
+ [PE_FRAMEWORK_UNKNOWN] = "unknown",
+ [PE_FRAMEWORK_FREESTD] = "freestd",
+ [PE_FRAMEWORK_PSXSCL] = "psxscl",
+ [PE_FRAMEWORK_MIDIPIX] = "midipix",
+ [PE_FRAMEWORK_CYGONE] = "cygone",
+ [PE_FRAMEWORK_CYGWIN] = "cygwin",
+ [PE_FRAMEWORK_MINGW] = "mingw",
+ [PE_FRAMEWORK_MSYS] = "msys",
+ [PE_FRAMEWORK_SUACON] = "suacon",
+ [PE_FRAMEWORK_WINCON] = "wincon",
+ [PE_FRAMEWORK_WINCLI] = "wincli",
+ [PE_FRAMEWORK_WIN32] = "win32",
+};
+
+static bool pe_image_is_psxscl(const struct pe_image_meta * m)
+{
+ return (!m->summary.nimplibs
+ && !pe_get_expsym_by_name(m,"__psx_init",0));
+}
+
+static bool pe_image_is_cygwin(const struct pe_image_meta * m)
+{
+ int i;
+
+ for (i=0; i<m->summary.nimplibs; i++)
+ if (!(strcmp(m->idata[i].name,"cygwin1.dll")))
+ return true;
+
+ return false;
+}
+
+static bool pe_image_is_msys(const struct pe_image_meta * m)
+{
+ int i;
+
+ for (i=0; i<m->summary.nimplibs; i++)
+ if (!(strcmp(m->idata[i].name,"msys-2.0.dll")))
+ return true;
+
+ return false;
+}
+
+static bool pe_image_is_mingw(const struct pe_image_meta * m)
+{
+ return ((pe_get_named_section_index(m,".CRT") >= 0)
+ && (pe_get_named_section_index(m,".bss") >= 0)
+ && (pe_get_named_section_index(m,".tls") >= 0));
+}
+
+int pe_get_image_framework(const struct pe_image_meta * m, struct pe_info_string * infostr)
+{
+ int framework;
+
+ if (pe_get_named_section_index(m,".midipix") >= 0)
+ framework = PE_FRAMEWORK_MIDIPIX;
+
+ else if (pe_get_named_section_index(m,".freestd") >= 0)
+ framework = PE_FRAMEWORK_FREESTD;
+
+ else if (pe_get_named_section_index(m,".cygheap") >= 0)
+ framework = PE_FRAMEWORK_CYGONE;
+
+ else if (pe_image_is_psxscl(m))
+ framework = PE_FRAMEWORK_PSXSCL;
+
+ else if (pe_image_is_cygwin(m))
+ framework = PE_FRAMEWORK_CYGWIN;
+
+ else if (pe_image_is_msys(m))
+ framework = PE_FRAMEWORK_MSYS;
+
+ else if (pe_image_is_mingw(m))
+ framework = PE_FRAMEWORK_MINGW;
+
+ else if (m->opt.img.subsystem == PE_IMAGE_SUBSYSTEM_POSIX_CUI)
+ framework = PE_FRAMEWORK_SUACON;
+
+ else if (m->opt.img.subsystem == PE_IMAGE_SUBSYSTEM_WINDOWS_CUI)
+ framework = PE_FRAMEWORK_WINCON;
+
+ else if (m->opt.img.subsystem == PE_IMAGE_SUBSYSTEM_WINDOWS_GUI)
+ framework = PE_FRAMEWORK_WIN32;
+
+ else
+ framework = PE_FRAMEWORK_UNKNOWN;
+
+ if (infostr)
+ strcpy(infostr->buffer,pe_framework_str[framework]);
+
+ return framework;
+}