diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..b370cb0 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,14 @@ +all: + ./lazy -x build + +install: + ./lazy -x build -e install + +clean: + rm -rf src + rm -rf lib + rm -f lazy + rm -f lazy.config.tag + rm -f lz_stack + rm -f *.objs + rm -rf *.lst diff --git a/config.lzy b/config.lzy new file mode 100644 index 0000000..9f71770 --- /dev/null +++ b/config.lzy @@ -0,0 +1,28 @@ +# package +lz_package=pemagine + + +# toolchain +lz_default_target=x86_64-nt64-midipix +lz_default_arch=x86_64 +lz_default_compiler=gcc + + +# lazy +lz_cflags_cmdline= +lz_cxxflags_cmdline= +lz_ldflags_cmdline= + +lz_cflags_debug= +lz_cflags_release= + +lz_cflags_include_first= +lz_cflags_include_last= +lz_cflags_include_cmdline= +lz_cxxflags_include_cmdline= + +lz_exec_prefix= +lz_bindir= +lz_libdir= +lz_includedir= +lz_syslibdir= diff --git a/configure b/configure new file mode 100755 index 0000000..1e02d8f --- /dev/null +++ b/configure @@ -0,0 +1,114 @@ +#!/bin/sh + +# a simple configure-make wrapper for use in conjunction with the 'lazy' build script. +# 'lazy' is deviant, occasionally useful, and permissively licensed; get_lazy() below, +# then look for configure.template in the root directory. + +init_vars() +{ + lz_config_dir=`readlink -f $(dirname $0)` + lz_pwd=`pwd` + + if [ x"$lz_config" = x ]; then + . $lz_config_dir/config.lzy || exit 2 + else + . "$lz_config" || exit 2 + fi +} + + +error_msg() +{ + echo $@ >&2 +} + + +require_out_of_tree() +{ + if [ x"$lz_config_dir" = x"$lz_pwd" ]; then + error_msg "$lz_package: out-of-tree builds are required." + error_msg "please invoke configure again from a clean build directory." + exit 2 + fi + + return 0 +} + + +get_lazy() +{ + which lazy && lazy=`which lazy` && return 0 + + if ! [ -d slazy ]; then + git clone git://midipix.org/lazy slazy || exit 2 + fi + + lazy=$lz_pwd/slazy/lazy +} + + +lazy_approach() +{ + if [ x"$lz_prefix" = x ]; then + error_msg "prefix is required." + exit 2 + fi + + if [ x"$lz_arch" = x ]; then lz_arch=$lz_default_arch; fi + if [ x"$lz_target" = x ]; then lz_target=$lz_default_target; fi + if [ x"$lz_compiler" = x ]; then lz_compiler=$lz_default_compiler; fi + if [ x"$lz_compiler" = x ]; then lz_compiler=gcc; fi + + $lazy -x config $lz_debug \ + -t $lz_target \ + -c $lz_compiler \ + -n $lz_package \ + -p $lz_config_dir \ + -f $lz_prefix \ + || exit 2 + +} + + +lazy_copy() +{ + cp "$lz_config_dir/Makefile.in" "$lz_pwd/Makefile" +} + + +for arg ; do + case "$arg" in + --help) usage + ;; + + --prefix=*) + lz_prefix=${arg#*=} + ;; + --host=*) + lz_target=${arg#*=} + ;; + --target=*) + lz_target=${arg#*=} + ;; + --compiler=*) + lz_compiler=${arg#*=} + ;; + --config=*) + lz_config=${arg#*=} + ;; + --debug) + lz_debug='-d' + ;; + *) + error_msg ${arg#}: "unsupported config argument." + exit 2 + ;; + esac +done + + +init_vars +require_out_of_tree +get_lazy +lazy_approach +lazy_copy diff --git a/include/pemagine/bits/nt32/pe_inline_asm__gcc.h b/include/pemagine/bits/nt32/pe_inline_asm__gcc.h new file mode 100644 index 0000000..10473b4 --- /dev/null +++ b/include/pemagine/bits/nt32/pe_inline_asm__gcc.h @@ -0,0 +1,89 @@ +static __inline__ void * pe_get_teb_address(void) +{ + void * ptrRet; + __asm__ __volatile__ ( + "mov %%fs:0x18, %0\n\t" + : "=r" (ptrRet) : : + ); + return ptrRet; +} + + +static __inline__ void * pe_get_peb_address(void) +{ + void * ptrRet; + __asm__ __volatile__ ( + "mov %%fs:0x18, %0\n\t" + "mov %%ds:0x30(%0), %0\n\t" + : "=r" (ptrRet) : : + ); + return ptrRet; +} + + +static __inline__ void * pe_get_peb_address_alt(void) +{ + void * ptrRet; + __asm__ __volatile__ ( + "mov %%fs:0x30, %0\n\t" + : "=r" (ptrRet) : : + ); + return ptrRet; +} + + +static __inline__ void * pe_get_peb_ldr_data_address(void) +{ + void * ptrRet; + __asm__ __volatile__ ( + "mov %%fs:0x18, %0\n\t" + "mov %%ds:0x30(%0), %0\n\t" + "mov %%ds:0x0C(%0), %0\n\t" + : "=r" (ptrRet) : : + ); + return ptrRet; +} + + +static __inline__ void * pe_get_peb_ldr_data_address_alt(void) +{ + void * ptrRet; + __asm__ __volatile__ ( + "mov %%fs:0x30, %0\n\t" + "mov %%ds:0x0C(%0), %0\n\t" + : "=r" (ptrRet) : : + ); + return ptrRet; +} + +static __inline__ uint32_t pe_get_current_process_id(void) +{ + uint32_t ptrRet; + __asm__ __volatile__ ( + "mov %%fs:0x20, %0\n\t" + : "=r" (ptrRet) : : + ); + return ptrRet; +} + +static __inline__ uint32_t pe_get_current_thread_id(void) +{ + uint32_t ptrRet; + __asm__ __volatile__ ( + "mov %%fs:0x24, %0\n\t" + : "=r" (ptrRet) : : + ); + return ptrRet; +} + +static __inline__ uint32_t pe_get_current_session_id(void) +{ + uint32_t ptrRet; + __asm__ __volatile__ ( + "mov %%fs:0x18, %0\n\t" + "mov %%ds:0x30(%0), %0\n\t" + "mov %%ds:0x1d4(%0), %0\n\t" + : "=r" (ptrRet) : : + ); + return ptrRet; +} diff --git a/include/pemagine/bits/nt32/pe_inline_asm__msvc.h b/include/pemagine/bits/nt32/pe_inline_asm__msvc.h new file mode 100644 index 0000000..161a846 --- /dev/null +++ b/include/pemagine/bits/nt32/pe_inline_asm__msvc.h @@ -0,0 +1,67 @@ +/* optimize: use __readfsdword rather than explicit eax */ + +static __inline__ void * pe_get_teb_address(void) +{ + __asm { + mov eax, fs:0x18 + }; +} + + +static __inline__ void * pe_get_peb_address(void) +{ + __asm { + mov eax, fs:0x18 + mov eax, ds:[eax+0x30] + }; +} + + +static __inline__ void * pe_get_peb_address_alt(void) +{ + __asm { + mov eax, fs:0x30 + }; +} + + +static __inline__ void * pe_get_peb_ldr_data_address(void) +{ + __asm { + mov eax, fs:0x18 + mov eax, ds:[eax+0x30] + mov eax, ds:[eax+0x0C] + }; +} + + +static __inline__ void * pe_get_peb_ldr_data_address_alt(void) +{ + __asm { + mov eax, fs:0x30 + mov eax, ds:[eax+0x0C] + }; +} + +static __inline__ uint32_t pe_get_current_process_id(void) +{ + __asm { + mov eax, fs:0x20 + }; +} + +static __inline__ uint32_t pe_get_current_thread_id(void) +{ + __asm { + mov eax, fs:0x24 + }; +} + +static __inline__ uint32_t pe_get_current_session_id(void) +{ + __asm { + mov eax, fs:0x18 + mov eax, ds:[eax+0x30] + mov eax, ds:[eax+0x1d4] + }; +} diff --git a/include/pemagine/bits/nt64/pe_inline_asm__gcc.h b/include/pemagine/bits/nt64/pe_inline_asm__gcc.h new file mode 100644 index 0000000..94d4e34 --- /dev/null +++ b/include/pemagine/bits/nt64/pe_inline_asm__gcc.h @@ -0,0 +1,87 @@ +static __inline__ void * pe_get_teb_address(void) +{ + void * ptrRet; + __asm__ __volatile__ ( + "mov %%gs:0x30, %0\n\t" + : "=r" (ptrRet) : : + ); + return ptrRet; +} + + +static __inline__ void * pe_get_peb_address(void) +{ + void * ptrRet; + __asm__ __volatile__ ( + "mov %%gs:0x60, %0\n\t" + : "=r" (ptrRet) : : + ); + return ptrRet; +} + + +static __inline__ void * pe_get_peb_address_alt(void) +{ + void * ptrRet; + __asm__ __volatile__ ( + "mov %%gs:0x60, %0\n\t" + : "=r" (ptrRet) : : + ); + return ptrRet; +} + + +static __inline__ void * pe_get_peb_ldr_data_address(void) +{ + void * ptrRet; + __asm__ __volatile__ ( + "mov %%gs:0x60, %0\n\t" + "mov %%ds:0x18(%0), %0\n\t" + : "=r" (ptrRet) : : + ); + return ptrRet; +} + + +static __inline__ void * pe_get_peb_ldr_data_address_alt(void) +{ + void * ptrRet; + __asm__ __volatile__ ( + "mov %%gs:0x60, %0\n\t" + "mov %%ds:0x18(%0), %0\n\t" + : "=r" (ptrRet) : : + ); + return ptrRet; +} + + +static __inline__ uint32_t pe_get_current_process_id(void) +{ + uint32_t ptrRet; + __asm__ __volatile__ ( + "mov %%gs:0x40, %0\n\t" + : "=r" (ptrRet) : : + ); + return ptrRet; +} + +static __inline__ uint32_t pe_get_current_thread_id(void) +{ + uint32_t ptrRet; + __asm__ __volatile__ ( + "mov %%gs:0x48, %0\n\t" + : "=r" (ptrRet) : : + ); + return ptrRet; +} + +static __inline__ uint32_t pe_get_current_session_id(void) +{ + uint32_t ptrRet; + __asm__ __volatile__ ( + "mov %%gs:0x60, %0\n\t" + "mov %%ds:0x2c0(%0), %0\n\t" + : "=r" (ptrRet) : : + ); + return ptrRet; +} diff --git a/include/pemagine/bits/nt64/pe_inline_asm__msvc.h b/include/pemagine/bits/nt64/pe_inline_asm__msvc.h new file mode 100644 index 0000000..e83d587 --- /dev/null +++ b/include/pemagine/bits/nt64/pe_inline_asm__msvc.h @@ -0,0 +1,58 @@ +#include + +unsigned __int64 __readgsqword(unsigned long); + +static __inline__ void * pe_get_teb_address(void) +{ + return (void *)__readgsqword(0x30); +} + + +static __inline__ void * pe_get_peb_address(void) +{ + return (void *)__readgsqword(0x60); +} + + +static __inline__ void * pe_get_peb_address_alt(void) +{ + return (void *)__readgsqword(0x60); +} + + +static __inline__ void * pe_get_peb_ldr_data_address(void) +{ + char * rsi; + + rsi = (char *)__readgsqword(0x60); + rsi += 0x18; + + return *(void **)rsi; +} + + +static __inline__ void * pe_get_peb_ldr_data_address_alt(void) +{ + return pe_get_peb_ldr_data_address(); +} + + +static __inline__ uint32_t pe_get_current_process_id(void) +{ + return (uint32_t)__readgsqword(0x40); +} + +static __inline__ uint32_t pe_get_current_thread_id(void) +{ + return (uint32_t)__readgsqword(0x48); +} + +static __inline__ uint32_t pe_get_current_session_id(void) +{ + char * rsi; + + rsi = (char *)__readgsqword(0x60); + rsi += 0x2c0; + + return *(uint32_t *)rsi; +} diff --git a/include/pemagine/pe_api.h b/include/pemagine/pe_api.h new file mode 100644 index 0000000..923daa9 --- /dev/null +++ b/include/pemagine/pe_api.h @@ -0,0 +1,36 @@ +#ifndef PE_API_H +#define PE_API_H + +/* portable integer types */ +#if defined (MIDIPIX_FREESTANDING) +#include +#else +#include +#endif + +/* pe_export */ +#if defined(__attr_export__) +#define pe_export __attr_export__ +#else +#define pe_export +#endif + +/* pe_import */ +#if defined(__attr_import__) +#define pe_import __attr_import__ +#else +#define pe_import +#endif + +/* pe_api */ +#if defined (PE_BUILD) +#define pe_api pe_export +#elif defined (PE_SHARED) +#define pe_api pe_import +#elif defined (PE_STATIC) +#define pe_api +#else +#define pe_api +#endif + +#endif /* _PE_API_H_ */ diff --git a/include/pemagine/pe_consts.h b/include/pemagine/pe_consts.h new file mode 100644 index 0000000..e7bd657 --- /dev/null +++ b/include/pemagine/pe_consts.h @@ -0,0 +1,371 @@ +#ifndef PE_CONSTS_H +#define PE_CONSTS_H + +#ifndef PE_BITWISE +#define PE_BITWISE(x) x +#endif + +#ifndef PE_ARBITRARY +#define PE_ARBITRARY(x) x +#endif + +#define PE_IMAGE_REL_BASED_ABSOLUTE PE_ARBITRARY (0x00000000) +#define PE_IMAGE_REL_BASED_HIGH PE_ARBITRARY (0x00000001) +#define PE_IMAGE_REL_BASED_LOW PE_ARBITRARY (0x00000002) +#define PE_IMAGE_REL_BASED_HIGHLOW PE_ARBITRARY (0x00000003) +#define PE_IMAGE_REL_BASED_HIGHADJ PE_ARBITRARY (0x00000004) +#define PE_IMAGE_REL_BASED_MIPS_JMPADDR PE_ARBITRARY (0x00000005) +#define PE_IMAGE_REL_BASED_ARM_MOV32A PE_ARBITRARY (0x00000005) +#define PE_IMAGE_REL_BASED_RESERVED PE_ARBITRARY (0x00000006) +#define PE_IMAGE_REL_BASED_ARM_MOV32T PE_ARBITRARY (0x00000007) +#define PE_IMAGE_REL_BASED_MIPS_JMPADDR16 PE_ARBITRARY (0x00000009) +#define PE_IMAGE_REL_BASED_DIR64 PE_ARBITRARY (0x0000000a) +#define PE_WIN_CERT_REVISION_1_0 PE_ARBITRARY (0x00000100) +#define PE_WIN_CERT_REVISION_2_0 PE_ARBITRARY (0x00000200) +#define PE_WIN_CERT_TYPE_X509 PE_ARBITRARY (0x00000001) +#define PE_WIN_CERT_TYPE_PKCS_SIGNED_DATA PE_ARBITRARY (0x00000002) +#define PE_WIN_CERT_TYPE_RESERVED_1 PE_ARBITRARY (0x00000003) +#define PE_WIN_CERT_TYPE_TS_STACK_SIGNED PE_ARBITRARY (0x00000004) +#define PE_IMAGE_REL_ARM_ABSOLUTE PE_ARBITRARY (0x00000000) +#define PE_IMAGE_REL_ARM_ADDR32 PE_ARBITRARY (0x00000001) +#define PE_IMAGE_REL_ARM_ADDR32NB PE_ARBITRARY (0x00000002) +#define PE_IMAGE_REL_ARM_BRANCH24 PE_ARBITRARY (0x00000003) +#define PE_IMAGE_REL_ARM_BRANCH11 PE_ARBITRARY (0x00000004) +#define PE_IMAGE_REL_ARM_TOKEN PE_ARBITRARY (0x00000005) +#define PE_IMAGE_REL_ARM_BLX24 PE_ARBITRARY (0x00000008) +#define PE_IMAGE_REL_ARM_BLX11 PE_ARBITRARY (0x00000009) +#define PE_IMAGE_REL_ARM_SECTION PE_ARBITRARY (0x0000000e) +#define PE_IMAGE_REL_ARM_SECREL PE_ARBITRARY (0x0000000f) +#define PE_IMAGE_REL_ARM_MOV32A PE_ARBITRARY (0x00000010) +#define PE_IMAGE_REL_ARM_MOV32T PE_ARBITRARY (0x00000011) +#define PE_IMAGE_REL_ARM_BRANCH20T PE_ARBITRARY (0x00000012) +#define PE_IMAGE_REL_ARM_BRANCH24T PE_ARBITRARY (0x00000014) +#define PE_IMAGE_REL_ARM_BLX23T PE_ARBITRARY (0x00000015) +#define PE_IMAGE_REL_SH3_ABSOLUTE PE_ARBITRARY (0x00000000) +#define PE_IMAGE_REL_SH3_DIRECT16 PE_ARBITRARY (0x00000001) +#define PE_IMAGE_REL_SH3_DIRECT32 PE_ARBITRARY (0x00000002) +#define PE_IMAGE_REL_SH3_DIRECT8 PE_ARBITRARY (0x00000003) +#define PE_IMAGE_REL_SH3_DIRECT8_WORD PE_ARBITRARY (0x00000004) +#define PE_IMAGE_REL_SH3_DIRECT8_LONG PE_ARBITRARY (0x00000005) +#define PE_IMAGE_REL_SH3_DIRECT4 PE_ARBITRARY (0x00000006) +#define PE_IMAGE_REL_SH3_DIRECT4_WORD PE_ARBITRARY (0x00000007) +#define PE_IMAGE_REL_SH3_DIRECT4_LONG PE_ARBITRARY (0x00000008) +#define PE_IMAGE_REL_SH3_PCREL8_WORD PE_ARBITRARY (0x00000009) +#define PE_IMAGE_REL_SH3_PCREL8_LONG PE_ARBITRARY (0x0000000a) +#define PE_IMAGE_REL_SH3_PCREL12_WORD PE_ARBITRARY (0x0000000b) +#define PE_IMAGE_REL_SH3_STARTOF_SECTION PE_ARBITRARY (0x0000000c) +#define PE_IMAGE_REL_SH3_SIZEOF_SECTION PE_ARBITRARY (0x0000000d) +#define PE_IMAGE_REL_SH3_SECTION PE_ARBITRARY (0x0000000e) +#define PE_IMAGE_REL_SH3_SECREL PE_ARBITRARY (0x0000000f) +#define PE_IMAGE_REL_SH3_DIRECT32_NB PE_ARBITRARY (0x00000010) +#define PE_IMAGE_REL_SH3_GPREL4_LONG PE_ARBITRARY (0x00000011) +#define PE_IMAGE_REL_SH3_TOKEN PE_ARBITRARY (0x00000012) +#define PE_IMAGE_REL_SHM_PCRELPT PE_ARBITRARY (0x00000013) +#define PE_IMAGE_REL_SHM_REFLO PE_ARBITRARY (0x00000014) +#define PE_IMAGE_REL_SHM_REFHALF PE_ARBITRARY (0x00000015) +#define PE_IMAGE_REL_SHM_RELLO PE_ARBITRARY (0x00000016) +#define PE_IMAGE_REL_SHM_RELHALF PE_ARBITRARY (0x00000017) +#define PE_IMAGE_REL_SHM_PAIR PE_ARBITRARY (0x00000018) +#define PE_IMAGE_REL_SHM_NOMODE PE_ARBITRARY (0x00008000) +#define PE_IMAGE_REL_I386_ABSOLUTE PE_ARBITRARY (0x00000000) +#define PE_IMAGE_REL_I386_DIR16 PE_ARBITRARY (0x00000001) +#define PE_IMAGE_REL_I386_REL16 PE_ARBITRARY (0x00000002) +#define PE_IMAGE_REL_I386_DIR32 PE_ARBITRARY (0x00000006) +#define PE_IMAGE_REL_I386_DIR32NB PE_ARBITRARY (0x00000007) +#define PE_IMAGE_REL_I386_SEG12 PE_ARBITRARY (0x00000009) +#define PE_IMAGE_REL_I386_SECTION PE_ARBITRARY (0x0000000a) +#define PE_IMAGE_REL_I386_SECREL PE_ARBITRARY (0x0000000b) +#define PE_IMAGE_REL_I386_TOKEN PE_ARBITRARY (0x0000000c) +#define PE_IMAGE_REL_I386_SECREL7 PE_ARBITRARY (0x0000000d) +#define PE_IMAGE_REL_I386_REL32 PE_ARBITRARY (0x00000014) +#define PE_IMAGE_REL_IA64_ABSOLUTE PE_ARBITRARY (0x00000000) +#define PE_IMAGE_REL_IA64_IMM14 PE_ARBITRARY (0x00000001) +#define PE_IMAGE_REL_IA64_IMM22 PE_ARBITRARY (0x00000002) +#define PE_IMAGE_REL_IA64_IMM64 PE_ARBITRARY (0x00000003) +#define PE_IMAGE_REL_IA64_DIR32 PE_ARBITRARY (0x00000004) +#define PE_IMAGE_REL_IA64_DIR64 PE_ARBITRARY (0x00000005) +#define PE_IMAGE_REL_IA64_PCREL21B PE_ARBITRARY (0x00000006) +#define PE_IMAGE_REL_IA64_PCREL21M PE_ARBITRARY (0x00000007) +#define PE_IMAGE_REL_IA64_PCREL21F PE_ARBITRARY (0x00000008) +#define PE_IMAGE_REL_IA64_GPREL22 PE_ARBITRARY (0x00000009) +#define PE_IMAGE_REL_IA64_LTOFF22 PE_ARBITRARY (0x0000000a) +#define PE_IMAGE_REL_IA64_SECTION PE_ARBITRARY (0x0000000b) +#define PE_IMAGE_REL_IA64_SECREL22 PE_ARBITRARY (0x0000000c) +#define PE_IMAGE_REL_IA64_SECREL64I PE_ARBITRARY (0x0000000d) +#define PE_IMAGE_REL_IA64_SECREL32 PE_ARBITRARY (0x0000000e) +#define PE_IMAGE_REL_IA64_DIR32NB PE_ARBITRARY (0x00000010) +#define PE_IMAGE_REL_IA64_SREL14 PE_ARBITRARY (0x00000011) +#define PE_IMAGE_REL_IA64_SREL22 PE_ARBITRARY (0x00000012) +#define PE_IMAGE_REL_IA64_SREL32 PE_ARBITRARY (0x00000013) +#define PE_IMAGE_REL_IA64_UREL32 PE_ARBITRARY (0x00000014) +#define PE_IMAGE_REL_IA64_PCREL60X PE_ARBITRARY (0x00000015) +#define PE_IMAGE_REL_IA64_PCREL60B PE_ARBITRARY (0x00000016) +#define PE_IMAGE_REL_IA64_PCREL60F PE_ARBITRARY (0x00000017) +#define PE_IMAGE_REL_IA64_PCREL60I PE_ARBITRARY (0x00000018) +#define PE_IMAGE_REL_IA64_PCREL60M PE_ARBITRARY (0x00000019) +#define PE_IMAGE_REL_IA64_IMMGPREL64 PE_ARBITRARY (0x0000001a) +#define PE_IMAGE_REL_IA64_TOKEN PE_ARBITRARY (0x0000001b) +#define PE_IMAGE_REL_IA64_GPREL32 PE_ARBITRARY (0x0000001c) +#define PE_IMAGE_REL_IA64_ADDEND PE_ARBITRARY (0x0000001f) +#define PE_IMAGE_REL_PPC_ABSOLUTE PE_ARBITRARY (0x00000000) +#define PE_IMAGE_REL_PPC_ADDR64 PE_ARBITRARY (0x00000001) +#define PE_IMAGE_REL_PPC_ADDR32 PE_ARBITRARY (0x00000002) +#define PE_IMAGE_REL_PPC_ADDR24 PE_ARBITRARY (0x00000003) +#define PE_IMAGE_REL_PPC_ADDR16 PE_ARBITRARY (0x00000004) +#define PE_IMAGE_REL_PPC_ADDR14 PE_ARBITRARY (0x00000005) +#define PE_IMAGE_REL_PPC_REL24 PE_ARBITRARY (0x00000006) +#define PE_IMAGE_REL_PPC_REL14 PE_ARBITRARY (0x00000007) +#define PE_IMAGE_REL_PPC_ADDR32NB PE_ARBITRARY (0x0000000a) +#define PE_IMAGE_REL_PPC_SECREL PE_ARBITRARY (0x0000000b) +#define PE_IMAGE_REL_PPC_SECTION PE_ARBITRARY (0x0000000c) +#define PE_IMAGE_REL_PPC_SECREL16 PE_ARBITRARY (0x0000000f) +#define PE_IMAGE_REL_PPC_REFHI PE_ARBITRARY (0x00000010) +#define PE_IMAGE_REL_PPC_REFLO PE_ARBITRARY (0x00000011) +#define PE_IMAGE_REL_PPC_PAIR PE_ARBITRARY (0x00000012) +#define PE_IMAGE_REL_PPC_SECRELLO PE_ARBITRARY (0x00000013) +#define PE_IMAGE_REL_PPC_GPREL PE_ARBITRARY (0x00000015) +#define PE_IMAGE_REL_PPC_TOKEN PE_ARBITRARY (0x00000016) +#define PE_IMAGE_REL_MIPS_ABSOLUTE PE_ARBITRARY (0x00000000) +#define PE_IMAGE_REL_MIPS_REFHALF PE_ARBITRARY (0x00000001) +#define PE_IMAGE_REL_MIPS_REFWORD PE_ARBITRARY (0x00000002) +#define PE_IMAGE_REL_MIPS_JMPADDR PE_ARBITRARY (0x00000003) +#define PE_IMAGE_REL_MIPS_REFHI PE_ARBITRARY (0x00000004) +#define PE_IMAGE_REL_MIPS_REFLO PE_ARBITRARY (0x00000005) +#define PE_IMAGE_REL_MIPS_GPREL PE_ARBITRARY (0x00000006) +#define PE_IMAGE_REL_MIPS_LITERAL PE_ARBITRARY (0x00000007) +#define PE_IMAGE_REL_MIPS_SECTION PE_ARBITRARY (0x0000000a) +#define PE_IMAGE_REL_MIPS_SECREL PE_ARBITRARY (0x0000000b) +#define PE_IMAGE_REL_MIPS_SECRELLO PE_ARBITRARY (0x0000000c) +#define PE_IMAGE_REL_MIPS_SECRELHI PE_ARBITRARY (0x0000000d) +#define PE_IMAGE_REL_MIPS_JMPADDR16 PE_ARBITRARY (0x00000010) +#define PE_IMAGE_REL_MIPS_REFWORDNB PE_ARBITRARY (0x00000022) +#define PE_IMAGE_REL_MIPS_PAIR PE_ARBITRARY (0x00000025) +#define PE_IMAGE_REL_M32R_ABSOLUTE PE_ARBITRARY (0x00000000) +#define PE_IMAGE_REL_M32R_ADDR32 PE_ARBITRARY (0x00000001) +#define PE_IMAGE_REL_M32R_ADDR32NB PE_ARBITRARY (0x00000002) +#define PE_IMAGE_REL_M32R_ADDR24 PE_ARBITRARY (0x00000003) +#define PE_IMAGE_REL_M32R_GPREL16 PE_ARBITRARY (0x00000004) +#define PE_IMAGE_REL_M32R_PCREL24 PE_ARBITRARY (0x00000005) +#define PE_IMAGE_REL_M32R_PCREL16 PE_ARBITRARY (0x00000006) +#define PE_IMAGE_REL_M32R_PCREL8 PE_ARBITRARY (0x00000007) +#define PE_IMAGE_REL_M32R_REFHALF PE_ARBITRARY (0x00000008) +#define PE_IMAGE_REL_M32R_REFHI PE_ARBITRARY (0x00000009) +#define PE_IMAGE_REL_M32R_REFLO PE_ARBITRARY (0x0000000a) +#define PE_IMAGE_REL_M32R_PAIR PE_ARBITRARY (0x0000000b) +#define PE_IMAGE_REL_M32R_SECTION PE_ARBITRARY (0x0000000c) +#define PE_IMAGE_REL_M32R_SECREL PE_ARBITRARY (0x0000000d) +#define PE_IMAGE_REL_M32R_TOKEN PE_ARBITRARY (0x0000000e) +#define PE_IMAGE_REL_AMD64_ABSOLUTE PE_ARBITRARY (0x00000000) +#define PE_IMAGE_REL_AMD64_ADDR64 PE_ARBITRARY (0x00000001) +#define PE_IMAGE_REL_AMD64_ADDR32 PE_ARBITRARY (0x00000002) +#define PE_IMAGE_REL_AMD64_ADDR32NB PE_ARBITRARY (0x00000003) +#define PE_IMAGE_REL_AMD64_REL32 PE_ARBITRARY (0x00000004) +#define PE_IMAGE_REL_AMD64_REL32_1 PE_ARBITRARY (0x00000005) +#define PE_IMAGE_REL_AMD64_REL32_2 PE_ARBITRARY (0x00000006) +#define PE_IMAGE_REL_AMD64_REL32_3 PE_ARBITRARY (0x00000007) +#define PE_IMAGE_REL_AMD64_REL32_4 PE_ARBITRARY (0x00000008) +#define PE_IMAGE_REL_AMD64_REL32_5 PE_ARBITRARY (0x00000009) +#define PE_IMAGE_REL_AMD64_SECTION PE_ARBITRARY (0x0000000a) +#define PE_IMAGE_REL_AMD64_SECREL PE_ARBITRARY (0x0000000b) +#define PE_IMAGE_REL_AMD64_SECREL7 PE_ARBITRARY (0x0000000c) +#define PE_IMAGE_REL_AMD64_TOKEN PE_ARBITRARY (0x0000000d) +#define PE_IMAGE_REL_AMD64_SREL32 PE_ARBITRARY (0x0000000e) +#define PE_IMAGE_REL_AMD64_PAIR PE_ARBITRARY (0x0000000f) +#define PE_IMAGE_REL_AMD64_SSPAN32 PE_ARBITRARY (0x00000010) +#define PE_IMAGE_COMDAT_SELECT_NODUPLICATES PE_ARBITRARY (0x00000001) +#define PE_IMAGE_COMDAT_SELECT_ANY PE_ARBITRARY (0x00000002) +#define PE_IMAGE_COMDAT_SELECT_SAME_SIZE PE_ARBITRARY (0x00000003) +#define PE_IMAGE_COMDAT_SELECT_EXACT_MATCH PE_ARBITRARY (0x00000004) +#define PE_IMAGE_COMDAT_SELECT_ASSOCIATIVE PE_ARBITRARY (0x00000005) +#define PE_IMAGE_COMDAT_SELECT_LARGEST PE_ARBITRARY (0x00000006) +#define PE_IMAGE_DLL_RESERVED_X0001 PE_BITWISE (0x00000000) +#define PE_IMAGE_DLL_RESERVED_X0002 PE_BITWISE (0x00000000) +#define PE_IMAGE_DLL_RESERVED_X0004 PE_BITWISE (0x00000000) +#define PE_IMAGE_DLL_RESERVED_X0008 PE_BITWISE (0x00000000) +#define PE_IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE PE_BITWISE (0x00000000) +#define PE_IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY PE_BITWISE (0x00000000) +#define PE_IMAGE_DLL_CHARACTERISTICS_NX_COMPAT PE_BITWISE (0x00000000) +#define PE_IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION PE_BITWISE (0x00000000) +#define PE_IMAGE_DLL_CHARACTERISTICS_NO_SEH PE_BITWISE (0x00000000) +#define PE_IMAGE_DLL_CHARACTERISTICS_NO_BIND PE_BITWISE (0x00000000) +#define PE_IMAGE_DLL_RESERVED_X1000 PE_BITWISE (0x00000000) +#define PE_IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER PE_BITWISE (0x00000000) +#define PE_IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE PE_BITWISE (0x00000000) +#define PE_IMAGE_FILE_RELOCS_STRIPPED PE_BITWISE (0x00000000) +#define PE_IMAGE_FILE_EXECUTABLE_IMAGE PE_BITWISE (0x00000000) +#define PE_IMAGE_FILE_LINE_NUMS_STRIPPED PE_BITWISE (0x00000000) +#define PE_IMAGE_FILE_LOCAL_SYMS_STRIPPED PE_BITWISE (0x00000000) +#define PE_IMAGE_FILE_AGGRESSIVE_WS_TRIM PE_BITWISE (0x00000000) +#define PE_IMAGE_FILE_LARGE_ADDRESS_AWARE PE_BITWISE (0x00000000) +#define PE_IMAGE_FILE_RESERVED_CHARACTERISTIC PE_BITWISE (0x00000000) +#define PE_IMAGE_FILE_BYTES_REVERSED_LO PE_BITWISE (0x00000000) +#define PE_IMAGE_FILE_32BIT_MACHINE PE_BITWISE (0x00000000) +#define PE_IMAGE_FILE_DEBUG_STRIPPED PE_BITWISE (0x00000000) +#define PE_IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP PE_BITWISE (0x00000000) +#define PE_IMAGE_FILE_NET_RUN_FROM_SWAP PE_BITWISE (0x00000000) +#define PE_IMAGE_FILE_SYSTEM PE_BITWISE (0x00000000) +#define PE_IMAGE_FILE_DLL PE_BITWISE (0x00000000) +#define PE_IMAGE_FILE_UP_SYSTEM_ONLY PE_BITWISE (0x00000000) +#define PE_IMAGE_FILE_BYTES_REVERSED_HI PE_BITWISE (0x00000000) +#define PE_IMAGE_DEBUG_TYPE_UNKNOWN PE_ARBITRARY (0x00000000) +#define PE_IMAGE_DEBUG_TYPE_COFF PE_ARBITRARY (0x00000001) +#define PE_IMAGE_DEBUG_TYPE_CODEVIEW PE_ARBITRARY (0x00000002) +#define PE_IMAGE_DEBUG_TYPE_FPO PE_ARBITRARY (0x00000003) +#define PE_IMAGE_DEBUG_TYPE_MISC PE_ARBITRARY (0x00000004) +#define PE_IMAGE_DEBUG_TYPE_EXCEPTION PE_ARBITRARY (0x00000005) +#define PE_IMAGE_DEBUG_TYPE_FIXUP PE_ARBITRARY (0x00000006) +#define PE_IMAGE_DEBUG_TYPE_OMAP_TO_SRC PE_ARBITRARY (0x00000007) +#define PE_IMAGE_DEBUG_TYPE_OMAP_FROM_SRC PE_ARBITRARY (0x00000008) +#define PE_IMAGE_DEBUG_TYPE_BORLAND PE_ARBITRARY (0x00000009) +#define PE_IMAGE_DEBUG_TYPE_RESERVED10 PE_ARBITRARY (0x0000000a) +#define PE_IMAGE_DEBUG_TYPE_CLSID PE_ARBITRARY (0x0000000b) +#define PE_IMAGE_SUBSYSTEM_UNKNOWN PE_ARBITRARY (0x00000000) +#define PE_IMAGE_SUBSYSTEM_NATIVE PE_ARBITRARY (0x00000001) +#define PE_IMAGE_SUBSYSTEM_WINDOWS_GUI PE_ARBITRARY (0x00000002) +#define PE_IMAGE_SUBSYSTEM_WINDOWS_CUI PE_ARBITRARY (0x00000003) +#define PE_IMAGE_SUBSYSTEM_POSIX_CUI PE_ARBITRARY (0x00000007) +#define PE_IMAGE_SUBSYSTEM_WINDOWS_CE_GUI PE_ARBITRARY (0x00000009) +#define PE_IMAGE_SUBSYSTEM_EFI_APPLICATION PE_ARBITRARY (0x0000000a) +#define PE_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER PE_ARBITRARY (0x0000000b) +#define PE_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER PE_ARBITRARY (0x0000000c) +#define PE_IMAGE_SUBSYSTEM_EFI_ROM PE_ARBITRARY (0x0000000d) +#define PE_IMAGE_SUBSYSTEM_XBOX PE_ARBITRARY (0x0000000e) +#define PE_IMPORT_ORDINAL PE_ARBITRARY (0x00000000) +#define PE_IMPORT_NAME PE_ARBITRARY (0x00000001) +#define PE_IMPORT_NAME_NOPREFIX PE_ARBITRARY (0x00000002) +#define PE_IMPORT_NAME_UNDECORATE PE_ARBITRARY (0x00000003) +#define PE_IMPORT_CODE PE_ARBITRARY (0x00000000) +#define PE_IMPORT_DATA PE_ARBITRARY (0x00000001) +#define PE_IMPORT_CONST PE_ARBITRARY (0x00000002) +#define PE_IMAGE_FILE_MACHINE_UNKNOWN PE_ARBITRARY (0x00000000) +#define PE_IMAGE_FILE_MACHINE_I386 PE_ARBITRARY (0x0000014c) +#define PE_IMAGE_FILE_MACHINE_R4000 PE_ARBITRARY (0x00000166) +#define PE_IMAGE_FILE_MACHINE_WCEMIPSV2 PE_ARBITRARY (0x00000169) +#define PE_IMAGE_FILE_MACHINE_SH3 PE_ARBITRARY (0x000001a2) +#define PE_IMAGE_FILE_MACHINE_SH3DSP PE_ARBITRARY (0x000001a3) +#define PE_IMAGE_FILE_MACHINE_SH4 PE_ARBITRARY (0x000001a6) +#define PE_IMAGE_FILE_MACHINE_SH5 PE_ARBITRARY (0x000001a8) +#define PE_IMAGE_FILE_MACHINE_ARM PE_ARBITRARY (0x000001c0) +#define PE_IMAGE_FILE_MACHINE_THUMB PE_ARBITRARY (0x000001c2) +#define PE_IMAGE_FILE_MACHINE_ARMV7 PE_ARBITRARY (0x000001c4) +#define PE_IMAGE_FILE_MACHINE_AM33 PE_ARBITRARY (0x000001d3) +#define PE_IMAGE_FILE_MACHINE_POWERPC PE_ARBITRARY (0x000001f0) +#define PE_IMAGE_FILE_MACHINE_POWERPCFP PE_ARBITRARY (0x000001f1) +#define PE_IMAGE_FILE_MACHINE_IA64 PE_ARBITRARY (0x00000200) +#define PE_IMAGE_FILE_MACHINE_MIPS16 PE_ARBITRARY (0x00000266) +#define PE_IMAGE_FILE_MACHINE_MIPSFPU PE_ARBITRARY (0x00000366) +#define PE_IMAGE_FILE_MACHINE_MIPSFPU16 PE_ARBITRARY (0x00000466) +#define PE_IMAGE_FILE_MACHINE_EBC PE_ARBITRARY (0x00000ebc) +#define PE_IMAGE_FILE_MACHINE_AMD64 PE_ARBITRARY (0x00008664) +#define PE_IMAGE_FILE_MACHINE_M32R PE_ARBITRARY (0x00009041) +#define PE_MAGIC_ROM_IMAGE PE_ARBITRARY (0x00000107) +#define PE_MAGIC_PE32 PE_ARBITRARY (0x0000010b) +#define PE_MAGIC_PE32_PLUS PE_ARBITRARY (0x0000020b) +#define PE_IMAGE_SCN_RESERVED_X00000001 PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_RESERVED_X00000002 PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_RESERVED_X00000004 PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_TYPE_NO_PAD PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_RESERVED_X00000010 PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_CNT_CODE PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_CNT_INITIALIZED_DATA PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_CNT_UNINITIALIZED_DATA PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_LNK_OTHER PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_LNK_INFO PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_RESERVED_X00000400 PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_LNK_REMOVE PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_LNK_COMDAT PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_GPREL PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_MEM_PURGEABLE PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_MEM_16BIT PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_MEM_LOCKED PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_MEM_PRELOAD PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_ALIGN_1BYTES PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_ALIGN_2BYTES PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_ALIGN_4BYTES PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_ALIGN_8BYTES PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_ALIGN_16BYTES PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_ALIGN_32BYTES PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_ALIGN_64BYTES PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_ALIGN_128BYTES PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_ALIGN_256BYTES PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_ALIGN_512BYTES PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_ALIGN_1024BYTES PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_ALIGN_2048BYTES PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_ALIGN_4096BYTES PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_ALIGN_8192BYTES PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_LNK_NRELOC_OVFL PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_MEM_DISCARDABLE PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_MEM_NOT_CACHED PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_MEM_NOT_PAGED PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_MEM_SHARED PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_MEM_EXECUTE PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_MEM_READ PE_BITWISE (0x00000000) +#define PE_IMAGE_SCN_MEM_WRITE PE_BITWISE (0x00000000) +#define PE_IMAGE_SYM_DEBUG PE_ARBITRARY ( -2) +#define PE_IMAGE_SYM_ABSOLUTE PE_ARBITRARY ( -1) +#define PE_IMAGE_SYM_UNDEFINED PE_ARBITRARY (0x00000000) +#define PE_IMAGE_SYM_CLASS_NULL PE_ARBITRARY (0x00000000) +#define PE_IMAGE_SYM_CLASS_AUTOMATIC PE_ARBITRARY (0x00000001) +#define PE_IMAGE_SYM_CLASS_EXTERNAL PE_ARBITRARY (0x00000002) +#define PE_IMAGE_SYM_CLASS_STATIC PE_ARBITRARY (0x00000003) +#define PE_IMAGE_SYM_CLASS_REGISTER PE_ARBITRARY (0x00000004) +#define PE_IMAGE_SYM_CLASS_EXTERNAL_DEF PE_ARBITRARY (0x00000005) +#define PE_IMAGE_SYM_CLASS_LABEL PE_ARBITRARY (0x00000006) +#define PE_IMAGE_SYM_CLASS_UNDEFINED_LABEL PE_ARBITRARY (0x00000007) +#define PE_IMAGE_SYM_CLASS_MEMBER_OF_STRUCT PE_ARBITRARY (0x00000008) +#define PE_IMAGE_SYM_CLASS_ARGUMENT PE_ARBITRARY (0x00000009) +#define PE_IMAGE_SYM_CLASS_STRUCT_TAG PE_ARBITRARY (0x0000000a) +#define PE_IMAGE_SYM_CLASS_MEMBER_OF_UNION PE_ARBITRARY (0x0000000b) +#define PE_IMAGE_SYM_CLASS_UNION_TAG PE_ARBITRARY (0x0000000c) +#define PE_IMAGE_SYM_CLASS_TYPE_DEFINITION PE_ARBITRARY (0x0000000d) +#define PE_IMAGE_SYM_CLASS_UNDEFINED_STATIC PE_ARBITRARY (0x0000000e) +#define PE_IMAGE_SYM_CLASS_ENUM_TAG PE_ARBITRARY (0x0000000f) +#define PE_IMAGE_SYM_CLASS_MEMBER_OF_ENUM PE_ARBITRARY (0x00000010) +#define PE_IMAGE_SYM_CLASS_REGISTER_PARAM PE_ARBITRARY (0x00000011) +#define PE_IMAGE_SYM_CLASS_BIT_FIELD PE_ARBITRARY (0x00000012) +#define PE_IMAGE_SYM_CLASS_BLOCK PE_ARBITRARY (0x00000064) +#define PE_IMAGE_SYM_CLASS_FUNCTION PE_ARBITRARY (0x00000065) +#define PE_IMAGE_SYM_CLASS_END_OF_STRUCT PE_ARBITRARY (0x00000066) +#define PE_IMAGE_SYM_CLASS_FILE PE_ARBITRARY (0x00000067) +#define PE_IMAGE_SYM_CLASS_SECTION PE_ARBITRARY (0x00000068) +#define PE_IMAGE_SYM_CLASS_WEAK_EXTERN PE_ARBITRARY (0x00000069) +#define PE_IMAGE_SYM_CLASS_CLR_TOKEN PE_ARBITRARY (0x0000006b) +#define PE_IMAGE_SYM_CLASS_END_OF_FUNC PE_ARBITRARY (0x000000ff) +#define PE_IMAGE_SYM_TYPE_NULL PE_ARBITRARY (0x00000000) +#define PE_IMAGE_SYM_TYPE_VOID PE_ARBITRARY (0x00000001) +#define PE_IMAGE_SYM_TYPE_CHAR PE_ARBITRARY (0x00000002) +#define PE_IMAGE_SYM_TYPE_SHORT PE_ARBITRARY (0x00000003) +#define PE_IMAGE_SYM_TYPE_INT PE_ARBITRARY (0x00000004) +#define PE_IMAGE_SYM_TYPE_LONG PE_ARBITRARY (0x00000005) +#define PE_IMAGE_SYM_TYPE_FLOAT PE_ARBITRARY (0x00000006) +#define PE_IMAGE_SYM_TYPE_DOUBLE PE_ARBITRARY (0x00000007) +#define PE_IMAGE_SYM_TYPE_STRUCT PE_ARBITRARY (0x00000008) +#define PE_IMAGE_SYM_TYPE_UNION PE_ARBITRARY (0x00000009) +#define PE_IMAGE_SYM_TYPE_ENUM PE_ARBITRARY (0x0000000a) +#define PE_IMAGE_SYM_TYPE_MOE PE_ARBITRARY (0x0000000b) +#define PE_IMAGE_SYM_TYPE_BYTE PE_ARBITRARY (0x0000000c) +#define PE_IMAGE_SYM_TYPE_WORD PE_ARBITRARY (0x0000000d) +#define PE_IMAGE_SYM_TYPE_UINT PE_ARBITRARY (0x0000000e) +#define PE_IMAGE_SYM_TYPE_DWORD PE_ARBITRARY (0x0000000f) +#define PE_IMAGE_SYM_DTYPE_NULL PE_ARBITRARY (0x00000000) +#define PE_IMAGE_SYM_DTYPE_POINTER PE_ARBITRARY (0x00000001) +#define PE_IMAGE_SYM_DTYPE_FUNCTION PE_ARBITRARY (0x00000002) +#define PE_IMAGE_SYM_DTYPE_ARRAY PE_ARBITRARY (0x00000003) +#define PE_IMAGE_DATA_DIR_ORDINAL_EXPORT PE_ARBITRARY (0x00000000) +#define PE_IMAGE_DATA_DIR_ORDINAL_IMPORT PE_ARBITRARY (0x00000001) +#define PE_IMAGE_DATA_DIR_ORDINAL_RESOURCE PE_ARBITRARY (0x00000002) +#define PE_IMAGE_DATA_DIR_ORDINAL_EXCEPTION PE_ARBITRARY (0x00000003) +#define PE_IMAGE_DATA_DIR_ORDINAL_CERTIFICATE PE_ARBITRARY (0x00000004) +#define PE_IMAGE_DATA_DIR_ORDINAL_BASE_RELOCATION PE_ARBITRARY (0x00000005) +#define PE_IMAGE_DATA_DIR_ORDINAL_DEBUG PE_ARBITRARY (0x00000006) +#define PE_IMAGE_DATA_DIR_ORDINAL_ARCHITECTURE PE_ARBITRARY (0x00000007) +#define PE_IMAGE_DATA_DIR_ORDINAL_GLOBAL_PTR PE_ARBITRARY (0x00000008) +#define PE_IMAGE_DATA_DIR_ORDINAL_TLS PE_ARBITRARY (0x00000009) +#define PE_IMAGE_DATA_DIR_ORDINAL_LOAD_CONFIG PE_ARBITRARY (0x0000000a) +#define PE_IMAGE_DATA_DIR_ORDINAL_BOUND_IMPORT PE_ARBITRARY (0x0000000b) +#define PE_IMAGE_DATA_DIR_ORDINAL_IAT PE_ARBITRARY (0x0000000c) +#define PE_IMAGE_DATA_DIR_ORDINAL_DELAY_IMPORT_DESCRIPTOR PE_ARBITRARY (0x0000000d) +#define PE_IMAGE_DATA_DIR_ORDINAL_CLR_RUNTIME_HEADER PE_ARBITRARY (0x0000000e) +#define PE_IMAGE_DATA_DIR_ORDINAL_RESERVED PE_ARBITRARY (0x0000000f) + +#endif diff --git a/include/pemagine/pe_inline_asm.h b/include/pemagine/pe_inline_asm.h new file mode 100644 index 0000000..65e1376 --- /dev/null +++ b/include/pemagine/pe_inline_asm.h @@ -0,0 +1,20 @@ +#if defined(__NT32) +#if (__COMPILER__ == __GCC__) +#include "bits/nt32/pe_inline_asm__gcc.h" +#elif (__COMPILER__ == __MSVC__) +#include "bits/nt32/pe_inline_asm__msvc.h" +#endif + +#elif defined(__NT64) +#if (__COMPILER__ == __GCC__) +#include "bits/nt64/pe_inline_asm__gcc.h" +#elif (__COMPILER__ == __MSVC__) +#include "bits/nt64/pe_inline_asm__msvc.h" +#endif +#endif + +/* trivial */ +static __inline__ void * pe_va_from_rva(const void * base, intptr_t offset) +{ + return (void *)((intptr_t)base + offset); +} diff --git a/include/pemagine/pe_structs.h b/include/pemagine/pe_structs.h new file mode 100644 index 0000000..4a7017d --- /dev/null +++ b/include/pemagine/pe_structs.h @@ -0,0 +1,635 @@ +#ifndef PE_STRUCTS_H +#define PE_STRUCTS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* pe_image_dos_header... */ +#define PE_DOS_MAGIC_BS 0x02 +#define PE_DOS_CBLP_BS 0x02 +#define PE_DOS_CP_BS 0x02 +#define PE_DOS_CRLC_BS 0x02 +#define PE_DOS_CPARHDR_BS 0x02 +#define PE_DOS_MINALLOC_BS 0x02 +#define PE_DOS_MAXALLOC_BS 0x02 +#define PE_DOS_SS_BS 0x02 +#define PE_DOS_SP_BS 0x02 +#define PE_DOS_CSUM_BS 0x02 +#define PE_DOS_IP_BS 0x02 +#define PE_DOS_CS_BS 0x02 +#define PE_DOS_LFARLC_BS 0x02 +#define PE_DOS_OVNO_BS 0x02 +#define PE_DOS_RES_BS 0x08 +#define PE_DOS_OEMID_BS 0x02 +#define PE_DOS_OEMINFO_BS 0x02 +#define PE_DOS_RES2_BS 0x14 +#define PE_DOS_LFANEW_BS 0x04 + +struct pe_image_dos_hdr { + unsigned char dos_magic [PE_DOS_MAGIC_BS]; /* 0x00 */ + unsigned char dos_cblp [PE_DOS_CBLP_BS]; /* 0x02 */ + unsigned char dos_cp [PE_DOS_CP_BS]; /* 0x04 */ + unsigned char dos_crlc [PE_DOS_CRLC_BS]; /* 0x06 */ + unsigned char dos_cparhdr [PE_DOS_CPARHDR_BS]; /* 0x08 */ + unsigned char dos_minalloc [PE_DOS_MINALLOC_BS]; /* 0x0a */ + unsigned char dos_maxalloc [PE_DOS_MAXALLOC_BS]; /* 0x0c */ + unsigned char dos_ss [PE_DOS_SS_BS]; /* 0x0e */ + unsigned char dos_sp [PE_DOS_SP_BS]; /* 0x10 */ + unsigned char dos_csum [PE_DOS_CSUM_BS]; /* 0x12 */ + unsigned char dos_ip [PE_DOS_IP_BS]; /* 0x14 */ + unsigned char dos_cs [PE_DOS_CS_BS]; /* 0x16 */ + unsigned char dos_lfarlc [PE_DOS_LFARLC_BS]; /* 0x18 */ + unsigned char dos_ovno [PE_DOS_OVNO_BS]; /* 0x1a */ + unsigned char dos_res [PE_DOS_RES_BS]; /* 0x1c */ + unsigned char dos_oemid [PE_DOS_OEMID_BS]; /* 0x24 */ + unsigned char dos_oeminfo [PE_DOS_OEMINFO_BS]; /* 0x26 */ + unsigned char dos_res2 [PE_DOS_RES2_BS]; /* 0x28 */ + unsigned char dos_lfanew [PE_DOS_LFANEW_BS]; /* 0x3c */ +}; + +#undef PE_DOS_MAGIC_BS +#undef PE_DOS_CBLP_BS +#undef PE_DOS_CP_BS +#undef PE_DOS_CRLC_BS +#undef PE_DOS_CPARHDR_BS +#undef PE_DOS_MINALLOC_BS +#undef PE_DOS_MAXALLOC_BS +#undef PE_DOS_SS_BS +#undef PE_DOS_SP_BS +#undef PE_DOS_CSUM_BS +#undef PE_DOS_IP_BS +#undef PE_DOS_CS_BS +#undef PE_DOS_LFARLC_BS +#undef PE_DOS_OVNO_BS +#undef PE_DOS_RES_BS +#undef PE_DOS_OEMID_BS +#undef PE_DOS_OEMINFO_BS +#undef PE_DOS_RES2_BS +#undef PE_DOS_LFANEW_BS + + +/* pe_coff_file_header... */ +#define PE_SIGNATURE_BS 0x04 +#define PE_MACHINE_BS 0x02 +#define PE_NUMBER_OF_SECTIONS_BS 0x02 +#define PE_TIME_DATE_STAMP_BS 0x04 +#define PE_POINTER_TO_SYMBOL_TABLE_BS 0x04 +#define PE_NUMBER_OF_SYMBOLS_BS 0x04 +#define PE_SIZE_OF_OPTIONAL_HEADER_BS 0x02 +#define PE_CHARACTERISTICS_BS 0x02 + +struct pe_coff_file_hdr { + unsigned char signature [PE_SIGNATURE_BS]; /* 0x00 */ + unsigned char machine [PE_MACHINE_BS]; /* 0x04 */ + unsigned char num_of_sections [PE_NUMBER_OF_SECTIONS_BS]; /* 0x06 */ + unsigned char time_date_stamp [PE_TIME_DATE_STAMP_BS]; /* 0x08 */ + unsigned char ptr_to_sym_tbl [PE_POINTER_TO_SYMBOL_TABLE_BS]; /* 0x0c */ + unsigned char num_of_syms [PE_NUMBER_OF_SYMBOLS_BS]; /* 0x10 */ + unsigned char size_of_opt_hdr [PE_SIZE_OF_OPTIONAL_HEADER_BS]; /* 0x14 */ + unsigned char characteristics [PE_CHARACTERISTICS_BS]; /* 0x16 */ +}; + +#undef PE_SIGNATURE_BS +#undef PE_MACHINE_BS +#undef PE_NUMBER_OF_SECTIONS_BS +#undef PE_TIME_DATE_STAMP_BS +#undef PE_POINTER_TO_SYMBOL_TABLE_BS +#undef PE_NUMBER_OF_SYMBOLS_BS +#undef PE_SIZE_OF_OPTIONAL_HEADER_BS +#undef PE_CHARACTERISTICS_BS + + +/* pe32_optional_header... */ +#define PE_MAGIC_BS 0x02 +#define PE_MAJOR_LINKER_VERSION_BS 0x01 +#define PE_MINOR_LINKER_VERSION_BS 0x01 +#define PE_SIZE_OF_CODE_BS 0x04 +#define PE_SIZE_OF_INITIALIZED_DATA_BS 0x04 +#define PE_SIZE_OF_UNINITIALIZED_DATA_BS 0x04 +#define PE_ADDRESS_OF_ENTRY_POINT_BS 0x04 +#define PE_BASE_OF_CODE_BS 0x04 +#define PE_BASE_OF_DATA_BS 0x04 +#define PE_IMAGE_BASE_BS 0x04 +#define PE_SECTION_ALIGNMENT_BS 0x04 +#define PE_FILE_ALIGNMENT_BS 0x04 +#define PE_MAJOR_OPERATING_SYSTEM_VERSION_BS 0x02 +#define PE_MINOR_OPERATING_SYSTEM_VERSION_BS 0x02 +#define PE_MAJOR_IMAGE_VERSION_BS 0x02 +#define PE_MINOR_IMAGE_VERSION_BS 0x02 +#define PE_MAJOR_SUBSYSTEM_VERSION_BS 0x02 +#define PE_MINOR_SUBSYSTEM_VERSION_BS 0x02 +#define PE_WIN32_VERSION_VALUE_BS 0x04 +#define PE_SIZE_OF_IMAGE_BS 0x04 +#define PE_SIZE_OF_HEADERS_BS 0x04 +#define PE_CHECK_SUM_BS 0x04 +#define PE_SUBSYSTEM_BS 0x02 +#define PE_DLL_CHARACTERISTICS_BS 0x02 +#define PE_SIZE_OF_STACK_RESERVE_BS 0x04 +#define PE_SIZE_OF_STACK_COMMIT_BS 0x04 +#define PE_SIZE_OF_HEAP_RESERVE_BS 0x04 +#define PE_SIZE_OF_HEAP_COMMIT_BS 0x04 +#define PE_LOADER_FLAGS_BS 0x04 +#define PE_NUMBER_OF_RVA_AND_SIZES_BS 0x04 +#define PE_EXPORT_TABLE_BS 0x08 +#define PE_IMPORT_TABLE_BS 0x08 +#define PE_RESOURCE_TABLE_BS 0x08 +#define PE_EXCEPTION_TABLE_BS 0x08 +#define PE_CERTIFICATE_TABLE_BS 0x08 +#define PE_BASE_RELOCATION_TABLE_BS 0x08 +#define PE_DEBUG_BS 0x08 +#define PE_ARCHITECTURE_BS 0x08 +#define PE_GLOBAL_PTR_BS 0x08 +#define PE_TLS_TABLE_BS 0x08 +#define PE_LOAD_CONFIG_TABLE_BS 0x08 +#define PE_BOUND_IMPORT_BS 0x08 +#define PE_IAT_BS 0x08 +#define PE_DELAY_IMPORT_DESCRIPTOR_BS 0x08 +#define PE_CLR_RUNTIME_HEADER_BS 0x08 +#define PE_RESERVED__MUST_BE_ZERO_BS 0x08 + +struct pe_opt_hdr_std { + unsigned char magic [PE_MAGIC_BS]; /* 0x00 */ + unsigned char major_linker_ver [PE_MAJOR_LINKER_VERSION_BS]; /* 0x02 */ + unsigned char minor_linker_ver [PE_MINOR_LINKER_VERSION_BS]; /* 0x03 */ + unsigned char size_of_code [PE_SIZE_OF_CODE_BS]; /* 0x04 */ + unsigned char size_of_initialized_data [PE_SIZE_OF_INITIALIZED_DATA_BS]; /* 0x08 */ + unsigned char size_of_uninitialized_data [PE_SIZE_OF_UNINITIALIZED_DATA_BS]; /* 0x0c */ + unsigned char entry_point [PE_ADDRESS_OF_ENTRY_POINT_BS]; /* 0x10 */ + unsigned char base_of_code [PE_BASE_OF_CODE_BS]; /* 0x14 */ +}; + +struct pe_opt_hdr_align { + unsigned char section_align [PE_SECTION_ALIGNMENT_BS]; /* 0x20 */ + unsigned char file_align [PE_FILE_ALIGNMENT_BS]; /* 0x24 */ +}; + +struct pe_opt_hdr_vers { + unsigned char major_os_ver [PE_MAJOR_OPERATING_SYSTEM_VERSION_BS]; /* 0x28 */ + unsigned char minor_os_ver [PE_MINOR_OPERATING_SYSTEM_VERSION_BS]; /* 0x2a */ + unsigned char major_image_ver [PE_MAJOR_IMAGE_VERSION_BS]; /* 0x2c */ + unsigned char minor_image_ver [PE_MINOR_IMAGE_VERSION_BS]; /* 0x2e */ + unsigned char major_subsys_ver [PE_MAJOR_SUBSYSTEM_VERSION_BS]; /* 0x30 */ + unsigned char minor_subsys_ver [PE_MINOR_SUBSYSTEM_VERSION_BS]; /* 0x32 */ + unsigned char win32_ver [PE_WIN32_VERSION_VALUE_BS]; /* 0x34 */ +}; + +struct pe_opt_hdr_img { + unsigned char size_of_image [PE_SIZE_OF_IMAGE_BS]; /* 0x38 */ + unsigned char size_of_headers [PE_SIZE_OF_HEADERS_BS]; /* 0x3c */ + unsigned char checksum [PE_CHECK_SUM_BS]; /* 0x40 */ + unsigned char subsystem [PE_SUBSYSTEM_BS]; /* 0x44 */ + unsigned char dll_characteristics [PE_DLL_CHARACTERISTICS_BS]; /* 0x46 */ +}; + +struct pe_opt_hdr_ldr { + unsigned char loader_flags [PE_LOADER_FLAGS_BS]; + unsigned char rva_and_sizes [PE_NUMBER_OF_RVA_AND_SIZES_BS]; +}; + +struct pe_opt_hdr_dirs { + unsigned char export_tbl [PE_EXPORT_TABLE_BS]; + unsigned char import_tbl [PE_IMPORT_TABLE_BS]; + unsigned char resource_tbl [PE_RESOURCE_TABLE_BS]; + unsigned char exception_tbl [PE_EXCEPTION_TABLE_BS]; + unsigned char certificate_tbl [PE_CERTIFICATE_TABLE_BS]; + unsigned char base_reloc_tbl [PE_BASE_RELOCATION_TABLE_BS]; + unsigned char debug [PE_DEBUG_BS]; + unsigned char arch [PE_ARCHITECTURE_BS]; + unsigned char global_ptr [PE_GLOBAL_PTR_BS]; + unsigned char tls_tbl [PE_TLS_TABLE_BS]; + unsigned char load_config_tbl [PE_LOAD_CONFIG_TABLE_BS]; + unsigned char bound_import [PE_BOUND_IMPORT_BS]; + unsigned char iat [PE_IAT_BS]; + unsigned char delay_import_descriptor [PE_DELAY_IMPORT_DESCRIPTOR_BS]; + unsigned char clr_runtime_hdr [PE_CLR_RUNTIME_HEADER_BS]; + unsigned char reserved [PE_RESERVED__MUST_BE_ZERO_BS]; +}; + +struct pe_data_dirs { + unsigned char rva_and_sizes [PE_NUMBER_OF_RVA_AND_SIZES_BS]; + unsigned char export_tbl [PE_EXPORT_TABLE_BS]; + unsigned char import_tbl [PE_IMPORT_TABLE_BS]; + unsigned char resource_tbl [PE_RESOURCE_TABLE_BS]; + unsigned char exception_tbl [PE_EXCEPTION_TABLE_BS]; + unsigned char certificate_tbl [PE_CERTIFICATE_TABLE_BS]; + unsigned char base_reloc_tbl [PE_BASE_RELOCATION_TABLE_BS]; + unsigned char debug [PE_DEBUG_BS]; + unsigned char arch [PE_ARCHITECTURE_BS]; + unsigned char global_ptr [PE_GLOBAL_PTR_BS]; + unsigned char tls_tbl [PE_TLS_TABLE_BS]; + unsigned char load_config_tbl [PE_LOAD_CONFIG_TABLE_BS]; + unsigned char bound_import [PE_BOUND_IMPORT_BS]; + unsigned char iat [PE_IAT_BS]; + unsigned char delay_import_descriptor [PE_DELAY_IMPORT_DESCRIPTOR_BS]; + unsigned char clr_runtime_hdr [PE_CLR_RUNTIME_HEADER_BS]; + unsigned char reserved [PE_RESERVED__MUST_BE_ZERO_BS]; +}; + +struct pe_opt_hdr_32 { + unsigned char magic [PE_MAGIC_BS]; /* 0x00 */ + unsigned char major_linker_ver [PE_MAJOR_LINKER_VERSION_BS]; /* 0x02 */ + unsigned char minor_linker_ver [PE_MINOR_LINKER_VERSION_BS]; /* 0x03 */ + unsigned char size_of_code [PE_SIZE_OF_CODE_BS]; /* 0x04 */ + unsigned char size_of_initialized_data [PE_SIZE_OF_INITIALIZED_DATA_BS]; /* 0x08 */ + unsigned char size_of_uninitialized_data [PE_SIZE_OF_UNINITIALIZED_DATA_BS]; /* 0x0c */ + unsigned char entry_point [PE_ADDRESS_OF_ENTRY_POINT_BS]; /* 0x10 */ + unsigned char base_of_code [PE_BASE_OF_CODE_BS]; /* 0x14 */ + unsigned char base_of_data [PE_BASE_OF_DATA_BS]; /* 0x18 */ + unsigned char image_base [PE_IMAGE_BASE_BS]; /* 0x1c */ + unsigned char section_align [PE_SECTION_ALIGNMENT_BS]; /* 0x20 */ + unsigned char file_align [PE_FILE_ALIGNMENT_BS]; /* 0x24 */ + unsigned char major_os_ver [PE_MAJOR_OPERATING_SYSTEM_VERSION_BS]; /* 0x28 */ + unsigned char minor_or_ver [PE_MINOR_OPERATING_SYSTEM_VERSION_BS]; /* 0x2a */ + unsigned char major_image_ver [PE_MAJOR_IMAGE_VERSION_BS]; /* 0x2c */ + unsigned char minor_image_ver [PE_MINOR_IMAGE_VERSION_BS]; /* 0x2e */ + unsigned char major_subsys_ver [PE_MAJOR_SUBSYSTEM_VERSION_BS]; /* 0x30 */ + unsigned char minor_subsys_ver [PE_MINOR_SUBSYSTEM_VERSION_BS]; /* 0x32 */ + unsigned char win32_ver [PE_WIN32_VERSION_VALUE_BS]; /* 0x34 */ + unsigned char size_of_image [PE_SIZE_OF_IMAGE_BS]; /* 0x38 */ + unsigned char size_of_headers [PE_SIZE_OF_HEADERS_BS]; /* 0x3c */ + unsigned char checksum [PE_CHECK_SUM_BS]; /* 0x40 */ + unsigned char subsystem [PE_SUBSYSTEM_BS]; /* 0x44 */ + unsigned char dll_characteristics [PE_DLL_CHARACTERISTICS_BS]; /* 0x46 */ + unsigned char size_of_stack_reserve [PE_SIZE_OF_STACK_RESERVE_BS]; /* 0x48 */ + unsigned char size_of_stack_commit [PE_SIZE_OF_STACK_COMMIT_BS]; /* 0x4c */ + unsigned char size_of_heap_reserve [PE_SIZE_OF_HEAP_RESERVE_BS]; /* 0x50 */ + unsigned char size_of_heap_commit [PE_SIZE_OF_HEAP_COMMIT_BS]; /* 0x54 */ + unsigned char loader_flags [PE_LOADER_FLAGS_BS]; /* 0x58 */ + unsigned char rva_and_sizes [PE_NUMBER_OF_RVA_AND_SIZES_BS]; /* 0x5c */ + unsigned char export_tbl [PE_EXPORT_TABLE_BS]; /* 0x60 */ + unsigned char import_tbl [PE_IMPORT_TABLE_BS]; /* 0x68 */ + unsigned char resource_tbl [PE_RESOURCE_TABLE_BS]; /* 0x70 */ + unsigned char exception_tbl [PE_EXCEPTION_TABLE_BS]; /* 0x78 */ + unsigned char certificate_tbl [PE_CERTIFICATE_TABLE_BS]; /* 0x80 */ + unsigned char base_reloc_tbl [PE_BASE_RELOCATION_TABLE_BS]; /* 0x88 */ + unsigned char debug [PE_DEBUG_BS]; /* 0x90 */ + unsigned char arch [PE_ARCHITECTURE_BS]; /* 0x98 */ + unsigned char global_ptr [PE_GLOBAL_PTR_BS]; /* 0xa0 */ + unsigned char tls_tbl [PE_TLS_TABLE_BS]; /* 0xa8 */ + unsigned char load_config_tbl [PE_LOAD_CONFIG_TABLE_BS]; /* 0xb0 */ + unsigned char bound_import [PE_BOUND_IMPORT_BS]; /* 0xb8 */ + unsigned char iat [PE_IAT_BS]; /* 0xc0 */ + unsigned char delay_import_descriptor [PE_DELAY_IMPORT_DESCRIPTOR_BS]; /* 0xc8 */ + unsigned char clr_runtime_hdr [PE_CLR_RUNTIME_HEADER_BS]; /* 0xd0 */ + unsigned char reserved [PE_RESERVED__MUST_BE_ZERO_BS]; /* 0xd8 */ +}; + +#undef PE_MAGIC_BS +#undef PE_MAJOR_LINKER_VERSION_BS +#undef PE_MINOR_LINKER_VERSION_BS +#undef PE_SIZE_OF_CODE_BS +#undef PE_SIZE_OF_INITIALIZED_DATA_BS +#undef PE_SIZE_OF_UNINITIALIZED_DATA_BS +#undef PE_ADDRESS_OF_ENTRY_POINT_BS +#undef PE_BASE_OF_CODE_BS +#undef PE_BASE_OF_DATA_BS +#undef PE_IMAGE_BASE_BS +#undef PE_SECTION_ALIGNMENT_BS +#undef PE_FILE_ALIGNMENT_BS +#undef PE_MAJOR_OPERATING_SYSTEM_VERSION_BS +#undef PE_MINOR_OPERATING_SYSTEM_VERSION_BS +#undef PE_MAJOR_IMAGE_VERSION_BS +#undef PE_MINOR_IMAGE_VERSION_BS +#undef PE_MAJOR_SUBSYSTEM_VERSION_BS +#undef PE_MINOR_SUBSYSTEM_VERSION_BS +#undef PE_WIN32_VERSION_VALUE_BS +#undef PE_SIZE_OF_IMAGE_BS +#undef PE_SIZE_OF_HEADERS_BS +#undef PE_CHECK_SUM_BS +#undef PE_SUBSYSTEM_BS +#undef PE_DLL_CHARACTERISTICS_BS +#undef PE_SIZE_OF_STACK_RESERVE_BS +#undef PE_SIZE_OF_STACK_COMMIT_BS +#undef PE_SIZE_OF_HEAP_RESERVE_BS +#undef PE_SIZE_OF_HEAP_COMMIT_BS +#undef PE_LOADER_FLAGS_BS +#undef PE_NUMBER_OF_RVA_AND_SIZES_BS +#undef PE_EXPORT_TABLE_BS +#undef PE_IMPORT_TABLE_BS +#undef PE_RESOURCE_TABLE_BS +#undef PE_EXCEPTION_TABLE_BS +#undef PE_CERTIFICATE_TABLE_BS +#undef PE_BASE_RELOCATION_TABLE_BS +#undef PE_DEBUG_BS +#undef PE_ARCHITECTURE_BS +#undef PE_GLOBAL_PTR_BS +#undef PE_TLS_TABLE_BS +#undef PE_LOAD_CONFIG_TABLE_BS +#undef PE_BOUND_IMPORT_BS +#undef PE_IAT_BS +#undef PE_DELAY_IMPORT_DESCRIPTOR_BS +#undef PE_CLR_RUNTIME_HEADER_BS +#undef PE_RESERVED__MUST_BE_ZERO_BS + + +/* pe64_optional_header... */ +#define PE_MAGIC_BS 0x02 +#define PE_MAJOR_LINKER_VERSION_BS 0x01 +#define PE_MINOR_LINKER_VERSION_BS 0x01 +#define PE_SIZE_OF_CODE_BS 0x04 +#define PE_SIZE_OF_INITIALIZED_DATA_BS 0x04 +#define PE_SIZE_OF_UNINITIALIZED_DATA_BS 0x04 +#define PE_ADDRESS_OF_ENTRY_POINT_BS 0x04 +#define PE_BASE_OF_CODE_BS 0x04 +#define PE_IMAGE_BASE_BS 0x08 +#define PE_SECTION_ALIGNMENT_BS 0x04 +#define PE_FILE_ALIGNMENT_BS 0x04 +#define PE_MAJOR_OPERATING_SYSTEM_VERSION_BS 0x02 +#define PE_MINOR_OPERATING_SYSTEM_VERSION_BS 0x02 +#define PE_MAJOR_IMAGE_VERSION_BS 0x02 +#define PE_MINOR_IMAGE_VERSION_BS 0x02 +#define PE_MAJOR_SUBSYSTEM_VERSION_BS 0x02 +#define PE_MINOR_SUBSYSTEM_VERSION_BS 0x02 +#define PE_WIN32_VERSION_VALUE_BS 0x04 +#define PE_SIZE_OF_IMAGE_BS 0x04 +#define PE_SIZE_OF_HEADERS_BS 0x04 +#define PE_CHECK_SUM_BS 0x04 +#define PE_SUBSYSTEM_BS 0x02 +#define PE_DLL_CHARACTERISTICS_BS 0x02 +#define PE_SIZE_OF_STACK_RESERVE_BS 0x08 +#define PE_SIZE_OF_STACK_COMMIT_BS 0x08 +#define PE_SIZE_OF_HEAP_RESERVE_BS 0x08 +#define PE_SIZE_OF_HEAP_COMMIT_BS 0x08 +#define PE_LOADER_FLAGS_BS 0x04 +#define PE_NUMBER_OF_RVA_AND_SIZES_BS 0x04 +#define PE_EXPORT_TABLE_BS 0x08 +#define PE_IMPORT_TABLE_BS 0x08 +#define PE_RESOURCE_TABLE_BS 0x08 +#define PE_EXCEPTION_TABLE_BS 0x08 +#define PE_CERTIFICATE_TABLE_BS 0x08 +#define PE_BASE_RELOCATION_TABLE_BS 0x08 +#define PE_DEBUG_BS 0x08 +#define PE_ARCHITECTURE_BS 0x08 +#define PE_GLOBAL_PTR_BS 0x08 +#define PE_TLS_TABLE_BS 0x08 +#define PE_LOAD_CONFIG_TABLE_BS 0x08 +#define PE_BOUND_IMPORT_BS 0x08 +#define PE_IAT_BS 0x08 +#define PE_DELAY_IMPORT_DESCRIPTOR_BS 0x08 +#define PE_CLR_RUNTIME_HEADER_BS 0x08 +#define PE_RESERVED__MUST_BE_ZERO_BS 0x08 + +struct pe_opt_hdr_64 { + unsigned char magic [PE_MAGIC_BS]; /* 0x00 */ + unsigned char major_linker_ver [PE_MAJOR_LINKER_VERSION_BS]; /* 0x02 */ + unsigned char minor_linker_ver [PE_MINOR_LINKER_VERSION_BS]; /* 0x03 */ + unsigned char size_of_code [PE_SIZE_OF_CODE_BS]; /* 0x04 */ + unsigned char size_of_initialized_data [PE_SIZE_OF_INITIALIZED_DATA_BS]; /* 0x08 */ + unsigned char size_of_uninitialized_data [PE_SIZE_OF_UNINITIALIZED_DATA_BS]; /* 0x0c */ + unsigned char entry_point [PE_ADDRESS_OF_ENTRY_POINT_BS]; /* 0x10 */ + unsigned char base_of_code [PE_BASE_OF_CODE_BS]; /* 0x14 */ + unsigned char image_base [PE_IMAGE_BASE_BS]; /* 0x18 */ + unsigned char section_align [PE_SECTION_ALIGNMENT_BS]; /* 0x20 */ + unsigned char file_align [PE_FILE_ALIGNMENT_BS]; /* 0x24 */ + unsigned char major_os_ver [PE_MAJOR_OPERATING_SYSTEM_VERSION_BS]; /* 0x28 */ + unsigned char minor_or_ver [PE_MINOR_OPERATING_SYSTEM_VERSION_BS]; /* 0x2a */ + unsigned char major_image_ver [PE_MAJOR_IMAGE_VERSION_BS]; /* 0x2c */ + unsigned char minor_image_ver [PE_MINOR_IMAGE_VERSION_BS]; /* 0x2e */ + unsigned char major_subsys_ver [PE_MAJOR_SUBSYSTEM_VERSION_BS]; /* 0x30 */ + unsigned char minor_subsys_ver [PE_MINOR_SUBSYSTEM_VERSION_BS]; /* 0x32 */ + unsigned char win32_ver [PE_WIN32_VERSION_VALUE_BS]; /* 0x34 */ + unsigned char size_of_image [PE_SIZE_OF_IMAGE_BS]; /* 0x38 */ + unsigned char size_of_headers [PE_SIZE_OF_HEADERS_BS]; /* 0x3c */ + unsigned char checksum [PE_CHECK_SUM_BS]; /* 0x40 */ + unsigned char subsystem [PE_SUBSYSTEM_BS]; /* 0x44 */ + unsigned char dll_characteristics [PE_DLL_CHARACTERISTICS_BS]; /* 0x46 */ + unsigned char size_of_stack_reserve [PE_SIZE_OF_STACK_RESERVE_BS]; /* 0x48 */ + unsigned char size_of_stack_commit [PE_SIZE_OF_STACK_COMMIT_BS]; /* 0x50 */ + unsigned char size_of_heap_reserve [PE_SIZE_OF_HEAP_RESERVE_BS]; /* 0x58 */ + unsigned char size_of_heap_commit [PE_SIZE_OF_HEAP_COMMIT_BS]; /* 0x60 */ + unsigned char loader_flags [PE_LOADER_FLAGS_BS]; /* 0x68 */ + unsigned char rva_and_sizes [PE_NUMBER_OF_RVA_AND_SIZES_BS]; /* 0x6c */ + unsigned char export_tbl [PE_EXPORT_TABLE_BS]; /* 0x70 */ + unsigned char import_tbl [PE_IMPORT_TABLE_BS]; /* 0x78 */ + unsigned char resource_tbl [PE_RESOURCE_TABLE_BS]; /* 0x80 */ + unsigned char exception_tbl [PE_EXCEPTION_TABLE_BS]; /* 0x88 */ + unsigned char certificate_tbl [PE_CERTIFICATE_TABLE_BS]; /* 0x90 */ + unsigned char base_reloc_tbl [PE_BASE_RELOCATION_TABLE_BS]; /* 0x98 */ + unsigned char debug [PE_DEBUG_BS]; /* 0xa0 */ + unsigned char arch [PE_ARCHITECTURE_BS]; /* 0xa8 */ + unsigned char global_ptr [PE_GLOBAL_PTR_BS]; /* 0xb0 */ + unsigned char tls_tbl [PE_TLS_TABLE_BS]; /* 0xb8 */ + unsigned char load_config_tbl [PE_LOAD_CONFIG_TABLE_BS]; /* 0xc0 */ + unsigned char bound_import [PE_BOUND_IMPORT_BS]; /* 0xc8 */ + unsigned char iat [PE_IAT_BS]; /* 0xd0 */ + unsigned char delay_import_descriptor [PE_DELAY_IMPORT_DESCRIPTOR_BS]; /* 0xd8 */ + unsigned char clr_runtime_hdr [PE_CLR_RUNTIME_HEADER_BS]; /* 0xe0 */ + unsigned char reserved [PE_RESERVED__MUST_BE_ZERO_BS]; /* 0xe8 */ +}; + +#undef PE_MAGIC_BS +#undef PE_MAJOR_LINKER_VERSION_BS +#undef PE_MINOR_LINKER_VERSION_BS +#undef PE_SIZE_OF_CODE_BS +#undef PE_SIZE_OF_INITIALIZED_DATA_BS +#undef PE_SIZE_OF_UNINITIALIZED_DATA_BS +#undef PE_ADDRESS_OF_ENTRY_POINT_BS +#undef PE_BASE_OF_CODE_BS +#undef PE_IMAGE_BASE_BS +#undef PE_SECTION_ALIGNMENT_BS +#undef PE_FILE_ALIGNMENT_BS +#undef PE_MAJOR_OPERATING_SYSTEM_VERSION_BS +#undef PE_MINOR_OPERATING_SYSTEM_VERSION_BS +#undef PE_MAJOR_IMAGE_VERSION_BS +#undef PE_MINOR_IMAGE_VERSION_BS +#undef PE_MAJOR_SUBSYSTEM_VERSION_BS +#undef PE_MINOR_SUBSYSTEM_VERSION_BS +#undef PE_WIN32_VERSION_VALUE_BS +#undef PE_SIZE_OF_IMAGE_BS +#undef PE_SIZE_OF_HEADERS_BS +#undef PE_CHECK_SUM_BS +#undef PE_SUBSYSTEM_BS +#undef PE_DLL_CHARACTERISTICS_BS +#undef PE_SIZE_OF_STACK_RESERVE_BS +#undef PE_SIZE_OF_STACK_COMMIT_BS +#undef PE_SIZE_OF_HEAP_RESERVE_BS +#undef PE_SIZE_OF_HEAP_COMMIT_BS +#undef PE_LOADER_FLAGS_BS +#undef PE_NUMBER_OF_RVA_AND_SIZES_BS +#undef PE_EXPORT_TABLE_BS +#undef PE_IMPORT_TABLE_BS +#undef PE_RESOURCE_TABLE_BS +#undef PE_EXCEPTION_TABLE_BS +#undef PE_CERTIFICATE_TABLE_BS +#undef PE_BASE_RELOCATION_TABLE_BS +#undef PE_DEBUG_BS +#undef PE_ARCHITECTURE_BS +#undef PE_GLOBAL_PTR_BS +#undef PE_TLS_TABLE_BS +#undef PE_LOAD_CONFIG_TABLE_BS +#undef PE_BOUND_IMPORT_BS +#undef PE_IAT_BS +#undef PE_DELAY_IMPORT_DESCRIPTOR_BS +#undef PE_CLR_RUNTIME_HEADER_BS +#undef PE_RESERVED__MUST_BE_ZERO_BS + +union pe_opt_hdr { + struct pe_opt_hdr_32 opt_hdr_32; + struct pe_opt_hdr_64 opt_hdr_64; +}; + + +/* pe_image_data_directory... */ +#define PE_VIRTUAL_ADDRESS_BS 0x04 +#define PE_SIZE_BS 0x04 + +struct pe_image_data_dir { + unsigned char rva [PE_VIRTUAL_ADDRESS_BS]; /* 0x00 */ + unsigned char size [PE_SIZE_BS]; /* 0x04 */ +}; + +#undef PE_VIRTUAL_ADDRESS_BS +#undef PE_SIZE_BS + + +/* pe_section_table... */ +#define PE_NAME_BS 0x08 +#define PE_VIRTUAL_SIZE_BS 0x04 +#define PE_VIRTUAL_ADDRESS_BS 0x04 +#define PE_SIZE_OF_RAW_DATA_BS 0x04 +#define PE_POINTER_TO_RAW_DATA_BS 0x04 +#define PE_POINTER_TO_RELOCATIONS_BS 0x04 +#define PE_POINTER_TO_LINENUMBERS_BS 0x04 +#define PE_NUMBER_OF_RELOCATIONS_BS 0x02 +#define PE_NUMBER_OF_LINENUMBERS_BS 0x02 +#define PE_CHARACTERISTICS_BS 0x04 + +struct pe_sec_hdr { + unsigned char name [PE_NAME_BS]; /* 0x00 */ + unsigned char virtual_size [PE_VIRTUAL_SIZE_BS]; /* 0x08 */ + unsigned char virtual_addr [PE_VIRTUAL_ADDRESS_BS]; /* 0x0c */ + unsigned char size_of_raw_data [PE_SIZE_OF_RAW_DATA_BS]; /* 0x10 */ + unsigned char ptr_to_raw_data [PE_POINTER_TO_RAW_DATA_BS]; /* 0x14 */ + unsigned char ptr_to_relocs [PE_POINTER_TO_RELOCATIONS_BS]; /* 0x18 */ + unsigned char ptr_to_line_nums [PE_POINTER_TO_LINENUMBERS_BS]; /* 0x1c */ + unsigned char num_of_relocs [PE_NUMBER_OF_RELOCATIONS_BS]; /* 0x20 */ + unsigned char num_of_line_nums [PE_NUMBER_OF_LINENUMBERS_BS]; /* 0x22 */ + unsigned char characteristics [PE_CHARACTERISTICS_BS]; /* 0x24 */ +}; + +#undef PE_NAME_BS +#undef PE_VIRTUAL_SIZE_BS +#undef PE_VIRTUAL_ADDRESS_BS +#undef PE_SIZE_OF_RAW_DATA_BS +#undef PE_POINTER_TO_RAW_DATA_BS +#undef PE_POINTER_TO_RELOCATIONS_BS +#undef PE_POINTER_TO_LINENUMBERS_BS +#undef PE_NUMBER_OF_RELOCATIONS_BS +#undef PE_NUMBER_OF_LINENUMBERS_BS +#undef PE_CHARACTERISTICS_BS + + +/* pe_export_directory_table... */ +#define PE_EXPORT_FLAGS_BS 0x04 +#define PE_TIME_DATE_STAMP_BS 0x04 +#define PE_MAJOR_VERSION_BS 0x02 +#define PE_MINOR_VERSION_BS 0x02 +#define PE_NAME_RVA_BS 0x04 +#define PE_ORDINAL_BASE_BS 0x04 +#define PE_ADDRESS_TABLE_ENTRIES_BS 0x04 +#define PE_NUMBER_OF_NAME_POINTERS_BS 0x04 +#define PE_EXPORT_ADDRESS_TABLE_RVA_BS 0x04 +#define PE_NAME_POINTER_RVA_BS 0x04 +#define PE_ORDINAL_TABLE_RVA_BS 0x04 + +struct pe_export_hdr { + unsigned char export_flags [PE_EXPORT_FLAGS_BS]; /* 0x00 */ + unsigned char time_date_stamp [PE_TIME_DATE_STAMP_BS]; /* 0x04 */ + unsigned char major_ver [PE_MAJOR_VERSION_BS]; /* 0x08 */ + unsigned char minor_ver [PE_MINOR_VERSION_BS]; /* 0x0a */ + unsigned char name_rva [PE_NAME_RVA_BS]; /* 0x0c */ + unsigned char ordinal_base [PE_ORDINAL_BASE_BS]; /* 0x10 */ + unsigned char addr_tbl_entries [PE_ADDRESS_TABLE_ENTRIES_BS]; /* 0x14 */ + unsigned char num_of_name_ptrs [PE_NUMBER_OF_NAME_POINTERS_BS]; /* 0x18 */ + unsigned char export_addr_tbl_rva [PE_EXPORT_ADDRESS_TABLE_RVA_BS]; /* 0x1c */ + unsigned char name_ptr_rva [PE_NAME_POINTER_RVA_BS]; /* 0x20 */ + unsigned char ordinal_tbl_rva [PE_ORDINAL_TABLE_RVA_BS]; /* 0x24 */ +}; + +#undef PE_EXPORT_FLAGS_BS +#undef PE_TIME_DATE_STAMP_BS +#undef PE_MAJOR_VERSION_BS +#undef PE_MINOR_VERSION_BS +#undef PE_NAME_RVA_BS +#undef PE_ORDINAL_BASE_BS +#undef PE_ADDRESS_TABLE_ENTRIES_BS +#undef PE_NUMBER_OF_NAME_POINTERS_BS +#undef PE_EXPORT_ADDRESS_TABLE_RVA_BS +#undef PE_NAME_POINTER_RVA_BS +#undef PE_ORDINAL_TABLE_RVA_BS + + +/* pe_export_address_table... */ +#define PE_EXPORT_RVA_BS 0x04 +#define PE_FORWARDER_RVA_BS 0x04 + +union pe_export_addr_tbl { + unsigned char export_rva [PE_EXPORT_RVA_BS]; /* 0x00 */ + unsigned char forwarder_rva [PE_FORWARDER_RVA_BS]; /* 0x00 */ +}; + +#undef PE_EXPORT_RVA_BS +#undef PE_FORWARDER_RVA_BS + + +/* image: pe_import_table_entry_lookup_item... */ +#define PE_IMPORT_LOOKUP_ENTRY_PE64_BS 0x08 +#define PE_IMPORT_LOOKUP_ENTRY_PE32_BS 0x04 +#define PE_HINT_NAME_TABLE_RVA_BS 0x04 +#define PE_ORDINAL_NUMBER_BS 0x02 + +struct pe_import_lookup_item { + union { + unsigned char import_lookup_entry_64 [PE_IMPORT_LOOKUP_ENTRY_PE64_BS]; /* 0x00 */ + unsigned char import_lookup_entry_32 [PE_IMPORT_LOOKUP_ENTRY_PE32_BS]; /* 0x00 */ + unsigned char hint_name_tbl_rva [PE_HINT_NAME_TABLE_RVA_BS]; /* 0x00 */ + unsigned char ordinal_number [PE_ORDINAL_NUMBER_BS]; /* 0x00 */ + } u; +}; + +#undef PE_IMPORT_LOOKUP_ENTRY_PE64_BS +#undef PE_IMPORT_LOOKUP_ENTRY_PE32_BS +#undef PE_HINT_NAME_TABLE_RVA_BS +#undef PE_ORDINAL_NUMBER_BS + + +/* image: pe_import_directory_table_entry... */ +#define PE_IMPORT_LOOKUP_TABLE_RVA_BS 0x04 +#define PE_TIME_DATE_STAMP_BS 0x04 +#define PE_FORWARDER_CHAIN_BS 0x04 +#define PE_NAME_RVA_BS 0x04 +#define PE_IMPORT_ADDRESS_TABLE_RVA_BS 0x04 + +struct pe_import_hdr { + unsigned char import_lookup_tbl_rva [PE_IMPORT_LOOKUP_TABLE_RVA_BS]; /* 0x00 */ + unsigned char time_date_stamp [PE_TIME_DATE_STAMP_BS]; /* 0x04 */ + unsigned char forwarder_chain [PE_FORWARDER_CHAIN_BS]; /* 0x08 */ + unsigned char name_rva [PE_NAME_RVA_BS]; /* 0x0c */ + unsigned char import_addr_tbl_rva [PE_IMPORT_ADDRESS_TABLE_RVA_BS]; /* 0x10 */ +}; + +#undef PE_IMPORT_LOOKUP_TABLE_RVA_BS +#undef PE_TIME_DATE_STAMP_BS +#undef PE_FORWARDER_CHAIN_BS +#undef PE_NAME_RVA_BS +#undef PE_IMPORT_ADDRESS_TABLE_RVA_BS + + +/* pe_hint_name_table_padded... */ +#define PE_HINT_BS 0x02 +#define PE_NAME_BS 0x02 + +struct pe_hint_name_entry { + unsigned char hint [PE_HINT_BS]; /* 0x00 */ + unsigned char name [PE_NAME_BS]; /* 0x02 */ +}; + +#undef PE_HINT_BS +#undef PE_NAME_BS + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/pemagine/pemagine.h b/include/pemagine/pemagine.h new file mode 100644 index 0000000..8beb5e4 --- /dev/null +++ b/include/pemagine/pemagine.h @@ -0,0 +1,196 @@ +#ifndef PEMAGINE_H +#define PEMAGINE_H + +#include "pe_api.h" +#include "pe_consts.h" +#include "pe_structs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum pe_callback_reason { + PE_CALLBACK_REASON_INIT = 0x00, + PE_CALLBACK_REASON_ITEM = 0x01, + PE_CALLBACK_REASON_INFO = 0x02, + PE_CALLBACK_REASON_QUERY = 0x04, + PE_CALLBACK_REASON_DONE = 0x1000, + PE_CALLBACK_REASON_ERROR = (-1) +}; + + +/* library specific structures */ +struct pe_export_sym { + uint32_t * ordinal_base; + uint16_t * ordinal; + void * addr; + void * forwarder_rva; + char * name; + long status; +}; + + +struct pe_unicode_str { + uint16_t strlen; + uint16_t maxlen; + uint16_t * buffer; +}; + + +struct pe_list_entry { + struct pe_list_entry * flink; + struct pe_list_entry * blink; +}; + + +struct pe_client_id { + uint32_t process_id; + uint32_t thread_id; +}; + + +struct pe_stack_heap_info { + size_t size_of_stack_reserve; + size_t size_of_stack_commit; + size_t size_of_heap_reserve; + size_t size_of_heap_commit; +}; + + +struct pe_peb_ldr_data { + uint32_t length; + uint32_t initialized; + void * ss_handle; + struct pe_list_entry in_load_order_module_list; + struct pe_list_entry in_memory_order_module_list; + struct pe_list_entry in_init_order_module_list; +}; + + +struct pe_ldr_tbl_entry { + struct pe_list_entry in_load_order_links; + struct pe_list_entry in_memory_order_links; + struct pe_list_entry in_init_order_links; + void * dll_base; + void * entry_point; + + union { + uint32_t size_of_image; + unsigned char size_of_image_padding[sizeof(uintptr_t)]; + }; + + struct pe_unicode_str full_dll_name; + struct pe_unicode_str base_dll_name; + uint32_t flags; + uint16_t load_count; + uint16_t tls_index; + + union { + struct pe_list_entry hash_links; + struct { + void * section_pointer; + uint32_t check_sum; + }; + }; + + union { + void * loaded_imports; + uint32_t time_date_stamp; + }; + + void * entry_point_activation_context; + void * patch_information; + struct pe_list_entry forwarder_links; + struct pe_list_entry service_tag_links; + struct pe_list_entry static_links; + void * context_information; + uintptr_t original_base; + int64_t load_time; +}; + + + +/* static inlined functions */ +static __inline__ void * pe_get_teb_address(void); +static __inline__ void * pe_get_peb_address(void); +static __inline__ void * pe_get_peb_address_alt(void); +static __inline__ void * pe_get_peb_ldr_data_address(void); +static __inline__ void * pe_get_peb_ldr_data_address_alt(void); +static __inline__ uint32_t pe_get_current_process_id(void); +static __inline__ uint32_t pe_get_current_thread_id(void); +static __inline__ uint32_t pe_get_current_session_id(void); +static __inline__ void * pe_va_from_rva(const void * base, intptr_t offset); + +#include "pe_inline_asm.h" + + +/** + * user callback function responses + * + * positive: continue enumeration. + * zero: exit enumeration (ok). + * negative: exit enumeration (error). +**/ + +/* callback signatures */ +typedef int pe_enum_modules_callback( + struct pe_ldr_tbl_entry * image_ldr_tbl_entry, + enum pe_callback_reason reason, + void * context); + +typedef int pe_enum_image_exports_callback( + const void * base, + struct pe_export_hdr * exp_hdr, + struct pe_export_sym * sym, + enum pe_callback_reason reason, + void * context); + +typedef int pe_enum_image_import_hdrs_callback( + const void * base, + struct pe_import_hdr * imp_hdr, + enum pe_callback_reason reason, + void * context); + +/* library functions */ +pe_api struct pe_image_dos_hdr *pe_get_image_dos_hdr_addr (const void * base); +pe_api struct pe_coff_file_hdr *pe_get_image_coff_hdr_addr (const void * base); +pe_api union pe_opt_hdr * pe_get_image_opt_hdr_addr (const void * base); +pe_api struct pe_data_dirs * pe_get_image_data_dirs_addr (const void * base); +pe_api struct pe_export_hdr * pe_get_image_export_hdr_addr (const void * base, uint32_t * sec_size); +pe_api struct pe_import_hdr * pe_get_image_import_dir_addr (const void * base, uint32_t * sec_size); +pe_api void * pe_get_image_special_hdr_addr (const void * base, uint32_t ordinal, uint32_t * sec_size); +pe_api void * pe_get_image_entry_point_addr (const void * base); +pe_api int pe_get_image_stack_heap_info (const void * base, struct pe_stack_heap_info *); + +pe_api void * pe_get_procedure_address (const void * base, const char * name); +pe_api int pe_get_export_symbol_info (const void * base, const char * name, struct pe_export_sym *); +pe_api int pe_enum_image_exports (const void * base, + pe_enum_image_exports_callback *, + struct pe_export_sym *, + void * ctx); + +pe_api int pe_enum_image_import_hdrs (const void * base, + pe_enum_image_import_hdrs_callback *, + void * ctx); + +pe_api char * pe_get_symbol_name (const void * base, const void * sym_addr); +pe_api struct pe_ldr_tbl_entry *pe_get_symbol_module_info (const void * sym_addr); +pe_api char * pe_get_import_symbol_info (const void * sym_addr, + void ** sym_image_addr, + char ** sym_name, + struct pe_ldr_tbl_entry ** ldr_tbl_entry); + +pe_api int pe_enum_modules_in_load_order (pe_enum_modules_callback *, void * ctx); +pe_api int pe_enum_modules_in_memory_order (pe_enum_modules_callback *, void * ctx); +pe_api int pe_enum_modules_in_init_order (pe_enum_modules_callback *, void * ctx); +pe_api void * pe_get_module_handle (const wchar16_t * name); +pe_api void * pe_get_first_module_handle (void); +pe_api void * pe_get_ntdll_module_handle (void); +pe_api void * pe_get_kernel32_module_handle (void); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pemagine.lzy b/pemagine.lzy new file mode 100644 index 0000000..ed1df9c --- /dev/null +++ b/pemagine.lzy @@ -0,0 +1,128 @@ +lz_project_rules() +{ + lz_rules="all install xstatic install_xstatic" +} + +lz_project_definitions() +{ + pemagine_lib_name=libpemagine + pemagine_so_name="$lz_build_dir/lib/$pemagine_lib_name$lz_dylib_ext" + pemagine_a_name="$lz_build_dir/lib/$pemagine_lib_name$lz_stlib_ext" + pemagine_so_def_name="$lz_build_dir/lib/$pemagine_lib_name$lz_libdef_ext" + pemagine_implib_name="$lz_build_dir/lib/$pemagine_lib_name$lz_implib_ext" + + lz_cflags_common="-DMIDIPIX_FREESTANDING + -D__NT$lz_arch_bits \ + -UWIN32 -U_WIN32 -U__WIN32 -U__WIN32__ \ + -UWIN64 -U_WIN64 -U__WIN64 -U__WIN64__ \ + -Werror=all -fno-builtin -ffreestanding" + + + # lz_cflags_extra="-Os -fno-stack-protector -fomit-frame-pointer -fno-unwind-tables -fno-asynchronous-unwind-tables" + + pemagine_so_ldflags="-shared --image-base=0x560000 \ + --entry "$lz_default_underscore"pe_lib_entry_point@12 \ + --exclude-all-symbols \ + --output-def $pemagine_so_def_name \ + --out-implib $pemagine_implib_name \ + --subsystem=windows" + + lz_cflags_include_common="-I$lz_project_dir/src/internal -I$lz_project_dir/include" + + if [ "$MIDIPIX_ROOT"x != x ]; then + lz_cflags_include_common="$lz_cflags_include_common -I$MIDIPIX_ROOT/include" + fi + + pemagine_so_obj_list=pemagine.so.objs + pemagine_so_src_list=pemagine.so.src.lst + + pemagine_a_obj_list=pemagine.a.objs + pemagine_a_src_list=pemagine.a.src.lst +} + +pemagine_shared() +{ + lz_src_dirs="src" + lz_cflags_step="-DPE_BUILD" + + if ! [ "$lz_pecoff_winnt"x = yesx ]; then + lz_cflags_step="$lz_cflags_step -fpic" + fi + + lz_compile "$pemagine_so_obj_list" "$pemagine_so_src_list" "$lz_dyobj_ext" + lz_link "$pemagine_so_obj_list" "$pemagine_so_src_list" "$pemagine_so_name" \ + "$pemagine_so_ldflags" \ + '' +} + + +pemagine_static() +{ + lz_src_dirs="src" + + lz_compile "$pemagine_a_obj_list" "$pemagine_a_src_list" "$lz_stobj_ext" + lz_archive "$pemagine_a_obj_list" "$pemagine_a_src_list" "$pemagine_a_name" +} + + +pemagine_xstatic() +{ + lz_src_dirs="src" + lz_cflags_step="-DPE_BUILD" + + lz_compile "$pemagine_a_obj_list" "$pemagine_a_src_list" "$lz_stobj_ext" + lz_archive "$pemagine_a_obj_list" "$pemagine_a_src_list" "$pemagine_a_name" +} + + +pemagine_install_headers() +{ + lz_pushd $lz_project_dir + + cp -r -t $lz_prefix/include include/$lz_project_name + + lz_popd +} + + +pemagine_install_shared() +{ + lz_pushd $lz_build_dir/lib + + cp -t $lz_prefix/lib $pemagine_lib_name$lz_dylib_ext + cp -t $lz_prefix/lib $pemagine_lib_name$lz_implib_ext + + lz_popd +} + + +pemagine_install_static() +{ + lz_pushd $lz_build_dir/lib + + cp -t $lz_prefix/lib $pemagine_lib_name$lz_stlib_ext + + lz_popd +} + + +pemagine_install_xstatic() +{ + lz_step pemagine_xstatic + lz_step pemagine_install_static +} + +pemagine_all() +{ + lz_step pemagine_shared + lz_step pemagine_static +} + + +pemagine_install() +{ + lz_step pemagine_all + lz_step pemagine_install_shared + lz_step pemagine_install_static + lz_step pemagine_install_headers +} diff --git a/src/exports/pe_enum_image_exports.c b/src/exports/pe_enum_image_exports.c new file mode 100644 index 0000000..85e92cf --- /dev/null +++ b/src/exports/pe_enum_image_exports.c @@ -0,0 +1,61 @@ +/*****************************************************************************/ +/* pemagination: a (virtual) tour into portable bits and executable bytes */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */ +/*****************************************************************************/ + +#include +#include +#include +#include + +pe_api +int pe_enum_image_exports( + const void * base, + pe_enum_image_exports_callback * callback, + struct pe_export_sym * sym, + void * ctx) +{ + struct pe_export_hdr * exp_hdr; + uint32_t * count; + uint32_t * fn_addr; + uint32_t * fn_names; + uint16_t * fn_ordinals; + uint32_t * offset; + uint32_t idx; + int ret; + + if (!(exp_hdr = pe_get_image_export_hdr_addr(base,0))) { + callback(base,0,0,PE_CALLBACK_REASON_ERROR,ctx); + return -1; + } + + offset = (uint32_t *)(exp_hdr->export_addr_tbl_rva); + fn_addr = (uint32_t *)pe_va_from_rva(base,*offset); + + offset = (uint32_t *)(exp_hdr->name_ptr_rva); + fn_names = (uint32_t *)pe_va_from_rva(base,*offset); + + offset = (uint32_t *)(exp_hdr->ordinal_tbl_rva); + fn_ordinals = (uint16_t *)pe_va_from_rva(base,*offset); + + if ((ret = callback(base,exp_hdr,0,PE_CALLBACK_REASON_INIT,ctx)) <= 0) + return ret; + + count = (uint32_t *)exp_hdr->num_of_name_ptrs; + sym->ordinal_base = (uint32_t *)exp_hdr->ordinal_base; + + for (idx=0; idx<*count; idx++) { + offset = (uint32_t *)pe_va_from_rva(fn_names,idx*sizeof(uint32_t)); + sym->name = (char *)pe_va_from_rva(base,*offset); + sym->ordinal = (uint16_t *)pe_va_from_rva(fn_ordinals,idx*sizeof(uint16_t)); + + offset = (uint32_t *)pe_va_from_rva(fn_addr,(*sym->ordinal)*sizeof(uint32_t)); + sym->addr = pe_va_from_rva(base,*offset); + + if ((ret = callback(base,exp_hdr,sym,PE_CALLBACK_REASON_ITEM,ctx)) <= 0) + return ret; + } + + return callback(base,exp_hdr,sym,PE_CALLBACK_REASON_DONE,ctx); +} diff --git a/src/exports/pe_get_export_symbol_info.c b/src/exports/pe_get_export_symbol_info.c new file mode 100644 index 0000000..9f00634 --- /dev/null +++ b/src/exports/pe_get_export_symbol_info.c @@ -0,0 +1,142 @@ +/*****************************************************************************/ +/* pemagination: a (virtual) tour into portable bits and executable bytes */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */ +/*****************************************************************************/ + +#include +#include +#include +#include +#include "pe_impl.h" + +static __inline__ int pe_addr_within_bounds(void * addr, void * bottom, void * top) +{ + return (((uintptr_t)addr >= (uintptr_t)bottom) && ((uintptr_t)addr < (uintptr_t)top)); +} + +pe_api +int pe_get_export_symbol_info( + const void * base, + const char * name, + struct pe_export_sym * sym) +{ + struct pe_export_hdr * exp_hdr; + + size_t len; + uint32_t * rva_offset; + uintptr_t * addr_offset; + + uint32_t sec_size; + void * sec_addr_cap; + + uint32_t * fn_addr; + uint32_t * fn_names; + uint16_t * fn_ordinals; + uint32_t * addr_entries; + uint32_t * name_entries; + + char * exp_name; + const char * src; + const char * dst; + size_t match; + + uint32_t lower; + uint32_t upper; + uint32_t idx; + + /* initialize pe_exp_item */ + sym->ordinal_base = (uint32_t *)0; + sym->ordinal = (uint16_t *)0; + sym->addr = (void *)0; + sym->forwarder_rva = (void *)0; + sym->name = (char *)0; + sym->status = 0; + + if (!(exp_hdr = pe_get_image_export_hdr_addr(base,&sec_size))) + return -1; + + sec_addr_cap = pe_va_from_rva(exp_hdr,sec_size); + rva_offset = (uint32_t *)(exp_hdr->export_addr_tbl_rva); + fn_addr = (uint32_t *)pe_va_from_rva(base,*rva_offset); + + rva_offset = (uint32_t *)(exp_hdr->name_ptr_rva); + fn_names = (uint32_t *)pe_va_from_rva(base,*rva_offset); + + rva_offset = (uint32_t *)(exp_hdr->ordinal_tbl_rva); + fn_ordinals = (uint16_t *)pe_va_from_rva(base,*rva_offset); + + addr_entries = (uint32_t *)exp_hdr->addr_tbl_entries; + name_entries = (uint32_t *)exp_hdr->num_of_name_ptrs; + + /* by ordinal? */ + if ((intptr_t)name < 0x10000) { + sym->ordinal_base = (uint32_t *)exp_hdr->ordinal_base; + + /* the array is zero-based, but ordinals are normally one-based... */ + if (((intptr_t)name - *sym->ordinal_base + 1) > *addr_entries) + return -1; + + rva_offset = (uint32_t *)pe_va_from_rva(fn_addr,((uintptr_t)name-*sym->ordinal_base)*sizeof(uint32_t)); + addr_offset = (uintptr_t *)pe_va_from_rva(base,*rva_offset); + + if (pe_addr_within_bounds(addr_offset,exp_hdr,sec_addr_cap)) { + sym->forwarder_rva = 0; + sym->addr = addr_offset; + } else + /* todo: resolve forwarder address */ + sym->addr = addr_offset; + + return 0; + } + + if ((len = pe_impl_strlen_ansi(name)) < 0) + return -1; + + len++; + lower = 0; + upper = *name_entries; + + while (lower < upper) { + idx = (lower + upper) / 2; + rva_offset = (uint32_t *)pe_va_from_rva(fn_names,idx*sizeof(uint32_t)); + exp_name = (char *)pe_va_from_rva(base,*rva_offset); + + src = name; + dst = exp_name; + + for (match=0; (matchordinal_base = (uint32_t *)exp_hdr->ordinal_base; + sym->ordinal = (uint16_t *)pe_va_from_rva(fn_ordinals,idx*sizeof(uint16_t)); + + rva_offset = (uint32_t *)pe_va_from_rva(fn_addr,(*sym->ordinal)*sizeof(uint32_t)); + addr_offset = (uintptr_t *)pe_va_from_rva(base,*rva_offset); + + if (pe_addr_within_bounds(addr_offset,exp_hdr,sec_addr_cap)) { + /* todo: resolve forwarder address */ + sym->forwarder_rva = 0; + sym->addr = 0; + } else { + sym->forwarder_rva = 0; + sym->addr = addr_offset; + } + + return 0; + } + + else { + if (*src > *dst) + lower = idx + 1; + else + upper = idx; + } + } + + /* export name not found */ + return -1; +} diff --git a/src/exports/pe_get_procedure_address.c b/src/exports/pe_get_procedure_address.c new file mode 100644 index 0000000..958f205 --- /dev/null +++ b/src/exports/pe_get_procedure_address.c @@ -0,0 +1,18 @@ +/*****************************************************************************/ +/* pemagination: a (virtual) tour into portable bits and executable bytes */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */ +/*****************************************************************************/ + +#include + +pe_api +void * pe_get_procedure_address(const void * base, const char * name) +{ + struct pe_export_sym sym; + + return pe_get_export_symbol_info(base,name,&sym) + ? 0 + : sym.addr; + +} diff --git a/src/headers/pe_get_image_coff_hdr_addr.c b/src/headers/pe_get_image_coff_hdr_addr.c new file mode 100644 index 0000000..d2ff03a --- /dev/null +++ b/src/headers/pe_get_image_coff_hdr_addr.c @@ -0,0 +1,30 @@ +/*****************************************************************************/ +/* pemagination: a (virtual) tour into portable bits and executable bytes */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */ +/*****************************************************************************/ + +#include +#include +#include +#include + +pe_api +struct pe_coff_file_hdr * pe_get_image_coff_hdr_addr(const void * base) +{ + struct pe_image_dos_hdr * dos; + struct pe_coff_file_hdr * coff; + uint32_t * offset; + + if (!(dos = pe_get_image_dos_hdr_addr(base))) + return 0; + + offset = (uint32_t *)(dos->dos_lfanew); + coff = (struct pe_coff_file_hdr *)pe_va_from_rva(base,*offset); + + if ((coff->signature[0] == 'P') && (coff->signature[1] == 'E') + && (coff->signature[2] == '\0') && (coff->signature[3] == '\0')) + return coff; + else + return 0; +} diff --git a/src/headers/pe_get_image_data_dirs_addr.c b/src/headers/pe_get_image_data_dirs_addr.c new file mode 100644 index 0000000..d0167c0 --- /dev/null +++ b/src/headers/pe_get_image_data_dirs_addr.c @@ -0,0 +1,33 @@ +/*****************************************************************************/ +/* pemagination: a (virtual) tour into portable bits and executable bytes */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */ +/*****************************************************************************/ + +#include +#include +#include +#include + +pe_api +struct pe_data_dirs * pe_get_image_data_dirs_addr(const void * base) +{ + uint16_t * magic; + union pe_opt_hdr * hdr; + + if (!(hdr = pe_get_image_opt_hdr_addr(base))) + return 0; + + magic = (uint16_t *)hdr; + + switch (*magic) { + case PE_MAGIC_PE32: + return (struct pe_data_dirs *)hdr->opt_hdr_32.rva_and_sizes; + + case PE_MAGIC_PE32_PLUS: + return (struct pe_data_dirs *)hdr->opt_hdr_64.rva_and_sizes; + + default: + return 0; + } +} diff --git a/src/headers/pe_get_image_dos_hdr_addr.c b/src/headers/pe_get_image_dos_hdr_addr.c new file mode 100644 index 0000000..279d04e --- /dev/null +++ b/src/headers/pe_get_image_dos_hdr_addr.c @@ -0,0 +1,24 @@ +/*****************************************************************************/ +/* pemagination: a (virtual) tour into portable bits and executable bytes */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */ +/*****************************************************************************/ + +#include + +#include +#include +#include + +pe_api +struct pe_image_dos_hdr * pe_get_image_dos_hdr_addr(const void * base) +{ + struct pe_image_dos_hdr * dos; + + dos = (struct pe_image_dos_hdr *)base; + + if ((dos->dos_magic[0] == 'M') && (dos->dos_magic[1] == 'Z')) + return dos; + else + return 0; +} diff --git a/src/headers/pe_get_image_entry_point_addr.c b/src/headers/pe_get_image_entry_point_addr.c new file mode 100644 index 0000000..5869633 --- /dev/null +++ b/src/headers/pe_get_image_entry_point_addr.c @@ -0,0 +1,39 @@ +/*****************************************************************************/ +/* pemagination: a (virtual) tour into portable bits and executable bytes */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */ +/*****************************************************************************/ + +#include +#include +#include +#include + + +pe_api +void * pe_get_image_entry_point_addr(const void * base) +{ + uint16_t * magic; + union pe_opt_hdr * hdr; + uint32_t * rva; + + if (!(hdr = pe_get_image_opt_hdr_addr(base))) + return 0; + + magic = (uint16_t *)hdr; + + switch (*magic) { + case PE_MAGIC_PE32: + rva = (uint32_t *)hdr->opt_hdr_32.entry_point; + break; + + case PE_MAGIC_PE32_PLUS: + rva = (uint32_t *)hdr->opt_hdr_64.entry_point; + break; + + default: + return 0; + } + + return pe_va_from_rva(base,*rva); +} diff --git a/src/headers/pe_get_image_opt_hdr_addr.c b/src/headers/pe_get_image_opt_hdr_addr.c new file mode 100644 index 0000000..dcb8c48 --- /dev/null +++ b/src/headers/pe_get_image_opt_hdr_addr.c @@ -0,0 +1,20 @@ +/*****************************************************************************/ +/* pemagination: a (virtual) tour into portable bits and executable bytes */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */ +/*****************************************************************************/ + +#include +#include +#include + +pe_api +union pe_opt_hdr * pe_get_image_opt_hdr_addr(const void * base) +{ + struct pe_coff_file_hdr * coff; + + if (!(coff = pe_get_image_coff_hdr_addr(base))) + return 0; + else + return (union pe_opt_hdr *)pe_va_from_rva(coff, sizeof(*coff)); +} diff --git a/src/headers/pe_get_image_special_hdr_addr.c b/src/headers/pe_get_image_special_hdr_addr.c new file mode 100644 index 0000000..276ec9f --- /dev/null +++ b/src/headers/pe_get_image_special_hdr_addr.c @@ -0,0 +1,49 @@ +/*****************************************************************************/ +/* pemagination: a (virtual) tour into portable bits and executable bytes */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */ +/*****************************************************************************/ + +#include +#include +#include +#include +#include "pe_impl.h" + +pe_api +void * pe_get_image_special_hdr_addr(const void * base, uint32_t ordinal, uint32_t * sec_size) +{ + struct pe_data_dirs * dirs; + struct pe_block * dir; + uint32_t * count; + + if (!(dirs = pe_get_image_data_dirs_addr(base))) + return 0; + + count = (uint32_t *)dirs->rva_and_sizes; + + if (*count < (ordinal+1)) + return 0; + + dir = (struct pe_block *)dirs->export_tbl; + dir += ordinal; + + if (sec_size) + *sec_size = dir->size; + + return dir->rva + ? pe_va_from_rva(base,dir->rva) + : 0; +} + +pe_api +struct pe_export_hdr * pe_get_image_export_hdr_addr(const void * base, uint32_t * sec_size) +{ + return (struct pe_export_hdr *)pe_get_image_special_hdr_addr(base,PE_IMAGE_DATA_DIR_ORDINAL_EXPORT,sec_size); +} + +pe_api +struct pe_import_hdr * pe_get_image_import_dir_addr(const void * base, uint32_t * sec_size) +{ + return (struct pe_import_hdr *)pe_get_image_special_hdr_addr(base,PE_IMAGE_DATA_DIR_ORDINAL_IMPORT,sec_size); +} diff --git a/src/imports/pe_enum_image_import_hdrs.c b/src/imports/pe_enum_image_import_hdrs.c new file mode 100644 index 0000000..0a1a10e --- /dev/null +++ b/src/imports/pe_enum_image_import_hdrs.c @@ -0,0 +1,35 @@ +/*****************************************************************************/ +/* pemagination: a (virtual) tour into portable bits and executable bytes */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */ +/*****************************************************************************/ + +#include +#include +#include + +pe_api +int pe_enum_image_import_hdrs( + const void * base, + pe_enum_image_import_hdrs_callback * callback, + void * ctx) +{ + struct pe_import_hdr * imp_hdr; + int ret; + + if (!(imp_hdr = pe_get_image_import_dir_addr(base,0))) { + callback(base,0,PE_CALLBACK_REASON_ERROR,ctx); + return -1; + } + + if ((ret = callback(base,0,PE_CALLBACK_REASON_INIT,ctx)) <= 0) + return ret; + + while (imp_hdr->name_rva[0]) { + if ((ret = callback(base,imp_hdr,PE_CALLBACK_REASON_ITEM,ctx)) <= 0) + return ret; + imp_hdr++; + }; + + return callback(base,imp_hdr,PE_CALLBACK_REASON_DONE,ctx); +} diff --git a/src/internal/pe_impl.c b/src/internal/pe_impl.c new file mode 100644 index 0000000..46069e8 --- /dev/null +++ b/src/internal/pe_impl.c @@ -0,0 +1,51 @@ +/*****************************************************************************/ +/* pemagination: a (virtual) tour into portable bits and executable bytes */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */ +/*****************************************************************************/ + +#include +#include +#include "pe_impl.h" + +size_t pe_impl_strlen_ansi(const char * str) +{ + char * ch; + char * upper_bound; + + /* sanity check */ + upper_bound = (char *)str + PE_STR_MAX_SYMBOL_LEN_ALLOWED; + + for (ch = (char *)str; (ch < upper_bound) && (*ch); ch++); + + if (ch < upper_bound) + return (size_t)((intptr_t)ch - (intptr_t)str); + else + return -1; +} + + +size_t pe_impl_strlen_utf16(const wchar16_t * str) +{ + wchar16_t * wch; + wchar16_t * upper_bound; + + /* sanity check */ + upper_bound = (wchar16_t *)str + PE_STR_MAX_SYMBOL_LEN_ALLOWED; + + for (wch = (wchar16_t *)str; (wch < upper_bound) && (*wch); wch++); + + if (wch < upper_bound) + return (size_t)((intptr_t)wch - (intptr_t)str); + else + return -1; +} + + +wchar16_t pe_impl_utf16_char_to_lower(const wchar16_t c) +{ + if ((c >= 'A') && (c <= 'Z')) + return c + 'a' - 'A'; + else + return c; +} diff --git a/src/internal/pe_impl.h b/src/internal/pe_impl.h new file mode 100644 index 0000000..09e81c9 --- /dev/null +++ b/src/internal/pe_impl.h @@ -0,0 +1,17 @@ +#include +#include + +#define PE_STR_MAX_SYMBOL_LEN_ALLOWED (uint32_t)0x10000 + +#define IN_LOAD_ORDER_MODULE_LIST_OFFSET (intptr_t)0x00 +#define IN_MEMORY_ORDER_MODULE_LIST_OFFSET (intptr_t)0x01 * sizeof(struct pe_list_entry) +#define IN_INITIALIZATION_ORDER_MODULE_LIST_OFFSET (intptr_t)0x02 * sizeof(struct pe_list_entry) + +struct pe_block { + uint32_t rva; + uint32_t size; +}; + +size_t pe_impl_strlen_ansi(const char * str); +size_t pe_impl_strlen_utf16(const wchar16_t * str); +wchar16_t pe_impl_utf16_char_to_lower(const wchar16_t c); diff --git a/src/internal/pe_lib_entry_point.c b/src/internal/pe_lib_entry_point.c new file mode 100644 index 0000000..efdaa26 --- /dev/null +++ b/src/internal/pe_lib_entry_point.c @@ -0,0 +1,6 @@ +#include + +int __stdcall pe_lib_entry_point(void * hinstance, uint32_t reason, void * reserved) +{ + return 1; +} diff --git a/src/meta/pe_get_image_stack_heap_info.c b/src/meta/pe_get_image_stack_heap_info.c new file mode 100644 index 0000000..ec1aba9 --- /dev/null +++ b/src/meta/pe_get_image_stack_heap_info.c @@ -0,0 +1,43 @@ +/*****************************************************************************/ +/* pemagination: a (virtual) tour into portable bits and executable bytes */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */ +/*****************************************************************************/ + +#include +#include +#include +#include + +pe_api +int pe_get_image_stack_heap_info(const void * base, struct pe_stack_heap_info * stack_heap_info) +{ + uint16_t * magic; + union pe_opt_hdr * hdr; + + if (!(hdr = pe_get_image_opt_hdr_addr(base))) + return 0; + + magic = (uint16_t *)hdr; + + switch (*magic) { + case PE_MAGIC_PE32: + stack_heap_info->size_of_stack_reserve = *(uint32_t *)hdr->opt_hdr_32.size_of_stack_reserve; + stack_heap_info->size_of_stack_commit = *(uint32_t *)hdr->opt_hdr_32.size_of_stack_commit; + stack_heap_info->size_of_heap_reserve = *(uint32_t *)hdr->opt_hdr_32.size_of_heap_reserve; + stack_heap_info->size_of_heap_commit = *(uint32_t *)hdr->opt_hdr_32.size_of_heap_commit; + break; + + case PE_MAGIC_PE32_PLUS: + stack_heap_info->size_of_stack_reserve = *(size_t *)hdr->opt_hdr_64.size_of_stack_reserve; + stack_heap_info->size_of_stack_commit = *(size_t *)hdr->opt_hdr_64.size_of_stack_commit; + stack_heap_info->size_of_heap_reserve = *(size_t *)hdr->opt_hdr_64.size_of_heap_reserve; + stack_heap_info->size_of_heap_commit = *(size_t *)hdr->opt_hdr_64.size_of_heap_commit; + break; + + default: + return -1; + } + + return 0; +} diff --git a/src/meta/pe_get_symbol_module_info.c b/src/meta/pe_get_symbol_module_info.c new file mode 100644 index 0000000..7dd8a5a --- /dev/null +++ b/src/meta/pe_get_symbol_module_info.c @@ -0,0 +1,56 @@ +/*****************************************************************************/ +/* pemagination: a (virtual) tour into portable bits and executable bytes */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */ +/*****************************************************************************/ + +#include +#include + + +struct pe_module_info_ctx { + uintptr_t sym_addr; + struct pe_ldr_tbl_entry * image_ldr_tbl_entry; +}; + + + +static int pe_get_symbol_module_info_callback( + struct pe_ldr_tbl_entry * ldr_tbl_entry, + enum pe_callback_reason reason, + void * context) +{ + uintptr_t image_base; + uintptr_t image_size; + struct pe_module_info_ctx * ctx; + + if (reason != PE_CALLBACK_REASON_ITEM) + return 1; + + ctx = (struct pe_module_info_ctx *)context; + image_base = (uintptr_t)(ldr_tbl_entry->dll_base); + image_size = (uintptr_t)(ldr_tbl_entry->size_of_image); + + if ((ctx->sym_addr > image_base) && (ctx->sym_addr < image_base + image_size)) { + /* within bounds */ + ctx->image_ldr_tbl_entry = ldr_tbl_entry; + return 0; + } else + return 1; +} + + +pe_api +struct pe_ldr_tbl_entry * pe_get_symbol_module_info(const void * sym_addr) +{ + struct pe_module_info_ctx ctx; + + ctx.sym_addr = (uintptr_t)sym_addr; + ctx.image_ldr_tbl_entry = 0; + + pe_enum_modules_in_load_order( + pe_get_symbol_module_info_callback, + &ctx); + + return ctx.image_ldr_tbl_entry; +} diff --git a/src/meta/pe_get_symbol_name.c b/src/meta/pe_get_symbol_name.c new file mode 100644 index 0000000..f9001ef --- /dev/null +++ b/src/meta/pe_get_symbol_name.c @@ -0,0 +1,209 @@ +/*****************************************************************************/ +/* pemagination: a (virtual) tour into portable bits and executable bytes */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */ +/*****************************************************************************/ + +#include +#include + +/* private args structure */ +struct pe_symbol_name_ctx { + const void * addr; + char * name; +}; + +/* private forward declarations */ +static int pe_enum_exports_callback( + const void * base, + struct pe_export_hdr * exp_hdr, + struct pe_export_sym * sym, + enum pe_callback_reason reason, + void * context); + +#if defined (__NT32) +static char * pe_get_imported_symbol_info_32( + const void * sym_addr, + void ** sym_image_addr, + char ** sym_name, + struct pe_ldr_tbl_entry ** ldr_tbl_entry); +#endif + +#if defined (__NT64) +static char * pe_get_imported_symbol_info_64( + const void * sym_addr, + void ** sym_image_addr, + char ** sym_name, + struct pe_ldr_tbl_entry ** ldr_tbl_entry); +; +#endif + +pe_api +char * pe_get_symbol_name(const void * base, const void * sym_addr) +{ + struct pe_export_sym exp_item; + struct pe_symbol_name_ctx ctx; + + ctx.name = 0; + ctx.addr = sym_addr; + + pe_enum_image_exports( + base, + pe_enum_exports_callback, + &exp_item, + &ctx); + + return ctx.name; +} + + +pe_api +char * pe_get_import_symbol_info( + const void * sym_addr, + void ** sym_image_addr, + char ** sym_name, + struct pe_ldr_tbl_entry ** ldr_tbl_entry) +{ + #if defined(__NT32) + return pe_get_imported_symbol_info_32( + sym_addr, + sym_image_addr, + sym_name, + ldr_tbl_entry); + #elif defined (__NT64) + return pe_get_imported_symbol_info_64( + sym_addr, + sym_image_addr, + sym_name, + ldr_tbl_entry); + #endif +} + +static int pe_enum_exports_callback( + const void * base, + struct pe_export_hdr * exp_hdr, + struct pe_export_sym * sym, + enum pe_callback_reason reason, + void * context) +{ + struct pe_symbol_name_ctx * ctx; + + if (reason != PE_CALLBACK_REASON_ITEM) + return 1; + + ctx = (struct pe_symbol_name_ctx *)context; + + if (sym->addr == ctx->addr) { + ctx->name = sym->name; + return 0; + } else + return 1; +} + + +#ifdef __NT32 +static char * pe_get_imported_symbol_info_32( + const void * sym_addr, + void ** sym_image_addr, + char ** sym_name, + struct pe_ldr_tbl_entry ** ldr_tbl_entry) +{ + struct symbol { + unsigned char call; + unsigned char ds; + unsigned char sym_addr[4]; + unsigned char padding[2]; + }; + + char * fn_name; + struct pe_ldr_tbl_entry * mod_info; + void * mod_base; + uint32_t *** sym_redirected_addr; + struct symbol * sym; + + fn_name = 0; + mod_info = 0; + sym = (struct symbol *)sym_addr; + + if ((sym->call == 0xff) && (sym->ds == 0x25)) { + sym_redirected_addr = (uint32_t ***)sym->sym_addr; + + if (sym_redirected_addr) + mod_info = pe_get_symbol_module_info(**sym_redirected_addr); + + if (mod_info) + mod_base = mod_info->dll_base; + else + mod_base = (void *)0; + + if (mod_base) + fn_name = pe_get_symbol_name( + mod_base, + **sym_redirected_addr); + } + + if (fn_name && ldr_tbl_entry) + *ldr_tbl_entry = mod_info; + + return fn_name; +} +#endif + + +#ifdef __NT64 +static char * pe_get_imported_symbol_info_64( + const void * sym_addr, + void ** sym_image_addr, + char ** sym_name, + struct pe_ldr_tbl_entry ** ldr_tbl_entry) +{ + struct symbol { + unsigned char call; + unsigned char ds; + unsigned char sym_addr[4]; + unsigned char padding[2]; + }; + + char * fn_name; + struct pe_ldr_tbl_entry * mod_info; + void * mod_base; + uint32_t * sym_offset; + uint32_t offset; + struct symbol * sym; + + fn_name = 0; + mod_info = 0; + sym = (struct symbol *)sym_addr; + + if ((sym->call == 0xff) && (sym->ds == 0x25)) { + sym_offset = (uint32_t *)sym->sym_addr; + + if (sym_offset) { + offset = *sym_offset; + sym_addr = *(void **)(offset + (uintptr_t)(++sym_offset)); + mod_info = pe_get_symbol_module_info(sym_addr); + } + + if (mod_info) + mod_base = mod_info->dll_base; + else + mod_base = (void *)0; + + if (mod_base) + fn_name = pe_get_symbol_name(mod_base,sym_addr); + } + + if (fn_name) { + if (ldr_tbl_entry) + *ldr_tbl_entry = mod_info; + + if (sym_image_addr) + *sym_image_addr = (void *)sym_addr; + + if (sym_name) + *sym_name = fn_name; + } + + return fn_name; +} +#endif diff --git a/src/modules/pe_enum_modules.c b/src/modules/pe_enum_modules.c new file mode 100644 index 0000000..c36b076 --- /dev/null +++ b/src/modules/pe_enum_modules.c @@ -0,0 +1,102 @@ +/*****************************************************************************/ +/* pemagination: a (virtual) tour into portable bits and executable bytes */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */ +/*****************************************************************************/ + +#include +#include +#include +#include +#include "pe_impl.h" + +static int pe_enum_modules( + pe_enum_modules_callback * callback, + const uintptr_t in_order_member_offset, + void * context) +{ + int ret; + uintptr_t peb_tbl_addr; + struct pe_peb_ldr_data * peb_ldr_data; + struct pe_ldr_tbl_entry * ldr_tbl_entry; + struct pe_list_entry * plist_head; + struct pe_list_entry * plist_current; + + peb_ldr_data = (struct pe_peb_ldr_data *)pe_get_peb_ldr_data_address(); + plist_head = (struct pe_list_entry *)0; + + if ((intptr_t)peb_ldr_data == 0) { + callback( + 0, + PE_CALLBACK_REASON_ERROR, + context); + return -1; + } + + ret = callback( + 0, + PE_CALLBACK_REASON_INIT, + context); + + if (ret <= 0) + return ret; + + switch (in_order_member_offset) { + case IN_LOAD_ORDER_MODULE_LIST_OFFSET: + plist_head = peb_ldr_data->in_load_order_module_list.flink; + break; + + case IN_MEMORY_ORDER_MODULE_LIST_OFFSET: + plist_head = peb_ldr_data->in_memory_order_module_list.flink; + break; + + case IN_INITIALIZATION_ORDER_MODULE_LIST_OFFSET: + plist_head = peb_ldr_data->in_init_order_module_list.flink; + break; + } + + plist_current = plist_head; + + do + { + peb_tbl_addr = (uintptr_t)plist_current - in_order_member_offset; + ldr_tbl_entry = (struct pe_ldr_tbl_entry *)peb_tbl_addr; + + ret = callback( + ldr_tbl_entry, + PE_CALLBACK_REASON_ITEM, + context); + + if (ret <= 0) + return ret; + else + plist_current = plist_current->flink; + + } while (plist_current != plist_head); + + ret = callback( + ldr_tbl_entry, + PE_CALLBACK_REASON_DONE, + context); + + return ret; +} + + +pe_api +int pe_enum_modules_in_load_order(pe_enum_modules_callback * fn, void * ctx) +{ + return pe_enum_modules(fn,IN_LOAD_ORDER_MODULE_LIST_OFFSET,ctx); +} + +pe_api +int pe_enum_modules_in_memory_order(pe_enum_modules_callback * fn, void * ctx) +{ + return pe_enum_modules(fn,IN_MEMORY_ORDER_MODULE_LIST_OFFSET,ctx); +} + +pe_api +int pe_enum_modules_in_init_order(pe_enum_modules_callback * fn, void * ctx) +{ + return pe_enum_modules(fn,IN_INITIALIZATION_ORDER_MODULE_LIST_OFFSET,ctx); +} diff --git a/src/modules/pe_get_kernel32_module_handle.c b/src/modules/pe_get_kernel32_module_handle.c new file mode 100644 index 0000000..9cd0c18 --- /dev/null +++ b/src/modules/pe_get_kernel32_module_handle.c @@ -0,0 +1,73 @@ +/*****************************************************************************/ +/* pemagination: a (virtual) tour into portable bits and executable bytes */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */ +/*****************************************************************************/ + +#include +#include +#include +#include +#include "pe_impl.h" + +static int pe_get_kernel32_handle_callback( + struct pe_ldr_tbl_entry * ldr_tbl_entry, + enum pe_callback_reason reason, + void * context) +{ + #define KERNEL32_UTF16_STRLEN 24 + + int32_t kernel32_base_name_le[4]; + char * kernel32_base_name_ansi; + + intptr_t * addr; + char * ch; + size_t match; + + /* avoid scan-based false positives */ + kernel32_base_name_le[0] = 0x6E72656B; /* 'kern' */ + kernel32_base_name_le[1] = 0x32336C65; /* 'el32' */ + kernel32_base_name_le[2] = 0x6C6C642E; /* '.dll' */ + kernel32_base_name_le[3] = 0; + + kernel32_base_name_ansi = (char *)&kernel32_base_name_le; + + match = 0; + addr = (intptr_t *)context; + + if (reason == PE_CALLBACK_REASON_ITEM) + if (ldr_tbl_entry->base_dll_name.strlen == KERNEL32_UTF16_STRLEN) { + ch = (char *)ldr_tbl_entry->base_dll_name.buffer; + match = 0; + + while ((match < sizeof(kernel32_base_name_ansi)) + && ((*ch == kernel32_base_name_ansi[match]) + || (*ch == (kernel32_base_name_ansi[match] + 'A' - 'a'))) + && (*(ch + 1) == 0)) { + ch+=sizeof(uint16_t); + match++; + } + } + + if (match == sizeof(kernel32_base_name_ansi)) { + *addr = (intptr_t)ldr_tbl_entry->dll_base; + return 0; + } + else + return 1; +} + + +pe_api +void * pe_get_kernel32_module_handle(void) +{ + + intptr_t kernel32_base_addr = 0; + void * ptr_to_callback = &kernel32_base_addr; + + pe_enum_modules_in_init_order( + &pe_get_kernel32_handle_callback, + ptr_to_callback); + + return (void *)kernel32_base_addr; +} diff --git a/src/modules/pe_get_module_handle.c b/src/modules/pe_get_module_handle.c new file mode 100644 index 0000000..7677ba0 --- /dev/null +++ b/src/modules/pe_get_module_handle.c @@ -0,0 +1,80 @@ +/*****************************************************************************/ +/* pemagination: a (virtual) tour into portable bits and executable bytes */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */ +/*****************************************************************************/ + +#include +#include +#include +#include +#include "pe_impl.h" + +pe_api +void * pe_get_first_module_handle(void) +{ + struct pe_peb_ldr_data * peb_ldr_data; + struct pe_list_entry * peb_list_entry; + intptr_t peb_tbl_addr; + struct pe_ldr_tbl_entry * peb_ldr_tbl_entry; + + peb_ldr_data = (struct pe_peb_ldr_data *)pe_get_peb_ldr_data_address(); + peb_list_entry = (struct pe_list_entry *)peb_ldr_data->in_load_order_module_list.flink; + peb_tbl_addr = (intptr_t)peb_list_entry - IN_LOAD_ORDER_MODULE_LIST_OFFSET; + peb_ldr_tbl_entry = (struct pe_ldr_tbl_entry *)peb_tbl_addr; + + return peb_ldr_tbl_entry->dll_base; +} + +pe_api +void * pe_get_module_handle(const wchar16_t * name) +{ + wchar16_t * src; + wchar16_t * dst; + + size_t match; + size_t len; + + struct pe_peb_ldr_data * peb_ldr_data; + struct pe_list_entry * plist_head; + + struct pe_list_entry * plist_current; + struct pe_ldr_tbl_entry * ldr_tbl_entry = 0; + + peb_ldr_data = (struct pe_peb_ldr_data *)pe_get_peb_ldr_data_address(); + plist_head = (struct pe_list_entry *)peb_ldr_data->in_load_order_module_list.flink; + plist_current = plist_head; + + len = pe_impl_strlen_utf16(name); + + do { + ldr_tbl_entry = (struct pe_ldr_tbl_entry *)plist_current - IN_LOAD_ORDER_MODULE_LIST_OFFSET; + + if (ldr_tbl_entry->base_dll_name.strlen == len) + dst = (wchar16_t *)ldr_tbl_entry->base_dll_name.buffer; + else if (ldr_tbl_entry->full_dll_name.strlen == len) + dst = (wchar16_t *)ldr_tbl_entry->full_dll_name.buffer; + else + dst = (wchar16_t *)0; + + if ((intptr_t)(dst)) { + src = (wchar16_t *)name; + match = 0; + + while ((match < len) + && ((pe_impl_utf16_char_to_lower(*src)) == (pe_impl_utf16_char_to_lower(*dst)))) { + src = (wchar16_t *)pe_va_from_rva(src,sizeof(wchar16_t)); + dst = (wchar16_t *)pe_va_from_rva(dst,sizeof(wchar16_t)); + match+=sizeof(wchar16_t); + } + + if (match == len) + return ldr_tbl_entry->dll_base; + } + + plist_current = plist_current->flink; + } while (plist_current != plist_head); + + /* address not found */ + return 0; +} diff --git a/src/modules/pe_get_ntdll_module_handle.c b/src/modules/pe_get_ntdll_module_handle.c new file mode 100644 index 0000000..72f81ec --- /dev/null +++ b/src/modules/pe_get_ntdll_module_handle.c @@ -0,0 +1,27 @@ +/*****************************************************************************/ +/* pemagination: a (virtual) tour into portable bits and executable bytes */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */ +/*****************************************************************************/ + +#include +#include +#include +#include +#include "pe_impl.h" + +pe_api +void * pe_get_ntdll_module_handle(void) +{ + struct pe_peb_ldr_data * peb_ldr_data; + struct pe_list_entry * peb_list_entry; + intptr_t peb_tbl_addr; + struct pe_ldr_tbl_entry * peb_ldr_tbl_entry; + + peb_ldr_data = (struct pe_peb_ldr_data *)pe_get_peb_ldr_data_address(); + peb_list_entry = peb_ldr_data->in_init_order_module_list.flink; + peb_tbl_addr = (intptr_t)peb_list_entry - IN_INITIALIZATION_ORDER_MODULE_LIST_OFFSET; + peb_ldr_tbl_entry = (struct pe_ldr_tbl_entry *)peb_tbl_addr; + + return peb_ldr_tbl_entry->dll_base; +}