diff --git a/.gitattributes b/.gitattributes index a31f8ef74a2d13b6dafa64a4a15af618bb8115f1..2b719019847400287f9036ac2b84a5b5dabdf401 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,80 +1,4 @@ * text=auto !eol -/INSTALL -text -/README.txt -text -/build-all.sh -text -centos_files/at-3.1.13-22.el7.x86_64.rpm -text -centos_files/audit-2.6.5-3.el7_3.1.x86_64.rpm -text -centos_files/audit-libs-2.6.5-3.el7_3.1.i686.rpm -text -centos_files/audit-libs-2.6.5-3.el7_3.1.x86_64.rpm -text -centos_files/bc-1.06.95-13.el7.x86_64.rpm -text -centos_files/cpp-4.8.5-11.el7.x86_64.rpm -text svneol=unset#application/x-rpm -centos_files/cracklib-2.9.0-11.el7.i686.rpm -text -centos_files/cups-client-1.6.3-26.el7.x86_64.rpm -text -centos_files/ed-1.9-4.el7.x86_64.rpm -text -centos_files/gcc-c++-4.8.5-11.el7.x86_64.rpm -text -centos_files/glibc-2.17-157.el7_3.1.i686.rpm -text -centos_files/jq-1.5-1.el7.x86_64.rpm -text -centos_files/kernel-headers-3.10.0-514.16.1.el7.x86_64.rpm -text svneol=unset#application/x-rpm -centos_files/libcap-ng-0.7.5-4.el7.i686.rpm -text -centos_files/libdb-5.3.21-19.el7.i686.rpm -text -centos_files/libgcc-4.8.5-11.el7.i686.rpm -text -centos_files/libgomp-4.8.5-11.el7.x86_64.rpm -text svneol=unset#application/x-rpm -centos_files/libmpc-1.0.1-3.el7.x86_64.rpm -text svneol=unset#application/x-rpm -centos_files/libpqxx-4.0.1-1.el7.x86_64.rpm -text -centos_files/libselinux-2.5-6.el7.i686.rpm -text -centos_files/libsepol-2.5-6.el7.i686.rpm -text -centos_files/libstdc++-4.8.5-11.el7.i686.rpm -text -centos_files/libstdc++-4.8.5-11.el7.x86_64.rpm -text svneol=unset#application/x-rpm -centos_files/libstdc++-devel-4.8.5-11.el7.x86_64.rpm -text svneol=unset#application/x-rpm -centos_files/m4-1.4.16-10.el7.x86_64.rpm -text svneol=unset#application/x-rpm -centos_files/mailx-12.5-12.el7_0.x86_64.rpm -text -centos_files/nasm-2.10.07-7.el7.x86_64.rpm -text svneol=unset#application/x-rpm -centos_files/ncurses-libs-5.9-13.20130511.el7.i686.rpm -text -centos_files/nspr-4.13.1-1.0.el7_3.i686.rpm -text -centos_files/nss-3.28.4-1.0.el7_3.i686.rpm -text -centos_files/nss-softokn-3.16.2.3-14.4.el7.i686.rpm -text -centos_files/nss-softokn-freebl-3.16.2.3-14.4.el7.i686.rpm -text -centos_files/nss-util-3.28.4-1.0.el7_3.i686.rpm -text -centos_files/oniguruma-5.9.5-3.el7.x86_64.rpm -text -centos_files/pam-1.1.8-18.el7.i686.rpm -text -centos_files/pam-1.1.8-18.el7.x86_64.rpm -text svneol=unset#application/x-rpm -centos_files/patch-2.7.1-8.el7.x86_64.rpm -text svneol=unset#application/x-rpm -centos_files/pcre-8.32-15.el7_2.1.i686.rpm -text -centos_files/pcre-8.32-15.el7_2.1.x86_64.rpm -text svneol=unset#application/x-rpm -centos_files/perl-Data-Dumper-2.145-3.el7.x86_64.rpm -text -centos_files/perl-JSON-PP-2.27202-2.el7.noarch.rpm -text -centos_files/postgresql-9.2.18-1.el7.x86_64.rpm -text svneol=unset#application/x-rpm -centos_files/postgresql-contrib-9.2.18-1.el7.x86_64.rpm -text svneol=unset#application/x-rpm -centos_files/postgresql-devel-9.2.18-1.el7.x86_64.rpm -text svneol=unset#application/x-rpm -centos_files/postgresql-libs-9.2.18-1.el7.x86_64.rpm -text svneol=unset#application/x-rpm -centos_files/postgresql-server-9.2.18-1.el7.x86_64.rpm -text svneol=unset#application/x-rpm -centos_files/readline-6.2-9.el7.i686.rpm -text -centos_files/redhat-lsb-core-4.1-27.el7.centos.1.i686.rpm -text -centos_files/redhat-lsb-submod-security-4.1-27.el7.centos.1.i686.rpm -text -centos_files/screen-4.1.0-0.23.20120314git3c2946.el7_2.x86_64.rpm -text svneol=unset#application/x-rpm -centos_files/spax-1.5.2-13.el7.x86_64.rpm -text svneol=unset#application/x-rpm -centos_files/sqlite-3.7.17-8.el7.i686.rpm -text -centos_files/time-1.7-45.el7.x86_64.rpm -text -centos_files/uuid-1.6.2-26.el7.x86_64.rpm -text svneol=unset#application/x-rpm -centos_files/zlib-1.2.7-17.el7.i686.rpm -text -centos_files/zlib-1.2.7-17.el7.x86_64.rpm -text svneol=unset#application/x-rpm -/cfar_postgres_setup.sh -text -/cfar_postgres_setup_for_other.sh -text -/clean-all.sh -text -/externals.conf -text -/get-peasoup-packages.sh -text -/irdb_vars -text -/manifest.txt -text -/postgres_setup.sh -text -/regen_install.sh -text -/set_command_envs -text -/set_env_vars -text -/set_ida_server -text -/start_dev.sh -text -ubuntu16_files/README.txt -text -ubuntu16_files/Vagrantfile -text -ubuntu16_files/generate_installer.sh -text -ubuntu16_files/install.sh -text -ubuntu16_files/manifest.txt -text -ubuntu16_files/test.sh -text -/yum_packages.sh -text +irdb-libs/libcapstone norecurse +irdb-libs/third_party/elfio-code norecurse + diff --git a/.gitignore b/.gitignore index fe5c3b91e4ab99d537b6d1d5c9bcf8f28c5dd0eb..2a254052c20413600b15f34157f2917660a91ad2 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,15 @@ ubuntu16_files/manifest.txt.config zest_runtime .sconsign.dblite build - +irdb-libs/build/ +irdb-libs/.sconsign.dblite +irdb-libs/bin/ +irdb-libs/lib/ +irdb-libs/manifest.txt.config +irdb-libs/tools/meds2pdb/meds2pdb +irdb-libs/plugins_install/*.exe +irdb-libs/plugins_install/*.so +irdb-libs/*.swp +irdb-libs/*.os +irdb-libs/*.o +scons_buiirdb-libs/ld diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 716c689e5b27a140dfc1c33754144807220a5e04..ff5de6fd1dd287858a9b75b75a3777a1f46a7bd1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,8 +1,9 @@ before_script: - "source ~gitlab-runner/cicd_support/cicd_support.shinc" + after_script: - - "source ~gitlab-runner/cicd_support/cicd_support.shinc" + - "echo Test Complete." stages: - clean @@ -18,20 +19,28 @@ stages: script: - ./cicd_testing/do-clean.sh +# per os items do-nightly-clean-ubuntu18: <<: *do-nightly-clean tags: - ubuntu18 + variables: + OS: 'ubuntu18' do-nightly-clean-ubuntu16: <<: *do-nightly-clean tags: - ubuntu16 + variables: + OS: 'ubuntu16' do-nightly-clean-centos75: <<: *do-nightly-clean tags: - centos75 + variables: + OS: 'centos75' + # # Building @@ -42,46 +51,43 @@ do-nightly-clean-centos75: script: - ./cicd_testing/do-build.sh -do-build-ubuntu18: - <<: *do-build - tags: - - ubuntu18 - -do-build-ubuntu16: - <<: *do-build - tags: - - ubuntu16 + variables: + OS: 'centos75' -do-build-centos75: - <<: *do-build - tags: - - centos75 # -# $PSZ ls +# building # -.xform-ls: &xform-ls - stage: test + +# template +.do-build: &do-build + stage: build script: - - ./cicd_testing/xform-ls.sh + - ./cicd_tests/do-build.sh -xform-ls-ubuntu18: - <<: *xform-ls +# per os items +do-build-ubuntu18: + <<: *do-build tags: - ubuntu18 + variables: + OS: 'ubuntu18' -xform-ls-ubuntu16: - <<: *xform-ls +do-build-ubuntu16: + <<: *do-build tags: - ubuntu16 + variables: + OS: 'ubuntu16' -xform-ls-centos75: - <<: *xform-ls +do-build-centos75: + <<: *do-build tags: - centos75 - + variables: + OS: 'centos75' # @@ -90,7 +96,7 @@ xform-ls-centos75: .basic-pgms-rida: &eh-tests stage: test script: - - ./cicd_testing/eh-tests.sh + - ./irdb-libs/cicd_testing/eh-tests.sh eh-tests-ubuntu18: <<: *eh-tests @@ -152,4 +158,36 @@ basic-pgms-fixcalls-centos75: <<: *basic-pgms-fixcalls tags: - centos75 + variables: + OS: 'centos75' + +# +# elfdep test +# +# template +.elfdep: &elfdep + stage: test + script: + - ./irdb-libs/cicd_tests/elfdep.sh + +elfdep-ubuntu18: + <<: *elfdep + tags: + - ubuntu18 + variables: + OS: 'ubuntu18' + +elfdep-ubuntu16: + <<: *elfdep + tags: + - ubuntu16 + variables: + OS: 'ubuntu16' + +elfdep-centos75: + <<: *elfdep + tags: + - centos75 + variables: + OS: 'centos75' diff --git a/.gitmodules b/.gitmodules index 4becba678968bb674d225bb08572bc3848ca15ba..70eaa0970f863f7249f483f806bf20ff7c568096 100644 --- a/.gitmodules +++ b/.gitmodules @@ -54,3 +54,12 @@ [submodule "irdb-sdk"] path = irdb-sdk url = git@git.zephyr-software.com:allnp/irdb-sdk.git +[submodule "libcapstone"] + path = irdb-libs/libcapstone + url = https://github.com/aquynh/capstone.git +[submodule "libehp"] + path = irdb-libs/libehp + url = git@git.zephyr-software.com:opensrc/libehp.git +[submodule "third_party/elfio-code"] + path = irdb-libs/third_party/elfio-code + url = http://git.code.sf.net/p/elfio/code diff --git a/irdb-lib/LICENSE.txt b/irdb-lib/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..312fba3fce32ba9e8a488ac58885ca41c59c2aa8 --- /dev/null +++ b/irdb-lib/LICENSE.txt @@ -0,0 +1,14 @@ +************************************************************************************* +* +* Unless otherwise specified, software artifacts in this directory and its +* subdirectories are subject to: +* +* GOVERNMENT PURPOSE RIGHTS +* +* The Government's rights to use, modify, reproduce, release, perform, display, or +* disclose this software are restricted by GOVERNMENT PURPOSE RIGHTS. +* +* Any reproduction of the software or portions thereof marked with this legend +* must also reproduce the markings. +* +************************************************************************************* diff --git a/irdb-lib/README b/irdb-lib/README new file mode 100644 index 0000000000000000000000000000000000000000..a0990367ef8b03c70c29d285e22ef85907e1d0b7 --- /dev/null +++ b/irdb-lib/README @@ -0,0 +1 @@ +TBD diff --git a/irdb-lib/README.p1 b/irdb-lib/README.p1 new file mode 100644 index 0000000000000000000000000000000000000000..ba13e836d04b70852ad9101e2a2c0f492daa18c0 --- /dev/null +++ b/irdb-lib/README.p1 @@ -0,0 +1,53 @@ +Note +------------------ +20110622 To turn on P1 off the main trun, uncomment the comments in $PEASOUP_HOME/tools/ps_analyze.h that have to do with P1. + +Tool Chain +------------------ + MEDS: produces annotations + Grace: produces inputs/outputs, instruction execution trace + Stratafication: produces stratafied binary + heaprand + pc_confinement + P1: produces validated stratafied binary + SPRI file + +Steps in producing P1 transform rules +------------------------------------- +Call the p1transform tool + For every candidate function (i.e., not marketd as safe by MEDS, nice stack frame allocation/dealloc) + Generate assembly SPRI files for every candidate function in statically-linked program + Generate binary SPRI files for every candidate function in statically-linked program + +Produce coverage information for all candidate functions + Use instruction execution information provided by Grace + instructions info per function provided by MEDS/ELF (for a fn, metric is: #instructions-visited/#instructions-in-function). A better metric here could be: #instructions-stack-reference/#instruction-stack-references-in-function (TBD). + +Run BED (Behavioral Equivalence Detector) + Use GrammaTech's replayer tool + +Produce final set of spri rules by merging all functions that pass BED + Literally a merge of all the files + +Validate binary with final merged set of rules + Use BED again + +Deploy binary + If the validation fails, we leave the original binary alone, i.e., PEASOUP runs the stratafied binary but w/o any P1 transform rules + Otherwise, PEASOUP automatically picks up the P1 transform rules + + NB: to do later: if validation fails we need to iterate and remove rules until we get a set of rules that pass BED. One way of doing this is to use coverage information to guide this search, i.e., start by removing the least covered functions first. + +Notes +------------------ +P1 only attempts to transform functions that are "nice" (1 stack frame alloc/dealloc, not memory safe) + Example stats for test1.exe: + 1027 functions, test1.exe(18), libc(1009) + P1 candidate fns (333) P1 non-candidate (not "p1-nice") (584), non-candidate-MEDS-safe (110) + filtered-out functions(896) [no instruction coverage] + P1 candidate functions(131) + BEDS(P1): 43/131 functions validated + #functions P1 transformed (43), libc(25), user-functions (13/18), MEDS safe:(4/18), main not transformed + +P1 works by pattern matching to find and transform stack references. The set of rules is incomplete and probably does not handle corner cases +P1 only tested on simple test programs (test1, dumbledore), and with -fomit-frame-pointer + +Next steps +------------------ +Push P1 through Spec2006. Find bugs. Fix them. Iterate. diff --git a/irdb-lib/SConscript b/irdb-lib/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..22820a5b5594af3fa36121fb60aebe42fa589dc9 --- /dev/null +++ b/irdb-lib/SConscript @@ -0,0 +1,132 @@ +import shutil +import os +import tarfile + +Import('env') + +(sysname, nodename, release, version, machine)=os.uname() + + +if env.GetOption('clean'): + if os.path.exists(os.environ['SECURITY_TRANSFORMS_HOME']+"/include/targ-config.h"): + print 'Removing include/targ-config.h' + os.remove(os.environ['SECURITY_TRANSFORMS_HOME']+"/include/targ-config.h") + os.chdir(os.environ['SECURITY_TRANSFORMS_HOME']+"/libcapstone") + os.system("make clean") + if os.path.exists(os.environ['SECURITY_TRANSFORMS_HOME']+"/libcapstone/zipr_unpack"): + shutil.rmtree(os.environ['SECURITY_TRANSFORMS_HOME']+"/libcapstone/zipr_unpack") + os.chdir(os.environ['SECURITY_TRANSFORMS_HOME']) + + +else: + + # check/install targ-config.h + #if not os.path.isfile(os.environ['SECURITY_TRANSFORMS_HOME']+"/include/targ-config.h"): + ##print "uname=", sysname, " xx ", nodename, " xx ", release, " xx ", version, " xx ", machine + #shutil.copy( os.path.join(os.environ['SECURITY_TRANSFORMS_HOME'],"include",machine,"config.h"), + #os.path.join(os.environ['SECURITY_TRANSFORMS_HOME'],"include","targ-config.h")) + + os.chdir(os.environ['SECURITY_TRANSFORMS_HOME']+"/libcapstone") + print "Rebuilding libcapstone." + jobs=env.GetOption('num_jobs') + os.system("make -j "+str(jobs)) + os.chdir(os.environ['SECURITY_TRANSFORMS_HOME']+"/libcapstone") + if not os.path.exists(os.environ['SECURITY_TRANSFORMS_HOME']+"/libcapstone/zipr_unpack"): + os.mkdir(os.environ['SECURITY_TRANSFORMS_HOME']+"/libcapstone/zipr_unpack") + os.chdir(os.environ['SECURITY_TRANSFORMS_HOME']+"/libcapstone/zipr_unpack") + print "Unpacking libcapstone.a for libIRDB-core." + os.system("ar x "+os.environ['SECURITY_TRANSFORMS_HOME']+"/libcapstone/libcapstone.a") + os.chdir(os.environ['SECURITY_TRANSFORMS_HOME']) + + + +if "PEDI_HOME" in os.environ: + pedi = Command( target = "./testoutput", + source = "./SConscript", + action = os.environ['PEDI_HOME']+"/pedi -m manifest.txt " ) + +env['BASE_IRDB_LIBS']="irdb-core", "pqxx", "pq" + +if sysname != "SunOS": + libPEBLISS=SConscript("pebliss/trunk/pe_lib/SConscript", variant_dir='scons_build/libPEBLISS') + # setup libraries needed for linking + env['BASE_IRDB_LIBS']=env['BASE_IRDB_LIBS']+("pebliss",) + if "PEDI_HOME" in os.environ: + Depends(pedi,libPEBLISS) + +# pebliss requires iconv, which needs to be explicit on cygwin. +if "CYGWIN" in sysname: + # add tuple of 1 item! + env['BASE_IRDB_LIBS']=env['BASE_IRDB_LIBS']+("iconv",) + +Export('env') + +# get the libcapstone.so.[version] file regardless of the version extension +libcapstone_path = Glob(os.environ['SECURITY_TRANSFORMS_HOME']+'/libcapstone/libcapstone.so.*') +assert len(libcapstone_path) <= 1, "More than one candidate for libcapstone.so.[version]?!" + +libcapstone_path = env.Install("$SECURITY_TRANSFORMS_HOME/lib/", libcapstone_path) + +env.Command(os.environ['SECURITY_TRANSFORMS_HOME']+"/lib/libcapstone.so", libcapstone_path, "ln -s $SOURCE.abspath $TARGET.abspath") +libcapstone=os.environ['SECURITY_TRANSFORMS_HOME']+"/lib/libcapstone.so" + +libehp=env.SConscript("libehp/SConscript", variant_dir='scons_build/libehp') +libehp=env.Install("$SECURITY_TRANSFORMS_HOME/lib", libehp); + +libIRDBcore=env.SConscript("libIRDB-core/src/SConscript", variant_dir='scons_build/libIRDB-core') +Depends(libIRDBcore,libcapstone) + +libIRDBcfg=env.SConscript("libIRDB-cfg/src/SConscript", variant_dir='scons_build/libIRDB-cfg') +libIRDButil=env.SConscript("libIRDB-util/src/SConscript", variant_dir='scons_build/libIRDB-util') +libIRDBsyscall=env.SConscript("libIRDB-syscall/src/SConscript", variant_dir='scons_build/libIRDB-syscall') +libElfDep=SConscript("libIRDB-elfdep/src/SConscript", variant_dir='scons_build/libIRDB-elfdep') +libtransform=SConscript("libIRDB-transform/src/SConscript", variant_dir='scons_build/libIRDB-transform') +libEXEIO=SConscript("libEXEIO/SConscript", variant_dir='scons_build/libEXEIO') +#libbea=SConscript("beaengine/SConscript", variant_dir='scons_build/beaengine') + +libMEDSannotation=SConscript("libMEDSannotation/SConscript", variant_dir='scons_build/libMEDSannotation') +# libxform=SConscript("xform/SConscript", variant_dir='scons_build/libxform') +# libIRDB=SConscript("libIRDB/SConscript", variant_dir='scons_build/libIRDB') +# Depends(libIRDB,libcapstone) +libStructDiv=SConscript("libStructDiv/SConscript", variant_dir='scons_build/libStructDiv') +thanos=SConscript("thanos/SConscript", variant_dir='scons_build/thanos') +rida=SConscript("rida/SConscript", variant_dir='scons_build/rida') +meds2pdb=SConscript("meds2pdb/SConscript", variant_dir='scons_build/meds2pdb') +dump_map=SConscript("dump_map/SConscript", variant_dir='scons_build/dump_map') +dump_insns=SConscript("dump_insns/SConscript", variant_dir='scons_build/dump_insns') +ir_builders=SConscript("ir_builders/SConscript", variant_dir='scons_build/ir_builders') + + +# no more tools in irdb-libs +#tools=None +#if 'build_tools' not in env or env['build_tools'] is None or int(env['build_tools']) == 1: +# tools=SConscript("tools/SConscript", variant_dir='scons_build/tools') +# if "PEDI_HOME" in os.environ: +# Depends(pedi,tools) + +libs=( libIRDBcore, + libIRDBcfg, + libIRDButil, + libIRDBcore, + libehp, + libtransform, + libEXEIO, + libMEDSannotation, + libStructDiv, + libElfDep, + libcapstone, + thanos, + rida, + meds2pdb, + dump_map, + dump_insns, + ir_builders) + +if "PEDI_HOME" in os.environ: + Depends(pedi, libs) + Default( pedi ) + Return('pedi') +else: + + Default(libIRDBcore, libIRDBcfg, libIRDButil, libIRDBdeep, libIRDBcore, libehp,libtransform,libEXEIO,libMEDSannotation,libStructDiv,libElfDep, libcapstone, thanos, rida, meds2pdb, dump_map, dump_insns, ir_builders) + diff --git a/irdb-lib/SConscript.deep b/irdb-lib/SConscript.deep new file mode 100644 index 0000000000000000000000000000000000000000..93a9b58dfe7cccc9438a77ce455f05072efb0fd2 --- /dev/null +++ b/irdb-lib/SConscript.deep @@ -0,0 +1,16 @@ +import os + +Import('env') + +pedi = Command( target = "./testoutput", + source = "./SConscript", + action = os.environ['PEDI_HOME']+"/pedi -m manifest.txt " ) + +env['BASE_IRDB_LIBS']="irdb-core", "pqxx", "pq" + +libIRDBdeep=env.SConscript("libIRDB-deep/src/SConscript", variant_dir='scons_build/libIRDB-deep') + +Depends(pedi, libIRDBdeep) +Default( pedi ) + +Return('pedi') diff --git a/irdb-lib/SConstruct b/irdb-lib/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..870baa527ce66caecdc36b2238b51008d243520b --- /dev/null +++ b/irdb-lib/SConstruct @@ -0,0 +1,77 @@ +import os +import sys + + + +(sysname, nodename, release, version, machine)=os.uname() + +env=Environment() + + +# default build options +env.Replace(CFLAGS="-fPIC -fmax-errors=2 -Wall -Werror -fmax-errors=2") +env.Replace(CXXFLAGS="-fPIC -fmax-errors=2 -Wall -Werror -fmax-errors=2 ") +env.Replace(LINKFLAGS="-fPIC -fmax-errors=2 -Wall -Werror -fmax-errors=2 ") + +# parse arguments into env and set default values. +env.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) +env.Replace(IRDB_SDK=os.environ['IRDB_SDK']) +env.Replace(SMPSA_HOME=os.environ['SMPSA_HOME']) +env.Replace(do_64bit_build=ARGUMENTS.get("do_64bit_build",None)) +env.Replace(debug=ARGUMENTS.get("debug",0)) +env.Replace(build_deep=ARGUMENTS.get("build_deep", 0)) +env.Replace(build_tools=ARGUMENTS.get("build_tools", 1)) +env.Replace(build_stars=ARGUMENTS.get("build_stars", 1)) +env.Replace(build_cgc=ARGUMENTS.get("build_cgc", 0)) + +if 'PEDI_HOME' in os.environ: + env.Replace(PEDI_HOME=os.environ['PEDI_HOME']) + +env.Append(LINKFLAGS=" -Wl,-unresolved-symbols=ignore-in-shared-libs ") + +if int(env['debug']) == 1: + print "Setting debug mode" + env.Append(CFLAGS=" -g ") + env.Append(CXXFLAGS=" -g ") + env.Append(LINKFLAGS=" -g ") + env.Append(SHLINKFLAGS=" -g ") +else: + print "Setting release mode" + env.Append(CFLAGS=" -O3 ") + env.Append(CXXFLAGS=" -O3 ") + env.Append(LINKFLAGS=" -O3 ") + env.Append(SHLINKFLAGS=" -O3 ") + +# set 32/64 bit build properly +print "env[64bit]="+str(env['do_64bit_build']) +if env['do_64bit_build'] is None: + print 'Defaulting to default compilation size.' +elif int(env['do_64bit_build']) == 1: + print 'Using 64-bit compilation size.' + env.Append(CFLAGS=" -m64 ") + env.Append(CXXFLAGS=" -m64 ") + env.Append(LINKFLAGS=" -m64 ") + env.Append(SHLINKFLAGS=" -m64 ") +else: + print 'Using 32-bit compilation size.' + env.Append(CFLAGS=" -m32 ") + env.Append(CXXFLAGS=" -m32 ") + env.Append(LINKFLAGS=" -m32 ") + env.Append(SHLINKFLAGS=" -m32 ") + + + +# add extra flag for solaris. +if sysname == "SunOS": + env.Append(LINKFLAGS=" -L/opt/csw/lib -DSOLARIS ") + env.Append(SHLINKFLAGS=" -L/opt/csw/lib -DSOLARIS ") + env.Append(CFLAGS=" -I/opt/csw/include -DSOLARIS ") + env.Append(CXXFLAGS=" -I/opt/csw/include -DSOLARIS ") + + +Export('env') +if int(env['build_deep']) == 1: + SConscript("SConscript.deep", variant_dir='build') +else: + SConscript("SConscript", variant_dir='build') + diff --git a/irdb-lib/bin/.ignore b/irdb-lib/bin/.ignore new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/irdb-lib/cicd_tests/do-build.sh b/irdb-lib/cicd_tests/do-build.sh new file mode 100755 index 0000000000000000000000000000000000000000..facd61a68834f2eb43e8882cd2fcbe27da134fb3 --- /dev/null +++ b/irdb-lib/cicd_tests/do-build.sh @@ -0,0 +1,40 @@ +#/bin/bash + +set -e +set -x + +main() +{ + + # gather info for debugging later, probably not necessary + pwd + hostname + whoami + env|grep "^CICD" + + git submodule sync + git submodule update --init --recursive + + local orig_dir=$(pwd) + + # puts irdblibs_umbrella (and all submodules) in CICD_MODULE_WORK_DIR + cicd_setup_module_dependency allnp/peasoup_umbrella.git irdblibs_umbrella + + + # puts the version of irdb-libs to test in irdblibs_umbrella/irdb-libs + cicd_put_module_in_tree irdblibs_umbrella/irdb-libs + + # Build/run $PSZ, test result + cd $CICD_MODULE_WORK_DIR/irdblibs_umbrella + source set_env_vars + sudo ./get-peasoup-packages.sh all + + # remove pedi files so that rebuilding includes re-doing pedi setup. + $PEDI_HOME/pedi -c -m manifest.txt || true # ignore errors in cleanup + ./build-all.sh + dropdb $PGDATABASE 2>/dev/null || true ; ./postgres_setup.sh + + cd $orig_dir +} + +main "$@" diff --git a/irdb-lib/cicd_tests/do-clean.sh b/irdb-lib/cicd_tests/do-clean.sh new file mode 100755 index 0000000000000000000000000000000000000000..940af5a554ef70271942e838f8cecd03e1859922 --- /dev/null +++ b/irdb-lib/cicd_tests/do-clean.sh @@ -0,0 +1,22 @@ +#/bin/bash + +set -e +set -x + +main() +{ + + # gather info for debugging later, probably not necessary + pwd + hostname + whoami + env|grep "^CICD" + + + if [[ $CICD_NIGHTLY == 1 ]] ; then + rm -rf $CICD_MODULE_WORK_DIR/irdblibs_umbrella + fi + +} + +main "$@" diff --git a/irdb-lib/cicd_tests/elfdep.sh b/irdb-lib/cicd_tests/elfdep.sh new file mode 100755 index 0000000000000000000000000000000000000000..81c3f7840af9d48a5ce27729e1df89d45cd6ca1e --- /dev/null +++ b/irdb-lib/cicd_tests/elfdep.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -e +set -x + +cd $CICD_MODULE_WORK_DIR/irdblibs_umbrella +source set_env_vars + +cd $SECURITY_TRANSFORMS_HOME/libIRDB-elfdep/test/ +./test-elfdep.sh diff --git a/irdb-lib/cicd_tests/test_fib.sh b/irdb-lib/cicd_tests/test_fib.sh new file mode 100755 index 0000000000000000000000000000000000000000..f2e487cd70d6b4058085e5dfd586d165010c9644 --- /dev/null +++ b/irdb-lib/cicd_tests/test_fib.sh @@ -0,0 +1,127 @@ +#!/bin/bash + +set -e +trap clean EXIT + +cd $CICD_MODULE_WORK_DIR/irdblibs_umbrella +source set_env_vars +cd ./irdb-libs/tools/selective_cfi/tests/cicd_tests/fib_src + +source ../../cfi_smokescreen_configs.sh + +get_correct() +{ + cp libfib.so.orig libfib.so + cp libfib2.so.orig libfib2.so + # for fib.exe, a non-zero exit status can indicate success + set +e + ./fib.exe $1 > correct + echo $? >> correct + set -e +} + +do_test() +{ + echo running test $1 $2 $3 $4 + + n=$2 + + get_correct $n + + cp $3 libfib.so + cp $4 libfib2.so + # for fib.exe, a non-zero exit status can indicate success + set +e + ./$1 $n > out + echo $? >> out + + + cmp out correct + res=$? + if [[ $res != 0 ]]; then + echo "detected output diff:" + diff out correct + exit 1 + fi + + set -e +} + + +build() +{ + gcc -o libfib.so libfib.c -w -shared -fPIC + gcc -o libfib2.so libfib2.c -w -shared -fPIC + gcc -o fib.exe fib.c -w -L. -lfib -lfib2 + gcc -o fib.exe.pie fib.c -fPIC -fpie -pie -w -L. -lfib -lfib2 + mv libfib.so libfib.so.orig + mv libfib2.so libfib2.so.orig +} + + +protect() +{ + files=(libfib.so.orig libfib2.so.orig fib.exe fib.exe.pie) + + libfib_so_orig_varients=(libfib.so.orig) + libfib2_so_orig_varients=(libfib2.so.orig) + fib_exe_varients=(fib.exe) + fib_exe_pie_varients=(fib.exe.pie) + + for file in "${files[@]}"; do + for config in "${configs[@]}"; do + echo Protecting file "$file" with config "$config" + set +e + "$config" ./"$file" ./"$file"".""$config" > out 2>&1 + res=$? + set -e + if [[ $res == 0 ]]; then + rm -rf out peasoup* + else + echo "Failed protection!" + cat out peasoup*/logs/* + exit 1 + fi + varient_array_name="$(echo "$file" | sed -e 's/\./_/g')""_varients" + varient_file="$file"".""$config" + eval $varient_array_name+=\(\$varient_file\) + done + done +} + +clean() +{ + local ec=$? + rm -f out >> /dev/null 2>&1 + rm -f correct >> /dev/null 2>&1 + rm -Rf fib.exe* peasoup_exe* lib*.so* >> /dev/null 2>&1 + + for config in "${configs[@]}"; do + rm -f *."$config" >> /dev/null 2>&1 + done + exit $ec +} + + +main() +{ + build + protect + + fib_varients=("${fib_exe_varients[@]}" "${fib_exe_pie_varients[@]}") + + for fib_varient in "${fib_varients[@]}"; do + for libfib_varient in "${libfib_so_orig_varients[@]}"; do + for libfib2_varient in "${libfib2_so_orig_varients[@]}"; do + for i in 2 6; do + do_test "$fib_varient" $i "$libfib_varient" "$libfib2_varient" + done + done + done + done + + exit 0 +} + + +main $* diff --git a/irdb-lib/cicd_tests/test_foo.sh b/irdb-lib/cicd_tests/test_foo.sh new file mode 100755 index 0000000000000000000000000000000000000000..77ae98d69679c6db8cf424ce674b6904bcb373b3 --- /dev/null +++ b/irdb-lib/cicd_tests/test_foo.sh @@ -0,0 +1,129 @@ +#!/bin/bash + +set -e +trap clean EXIT + +cd $CICD_MODULE_WORK_DIR/irdblibs_umbrella +source set_env_vars +cd ./irdb-libs/tools/selective_cfi/tests/cicd_tests/foo_src + +source ../../cfi_smokescreen_configs.sh + +get_correct() +{ + cp libfoo.so.orig libfoo.so + ./foo.exe > correct + echo $? >> correct +} + +do_test() +{ + echo Running test: "$1" "$2" + + set +e + cp $2 libfoo.so + ./$1 > out + echo $? >> out + + cmp out correct + res=$? + if [[ $res != 0 ]]; then + echo "detected output diff:" + diff out correct + exit 1 + fi + set -e + +} + + +build() +{ + gcc -o libfoo.so libfoo.c -w -shared -fPIC + gcc -o foo.exe foo.c -w -L. -lfoo + mv libfoo.so libfoo.so.orig + + gcc -o libfoo.O.so libfoo.c -O -w -shared -fPIC + gcc -o libfoo.O2.so libfoo.c -O2 -w -shared -fPIC + gcc -o libfoo.O3.so libfoo.c -O3 -w -shared -fPIC + gcc -o libfoo.Os.so libfoo.c -Os -w -shared -fPIC + mv libfoo.O.so libfoo.O.so.orig + mv libfoo.O2.so libfoo.O2.so.orig + mv libfoo.O3.so libfoo.O3.so.orig + mv libfoo.Os.so libfoo.Os.so.orig +} + + +protect() +{ + files=(foo.exe libfoo.so.orig libfoo.O.so.orig libfoo.O2.so.orig libfoo.O3.so.orig libfoo.Os.so.orig) + + foo_exe_varients=(foo.exe) + libfoo_so_orig_varients=(libfoo.so.orig) + libfoo_O_so_orig_varients=(libfoo.O.so.orig) + libfoo_O2_so_orig_varients=(libfoo.O2.so.orig) + libfoo_O3_so_orig_varients=(libfoo.O3.so.orig) + libfoo_Os_so_orig_varients=(libfoo.Os.so.orig) + + for file in "${files[@]}"; do + for config in "${configs[@]}"; do + echo Protecting file "$file" with config "$config" + set -e + "$config" ./"$file" ./"$file"".""$config" > ps.log 2>&1 + res=$? + set +e + if [[ $res != 0 ]]; then + echo "Failed to xform!" + cat peasoup*/logs/* + exit 1 + else + rm -Rf peasoup* + fi + + varient_array_name="$(echo "$file" | sed -e 's/\./_/g')""_varients" + varient_file="$file"".""$config" + eval $varient_array_name+=\(\$varient_file\) + done + done + +} + +clean() +{ + local ec=$? + rm -f out >> /dev/null 2&>1 + rm -f correct >> /dev/null 2&>1 + rm -rf peasoup_executable_directory.* >> /dev/null 2&>1 + rm -f *.orig >> /dev/null 2&>1 + rm -f *.exe >> /dev/null 2&>1 + rm -f *.so >> /dev/null 2&>1 + + for config in "${configs[@]}"; do + rm -f *."$config" >> /dev/null 2&>1 + done + + exit $ec +} + + +main() +{ + build + protect + get_correct + + libfoo_varients=("${libfoo_so_orig_varients[@]}" "${libfoo_O_so_orig_varients[@]}" "${libfoo_O2_so_orig_varients[@]}" + "${libfoo_O3_so_orig_varients[@]}" "${libfoo_Os_so_orig_varients[@]}") + + + for foo_varient in "${foo_exe_varients[@]}"; do + for libfoo_varient in "${libfoo_varients[@]}"; do + do_test "$foo_varient" "$libfoo_varient" + done + done + + exit 0 +} + + +main $* diff --git a/irdb-lib/cicd_tests/xform-cat.sh b/irdb-lib/cicd_tests/xform-cat.sh new file mode 100755 index 0000000000000000000000000000000000000000..4ee04a86db0c6c2776626dcd25414d00915e3089 --- /dev/null +++ b/irdb-lib/cicd_tests/xform-cat.sh @@ -0,0 +1,11 @@ +cd $CICD_MODULE_WORK_DIR/irdblibs_umbrella + +set -e +set -x + +source set_env_vars +cd /tmp +rm -rf cat.rida ped_cat; +$PSZ $(which cat) ./cat.rida -c rida=on -s meds_static=off -c p1transform=on --tempdir ped_cat || true +if [[ ! -x ./cat.rida ]]; then cat ped_cat/logs/*; fi +./cat.rida /dev/null diff --git a/irdb-lib/cicd_tests/xform-ls.sh b/irdb-lib/cicd_tests/xform-ls.sh new file mode 100755 index 0000000000000000000000000000000000000000..f31df7b4023e81619efa86fb57d12b6574b5664d --- /dev/null +++ b/irdb-lib/cicd_tests/xform-ls.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -e +set -x + +cd $CICD_MODULE_WORK_DIR/irdblibs_umbrella +source set_env_vars +cd /tmp +rm -rf ls.rida ped_ls +$PSZ /bin/ls ./ls.rida -c rida=on -s meds_static=off -c p1transform=on --tempdir ped_ls || true +if [[ ! -x ./ls.rida ]]; then cat ped_ls/logs/*; fi +rm -rf ped_ls +./ls.rida diff --git a/irdb-lib/dump_insns/Makefile.in b/irdb-lib/dump_insns/Makefile.in new file mode 100644 index 0000000000000000000000000000000000000000..521dc2c07323f832d457aae0085a8e59c89f1858 --- /dev/null +++ b/irdb-lib/dump_insns/Makefile.in @@ -0,0 +1,42 @@ + + +PROGS=fix_rets.exe + +CXX=@CXX@ +CXXFLAGS= +INCLUDE=-I. -I../include -I../xform -I../../beaengine/include -I../../libIRDB/include/ -I../../libMEDSannotation/include/ -I../libtransform/include/ -I../transforms +CXXFLAGS= @EXTRA_CXXFLAGS@ $(INCLUDE) -Wall +LIBS=-L../../lib -lxform -lIRDB-core -lIRDB-cfg -lBeaEngine_s_d -lpqxx -lMEDSannotation -ltransform -lpq + + +OBJS=fix_rets.o fix_rets_driver.o +programs=fix_rets.exe + +.SUFFIXES: .o .c .exe .cpp .hpp + +all: $(programs) + @echo "---------------------------------------------" + @echo "- Fix Rets directory -- Build complete -" + @echo "---------------------------------------------" + + +-include $(OBJS:.o=.d) + +%.o: %.cpp + $(CXX) -c $(CXXFLAGS) $*.cpp + @# + @# build dependencies -- http://scottmcpeak.com/autodepend/autodepend.html + @# + @cpp -M $(CXXFLAGS) $*.cpp > $*.d || true + @cp -f $*.d $*.d.tmp + @sed -e 's/.*://' -e 's/\\$$//' < $*.d.tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $*.d + @rm -f $*.d.tmp + +clean: + rm -f *.o core *.exe + +$(programs): ../../lib/*.a + +fix_rets.exe: $(OBJS) + $(CXX) $(CXXFLAGS) $^ $(INCLUDE) $(LIBS) -o $@ + diff --git a/irdb-lib/dump_insns/SConscript b/irdb-lib/dump_insns/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..a087b1bb3ea468eecca4f5a555bbbcce1f73306d --- /dev/null +++ b/irdb-lib/dump_insns/SConscript @@ -0,0 +1,28 @@ +import os + + + +Import('env') +myenv=env.Clone() +myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) + +cpppath=''' + $IRDB_SDK/include + ''' + + +files=Glob( Dir('.').srcnode().abspath+"/*.cpp") + +myenv.Append(CPPFLAGS="-std=c++11") + + +pgm="dump_insns.exe" + +LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" +LIBS=Split( env.subst('$BASE_IRDB_LIBS')+ " irdb-cfg irdb-util irdb-transform ") +myenv=myenv.Clone(CPPPATH=Split(cpppath)) +pgm=myenv.Program(pgm, files, LIBPATH=LIBPATH, LIBS=LIBS) +#install=myenv.Install("$SECURITY_TRANSFORMS_HOME/bin/", pgm) +install=myenv.Install("$SECURITY_TRANSFORMS_HOME/plugins_install/", pgm) +Default(install) +Return('install') diff --git a/irdb-lib/dump_insns/SConstruct b/irdb-lib/dump_insns/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..17f632b8c29cd420163897b1eb044ca3486df362 --- /dev/null +++ b/irdb-lib/dump_insns/SConstruct @@ -0,0 +1,7 @@ + + + +env=Environment() +Export('env') +install=SConscript("SConscript") +Return('install') diff --git a/irdb-lib/dump_insns/dump_insns.cpp b/irdb-lib/dump_insns/dump_insns.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a51b71f075f94bcbf23ab525dc336ecce1c1d2f5 --- /dev/null +++ b/irdb-lib/dump_insns/dump_insns.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2014, 2015 - University of Virginia + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#include <stdlib.h> +#include <fstream> +#include <irdb-core> +#include <libgen.h> +#include <iomanip> +#include <algorithm> + + +using namespace std; +using namespace IRDB_SDK; + +void usage(char* name) +{ + cerr<<"Usage: "<<name<<" <variant_id>\n"; +} + + + +int main(int argc, char **argv) +{ + if(argc != 2) + { + usage(argv[0]); + exit(1); + } + + + string programName(argv[0]); + int variantID = atoi(argv[1]); + + + /* setup the interface to the sql server */ + auto pqxx_interface=pqxxDB_t::factory(); + BaseObj_t::setInterface(pqxx_interface.get()); + + auto pidp=VariantID_t::factory(variantID); + assert(pidp->isRegistered()==true); + + + + bool one_success = false; + for(set<File_t*>::iterator it=pidp->getFiles().begin(); + it!=pidp->getFiles().end(); + ++it) + { + File_t* this_file = *it; + try + { + auto firp = FileIR_t::factory(pidp.get(), this_file); + + assert(firp && pidp); + + for(auto insn : firp->getInstructions()) + { + assert(insn); + const auto p_d=DecodedInstruction_t::factory(insn); + const auto &d=*p_d; + const auto &operands=d.getOperands(); + + cout<<" "<<d.getDisassembly()<<endl; + int op_count=0; + for(const auto p_op : operands) + { + const auto &op=*p_op; + auto readWriteString= string(); + if(op.isRead()) readWriteString += "READ "; + if(op.isWritten()) readWriteString += "WRITE "; + + cout<<"\t"<<"operand["<<op_count<<"]="<<op.getString() << boolalpha + <<" rw=" <<readWriteString + <<" isGPReg="<<op.isGeneralPurposeRegister() + <<" isMem=" <<op.isMemory() + <<" isImm=" <<op.isConstant() + <<" isPcrel="<<op.isPcrel() + << endl; + + op_count++; + } + + + } + + + + } + catch (DatabaseError_t pnide) + { + cerr << programName << ": Unexpected database error: " << pnide << "file url: " << this_file->getURL() << endl; + } + catch (...) + { + cerr << programName << ": Unexpected error file url: " << this_file->getURL() << endl; + } + } // end file iterator + + // if any integer transforms for any files succeeded, we commit + if (one_success) + { + cout<<"Commiting changes...\n"; + pqxx_interface->commit(); + } + + return 0; +} + diff --git a/irdb-lib/dump_map/Makefile.in b/irdb-lib/dump_map/Makefile.in new file mode 100644 index 0000000000000000000000000000000000000000..521dc2c07323f832d457aae0085a8e59c89f1858 --- /dev/null +++ b/irdb-lib/dump_map/Makefile.in @@ -0,0 +1,42 @@ + + +PROGS=fix_rets.exe + +CXX=@CXX@ +CXXFLAGS= +INCLUDE=-I. -I../include -I../xform -I../../beaengine/include -I../../libIRDB/include/ -I../../libMEDSannotation/include/ -I../libtransform/include/ -I../transforms +CXXFLAGS= @EXTRA_CXXFLAGS@ $(INCLUDE) -Wall +LIBS=-L../../lib -lxform -lIRDB-core -lIRDB-cfg -lBeaEngine_s_d -lpqxx -lMEDSannotation -ltransform -lpq + + +OBJS=fix_rets.o fix_rets_driver.o +programs=fix_rets.exe + +.SUFFIXES: .o .c .exe .cpp .hpp + +all: $(programs) + @echo "---------------------------------------------" + @echo "- Fix Rets directory -- Build complete -" + @echo "---------------------------------------------" + + +-include $(OBJS:.o=.d) + +%.o: %.cpp + $(CXX) -c $(CXXFLAGS) $*.cpp + @# + @# build dependencies -- http://scottmcpeak.com/autodepend/autodepend.html + @# + @cpp -M $(CXXFLAGS) $*.cpp > $*.d || true + @cp -f $*.d $*.d.tmp + @sed -e 's/.*://' -e 's/\\$$//' < $*.d.tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $*.d + @rm -f $*.d.tmp + +clean: + rm -f *.o core *.exe + +$(programs): ../../lib/*.a + +fix_rets.exe: $(OBJS) + $(CXX) $(CXXFLAGS) $^ $(INCLUDE) $(LIBS) -o $@ + diff --git a/irdb-lib/dump_map/SConscript b/irdb-lib/dump_map/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..8eaf74bbfcb93d2087ada4d39f0a731348dc235e --- /dev/null +++ b/irdb-lib/dump_map/SConscript @@ -0,0 +1,28 @@ +import os + + + +Import('env') +myenv=env.Clone() +myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) + +cpppath=''' + $IRDB_SDK/include + ''' + + +files=Glob( Dir('.').srcnode().abspath+"/*.cpp") + +myenv.Append(CPPFLAGS="-std=c++11") + + +pgm="dump_map.exe" + +LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" +LIBS=Split( env.subst('$BASE_IRDB_LIBS')+ " irdb-cfg irdb-util irdb-transform ") +myenv=myenv.Clone(CPPPATH=Split(cpppath)) +pgm=myenv.Program(pgm, files, LIBPATH=LIBPATH, LIBS=LIBS) +#install=myenv.Install("$SECURITY_TRANSFORMS_HOME/bin/", pgm) +install=myenv.Install("$SECURITY_TRANSFORMS_HOME/plugins_install/", pgm) +Default(install) +Return('install') diff --git a/irdb-lib/dump_map/SConstruct b/irdb-lib/dump_map/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..17f632b8c29cd420163897b1eb044ca3486df362 --- /dev/null +++ b/irdb-lib/dump_map/SConstruct @@ -0,0 +1,7 @@ + + + +env=Environment() +Export('env') +install=SConscript("SConscript") +Return('install') diff --git a/irdb-lib/dump_map/dump_map.cpp b/irdb-lib/dump_map/dump_map.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e9d996a857e6f293119a16e8fc91d29df6f2847c --- /dev/null +++ b/irdb-lib/dump_map/dump_map.cpp @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2014, 2015 - University of Virginia + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#include <stdlib.h> +#include <fstream> +#include <irdb-core> +#include <libgen.h> +#include <iomanip> +#include <algorithm> + + +using namespace std; +using namespace IRDB_SDK; + +void usage(char* name) +{ + cerr<<"Usage: "<<name<<" <variant_id>\n"; +} + + +void dump_icfs(Instruction_t* insn) +{ + if(insn->getIBTargets()==NULL) + return; + + cout<<"\tComplete: "<<boolalpha<<insn->getIBTargets()->isComplete()<<endl; + cout<<"\tModComplete: "<<boolalpha<<insn->getIBTargets()->isModuleComplete()<<endl; + cout<<"\tTargets: "<<endl; + for_each(insn->getIBTargets()->begin(), insn->getIBTargets()->end(), [&](const Instruction_t* targ) + { + const auto d=DecodedInstruction_t::factory(targ); + cout<<"\t"<<targ->getBaseID()<<":"<<d->getDisassembly()<<endl; + }); +} + +int main(int argc, char **argv) +{ + if(argc != 2) + { + usage(argv[0]); + exit(1); + } + + auto dump_icfs_flag=(DatabaseID_t)BaseObj_t::NOT_IN_DATABASE; + auto dump_icfs_str=getenv("DUMP_ICFS"); + if(dump_icfs_str) + dump_icfs_flag=(DatabaseID_t)strtoull(dump_icfs_str,NULL,0); + + + string programName(argv[0]); + int variantID = atoi(argv[1]); + + /* setup the interface to the sql server */ + auto pqxx_interface=pqxxDB_t::factory(); + BaseObj_t::setInterface(pqxx_interface.get()); + + auto pidp=VariantID_t::factory(variantID); + assert(pidp->isRegistered()==true); + + + + bool one_success = false; + for(set<File_t*>::iterator it=pidp->getFiles().begin(); + it!=pidp->getFiles().end(); + ++it) + { + File_t* this_file = *it; + try + { + auto firp = FileIR_t::factory(pidp.get(), this_file); + + cout<<"file: "<<this_file->getURL()<<endl; + cout<<setw(9)<<"ID"<<" " + <<setw(10)<<"Addr."<<" " + <<setw(10)<<"IBTA"<<" " + <<setw(9)<<"FT ID"<<" " + <<setw(9)<<"TargID"<<" " + <<setw(9)<<"Func"<<" " + <<"Disassembly"<< endl; + + assert(firp && pidp); + + for(auto it=firp->getInstructions().begin(); it!=firp->getInstructions().end(); ++it) + { + Instruction_t* insn=*it; + assert(insn); + cout<<hex<<setw(9)<<insn->getBaseID()<<" "<<hex<<setw(10)<<insn->getAddress()->getVirtualOffset(); + + cout<<" "<<hex<<setw(10)<< + (insn->getIndirectBranchTargetAddress() ? + insn->getIndirectBranchTargetAddress()->getVirtualOffset() : + 0 + ) + <<" "; + cout<<hex<<setw(9)<<(insn->getFallthrough() ? insn->getFallthrough()->getBaseID() : -1) << " "; + cout<<hex<<setw(9)<<(insn->getTarget() ? insn->getTarget()->getBaseID() : -1) << " "; + if(insn->getFunction() && insn->getFunction()->getEntryPoint()) + cout<<hex<<setw(9)<<insn->getFunction()->getEntryPoint()->getBaseID(); + else + cout<<setw(9)<<"NoFunc"; + + const auto d=DecodedInstruction_t::factory(insn); + cout<<" "<<d->getDisassembly()<<"("<<insn->getComment()<<")"<<endl; + + if(dump_icfs_flag == insn->getBaseID()) + dump_icfs(insn); + } + + + + } + catch (DatabaseError_t pnide) + { + cerr << programName << ": Unexpected database error: " << pnide << "file url: " << this_file->getURL() << endl; + } + catch (...) + { + cerr << programName << ": Unexpected error file url: " << this_file->getURL() << endl; + } + } // end file iterator + + // if any integer transforms for any files succeeded, we commit + if (one_success) + { + cout<<"Commiting changes...\n"; + pqxx_interface->commit(); + } + + return 0; +} + diff --git a/irdb-lib/ir_builders/SConscript b/irdb-lib/ir_builders/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..fb5eba73a4c74fbaf7a37657916c11e30cb6f271 --- /dev/null +++ b/irdb-lib/ir_builders/SConscript @@ -0,0 +1,64 @@ +import os + + + +Import('env') +myenv=env.Clone() +myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) + +installed=[] + +if 'build_tools' not in myenv or myenv['build_tools'] is None or int(myenv['build_tools']) == 1: + + cpppath=''' + $IRDB_SDK/include + $SECURITY_TRANSFORMS_HOME/libEXEIO/include + $SECURITY_TRANSFORMS_HOME/libehp/include + $SECURITY_TRANSFORMS_HOME/libMEDSannotation/include/ + $SECURITY_TRANSFORMS_HOME/third_party/elfio-code + ''' + + LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" + LIBS=Split( 'irdb-cfg irdb-util ' + env.subst('$BASE_IRDB_LIBS')+ " ehp irdb-transform MEDSannotation EXEIO") + + myenv=myenv.Clone(CPPPATH=Split(cpppath)) + + myenv.Append(CCFLAGS=" -std=c++11 -Wall") + + ehframe=myenv.SharedObject("read_ehframe.cpp"); + split_eh_frame=myenv.SharedObject("split_eh_frame.cpp"); + + pgm=myenv.SharedLibrary("fill_in_indtargs.so", ehframe+split_eh_frame+Split("fill_in_indtargs.cpp check_thunks.cpp"), LIBPATH=LIBPATH, LIBS=LIBS) + install=myenv.Install("$SECURITY_TRANSFORMS_HOME/plugins_install", pgm) + Default(install) + installed=installed+install + + pgm=myenv.SharedLibrary("fill_in_cfg.so", Split("fill_in_cfg.cpp")+split_eh_frame, LIBPATH=LIBPATH, LIBS=LIBS) + install=myenv.Install("$SECURITY_TRANSFORMS_HOME/plugins_install", pgm) + Default(install) + installed=installed+install + + pgm=myenv.SharedLibrary("fix_calls.so", ehframe+Split("fix_calls.cpp"), LIBPATH=LIBPATH, LIBS=LIBS) + install=myenv.Install("$SECURITY_TRANSFORMS_HOME/plugins_install", pgm) + Default(install) + installed=installed+install + + # most programs go to $sectrans/bin + pgms='''clone + ''' + for i in Split(pgms): + # print "Registering pgm: "+ i + pgm=myenv.Program(target=i+".exe", source=Split(i+".cpp"), LIBPATH=LIBPATH, LIBS=LIBS) + install=myenv.Install("$SECURITY_TRANSFORMS_HOME/plugins_install/", pgm) + Default(install) + installed=installed+install + + + # ilr goes to $sectrans/plugins_install + # pgm=myenv.Program(target="ilr.exe", source=Split("ilr.cpp"), LIBPATH=LIBPATH, LIBS=LIBS) + # install=myenv.Install("$SECURITY_TRANSFORMS_HOME/plugins_install/", pgm) + # Default(install) + # installed=installed+install + +Return('installed') + diff --git a/irdb-lib/ir_builders/SConstruct b/irdb-lib/ir_builders/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..b5b7b78c5f88640c7e8877a9df76dc9191af7498 --- /dev/null +++ b/irdb-lib/ir_builders/SConstruct @@ -0,0 +1,8 @@ + + + +env=Environment() +Export('env') +lib=SConscript("SConscript") + +Return('lib') diff --git a/irdb-lib/ir_builders/build_callgraph.cpp b/irdb-lib/ir_builders/build_callgraph.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a0ca36f7209ae516387bcc5893e81674ac06714b --- /dev/null +++ b/irdb-lib/ir_builders/build_callgraph.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + + +#include <irdb=-sdk> +#include <irdb-cfg> +#include <utils.hpp> // to_string function from libIRDB +#include <iostream> +#include <fstream> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +using namespace std; + +// +// main routine to build and print a call graph. +// +main(int argc, char* argv[]) +{ + if(argc!=2) + { + cerr<<"Usage: "<<argv[0]<<" <variant id> "<<endl; + exit(-1); + } + + string filename; + ostream *fout; + fout=&cout; + + + VariantID_t *varidp=NULL; + FileIR_t *firp=NULL; + + /* setup the interface to the sql server */ + pqxxDB_t pqxx_interface; + BaseObj_t::SetInterface(&pqxx_interface); + + try + { + + cerr<<"Looking up variant "<<string(argv[1])<<" from database." << endl; + varidp=new VariantID_t(atoi(argv[1])); + + // A callgraph + auto cg=Callgraph_t::factory(); + + assert(varidp->IsRegistered()==true); + + + for(set<File_t*>::iterator it=varidp->GetFiles().begin(); + it!=varidp->GetFiles().end(); + ++it + ) + { + File_t* this_file=*it; + assert(this_file); + cerr<<"Reading variant "<<string(argv[1])<<":"<<this_file->GetURL() + <<" from database." << endl; + + // read the db + firp=new FileIR_t(*varidp,this_file); + + // ILR only for the main file. + cg->AddFile(firp); + } + + cg->Dump(*fout); + + } + catch (DatabaseError_t pnide) + { + cerr<<"Unexpected database error: "<<pnide<<endl; + exit(-1); + } + + cerr<<"Done!"<<endl; + + if(fout!=&cout) + ((ofstream*)fout)->close(); + + + delete varidp; +} + + diff --git a/irdb-lib/ir_builders/build_preds.cpp b/irdb-lib/ir_builders/build_preds.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ae87ac7dc1639cc39f7afb84fafcd993e0ab2c82 --- /dev/null +++ b/irdb-lib/ir_builders/build_preds.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + + +#include <libIRDB-core.hpp> +#include <libIRDB-util.hpp> +#include <utils.hpp> // to_string function from libIRDB +#include <iostream> +#include <fstream> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +using namespace libIRDB; +using namespace std; + +// +// main routine to build and print a call graph. +// +int main(int argc, char* argv[]) +{ + if(argc!=2) + { + cerr<<"Usage: "<<argv[0]<<" <variant id> "<<endl; + exit(-1); + } + + string filename; + ostream *fout; + fout=&cout; + + + VariantID_t *varidp=NULL; + FileIR_t *firp=NULL; + + /* setup the interface to the sql server */ + pqxxDB_t pqxx_interface; + BaseObj_t::SetInterface(&pqxx_interface); + + try + { + + cerr<<"Looking up variant "<<string(argv[1])<<" from database." << endl; + varidp=new VariantID_t(atoi(argv[1])); + + // A callgraph + InstructionPredecessors_t *ip=new InstructionPredecessors_t; + + assert(varidp->IsRegistered()==true); + + + for(set<File_t*>::iterator it=varidp->GetFiles().begin(); + it!=varidp->GetFiles().end(); + ++it + ) + { + File_t* this_file=*it; + assert(this_file); + cerr<<"Reading variant "<<string(argv[1])<<":"<<this_file->GetURL() + <<" from database." << endl; + + // read the db + firp=new FileIR_t(*varidp,this_file); + + // ILR only for the main file. + ip->AddFile(firp); + } + + + } + catch (DatabaseError_t pnide) + { + cerr<<"Unexpected database error: "<<pnide<<endl; + exit(-1); + } + + cerr<<"Done!"<<endl; + + if(fout!=&cout) + ((ofstream*)fout)->close(); + + + delete varidp; + + return 0; +} + + diff --git a/irdb-lib/ir_builders/calc_conflicts.cpp b/irdb-lib/ir_builders/calc_conflicts.cpp new file mode 100644 index 0000000000000000000000000000000000000000..15dd95ead800f405a927cc48f0c4347cb866f821 --- /dev/null +++ b/irdb-lib/ir_builders/calc_conflicts.cpp @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + + +#include <libIRDB-core.hpp> +#include <iostream> +#include <stdlib.h> +#include <string.h> +#include <map> +#include <assert.h> +#include <elf.h> +#include <sys/mman.h> +#include <ctype.h> +#include "targ-config.h" +#include "elfio/elfio.hpp" +#include "elfio/elfio_dump.hpp" + + + + +int odd_target_count=0; +int bad_target_count=0; +int bad_fallthrough_count=0; + +using namespace libIRDB; +using namespace std; + +set< pair<DatabaseID_t,int> > missed_instructions; +int failed_target_count=0; + +pqxxDB_t pqxx_interface; + +long long num_addresses=0,num_conflicts=0,tot_conflicts=0; +long long total_bytes=0; + +void count_conflicts (FileIR_t* virp) +{ + map<int,int> conflict_map; + + + /* for each instruction in the IR */ + for( + set<Instruction_t*>::const_iterator it=virp->GetInstructions().begin(); + it!=virp->GetInstructions().end(); + ++it + ) + { + Instruction_t *insn=*it; + + VirtualOffset_t vo=insn->GetAddress()->GetVirtualOffset(); + + for(int i=0;i<insn->GetDataBits().length();i++) + conflict_map[(vo+i)]++; + } + + + for(map<int,int>::const_iterator it=conflict_map.begin(); + it!=conflict_map.end(); + ++it) + { + int address=(*it).first; + int conflicts=(*it).second; + + num_addresses++; + if(conflicts>1) + { + num_conflicts++; + tot_conflicts+=conflicts; + } + + + + } + +} + + + + +void get_total(char* filename) +{ + + FILE* loa=fopen(filename, "r"); + + assert(loa && "Cannot open input file"); + + + IRDB_Elf_Off sec_hdr_off, sec_off; + IRDB_Elf_Half secnum, strndx, secndx; + IRDB_Elf_Word secsize; + + + /* allcoate memory */ + IRDB_Elf_Ehdr elfhdr; + + /* Read ELF header */ + fread((char*)&elfhdr, sizeof(IRDB_Elf_Ehdr), 1, loa); + + sec_hdr_off = elfhdr.e_shoff; + secnum = elfhdr.e_shnum; + strndx = elfhdr.e_shstrndx; + + /* Read Section headers */ + IRDB_Elf_Shdr *sechdrs=(IRDB_Elf_Shdr*)malloc(sizeof(IRDB_Elf_Shdr)*secnum); + fseek(loa,sec_hdr_off, std::ios_base::beg); + fread((char*)sechdrs, sizeof(IRDB_Elf_Shdr), secnum, loa); + + + + /* look through each section and find the missing target*/ + for (secndx=1; secndx<secnum; secndx++) + { + int flags = sechdrs[secndx].sh_flags; + + /* not a loaded section */ + if( (flags & SHF_ALLOC) != SHF_ALLOC) + continue; + + /* loaded, and contains instruction, record the bounds */ + if( (flags & SHF_EXECINSTR) != SHF_EXECINSTR) + continue; + + + total_bytes+=sechdrs[secndx].sh_size; + } + + +} + + + +main(int argc, char* argv[]) +{ + + if(argc!=3) + { + cerr<<"Usage: calc_conflicts <id> <a.out>"<<endl; + exit(-1); + } + + VariantID_t *pidp=NULL; + FileIR_t * virp=NULL; + + try + { + /* setup the interface to the sql server */ + BaseObj_t::SetInterface(&pqxx_interface); + + pidp=new VariantID_t(atoi(argv[1])); + + assert(pidp->IsRegistered()==true); + + cout<<"New Variant, after reading registration, is: "<<*pidp << endl; + + // read the db + virp=new FileIR_t(*pidp); + + get_total(argv[2]); + count_conflicts(virp); + + } + catch (DatabaseError_t pnide) + { + cout<<"Unexpected database error: "<<pnide<<endl; + exit(-1); + } + + assert(virp && pidp); + + cout<<"# ATTRIBUTE calc_conflicts::num_addresses="<<std::dec<<num_addresses<<endl; + cout<<"# ATTRIBUTE calc_conflicts::num_conflicts="<<std::dec<<num_conflicts<<endl; + cout<<"# ATTRIBUTE calc_conflicts::total_conflicts="<<std::dec<<tot_conflicts<<endl; + cout<<"# ATTRIBUTE calc_conflicts::pct_conflicts="<<std::fixed<<((float)num_conflicts/(float)tot_conflicts)*100.00<<"%"<<endl; + cout<<"# ATTRIBUTE calc_conflicts::ave_conflicts="<<std::dec<<((double)tot_conflicts/num_addresses)<<endl; + cout<<"# ATTRIBUTE calc_conflicts::ave_bytes_conflicted="<<std::dec<<((double)num_conflicts/num_addresses)<<endl; + cout <<"# ATTRIBUTE calc_conflicts::total_executable_bytes = "<< std::dec << total_bytes<<endl; + cout<<"# ATTRIBUTE calc_conflicts::ave_conflicts_within_exe="<<std::dec<<((double)tot_conflicts/total_bytes)<<endl; + cout<<"# ATTRIBUTE calc_conflicts::ave_bytes_conflicted_within_exe="<<std::dec<<((double)num_conflicts/total_bytes)<<endl; + + + delete virp; + delete pidp; +} diff --git a/irdb-lib/ir_builders/check_thunks.cpp b/irdb-lib/ir_builders/check_thunks.cpp new file mode 100644 index 0000000000000000000000000000000000000000..716b2cd30cebaa0a6a9b49a4fe26b883aa426c44 --- /dev/null +++ b/irdb-lib/ir_builders/check_thunks.cpp @@ -0,0 +1,413 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + + + + + +#include <irdb-core> +#include <algorithm> +#include <iostream> +#include <stdlib.h> +#include <assert.h> +#include <string.h> +#include <elf.h> + +#include "check_thunks.hpp" +#include "fill_in_indtargs.hpp" + + +using namespace IRDB_SDK; +using namespace std; + +#define HIWORD(a) ((a)&0xFFFF0000) + + +/* + * check_for_thunk_offsets - check non-function thunks for extra offsets + */ +void check_for_thunk_offsets(FileIR_t* firp, VirtualOffset_t thunk_base) +{ + + for(auto insn : firp->getInstructions()) + { + const auto d=DecodedInstruction_t::factory(insn); + if(d->getMnemonic()=="add") + { + // check that arg2 is a constant + if(!d->getOperand(1)->isConstant()) + continue; + + auto addoff=d->getOperand(1)->getConstant(); + + /* bounds check gently */ + if(0<addoff && addoff<100) + continue; + + possible_target(thunk_base+addoff, 0, ibt_provenance_t::ibtp_text); + } + // else if(string(d.Instruction.Mnemonic)==string("lea ")) + if(d->getMnemonic()=="lea") + { + assert (d->getOperand(1)->isMemory()); + + /* no indexing please! */ + if(d->getOperand(1)->hasIndexRegister()) + continue; + + auto leaoff=d->getOperand(1)->getMemoryDisplacement(); + + /* bounds check gently */ + if(0<leaoff && leaoff<100) + continue; + + /* record that there's a possible target here */ + possible_target(thunk_base+leaoff, 0, ibt_provenance_t::ibtp_text); + + } + + } +} + +void check_for_thunk_offsets(FileIR_t* firp, Instruction_t *thunk_insn, string reg, uint64_t offset) +{ + + auto thunk_base=thunk_insn->getFallthrough()->getAddress()->getVirtualOffset()+offset; + + /* don't check inserted thunk addresses */ + if(thunk_insn->getAddress()->getVirtualOffset()==0) + return; + + check_for_thunk_offsets(firp,thunk_base); +} + + + +/* + * check_func_for_thunk_offsets - we know that insn represents a thunk call, with reg+offset as the constant. + * check the rest of the function for offsets that might help form a code pointer. + */ +void check_func_for_thunk_offsets(Function_t *func, Instruction_t* thunk_insn, + string reg, uint64_t offset) +{ + + + + auto thunk_base=thunk_insn->getFallthrough()->getAddress()->getVirtualOffset()+offset; + + + /* don't check inserted thunk addresses */ + if(thunk_insn->getAddress()->getVirtualOffset()==0) + return; + + for(auto insn : func->getInstructions()) + { + // if it has a targ and fallthrough (quick test) it might be a call + const auto d=DecodedInstruction_t::factory(insn); + + if(d->getMnemonic()=="add") + { + // check that arg2 is a constant + if(!d->getOperand(1)->isConstant()) + continue; + + auto addoff=d->getOperand(1)->getConstant(); + + /* bounds check gently */ + if(0<addoff && addoff<100) + continue; + + /* record that there's a possible target here */ +// cout <<"Possible thunk target (add): call:"<<thunk_call_addr<<" offset:"<<thunk_call_offset +// <<" addoff: " << addoff << " total: "<< (thunk_base+addoff)<<endl; + possible_target(thunk_base+addoff, 0, ibt_provenance_t::ibtp_text); + } + else if(d->getMnemonic()=="lea") + { + assert (d->getOperand(1)->isMemory()); + + /* no indexing please! */ + if(!d->getOperand(1)->hasIndexRegister()) + continue; + + VirtualOffset_t leaoff=d->getOperand(1)->getMemoryDisplacement(); + + /* bounds check gently */ + if(0<leaoff && leaoff<100) + continue; + + /* record that there's a possible target here */ +// cout <<"Possible thunk target (lea): call:"<<thunk_call_addr<<" offset:"<<thunk_call_offset +// <<" leaoff: " << leaoff << " total: "<< (thunk_base+leaoff)<<endl; + possible_target(thunk_base+leaoff, 0, ibt_provenance_t::ibtp_text); + + } + + } +} + + +/* + * is_thunk_load - look for a mov reg<[esp], return reg in output parameter. + */ +bool is_thunk_load(Instruction_t* insn, string ®) +{ + const auto d=DecodedInstruction_t::factory(insn); + + if(d->getMnemonic()!="mov") + return false; + + if(!d->getOperand(1)->isMemory() || d->getOperand(1)->getString()!="esp") + return false; + + reg=d->getOperand(0)->getString(); + return true; +} + +/* + * is_ret - return true if insn is a return + */ +bool is_ret(Instruction_t* insn) +{ + const auto d=DecodedInstruction_t::factory(insn); + return d->isReturn(); +} + +/* + * is_pop - return true if insn is a return + */ +bool is_pop(Instruction_t* insn, string ®) +{ + const auto d=DecodedInstruction_t::factory(insn); + + if(d->getMnemonic()!="pop") + return false; + + reg=d->getOperand(0)->getString(); + return true; +} + + + +/* + * is_thunk_call - check if this instruction is a call to a thunk function, return the thunk function's reg. + */ +/* note: reg is output paramater */ +bool is_thunk_call(Instruction_t* insn, string ®) +{ + const auto d=DecodedInstruction_t::factory(insn); + + /* not a call */ + if(!d->isCall()) + return false; + + /* no target in IRDB */ + if(insn->getTarget()==NULL) + return false; + + /* Target not the right type of load */ + if(!is_thunk_load(insn->getTarget(),reg)) + return false; + + /* target has no FT? */ + if(!insn->getTarget()->getFallthrough()) + return false; + + /* target's FT is a return insn */ + if(!is_ret(insn->getTarget()->getFallthrough())) + return false; + + return true; +} + +bool is_thunk_call_type2(Instruction_t* insn, string ®, Instruction_t** newinsn) +{ + const auto d=DecodedInstruction_t::factory(insn); + + /* not a call */ + if(!d->isCall()) + return false; + + /* no target in IRDB */ + if(insn->getTarget()==NULL) + return false; + + if(insn->getTarget() != insn->getFallthrough()) + return false; + + /* target's FT is a return insn */ + if(!is_pop(insn->getTarget(), reg)) + return false; + + *newinsn=insn->getTarget()->getFallthrough(); + + return true; +} + +/* + * is_thunk_add - Check the given instruction for an add of reg, return the constant K1 + */ +/* note: offset is an output parameter */ +bool is_thunk_add(Instruction_t *insn, string reg, uint64_t &offset) +{ + const auto d=DecodedInstruction_t::factory(insn); + + // make sure it's an add instruction + if(d->getMnemonic()!="add") + return false; + + // check that it's an add of the proper reg + if(d->getOperand(0)->getString()!=reg) + return false; + + // check that arg2 is a constant + if(!d->getOperand(1)->isConstant()) + return false; + + offset=d->getOperand(1)->getConstant(); + + auto intoff=d->getOperand(1)->getConstant(); + + /* bounds check gently */ + if(0<intoff && intoff<100) + return false; + + return true; +} + +/* + * check_func_for_thunk_calls - check this function for a thunk call (see check_for_thunks for description of thunk calls) + */ +void check_func_for_thunk_calls(Function_t* func) +{ + // for each insn in the func + for(auto insn : func->getInstructions()) + { + // if it has a targ and fallthrough (quick test) it might be a call + /* check if we might be calling a thunk */ + if(insn->getFallthrough() && insn->getTarget()) + { + + // check for a call, followed by an add of reg (note the output params of reg and offset) + string reg; + uint64_t offset=0; + if(is_thunk_call(insn,reg) && + is_thunk_add(insn->getFallthrough(),reg,offset)) + { + check_func_for_thunk_offsets(func,insn,reg,offset); + } + } + } +} + + + +void check_non_funcs_for_thunks(FileIR_t *firp) +{ + // for each insn in the func + for(auto insn : firp->getInstructions()) + { + // if it has a targ and fallthrough (quick test) it might be a call + + /* these instructions/thunks are checked with the functions */ + + /* check if we might be calling a thunk */ + if(insn->getFallthrough() && insn->getTarget()) + { + + // check for a call, followed by an add of reg (note the output params of reg and offset) + string reg; + uint64_t offset=0; + if(is_thunk_call(insn,reg) && + is_thunk_add(insn->getFallthrough(),reg,offset)) + { + cout<<"Found non-function thunk at "<< + insn->getAddress()->getVirtualOffset()<<endl; + check_for_thunk_offsets(firp,insn,reg,offset); + } + } + } +} + + +/* + * check_for_thunks - + * + * check the program (file) for this pattern: + * + * call ebx_thunk + * L1: add K1,%ebx + * + * ebx_thunk: mov ebx <- [esp] + * ret + * + * If found, check the function for L1+K1+K2 (where K2 is any constant in the function) + * If L1+k1+k2 is found, and points at a code address (outside this function?), mark it as an indirect branch target. + * + */ +void check_for_thunks(FileIR_t* firp, const std::set<VirtualOffset_t>& thunk_bases) +{ + /* thunk bases is the module start's found for this firp */ + + cout<<"Starting check for thunks"<<endl; + + for(auto offset : thunk_bases) + check_for_thunk_offsets(firp,offset); +} + +void find_all_module_starts(FileIR_t* firp, set<VirtualOffset_t> &thunk_bases) +{ + thunk_bases.clear(); + + cout<<"Finding thunk bases"<<endl; + + // for each insn in the func + for(auto insn : firp->getInstructions()) + { + // if it has a targ and fallthrough (quick test) it might be a call + /* check if we might be calling a thunk */ + if(insn->getFallthrough() && insn->getTarget()) + { + // check for a call, followed by an add of reg (note the output params of reg and offset) + string reg; + uint64_t offset=0; + if(is_thunk_call(insn,reg) && + is_thunk_add(insn->getFallthrough(),reg,offset)) + { + auto thunk_base=insn->getFallthrough()->getAddress()->getVirtualOffset()+ offset; + if(thunk_bases.find(thunk_base)==thunk_bases.end()) + cout<<"Found new thunk at "<<insn->getAddress()->getVirtualOffset()<<" with base: "<<hex<<thunk_base<<endl; + thunk_bases.insert(thunk_base); + } + Instruction_t* newinsn=NULL; + if(is_thunk_call_type2(insn,reg,&newinsn)) + { + if(newinsn && is_thunk_add(newinsn,reg,offset)) + { + VirtualOffset_t thunk_base=insn->getFallthrough()->getAddress()->getVirtualOffset()+ offset; + if(thunk_bases.find(thunk_base)==thunk_bases.end()) + cout<<"Found new thunk at "<<insn->getAddress()->getVirtualOffset()<<" with base: "<<hex<<thunk_base<<endl; + thunk_bases.insert(thunk_base); + } + } + } + } +} diff --git a/irdb-lib/ir_builders/check_thunks.hpp b/irdb-lib/ir_builders/check_thunks.hpp new file mode 100644 index 0000000000000000000000000000000000000000..27b77593fce91e937501b16524d81cc9323e753b --- /dev/null +++ b/irdb-lib/ir_builders/check_thunks.hpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +#ifndef check_thunks_hpp +#define check_thunks_hpp + +#include <set> +#include <irdb-core> + +void find_all_module_starts(IRDB_SDK::FileIR_t* firp, std::set<IRDB_SDK::VirtualOffset_t>& thunk_bases); +void check_for_thunks(IRDB_SDK::FileIR_t* firp, const std::set<IRDB_SDK::VirtualOffset_t>& thunk_bases); + + +#endif + diff --git a/irdb-lib/ir_builders/clone.cpp b/irdb-lib/ir_builders/clone.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d5211b72361faafdeb6d11acc4b5300f103f725e --- /dev/null +++ b/irdb-lib/ir_builders/clone.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + + +#include <irdb-core> +#include <iostream> +#include <fstream> + +#include <stdlib.h> + +using namespace IRDB_SDK; +using namespace std; + +int main(int argc, char* argv[]) +{ + + if(argc!=3) + { + cerr<<"Usage: clone <vid> <output.id>"<<endl; + exit(-1); + } + + + /* setup the interface to the sql server */ + auto pqxx_interface=pqxxDB_t::factory(); + BaseObj_t::setInterface(pqxx_interface.get()); + + + try + { + auto pidp=VariantID_t::factory(atoi(argv[1])); + assert(pidp->isRegistered()==true); + + auto newpidp=pidp->clone(); + assert(newpidp->isRegistered()==true); + + cout<<"Cloned Variant is: "<<*newpidp << endl; + + // commit the changes to the db if all went well + pqxx_interface->commit(); + + auto newpid_id=newpidp->getBaseID(); + ofstream f; + f.open(argv[2]); + if(!f.is_open()) + { + cerr<<"Cannot open output file"<<endl; + exit(-1); + } + f<<std::dec<<newpid_id<<endl; + f.close(); + + } + catch (DatabaseError_t pnide) + { + cout<<"Unexpected database error: "<<pnide<<endl; + exit(-1); + } + + + + return 0; +} diff --git a/irdb-lib/ir_builders/create_variant.cpp b/irdb-lib/ir_builders/create_variant.cpp new file mode 100644 index 0000000000000000000000000000000000000000..98052436e34a3ced2ec237ff235d83117017525e --- /dev/null +++ b/irdb-lib/ir_builders/create_variant.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + + +#include <libIRDB-core.hpp> +#include <iostream> +#include <stdlib.h> + +using namespace libIRDB; +using namespace std; + +int main(int argc, char* argv[]) +{ + + if(argc!=2) + { + cerr<<"Usage: create_variant <name>"<<endl; + exit(-1); + } + + + /* setup the interface to the sql server */ + pqxxDB_t pqxx_interface; + BaseObj_t::SetInterface(&pqxx_interface); + + + VariantID_t *pidp=NULL; + try + { + pidp=new VariantID_t(); + + assert(pidp->IsRegistered()==false); + + pidp->SetName(argv[1]); + + cout<<"New Variant, before registration, is: "<<*pidp << endl; + + pidp->Register(); + + assert(pidp->IsRegistered()==true); + + cout<<"New Variant, after registration, is: "<<*pidp << endl; + + pidp->WriteToDB(); + + cout<<"New Variant, after writing to DB, is: "<<*pidp << endl; + + // commit the changes to the db if all went well + pqxx_interface.Commit(); + + } + catch (DatabaseError_t pnide) + { + cout<<"Unexpected database error: "<<pnide<<endl; + exit(-1); + } + + delete pidp; + return 0; +} diff --git a/irdb-lib/ir_builders/create_variantir.cpp b/irdb-lib/ir_builders/create_variantir.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8a8efe54b05d3df3f3371c68ee9339962ff76b8b --- /dev/null +++ b/irdb-lib/ir_builders/create_variantir.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + + +#include <libIRDB-core.hpp> +#include <iostream> +#include <stdlib.h> + +using namespace libIRDB; +using namespace std; + +int main(int argc, char* argv[]) +{ + + if(argc!=2) + { + cerr<<"Usage: create_variant <name>"<<endl; + exit(-1); + } + + + /* setup the interface to the sql server */ + pqxxDB_t pqxx_interface; + BaseObj_t::SetInterface(&pqxx_interface); + + + VariantID_t *pidp=NULL; + FileIR_t * virp=NULL; + try + { + pidp=new VariantID_t(); + + assert(pidp->IsRegistered()==false); + + pidp->SetName(argv[1]); + + cout<<"New Variant, before registration, is: "<<*pidp << endl; + + pidp->Register(); + + assert(pidp->IsRegistered()==true); + + cout<<"New Variant, after registration, is: "<<*pidp << endl; + + pidp->WriteToDB(); + + cout<<"New Variant, after writing to DB, is: "<<*pidp << endl; + + virp=new FileIR_t(*pidp); + + + // commit the changes to the db if all went well + pqxx_interface.Commit(); + + + } + catch (DatabaseError_t pnide) + { + cout<<"Unexpected database error: "<<pnide<<endl; + exit(-1); + } + + delete virp; + delete pidp; + return 0; +} diff --git a/irdb-lib/ir_builders/decode_test.cpp b/irdb-lib/ir_builders/decode_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cec74d350f6be02170266507e85b1bfe93caabd6 --- /dev/null +++ b/irdb-lib/ir_builders/decode_test.cpp @@ -0,0 +1,16 @@ +#include <libIRDB-core.hpp> + +using namespace std; +using namespace libIRDB; + +int main() +{ + + FileIR_t::SetArchitecture(64,admtX86_64); + + for(auto i=0U; i<10*1000*1000; i++) + { + const auto d=DecodedInstruction_t(1024, "\x90", 1); + } + return 0; +} diff --git a/irdb-lib/ir_builders/drop_variant.cpp b/irdb-lib/ir_builders/drop_variant.cpp new file mode 100644 index 0000000000000000000000000000000000000000..14d0dd98d82b1047518294129c23de896c1d7dd8 --- /dev/null +++ b/irdb-lib/ir_builders/drop_variant.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + + +#include <libIRDB-core.hpp> +#include <iostream> +#include <stdlib.h> + +using namespace libIRDB; +using namespace std; + +int main(int argc, char* argv[]) +{ + + if(argc!=2) + { + cerr<<"Usage: simple (<pid>)"<<endl; + exit(-1); + } + + + /* setup the interface to the sql server */ + pqxxDB_t pqxx_interface; + BaseObj_t::SetInterface(&pqxx_interface); + + + VariantID_t *pidp=NULL; + try + { + pidp=new VariantID_t(atoi(argv[1])); + cout<<"Variant "<< argv[1]<< " found in db: "<<*pidp << ". Dropping..."<< endl; + pidp->DropFromDB(); + pqxx_interface.Commit(); + } + catch (DatabaseError_t pnide) + { + if(pnide.GetErrorCode()==DatabaseError_t::VariantNotInDatabase) + { + cout<<"Variant "<< argv[1]<< " not found in db"<<endl; + exit(-2); + } + else + { + cout<<"Unexpected database error: "<<pnide<<endl; + exit(-1); + } + } + + cout<<"Done!"<<endl; + delete pidp; + return 0; +} diff --git a/irdb-lib/ir_builders/fill_in_cfg.cpp b/irdb-lib/ir_builders/fill_in_cfg.cpp new file mode 100644 index 0000000000000000000000000000000000000000..85ce8cf0efda608519158b4c4e1e42f67b89354b --- /dev/null +++ b/irdb-lib/ir_builders/fill_in_cfg.cpp @@ -0,0 +1,732 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include "fill_in_cfg.hpp" +#include <iostream> +#include <fstream> +#include <string.h> +#include <assert.h> +#include <sys/mman.h> +#include <ctype.h> +#include "elfio/elfio.hpp" +#include "split_eh_frame.hpp" + +using namespace std; +using namespace EXEIO; +using namespace IRDB_SDK; + +void PopulateCFG::populate_instruction_map + ( + map< pair<DatabaseID_t,VirtualOffset_t>, Instruction_t*> &insnMap, + FileIR_t *firp + ) +{ + /* start from scratch each time */ + insnMap.clear(); + + + /* for each instruction in the IR */ + for(auto insn : firp->getInstructions()) + { + auto fileID=insn->getAddress()->getFileID(); + auto vo=insn->getAddress()->getVirtualOffset(); + + auto p=pair<DatabaseID_t,VirtualOffset_t>(fileID,vo); + + assert(insnMap[p]==NULL); + insnMap[p]=insn; + } + +} + +void PopulateCFG::set_fallthrough + ( + map< pair<DatabaseID_t,VirtualOffset_t>, Instruction_t*> &insnMap, + DecodedInstruction_t *disasm, Instruction_t *insn, FileIR_t *firp + ) +{ + assert(disasm); + assert(insn); + + if(insn->getFallthrough()) + return; + + // check for branches with targets + if( + (disasm->isUnconditionalBranch() ) || // it is a unconditional branch + (disasm->isReturn()) // or a return + ) + { + // this is a branch with no fallthrough instruction + return; + } + + /* get the address of the next instrution */ + + auto virtual_offset=insn->getAddress()->getVirtualOffset() + insn->getDataBits().size(); + + /* create a pair of offset/file */ + auto p=pair<DatabaseID_t,VirtualOffset_t>(insn->getAddress()->getFileID(),virtual_offset); + + /* lookup the target insn from the map */ + auto fallthrough_insn=insnMap[p]; + + /* sanity, note we may see odd control transfers to 0x0 */ + if(fallthrough_insn==NULL && virtual_offset!=0) + { + cout<<"Cannot set fallthrough for "<<std::hex<<insn->getAddress()->getVirtualOffset(); + cout<< " : "<<insn->getDisassembly()<<endl; + bad_fallthrough_count++; + } + + /* set the target for this insn */ + if(fallthrough_insn!=0) + { + fallthroughs_set++; + insn->setFallthrough(fallthrough_insn); + } + else + missed_instructions.insert(pair<DatabaseID_t,VirtualOffset_t>(insn->getAddress()->getFileID(),virtual_offset)); +} + + +void PopulateCFG::set_target + ( + map< pair<DatabaseID_t,VirtualOffset_t>, Instruction_t*> &insnMap, + DecodedInstruction_t *disasm, Instruction_t *insn, FileIR_t *firp + ) +{ + + assert(insn); + assert(disasm); + + if(insn->getTarget()) + return; + + const auto &operands = disasm->getOperands(); + for(auto operand : operands) + { + // check for branches with targets + if( + disasm->isBranch() && // it is a branch + !disasm->isReturn() && // and not a return + operand->isConstant() // and has a constant argument + ) + { + // cout<<"Found direct jump with addr=" << insn->getAddress()->getVirtualOffset() << + // " disasm="<<disasm->CompleteInstr<<" ArgMnemonic="<< + // disasm->Argument1.ArgMnemonic<<"."<<endl; + + /* get the offset */ + auto virtual_offset=disasm->getAddress(); + + /* create a pair of offset/file */ + auto p=pair<DatabaseID_t,VirtualOffset_t>(insn->getAddress()->getFileID(),virtual_offset); + + /* lookup the target insn from the map */ + auto target_insn=insnMap[p]; + + /* sanity, note we may see odd control transfers to 0x0 */ + if(target_insn==NULL) + { + unsigned char first_byte=0; + if(insn->getFallthrough()) + first_byte=(insn->getFallthrough()->getDataBits().c_str())[0]; + VirtualOffset_t jump_dist=virtual_offset-(insn->getAddress()->getVirtualOffset()+(insn->getDataBits()).size()); + if( + // jump 1 byte forward + jump_dist == 1 && + + // and we calculated the fallthrough + insn->getFallthrough()!=NULL && + + // and the fallthrough starts with a lock prefix + first_byte==0xf0 + ) + { + odd_target_count++; + target_insn=insn->getFallthrough(); + } + else + { + if(virtual_offset!=0) + cout<<"Cannot set target (target="<< std::hex << virtual_offset << ") for "<<std::hex<<insn->getAddress()->getVirtualOffset()<<"."<<endl; + bad_target_count++; + } + } + + /* set the target for this insn */ + if(target_insn!=0) + { + targets_set++; + insn->setTarget(target_insn); + } + else + missed_instructions.insert( pair<DatabaseID_t,VirtualOffset_t>(insn->getAddress()->getFileID(),virtual_offset)); + + } + } +} + +File_t* PopulateCFG::find_file(FileIR_t* firp, DatabaseID_t fileid) +{ + assert(firp->getFile()->getBaseID()==fileid); + return firp->getFile(); +} + + +void PopulateCFG::add_new_instructions(FileIR_t *firp) +{ + int found_instructions=0; + for(auto p : missed_instructions) + { + /* get the address we've missed */ + auto missed_address=p.second; + + /* get the address ID of the instruction that's missing the missed addressed */ + auto missed_fileid=p.first; + + /* figure out which file we're looking at */ + auto filep=find_file(firp,missed_fileid); + assert(filep); + + + + int secnum = elfiop->sections.size(); + int secndx=0; + + bool found=false; + + /* look through each section and find the missing target*/ + for (secndx=1; secndx<secnum; secndx++) + { + /* not a loaded section */ + if( !elfiop->sections[secndx]->isLoadable()) + continue; + + /* loaded, and contains instruction, record the bounds */ + if( !elfiop->sections[secndx]->isExecutable()) + continue; + + VirtualOffset_t first=elfiop->sections[secndx]->get_address(); + VirtualOffset_t second=elfiop->sections[secndx]->get_address()+elfiop->sections[secndx]->get_size(); + + /* is the missed instruction in this section */ + if(first<=missed_address && missed_address<second) + { + const char* data=elfiop->sections[secndx]->get_data(); + // second=data? + VirtualOffset_t offset_into_section=missed_address-elfiop->sections[secndx]->get_address(); + + /* disassemble the instruction */ + auto disasm_p=DecodedInstruction_t::factory(missed_address, (void*)&data[offset_into_section], elfiop->sections[secndx]->get_size()-offset_into_section ); + auto &disasm=*disasm_p; + + + + /* if we found the instruction, but can't disassemble it, then we skip out for now */ + if(!disasm.valid()) + { + if(getenv("VERBOSE_CFG")) + cout<<"Found invalid insn at "<<missed_address<<endl; + break; + } + else if(getenv("VERBOSE_CFG")) + cout<<"Found valid insn at "<<missed_address<<": "<<disasm.getDisassembly()<<endl; + + const auto instr_len = disasm.length(); + + /* intel instructions have a max size of 16 */ + assert(1<=instr_len && instr_len<=16); + + + /* here we are certain we found the instruction */ + found=true; + + /* get the new bits for an instruction */ + string newinsnbits; + newinsnbits.resize(instr_len); + for(auto i=0U;i<instr_len;i++) + newinsnbits[i]=data[offset_into_section+i]; + + /* create a new address */ + /* + auto newaddr=new AddressID_t(); + assert(newaddr); + newaddr->setVirtualOffset(missed_address); + newaddr->setFileID(missed_fileid); + firp->getAddresses().insert(newaddr); + */ + auto newaddr=firp->addNewAddress(missed_fileid,missed_address); + + /* create a new instruction */ + /* + auto newinsn=new Instruction_t(); + assert(newinsn); + newinsn->setAddress(newaddr); + newinsn->setDataBits(newinsnbits); + newinsn->setComment(disasm.getDisassembly()+string(" from fill_in_cfg ")); + firp->getInstructions().insert(newinsn); + newinsn->setAddress(newaddr); + */ + auto newinsn=firp->addNewInstruction(newaddr, nullptr, newinsnbits, disasm.getDisassembly()+string(" from fill_in_cfg "), nullptr); + (void)newinsn;// just add to IR + + /* fallthrough/target/is indirect will be set later */ + + /* insert into the IR */ + + + cout<<"Found new instruction, "<<newinsn->getComment()<<", at "<<std::hex<<newinsn->getAddress()->getVirtualOffset()<<" in file "<<"<no name yet>"<<"."<<endl; + found_instructions++; + } + + } + if(!found) + { + failed_target_count++; + + cout<<"Cannot find address "<<std::hex<<missed_address<<" in file "<<"<no name yet>"<<"."<<endl; + } + } + cout<<"Found a total of "<<std::dec<<found_instructions<<" new instructions."<<endl; + +} + +void PopulateCFG::fill_in_cfg(FileIR_t *firp) +{ + int round=0; + + do + { + bad_target_count=0; + bad_fallthrough_count=0; + failed_target_count=0; + missed_instructions.clear(); + + map< pair<DatabaseID_t,VirtualOffset_t>, Instruction_t*> insnMap; + populate_instruction_map(insnMap, firp); + + cout << "Found "<<firp->getInstructions().size()<<" instructions." <<endl; + + /* for each instruction, disassemble it and set the target/fallthrough */ + for(auto insn : firp->getInstructions()) + { + auto disasm=DecodedInstruction_t::factory(insn); + + const auto instr_len = disasm->length(); + + assert(instr_len==insn->getDataBits().size()); + + set_fallthrough(insnMap, disasm.get(), insn, firp); + set_target(insnMap, disasm.get(), insn, firp); + + } + if(bad_target_count>0) + cout<<std::dec<<"Found "<<bad_target_count<<" bad targets at round "<<round<<endl; + if(bad_fallthrough_count>0) + cout<<"Found "<<bad_fallthrough_count<<" bad fallthroughs at round "<<round<<endl; + cout<<"Missed instruction count="<<missed_instructions.size()<<endl; + + add_new_instructions(firp); + + round++; + + /* keep trying this while we're resolving targets. if at any point we fail to resolve a new target/fallthrough address, then we give up */ + } while(missed_instructions.size()>failed_target_count); + + cout<<"Caution: Was unable to find instructions for these addresses:"<<hex<<endl; + for(auto p : missed_instructions) + { + /* get the address we've missed */ + VirtualOffset_t missed_address=p.second; + cout << missed_address << ", "; + } + cout<<dec<<endl; + + + /* set the base IDs for all instructions */ + firp->setBaseIDS(); + + /* for each instruction, set the original address id to be that of the address id, as fill_in_cfg is + * designed to work on only original programs. + */ + for(auto insn : firp->getInstructions()) + insn->setOriginalAddressID(insn->getAddress()->getBaseID()); + + +} + +bool PopulateCFG::is_in_relro_segment(const int secndx) +{ + ELFIO::elfio *real_elfiop = reinterpret_cast<ELFIO::elfio*>(elfiop->get_elfio()); + if(!real_elfiop) + return false; + + int segnum = real_elfiop->segments.size(); + + VirtualOffset_t sec_start=(VirtualOffset_t)(elfiop->sections[secndx]->get_address()); + VirtualOffset_t sec_end=(VirtualOffset_t)(elfiop->sections[secndx]->get_address() + elfiop->sections[secndx]->get_size() - 1 ); + + /* look through each section */ + for (int segndx=1; segndx<segnum; segndx++) + { + ELFIO::Elf_Word type=real_elfiop->segments[segndx]->get_type(); +#ifndef PT_GNU_RELRO +#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ +#endif + + if(type==PT_GNU_RELRO) + { + VirtualOffset_t seg_start=(VirtualOffset_t)(real_elfiop->segments[segndx]->get_virtual_address()); + VirtualOffset_t seg_end=(VirtualOffset_t)(real_elfiop->segments[segndx]->get_virtual_address() + real_elfiop->segments[segndx]->get_memory_size() - 1 ); + + // check if start lies within + if(seg_start <= sec_start && sec_start <= seg_end) + return true; + + // check if end lies within + if(seg_start <= sec_end && sec_end <= seg_end) + return true; + + // check if crosses + if(sec_start < seg_start && seg_end < sec_end) + return true; + } + } + + return false; +} + +void PopulateCFG::fill_in_scoops(FileIR_t *firp) +{ + + auto max_base_id=firp->getMaxBaseID(); + auto secnum = elfiop->sections.size(); + auto secndx=0; + + /* look through each section */ + for (secndx=1; secndx<secnum; secndx++) + { + /* not a loaded section, try next section */ + if(!elfiop->sections[secndx]->isLoadable()) + { + cout<<"Skipping scoop for section (not loadable) "<<elfiop->sections[secndx]->get_name()<<endl; + continue; + } + + if(elfiop->sections[secndx]->isWriteable() && elfiop->sections[secndx]->isExecutable()) + { + ofstream fout("warning.txt"); + fout<<"Found that section "<<elfiop->sections[secndx]->get_name()<<" is both writeable and executable. Program is inherently unsafe!"<<endl; + } + + /* executable sections handled by zipr/spri. */ + if(elfiop->sections[secndx]->isExecutable()) + { + cout<<"Skipping scoop for section (executable) "<<elfiop->sections[secndx]->get_name()<<endl; + continue; + } + /* name */ + string name=elfiop->sections[secndx]->get_name(); + + /* start address */ + /* + auto startaddr=new AddressID_t(); + assert(startaddr); + startaddr->setVirtualOffset( elfiop->sections[secndx]->get_address()); + startaddr->setFileID(firp->getFile()->getBaseID()); + firp->getAddresses().insert(startaddr); + */ + auto startaddr=firp->addNewAddress(firp->getFile()->getBaseID(), elfiop->sections[secndx]->get_address()); + + /* end */ + /* + auto endaddr=new AddressID_t(); + assert(endaddr); + endaddr->setVirtualOffset( elfiop->sections[secndx]->get_address() + elfiop->sections[secndx]->get_size()-1); + endaddr->setFileID(firp->getFile()->getBaseID()); + firp->getAddresses().insert(endaddr); + */ + auto endaddr=firp->addNewAddress(firp->getFile()->getBaseID(), elfiop->sections[secndx]->get_address() + elfiop->sections[secndx]->get_size()-1); + + + string the_contents; + the_contents.resize(elfiop->sections[secndx]->get_size()); + // deal with .bss segments that are 0 init'd. + if (elfiop->sections[secndx]->get_data()) + the_contents.assign(elfiop->sections[secndx]->get_data(),elfiop->sections[secndx]->get_size()); + +// Type_t *chunk_type=NULL; /* FIXME -- need to figure out the type system for scoops, but NULL should remain valid */ + + /* permissions */ + int permissions= + ( elfiop->sections[secndx]->isReadable() << 2 ) | + ( elfiop->sections[secndx]->isWriteable() << 1 ) | + ( elfiop->sections[secndx]->isExecutable() << 0 ) ; + + bool is_relro=is_in_relro_segment(secndx); + scoops_detected++; + /* + DataScoop_t *newscoop=new DataScoop_t(max_base_id++, name, startaddr, endaddr, NULL, permissions, is_relro, the_contents); + assert(newscoop); + firp->getDataScoops().insert(newscoop); + */ + auto newscoop=firp->addNewDataScoop( name, startaddr, endaddr, NULL, permissions, is_relro, the_contents, max_base_id++ ); + (void)newscoop; // just give it to the IR + + cout<<"Allocated new scoop for section "<<name + <<"("<<hex<<startaddr->getVirtualOffset()<<"-" + <<hex<<endaddr->getVirtualOffset()<<")" + <<" perms="<<permissions<<" relro="<<boolalpha<<is_relro<<endl; + + } + +} + +void PopulateCFG::detect_scoops_in_code(FileIR_t *firp) +{ + // data for this function + auto already_scoopified=set<VirtualOffset_t>(); + + // only valid for arm64 + if(firp->getArchitecture()->getMachineType() != admtAarch64) return; + + // check each insn for an ldr with a pcrel operand. + for(auto insn : firp->getInstructions()) + { + // look for ldr's with a pcrel operand + const auto d=DecodedInstruction_t::factory(insn); + if(d->getMnemonic()!="ldr") continue; // only valid on arm. + const auto op0=d->getOperand(0); + const auto op1=d->getOperand(1); + if( !op1->isPcrel()) continue; + + // sanity check that it's a memory operation, and extract fields + assert(op1->isMemory()); + const auto referenced_address=op1->getMemoryDisplacement(); + const auto op0_str=op0->getString(); + const auto referenced_size= // could use API call? + op0_str[0]=='w' ? 4 : + op0_str[0]=='x' ? 8 : + op0_str[0]=='s' ? 4 : + op0_str[0]=='d' ? 8 : + op0_str[0]=='q' ? 16 : + throw domain_error("Cannot decode instruction size"); + ; + + // check if we've seen this address already + const auto already_seen_it=already_scoopified.find(referenced_address); + if(already_seen_it!=end(already_scoopified)) continue; + + // not seen, add it + already_scoopified.insert(referenced_address); + + + // find section and sanity check. + const auto sec=elfiop->sections.findByAddress(referenced_address); + if(sec==nullptr) continue; + + // only trying to do this for executable chunks, other code deals with + // scoops not in the .text section. + if(!sec->isExecutable()) continue; + + const auto sec_data=sec->get_data(); + const auto sec_start=sec->get_address(); + const auto the_contents=string(&sec_data[referenced_address-sec_start],referenced_size); + const auto fileid=firp->getFile()->getBaseID(); + + + /* + auto start_addr=new AddressID_t(BaseObj_t::NOT_IN_DATABASE,fileid,referenced_address); + assert(start_addr); + firp->getAddresses().insert(start_addr); + + auto end_addr=new AddressID_t(BaseObj_t::NOT_IN_DATABASE,fileid,referenced_address+referenced_size-1); + assert(end_addr); + firp->getAddresses().insert(end_addr); + */ + auto start_addr=firp->addNewAddress(fileid,referenced_address); + auto end_addr =firp->addNewAddress(fileid,referenced_address+referenced_size-1); + + const auto name="data_in_text_"+to_string(referenced_address); + const auto permissions=0x4; /* R-- */ + const auto is_relro=false; + /* + auto newscoop=new DataScoop_t(BaseObj_t::NOT_IN_DATABASE, name, start_addr, end_addr, NULL, permissions, is_relro, the_contents); + firp->getDataScoops().insert(newscoop); + */ + auto newscoop=firp->addNewDataScoop(name, start_addr, end_addr, NULL, permissions, is_relro, the_contents); + (void)newscoop; + + cout<< "Allocated data in text segment "<<name<<"=("<<start_addr->getVirtualOffset()<<"-" + << end_addr->getVirtualOffset()<<")"<<endl; + } +} + +void PopulateCFG::fill_in_landing_pads(FileIR_t *firp) +{ + const auto eh_frame_rep_ptr = split_eh_frame_t::factory(firp); + // eh_frame_rep_ptr->parse(); already parsed now. + if(getenv("EHIR_VERBOSE")) + eh_frame_rep_ptr->print(); + cout<<"Completed eh-frame parsing"<<endl; + + map<Function_t*,set<Instruction_t*> > insns_to_add_to_funcs; + + for(const auto t : firp->getInstructions()) + { + if(t->getFunction()==NULL) + continue; + auto lp=eh_frame_rep_ptr->find_lp(t); + if(lp && lp->getFunction()==NULL) + insns_to_add_to_funcs[t->getFunction()].insert(lp); + }; + + + for(const auto & p : insns_to_add_to_funcs) + { + auto & func=p.first; + auto insns=p.second; /* copy */ + auto insn_count=0; + + while(insns.size()>0 ) + { + auto it=insns.begin(); + auto insn=*it; + insns.erase(it); + + assert(insn); + if(insn->getFunction()!=NULL) + continue; + + auto lp=eh_frame_rep_ptr->find_lp(insn); + if(lp && lp->getFunction()==NULL) + insns.insert(lp); + + insn->setFunction(func); + cout<<" Adding "<<insn->getBaseID()<<":"<<insn->getDisassembly()<<"@"<<hex<<insn->getAddress()->getVirtualOffset()<<dec<<endl; + insn_count++; + + + auto target=insn->getTarget(); + auto fallthru=insn->getFallthrough(); + + if(target) insns.insert(target); + if(fallthru) insns.insert(fallthru); + } + cout<<"Found LP outside of function "<<func->getName()<<" added "<<insn_count<<" instructions"<<endl; + }; + +} + +int PopulateCFG::parseArgs(const vector<string> step_args) +{ + if(step_args.size()<1) + { + cerr<<"Usage: <id> [--fix-landing-pads | --no-fix-landing-pads]"<<endl; + return -1; + } + + variant_id = stoi(step_args[0]); + + for (unsigned int i = 1; i < step_args.size(); ++i) + { + if (step_args[i]=="--fix-landing-pads") + { + fix_landing_pads = true; + } + else if (step_args[i]=="--no-fix-landing-pads") + { + fix_landing_pads = false; + } + } + + cout<<"fix_landing_pads="<<fix_landing_pads<<endl; + + return 0; +} + +int PopulateCFG::executeStep(IRDBObjects_t *const irdb_objects) +{ + try + { + const auto pqxx_interface = irdb_objects->getDBInterface(); + // now set the DB interface for THIS PLUGIN LIBRARY -- VERY IMPORTANT + BaseObj_t::setInterface(pqxx_interface); + + const auto variant = irdb_objects->addVariant(variant_id); + for(File_t* file : variant->getFiles()) + { + const auto firp = irdb_objects->addFileIR(variant_id, file->getBaseID()); + assert(firp); + cout<<"Filling in cfg for "<<firp->getFile()->getURL()<<endl; + + /* get the OID of the file */ + const int elfoid=firp->getFile()->getELFOID(); + + pqxx::largeobject lo(elfoid); + lo.to_file(pqxx_interface->getTransaction(),"readeh_tmp_file.exe"); + + elfiop.reset(new exeio()); + elfiop->load(string("readeh_tmp_file.exe")); + + fill_in_cfg(firp); + fill_in_scoops(firp); + detect_scoops_in_code(firp); + + if (fix_landing_pads) + { + fill_in_landing_pads(firp); + } + } + } + catch (DatabaseError_t pnide) + { + cerr<<"Unexpected database error: "<<pnide<<endl; + return -1; + } + catch(...) + { + cerr<<"Unexpected error"<<endl; + return -1; + } + + cout<<"#ATTRIBUTE targets_set="<<targets_set<<endl; + cout<<"#ATTRIBUTE fallthroughs_set="<<fallthroughs_set<<endl; + cout<<"#ATTRIBUTE scoops_detected="<<scoops_detected<<endl; + + if(getenv("SELF_VALIDATE")) + { + assert(targets_set > 10); + assert(fallthroughs_set > 100); + assert(scoops_detected > 5 ); + } + + return 0; +} + + +extern "C" +shared_ptr<TransformStep_t> getTransformStep(void) +{ + const shared_ptr<TransformStep_t> the_step(new PopulateCFG()); + return the_step; +} diff --git a/irdb-lib/ir_builders/fill_in_cfg.hpp b/irdb-lib/ir_builders/fill_in_cfg.hpp new file mode 100644 index 0000000000000000000000000000000000000000..93c36e48becad489a64b6fce26734a46b9335e77 --- /dev/null +++ b/irdb-lib/ir_builders/fill_in_cfg.hpp @@ -0,0 +1,95 @@ +#ifndef fill_in_cfg_hpp +#define fill_in_cfg_hpp + +#include <irdb-core> +#include <stdlib.h> +#include <map> +#include <exeio.h> + +class PopulateCFG : public IRDB_SDK::TransformStep_t +{ + public: + PopulateCFG(IRDB_SDK::DatabaseID_t p_variant_id = 0, + bool p_fix_landing_pads = true + ) + : + variant_id(p_variant_id), + fix_landing_pads(p_fix_landing_pads) + { + odd_target_count = 0; + bad_target_count = 0; + bad_fallthrough_count = 0; + failed_target_count = 0U; + + targets_set=0; + fallthroughs_set=0; + scoops_detected=0; + + elfiop = std::unique_ptr<EXEIO::exeio>(nullptr); + } + + ~PopulateCFG(void) override + { + // do nothing (this class uses shared IRDB objects that + // are not managed by this class). + } + + std::string getStepName(void) const override + { + return std::string("fill_in_cfg"); + } + int parseArgs(const std::vector<std::string> step_args) override; + int executeStep(IRDB_SDK::IRDBObjects_t *const) override; + + private: // methods + + // main workers + void fill_in_cfg(IRDB_SDK::FileIR_t *); + void fill_in_scoops(IRDB_SDK::FileIR_t *); + void detect_scoops_in_code(IRDB_SDK::FileIR_t *firp); + void fill_in_landing_pads(IRDB_SDK::FileIR_t *); + + // helpers + void populate_instruction_map + ( + std::map< std::pair<IRDB_SDK::DatabaseID_t,IRDB_SDK::VirtualOffset_t>, IRDB_SDK::Instruction_t*>&, + IRDB_SDK::FileIR_t * + ); + + void set_fallthrough + ( + std::map< std::pair<IRDB_SDK::DatabaseID_t,IRDB_SDK::VirtualOffset_t>, IRDB_SDK::Instruction_t*>&, + IRDB_SDK::DecodedInstruction_t *, IRDB_SDK::Instruction_t *, IRDB_SDK::FileIR_t * + ); + + void set_target + ( + std::map< std::pair<IRDB_SDK::DatabaseID_t,IRDB_SDK::VirtualOffset_t>, IRDB_SDK::Instruction_t*>&, + IRDB_SDK::DecodedInstruction_t *, IRDB_SDK::Instruction_t *, IRDB_SDK::FileIR_t * + ); + + IRDB_SDK::File_t* find_file(IRDB_SDK::FileIR_t *, IRDB_SDK::DatabaseID_t); + void add_new_instructions(IRDB_SDK::FileIR_t *); + bool is_in_relro_segment(const int); + + private: //data + + // stats + int odd_target_count; + int bad_target_count; + int bad_fallthrough_count; + unsigned int failed_target_count; + + size_t targets_set=0; + size_t fallthroughs_set=0; + size_t scoops_detected=0; + + // non-optional + IRDB_SDK::DatabaseID_t variant_id; + bool fix_landing_pads; + + std::unique_ptr<EXEIO::exeio> elfiop; + std::set< std::pair<IRDB_SDK::DatabaseID_t,IRDB_SDK::VirtualOffset_t> > missed_instructions; +}; + +#endif diff --git a/irdb-lib/ir_builders/fill_in_indtargs.cpp b/irdb-lib/ir_builders/fill_in_indtargs.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0eff242bbd708189b4cbe2a4613d418ed528669e --- /dev/null +++ b/irdb-lib/ir_builders/fill_in_indtargs.cpp @@ -0,0 +1,3761 @@ + +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <irdb-core> +#include <irdb-util> +#include <iostream> +#include <fstream> +#include <limits> +#include <string> +#include <algorithm> +#include <stdlib.h> +#include <string.h> +#include <map> +#include <assert.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <regex.h> +#include <ctype.h> +#include <list> +#include <stdio.h> +#include <elf.h> + +#include <exeio.h> +#include "check_thunks.hpp" +#include "fill_in_indtargs.hpp" +#include "libMEDSAnnotation.h" + +using namespace IRDB_SDK; +using namespace std; +using namespace EXEIO; +using namespace MEDS_Annotation; + + +/* + * defines + */ +#define ALLOF(a) begin(a),end(a) + +extern void read_ehframe(FileIR_t* firp, EXEIO::exeio* ); + + + +class PopulateIndTargs_t : public TransformStep_t +{ + +// record all full addresses and page-addresses found per function (or null for no function +using PerFuncAddrSet_t=set<VirtualOffset_t>; +map<Function_t*,PerFuncAddrSet_t> all_adrp_results; +map<Function_t*,PerFuncAddrSet_t> all_add_adrp_results; + +// record all full addresses and page-addresses found that are spilled to the stack +using SpillPoint_t = pair<Function_t*, VirtualOffset_t>; +map<SpillPoint_t,PerFuncAddrSet_t> spilled_add_adrp_results; +map<SpillPoint_t,PerFuncAddrSet_t> spilled_adrps; + +// record all full addresses found that are spilled to to a floating-point register (e.g., D10) +using DregSpillPoint_t = pair<Function_t*, string>; +map<DregSpillPoint_t, PerFuncAddrSet_t> spilled_to_dreg; + +map<string,PerFuncAddrSet_t> per_reg_add_adrp_results; + +public: + + +/* + * class variables + */ + + +// the bounds of the executable sections in the pgm. +set< pair <VirtualOffset_t,VirtualOffset_t> > bounds; + +// the set of (possible) targets we've found. +map<VirtualOffset_t,ibt_provenance_t> targets; + +// the set of ranges represented by the eh_frame section, could be empty for non-elf files. +set< pair< VirtualOffset_t, VirtualOffset_t> > ranges; + +// a way to map an instruction to its set of (direct) predecessors. +map< Instruction_t* , InstructionSet_t > preds; + +// keep track of jmp tables +map< Instruction_t*, fii_icfs > jmptables; + +// a map of virtual offset -> instruction for quick access. +map<VirtualOffset_t,Instruction_t*> lookupInstructionMap; + +// the set of things that are partially unpinned already. +set<Instruction_t*> already_unpinned; + +long total_unpins=0; + +void range(VirtualOffset_t start, VirtualOffset_t end) +{ + pair<VirtualOffset_t,VirtualOffset_t> foo(start,end); + ranges.insert(foo); +} + + +/* + * is_in_range - determine if an address is referenced by the eh_frame section + */ +bool is_in_range(VirtualOffset_t p) +{ + for(auto bound : ranges) + { + auto start=bound.first; + auto end=bound.second; + if(start<=p && p<=end) + return true; + } + return false; +} + +/* + * process_range - do nothing now -- fix calls deals with this. + */ +void process_ranges(FileIR_t* firp) +{ + +} + +bool possible_target(VirtualOffset_t p, VirtualOffset_t from_addr, ibt_provenance_t prov) +{ + if(is_possible_target(p,from_addr)) + { + if(getenv("IB_VERBOSE")!=nullptr) + { + if(from_addr!=0) + cout<<"Found IB target address 0x"<<std::hex<<p<<" at 0x"<<from_addr<<std::dec<<", prov="<<prov<<endl; + else + cout<<"Found IB target address 0x"<<std::hex<<p<<" from unknown location, prov="<<prov<<endl; + } + targets[p].add(prov); + return true; + } + return false; +} + +bool is_possible_target(VirtualOffset_t p, VirtualOffset_t addr) +{ + for(auto bound : bounds) + { + auto start=bound.first; + auto end=bound.second; + if(start<=p && p<=end) + { + return true; + } + } + return false; + +} + +EXEIO::section* find_section(VirtualOffset_t addr, EXEIO::exeio *elfiop) +{ + for ( int i = 0; i < elfiop->sections.size(); ++i ) + { + EXEIO::section* pSec = elfiop->sections[i]; + assert(pSec); + if(pSec->get_address() > addr) + continue; + if(addr >= pSec->get_address()+pSec->get_size()) + continue; + + return pSec; + } + return nullptr; +} + +void handle_argument( + const DecodedInstruction_t& decoded_insn, + const DecodedOperand_t &arg, + Instruction_t* insn, + ibt_provenance_t::provtype_t pt = ibt_provenance_t::ibtp_text + ) +{ + if(arg.isMemory() && decoded_insn.getMnemonic()=="lea") + { + if(arg.isPcrel()) + { + assert(insn); + assert(insn->getAddress()); + possible_target(arg.getMemoryDisplacement() + insn->getAddress()->getVirtualOffset() + + insn->getDataBits().length(), insn->getAddress()->getVirtualOffset(), pt); + } + else + { + possible_target(arg.getMemoryDisplacement(), insn->getAddress()->getVirtualOffset(), pt); + } + } +} + + +void lookupInstruction_init(FileIR_t *firp) +{ + lookupInstructionMap.clear(); + for(auto insn : firp->getInstructions()) + { + const auto addr=insn->getAddress()->getVirtualOffset(); + lookupInstructionMap[addr]=insn; + } +} + +Instruction_t *lookupInstruction(FileIR_t *firp, VirtualOffset_t virtual_offset) +{ + if(lookupInstructionMap.find(virtual_offset)!=lookupInstructionMap.end()) + return lookupInstructionMap[virtual_offset]; + return nullptr; +} + +void mark_targets(FileIR_t *firp) +{ + for(auto insn : firp->getInstructions()) + { + auto addr=insn->getAddress()->getVirtualOffset(); + + /* lookup in the list of targets */ + if(targets.find(addr)!=targets.end()) + { + const auto isret=targets[addr].areOnlyTheseSet(ibt_provenance_t::ibtp_ret); + const auto isprintf=targets[addr].areOnlyTheseSet(ibt_provenance_t::ibtp_stars_data|ibt_provenance_t::ibtp_texttoprintf); + if (isret) + { + if(getenv("IB_VERBOSE")!=nullptr) + cout<<"Skipping pin for ret at "<<hex<<addr<<endl; + } + else if(isprintf) + { + if(getenv("IB_VERBOSE")!=nullptr) + cout<<"Skipping pin for text to printf at "<<hex<<addr<<endl; + } + else + { + if(getenv("IB_VERBOSE")!=nullptr) + cout<<"Setting pin at "<<hex<<addr<<endl; + /* + AddressID_t* newaddr = new AddressID_t; + newaddr->SetFileID(insn->getAddress()->getFileID()); + newaddr->setVirtualOffset(insn->getAddress()->getVirtualOffset()); + firp->getAddresses().insert(newaddr); + */ + auto newaddr=firp->addNewAddress(insn->getAddress()->getFileID(), insn->getAddress()->getVirtualOffset()); + insn->setIndirectBranchTargetAddress(newaddr); + } + } + } +} + + +bool CallToPrintfFollows(FileIR_t *firp, Instruction_t* insn, const string& arg_str) +{ + for(auto ptr=insn->getFallthrough(); ptr!=nullptr; ptr=ptr->getFallthrough()) + { + auto d=DecodedInstruction_t ::factory(ptr); + if(d->getMnemonic() == string("call")) + { + // check we have a target + if(ptr->getTarget()==nullptr) + return false; + + // check the target has a function + if(ptr->getTarget()->getFunction()==nullptr) + return false; + + // check if we're calling printf. + if(ptr->getTarget()->getFunction()->getName().find("printf")==string::npos) + return false; + + // found it + return true; + } + + // found reference to argstring, assume it's a write and exit + if(d->getDisassembly().find(arg_str)!= string::npos) + return false; + } + + return false; +} + +bool texttoprintf(FileIR_t *firp,Instruction_t* insn) +{ + string dst=""; + // note that dst is an output parameter of IsParameterWrite and an input parameter to CallFollows + if(isParameterWrite(firp,insn, dst) && CallToPrintfFollows(firp,insn,dst)) + { + return true; + } + return false; +} + +void get_instruction_targets(FileIR_t *firp, EXEIO::exeio* elfiop, const set<VirtualOffset_t>& thunk_bases) +{ + + for(auto insn : firp->getInstructions()) + { + auto disasm=DecodedInstruction_t::factory(insn); + VirtualOffset_t instr_len = disasm->length(); // Disassemble(insn,disasm); + + assert(instr_len==insn->getDataBits().size()); + + const auto mt=firp->getArchitecture()->getMachineType(); + + if(mt==admtX86_64 || mt==admtI386) + { + // work for both 32- and 64-bit. + check_for_PIC_switch_table32_type2(firp, insn, *disasm, elfiop, thunk_bases); + check_for_PIC_switch_table32_type3(firp, insn, *disasm, elfiop, thunk_bases); + + if (firp->getArchitectureBitWidth()==32) + check_for_PIC_switch_table32(firp, insn, *disasm, elfiop, thunk_bases); + else if (firp->getArchitectureBitWidth()==64) + check_for_PIC_switch_table64(firp, insn, *disasm, elfiop); + else + assert(0); + + check_for_nonPIC_switch_table(firp, insn, *disasm, elfiop); + check_for_nonPIC_switch_table_pattern2(firp, insn, *disasm, elfiop); + } + else if(mt==admtAarch64) + { + check_for_arm_switch_type1(firp,insn, *disasm, elfiop); + } + else + throw invalid_argument("Cannot determine machine type"); + + /* other branches can't indicate an indirect branch target */ + if(disasm->isBranch()) // disasm.Instruction.BranchType) + continue; + + ibt_provenance_t::provtype_t prov=0; + if(!texttoprintf(firp,insn)) + { + prov=ibt_provenance_t::ibtp_text; + } + else + { + cout<<"TextToPrintf analysis of '"<<disasm->getDisassembly()<<"' successful at " <<hex<<insn->getAddress()->getVirtualOffset()<<endl; + prov=ibt_provenance_t::ibtp_texttoprintf; + } + /* otherwise, any immediate is a possible branch target */ + for(const auto& op: disasm->getOperands()) + { + if(op->isConstant()) + possible_target(op->getConstant(), 0, prov); + } + + for(auto i=0;i<4;i++) + { + if(disasm->hasOperand(i)) + { + const auto op=disasm->getOperand(i); + handle_argument(*disasm, *op, insn, prov); + } + } + } +} + +void get_executable_bounds(FileIR_t *firp, const section* shdr) +{ + + /* not a loaded section */ + if( !shdr->isLoadable()) + return; + + /* loaded, and contains instruction, record the bounds */ + if( !shdr->isExecutable() ) + return; + + VirtualOffset_t first=shdr->get_address(); + VirtualOffset_t second=shdr->get_address()+shdr->get_size(); + + bounds.insert(pair<VirtualOffset_t,VirtualOffset_t>(first,second)); + + +} + +void infer_targets(FileIR_t *firp, section* shdr) +{ +// int flags = shdr->get_flags(); + + if( ! shdr->isLoadable()) // (flags & SHF_ALLOC) != SHF_ALLOC) + /* not a loaded section */ + return; + + if( shdr->isExecutable() ) //(flags & SHF_EXECINSTR) == SHF_EXECINSTR) + /* loaded, but contains instruction. we'll look through the VariantIR for this section. */ + return; + + /* if the type is NOBITS, then there's no actual data to look through */ + if(shdr->isBSS() ) // get_type()==SHT_NOBITS) + return; + + + cout<<"Checking section "<<shdr->get_name() <<endl; + + const char* data=shdr->get_data() ; // C(char*)malloc(shdr->sh_size); + + assert(arch_ptr_bytes()==4 || arch_ptr_bytes()==8); + for(auto i=0u;i+arch_ptr_bytes()<=(size_t)shdr->get_size();i++) + { + // even on 64-bit, pointers might be stored as 32-bit, as a + // elf object has the 32-bit limitations. + // there's no real reason to look for 64-bit pointers + uintptr_t p=0; + if(arch_ptr_bytes()==4) + p=*(int*)&data[i]; + else + p=*(VirtualOffset_t*)&data[i]; // 64 or 32-bit depending on sizeof uintptr_t, may need porting for cross platform analysis. + + + + ibt_provenance_t prov; + if(shdr->get_name()==".init_array") + prov=ibt_provenance_t::ibtp_initarray; + else if(shdr->get_name()==".fini_array") + prov=ibt_provenance_t::ibtp_finiarray; + else if(shdr->get_name()==".got.plt") + prov=ibt_provenance_t::ibtp_gotplt; + else if(shdr->get_name()==".got") + prov=ibt_provenance_t::ibtp_got; + else if(shdr->get_name()==".dynsym") + prov=ibt_provenance_t::ibtp_dynsym; + else if(shdr->get_name()==".symtab") + prov=ibt_provenance_t::ibtp_symtab; + else if(shdr->isWriteable()) + prov=ibt_provenance_t::ibtp_data; + else + prov=ibt_provenance_t::ibtp_rodata; + + possible_target(p, i+shdr->get_address(), prov); + + } + +} + +void handle_scoop_scanning(FileIR_t* firp) +{ + // check for addresses in scoops in the text section. + for(auto scoop : firp->getDataScoops()) + { + // test if scoop was added by fill_in_cfg -- make this test better. + if(scoop->getName().find("data_in_text_")==string::npos) continue; + + + // at the moment, FIC only creates 4-, 8-, and 16- bytes scoops + // change this code if FIC chagnes. + if(scoop->getSize() == 4 ) + { + // may be a 4-byter, which can't hold an address. + continue; + } + if(scoop->getSize() == 8 ) + { + // check to see if the scoop has an IBTA + const auto addr=*(uint64_t*)(scoop->getContents().c_str()); + possible_target(addr, scoop->getStart()->getVirtualOffset(), ibt_provenance_t::ibtp_unknown); + } + else + { + // we may see 16 indicating that a ldr q-word happened. + // this isn't likely an IBT, so we skip scanning it. + assert(scoop->getSize() == 16 ); + } + } +} + + + +void print_targets() +{ + int j=1; + for(auto p : targets ) + { + const auto target=p.first; + + cout<<hex<<target; + if(j%10 == 0) + cout<<endl; + else + cout<<", "; + j++; + } + + cout<<endl; +} + +set<Instruction_t*> find_in_function(string needle, Function_t *haystack) +{ + regex_t preg; + set<Instruction_t*> found_instructions; + + assert(0 == regcomp(&preg, needle.c_str(), REG_EXTENDED)); + + for (auto candidate : haystack->getInstructions()) + { + auto disasm=DecodedInstruction_t::factory(candidate); + + // check it's the requested type + if(regexec(&preg, disasm->getDisassembly().c_str(), 0, nullptr, 0) == 0) + { + found_instructions.insert(candidate); + } + } + regfree(&preg); + return found_instructions; +} + + + +bool backup_until(const string &insn_type_regex_str, + Instruction_t *& prev, + Instruction_t* orig, + const string & stop_if_set="", + bool recursive=false, + uint32_t max_insns=10000u, + uint32_t max_recursions=5u) +{ + + const auto find_or_build_regex=[&] (const string& s) -> regex_t& + { + // declare a freer for regexs so they go away when the program ends. + const auto regex_freer=[](regex_t* to_free) -> void + { + regfree(to_free); + delete to_free; + }; + // keep the map safe from anyone but me using it. + using regex_unique_ptr_t=unique_ptr<regex_t, decltype(regex_freer)>; + static map<string, regex_unique_ptr_t > regexs_used; + + if(s=="") + { + static regex_t empty; + return empty; + } + const auto it=regexs_used.find(s); + if(it==regexs_used.end()) + { + // allocate a new regex ptr + regexs_used.insert(pair<string,regex_unique_ptr_t>(s,move(regex_unique_ptr_t(new regex_t, regex_freer)))); + // and compile it. + auto ®ex_ptr=regexs_used.at(s); + const auto ret=regcomp(regex_ptr.get(), s.c_str(), REG_EXTENDED); + // error check + assert(ret==0); + } + return *regexs_used.at(s).get(); + }; + + + // build regexs. + const auto &preg = find_or_build_regex(insn_type_regex_str); + const auto &stop_expression = find_or_build_regex(stop_if_set); + + + prev=orig; + while(preds[prev].size()==1 && max_insns > 0) + { + // dec max for next loop + max_insns--; + + // get the only item in the list. + prev=*(preds[prev].begin()); + + + // get I7's disassembly + const auto disasm=DecodedInstruction_t::factory(prev); + + // check it's the requested type + if(regexec(&preg, disasm->getDisassembly().c_str(), 0, nullptr, 0) == 0) + return true; + + if(stop_if_set!="") + { + for(const auto operand : disasm->getOperands()) + { + if(operand->isWritten() && regexec(&stop_expression, operand->getString().c_str(), 0, nullptr, 0) == 0) + return false; + } + } + + // otherwise, try backing up again. + } + if(recursive && max_insns > 0 && max_recursions > 0 ) + { + const auto myprev=prev; + // can't just use prev because recursive call will update it. + const auto &mypreds=preds[myprev]; + for(const auto pred : mypreds) + { + prev=pred;// mark that we are here, in case we return true here. + const auto disasm=DecodedInstruction_t::factory(pred); + // check it's the requested type + if(regexec(&preg, disasm->getDisassembly().c_str(), 0, nullptr, 0) == 0) + return true; + if(stop_if_set!="") + { + for(const auto operand : disasm->getOperands()) + { + if(operand->isWritten() && regexec(&stop_expression, operand->getString().c_str(), 0, nullptr, 0) == 0) + return false; + } + } + if(backup_until(insn_type_regex_str, prev, pred, stop_if_set, recursive, max_insns, max_recursions/mypreds.size())) + return true; + + // reset for next call + prev=myprev; + } + } + return false; +} + + + +void check_for_arm_switch_type1( + FileIR_t *firp, + Instruction_t* i10, + const DecodedInstruction_t &d10, + EXEIO::exeio* elfiop) +{ + ibt_provenance_t prov=ibt_provenance_t::ibtp_switchtable_type1; + +#if 0 +Sample code for this branch type: + + ; x2 gets the value of x0 + ; this probably is not normal or required, but we are not checking + ; it anyhow. This is just to understand the example. + +i1: 0x4039c4: cmp table_index_reg, #0x3 +i2: 0x4039c8: b.hi 0x4039d4 ; may also be a b.ls + + // generate switch table base address + // this code may be hard to find if the compiler optimizes it + // outside the block with the rest of the dispatch code, and/or + // spills a register. + // thus, we allow for it not to be found, and instead us any "unk" + // we return true if we've found the entry to avoid looking at unks + // if we don't need to. +i5: 0x40449c: adrp table_page_reg, 0x415000 // table page +i6: 0x4044a0: add table_base_reg, table_page_reg, #0x2b0 // table offset + // table=table_page+table_offset + // + // load from switch table +i7: 0x4044a4: ldrh table_entry_reg, [table_base_reg,table_index_reg,uxtw #1] +or +i7: 0x4044a4: ldrb table_entry_reg, [table_base_reg,table_index_reg,uxtw ] + + // calculate branch_addr+4+table[i]*4 +i8: 0x4044a8: adr branch_reg, 0x4044b4 // jump base addr +i9: 0x4044ac: add i10_reg, branch_reg, table_entry_reg, sxth #2 + // actually take the branch +i10: 0x4044b0: br i10_reg +i11: 0x4044b4: + + +notes: + +1) jump table entries are 2-bytes +2) jump table entries specify an offset from the byte after dispatch branch +3) jump table entries dont store the lower 2 bits of the offset, as they + have to be 0 due to instruction alignment + + +#endif + // sanity check the jump + if(d10.getMnemonic() != "br") return; + + // grab the reg + const auto i10_reg=d10.getOperand(0)->getString(); + + // try to find I9 + auto i9=(Instruction_t*)nullptr; + /* search for externder=sxth or sxtb */ + if(!backup_until( string()+"(add "+i10_reg+",.* sxth #2)|(add "+i10_reg+",.* sxtb #2)", /* look for this pattern. */ + i9, /* find i9 */ + i10, /* before I10 */ + "^"+i10_reg+"$" /* stop if i10_reg set */ + )) + { + return; + } + + // Extract the I9 fields. + assert(i9); + const auto d9p = DecodedInstruction_t::factory(i9); + const auto &d9 = *d9p; + const auto offset_reg = d9.getOperand(1)->getString(); + const auto table_entry_reg = d9.getOperand(2)->getString(); + + + // try to find I8 + auto i8=(Instruction_t*)nullptr; + if(!backup_until(string()+"adr "+offset_reg+",", /* look for this pattern. */ + i8, /* find i8 */ + i9, /* before I9 */ + "^"+offset_reg+"$" /* stop if offste_reg set */ + )) + return; + + + // extract the I8 fields + assert(i8); + const auto d8p = DecodedInstruction_t::factory(i8); + const auto &d8 = *d8p; + const auto jump_base_addr = d8.getOperand(1)->getConstant(); + + // try to find I7 + auto i7=(Instruction_t*)nullptr; + if(!backup_until(string()+ "(ldrh "+table_entry_reg+",)|(ldrb "+table_entry_reg+",)", /* look for this pattern. */ + i7, /* find i7 */ + i9, /* before I9 */ + "^"+table_entry_reg+"$" /* stop if index_reg set */ + )) + return; + + + // extract the I7 fields + assert(i7); + const auto d7p = DecodedInstruction_t::factory(i7); + const auto &d7 = *d7p; + const auto memory_op_string = d7.getOperand(1)->getString(); + const auto plus_pos = memory_op_string.find(" +"); + const auto table_base_reg = memory_op_string.substr(0,plus_pos); + const auto table_index_reg = memory_op_string.substr(plus_pos+3); + const auto table_entry_size = + d7.getMnemonic()=="ldrb" ? 1 : + d7.getMnemonic()=="ldrh" ? 2 : + throw invalid_argument("Unable to detected switch table entry size for ARM64"); + + // now we try to find the table base in I5 and I6 + // but we may fail due to compiler opts. Prepare for such failures + // by creating a set of possible table bases. + // If we find i5/i6 or a reload of a spilled table address, + // we will refine our guess. + auto all_table_bases= per_reg_add_adrp_results[table_base_reg]; + + // try to find I6 + auto i6=(Instruction_t*)nullptr; + if(backup_until(string()+"add "+table_base_reg+",", /* look for this pattern. */ + i6, /* find i6 */ + i7, /* before I7 */ + "^"+table_base_reg+"$", /* stop if table_base_reg set */ + true, /* look hard -- recursely examine up to 10k instructions and 500 blocks */ + 10000, + 500 + )) + { + + + // extract the I6 fields + assert(i6); + const auto d6p = DecodedInstruction_t::factory(i6); + const auto &d6 = *d6p; + const auto table_page_reg = d6.getOperand(1)->getString(); + const auto table_page_offset = d6.getOperand(2)->getConstant(); + + // try to find I5 + auto i5=(Instruction_t*)nullptr; + if(backup_until(string()+"adrp "+table_page_reg+",", /* look for this pattern. */ + i5, /* find i5 */ + i6, /* before I6 */ + "^"+table_page_reg+"$", /* stop if table_page set */ + true, /* look hard -- recursely examine up to 10k instructions and 500 blocks */ + 10000, + 500 + )) + { + // extract i5 fields + assert(i5); + const auto d5p = DecodedInstruction_t::factory(i5); + const auto &d5 = *d5p; + const auto table_page = d5.getOperand(1)->getConstant(); + const auto table_addr=table_page+table_page_offset; + all_table_bases= PerFuncAddrSet_t({table_addr}); + } + else + { + for(auto adrp_value : all_adrp_results[i10->getFunction()]) + { + all_table_bases.insert(adrp_value+table_page_offset); + } + } + } + // could not find i5/i6, it's possible (likely) that the table was just spilled and is being + // reloaded from the stack. check for that. + else if(backup_until(string()+"ldr "+table_base_reg+",", /* look for this pattern. */ + i6, /* find i6 -- the reload of the table */ + i7, /* before I7 */ + "^"+table_base_reg+"$", /* stop if table_base_reg set */ + true, /* look hard -- recursely examine up to 10k instructions and 500 blocks */ + 10000, + 500 + )) + { + assert(i6); + const auto d6p = DecodedInstruction_t::factory(i6); + const auto &d6 = *d6p; + // found reload of table address from spill location! + // reloads write to the stack with a constant offset. + const auto reload_op1=d6.getOperand(1); + assert(reload_op1->isMemory()); + const auto reload_op1_string=reload_op1->getString(); + + // needs to have a base reg, which is either sp or x29 + const auto hasbr = (reload_op1->hasBaseRegister()) ; + const auto okbr = (reload_op1_string.substr(0,2)=="sp" || reload_op1_string.substr(0,3)=="x29" ) ; + const auto hasdisp = (reload_op1->hasMemoryDisplacement()) ; + const auto hasir = (reload_op1->hasIndexRegister()) ; + const auto ok = hasbr && okbr && hasdisp && !hasir; + + if(ok) + { + // extract fields + const auto reload_disp=reload_op1->getMemoryDisplacement(); + const auto reload_loc=SpillPoint_t({i10->getFunction(),reload_disp}); + const auto &spills=spilled_add_adrp_results[reload_loc]; + if(spills.size()>0) + { + all_table_bases=spills; + cout<<"Using spilled table bases from stack!"<<endl; + } + } + + } + // also possible we couldn't find it spilled to the stack, and it's instead spilled to an FP register. + else if(backup_until(string()+"fmov "+table_base_reg+",", /* look for this pattern. */ + i6, /* find i6 -- the reload of the table from an FP reg*/ + i7, /* before I7 */ + "^"+table_base_reg+"$", /* stop if table_base_reg set */ + true, /* look hard -- recursely examine up to 10k instructions and 500 blocks */ + 10000, + 500 + )) + { + assert(i6); + const auto d6p = DecodedInstruction_t::factory(i6); + const auto &d6 = *d6p; + const auto reload_op1 = d6.getOperand(1); + const auto reload_op1_str = reload_op1->getString(); + const auto is_dreg = reload_op1_str[0]=='d'; + + if(is_dreg) + { + + const auto reload_loc = DregSpillPoint_t({i6->getFunction(), reload_op1_str}); + const auto spills = spilled_to_dreg[reload_loc]; + if(spills.size()>0) + { + all_table_bases=spills; + cout<<"Using spilled table bases from d-reg!"<<endl; + } + } + } + // end trying to find the table base. + + // try to find i1+i2 so we can assign a resonable bound on the switch table size. + // assume it's 1024 if we can't otherwise find it. + const auto max_bound=1024u; + auto my_bound=max_bound; + + // start by finding i2. + auto i2=(Instruction_t*)nullptr; + if(backup_until(string()+"(b.hi)|(b.ls)", /* look for this pattern. */ + i2, /* find i2 */ + i7, /* before I7 */ + "", /* don't stop for reg sets, just look for control flow */ + true /* recurse into other blocks */ + )) + { + /* find i1 */ + auto i1=(Instruction_t*)nullptr; + if(backup_until(string()+"cmp ", /* look for this pattern. */ + i1, /* find i1 */ + i2, /* before I2 */ + "(cmp)|(adds)|(subs)|(cmn)", /* stop for CC-setting insns -- fixme, probably not the right syntax for stop-if */ + true /* recurse into other blocks */ + )) + { + // try to verify that there's data flow from the ldr[bh] to the cmp + auto next_reg=table_index_reg; + auto prev_insn=i7; + while(true) + { + auto new_i1=(Instruction_t*)nullptr; + if(backup_until(string()+"cmp "+next_reg+",", /* look for this pattern. */ + new_i1, /* find i1 */ + prev_insn, /* before prev_insn */ + "^"+next_reg+"$", /* stop if next_reg is set */ + true /* recurse into other blocks */ + )) + { + if(i1!=new_i1) /* sanity check that we got to the same place */ + break; + const auto d1 = DecodedInstruction_t::factory(i1); + const auto d1op1 = d1->getOperand(1); + if(d1op1->isConstant()) + { + my_bound=d1op1->getConstant(); + } + break; + + } + else if(backup_until(string()+"mov "+next_reg+",", /* look for this pattern. */ + new_i1, /* find i1 */ + prev_insn, /* before I2 */ + "^"+next_reg+"$", /* stop if next_reg is set */ + true /* recurse into other blocks */ + )) + { + // track backwards on reg 2 if we find a mov <reg1>, <reg2> + const auto d1 = DecodedInstruction_t::factory(new_i1); + const auto new_d1op1 = d1->getOperand(1); + if(new_d1op1->isRegister()) + { + next_reg=new_d1op1->getString(); + continue; + } + else + { + // movd constant into table reg? wtf + break; + } + } + else + { + // no bound found + break; + } + assert(0); + } + } + + } + + const auto do_verbose=getenv("IB_VERBOSE"); + + // given: + // 1) a set of possible places for a jump table (all_table_bases) + // 2) address from which the the tables is relative (jump_base_addr) + // 3) the size of the table (my_bound) + // + // calculate any possible targets for this switch. + + // consider each jump table + auto my_targets=set<VirtualOffset_t>(); + auto valid_table_count=0u; + for(auto cur_table_addr : all_table_bases) + { + + // try to find switch table jumps + const auto i10_func=i10->getFunction(); + + // find the section with the jump table + const auto table_section=find_section(cur_table_addr,elfiop); + if(!table_section) continue; + + // if the section has no data, abort if not found + const auto table_section_data_ptr=table_section->get_data(); + if(table_section_data_ptr == nullptr ) continue; + + // get the section's adddress, abort if not loaded + const auto table_section_address=table_section->get_address(); + if(table_section_address==0) continue; + + // ARM swith tables are in ROdata, thus not exectuable and not writeable. + if( table_section->isExecutable() ) continue; + if( table_section->isWriteable() ) continue; + + // calculate how far into the section the table is. + const auto table_offset_into_section=(cur_table_addr-table_section_address); + + // calculate the actual data for the table + const auto table_data_ptr = table_section_data_ptr + table_offset_into_section; + + // calculate a stop point so we don't fall out of the section. + const auto table_section_end_ptr=table_section_data_ptr+table_section->get_size(); + + // define how to map an index in the table into an address to deref. + const auto getEntryPtr = [&](const uint64_t index) { return table_data_ptr + index*table_entry_size; }; + const auto getEntryAddr = [&](const uint64_t index) { return cur_table_addr + index*table_entry_size; }; + + if(do_verbose) + { + // log that we've found a table, etc. + cout << "Found ARM type1 at 0x"<<hex<<i10->getAddress()->getVirtualOffset() + << " with my_bound = 0x"<<hex<<my_bound + << ", table_entry_size = "<<dec<<table_entry_size + << ", jump_base_addr = 0x"<<hex<<jump_base_addr + << ", table_base_reg='"<<table_base_reg<<"'" + << ", table_index_reg='"<<table_index_reg<<"'" + << ", table_addr="<<cur_table_addr + << endl; + } + + const auto do_verbose=getenv("IB_VERBOSE") != nullptr; + + // look at each table entry + auto target_count=0U; + using OffOffProvTuple_t = tuple<VirtualOffset_t, VirtualOffset_t, ibt_provenance_t> ; + auto this_table_targets=vector<OffOffProvTuple_t>(); + for ( ; getEntryPtr(target_count)+table_entry_size < table_section_end_ptr ; target_count++ ) + { + const auto entry_ptr = getEntryPtr(target_count); + const auto entry_address = getEntryAddr(target_count); + const auto table_entry = + table_entry_size==1 ? *(int8_t* )entry_ptr : + table_entry_size==2 ? *(int16_t*)entry_ptr : + throw invalid_argument("Cannot determine how to load table entry from size"); + const auto candidate_ibta = jump_base_addr+table_entry*4; // 4 being instruction alignment factor for ARM64 + const auto ibtarget = lookupInstruction(firp, candidate_ibta); + + if(do_verbose) + cout << "\tEntry #"<<dec<<target_count<<"= ent-addr="<<hex<<entry_address + << " ent="<<hex<<+table_entry // print as int, not char. + << " ibta="<<candidate_ibta; + + // stop if we failed to find an instruction, + // or find an instruction outside the function + if( ibtarget == nullptr ) + { + if(do_verbose) + cout<<" -- no target insn!"<<endl; + break; + } + const auto ibtarget_func=ibtarget->getFunction(); + if( i10_func == nullptr ) + { + // finding switch in non-function is OK. + } + else if(ibtarget_func == nullptr ) + { + // finding target in non-function is OK + } + else if( i10_func != ibtarget_func ) + { + // finding switch in function to different function, not ok. + if(do_verbose) + cout<<" -- switch to diff func? No."<<endl; + break; + + } + + // record that we found something that looks valid-enough to try to pin + // stop if we couldn't pin. + if(!is_possible_target(candidate_ibta,entry_address)) + { + if(do_verbose) + cout<<" -- not valid target!"<<endl; + break; + } + if(firp->findScoop(candidate_ibta)!=nullptr) + { + if(do_verbose) + cout<<" -- not valid target due to data-in-text detection!"<<endl; + break; + + } + + if(do_verbose) + cout<<" -- valid target!"<<endl; + + // record this entry of the table + // this works on newer compilers and is easier to read, but older compilers.... + // this_table_targets.push_back({candidate_ibta, entry_address,prov}); + this_table_targets.push_back(make_tuple(candidate_ibta, entry_address,prov)); + + if(target_count>my_bound) + break; + + } + // allow this table if the bound was a max-bound situation. + // also allow if all the table entries were valid. + // (allow week off-by-one comparison due to inaccurancies in detecting exact bound) + if(my_bound == max_bound || target_count+1 >= my_bound) + { + // since this table is valid, add all entries to the list of IBT's for this IR. + for(auto &t : this_table_targets) + { + const auto candidate_ibta=get<0>(t); + possible_target(candidate_ibta, get<1>(t), get<2>(t)); + my_targets.insert(candidate_ibta); + } + valid_table_count++; + } + } + cout << "Across "<<dec<<all_table_bases.size()<< " tables, "<<valid_table_count<<" are valid, bound="<<my_bound + << " unique target count="<<my_targets.size()<<" entry_size="<<table_entry_size<<endl; + return; +} + + +/* + * check_for_PIC_switch_table32 - look for switch tables in PIC code for 32-bit code. + */ +void check_for_PIC_switch_table32(FileIR_t *firp, Instruction_t* insn, const DecodedInstruction_t& disasm, EXEIO::exeio* elfiop, const set<VirtualOffset_t> &thunk_bases) +{ + + ibt_provenance_t prov=ibt_provenance_t::ibtp_switchtable_type1; +#if 0 + +/* here's typical code */ + +I1: 080a9037 <gedit_floating_slider_get_type+0x607> call 0806938e <_gedit_app_ready+0x8e> // ebx=080a903c +I2: 080a903c <gedit_floating_slider_get_type+0x60c> add $0x45fb8,%ebx // ebx=<module_start> +... +I3: 080a90f8 <gedit_floating_slider_get_type+0x6c8> mov -0x1ac14(%ebx,%esi,4),%eax // table_start=<module_start-0x1ac14 + // table_offset=eax=table_start[esi] +I4: 080a90ff <gedit_floating_slider_get_type+0x6cf> add %ebx,%eax // switch_case=eax=<module_start>+table_offset +I5: 080a9101 <gedit_floating_slider_get_type+0x6d1> jmp *%eax // jump switch_case +... +I6: 0806938e <_gedit_app_ready+0x8e> mov (%esp),%ebx +I7: 08069391 <_gedit_app_ready+0x91> ret + + +/* However, since the thunk and the switch table can be (and sometimes are) very control-flow distinct, + * we just collect all the places where a module can start by examining all the thunk/add pairs. + * After that, we look for all jumps that match the I3-I5 pattern, and consider the offset against each + * module start. If we find that there are possible targets at <module_start>+table_offset, we record them. + */ + +#endif + + Instruction_t* I5=insn; + Instruction_t* Icmp=nullptr; + Instruction_t* I4=nullptr; + Instruction_t* I3=nullptr; + // check if I5 is a jump + if(disasm.getMnemonic() != "jmp") + return; + + // return if it's a jump to a constant address, these are common + if(disasm.getOperand(0)->isConstant() ) + return; + + // return if it's a jump to a memory address + if(disasm.getOperand(0)->isMemory() ) + return; + + assert(disasm.getOperand(0)->isRegister()); + const auto I5_reg=disasm.getOperand(0)->getString(); + auto jmp_reg=string(); + auto add_reg=string(); + + // has to be a jump to a register now + + // backup and find the instruction that's an add before I8 + if(!backup_until(string()+"add "+I5_reg+"|lea "+I5_reg, I4, I5, I5_reg)) + { + auto mov_insn=static_cast<Instruction_t*>(nullptr); + if(!backup_until(string()+"mov "+I5_reg, mov_insn, I5, I5_reg)) + return; + const auto p_mov_insn_disasm=DecodedInstruction_t::factory(mov_insn); + const auto &mov_insn_disasm=*p_mov_insn_disasm; + if(!mov_insn_disasm.getOperand(1)->isRegister()) + return; + const auto mov_reg=mov_insn_disasm.getOperand(1)->getString(); + if(!backup_until(string()+"add "+mov_reg, I4, mov_insn, mov_reg)) + return; + jmp_reg=mov_reg; + } + else + { + const auto p_d4=DecodedInstruction_t::factory(I4); + const auto &d4=*p_d4; + if(d4.getMnemonic()=="lea") + { + const auto base_reg=d4.getOperand(1)->getBaseRegister(); + switch(base_reg) + { + case 0/*REG0*/: jmp_reg="eax"; break; + case 1/*REG1*/: jmp_reg="ecx"; break; + case 2/*REG2*/: jmp_reg="edx"; break; + case 3/*REG3*/: jmp_reg="ebx"; break; + case 4/*REG4*/: jmp_reg="esp"; break; + case 5/*REG5*/: jmp_reg="ebp"; break; + case 6/*REG6*/: jmp_reg="esi"; break; + case 7/*REG7*/: jmp_reg="edi"; break; + default: + // no base register; + return; + } + const auto index_reg=d4.getOperand(1)->getBaseRegister(); + switch(index_reg) + { + case 0/*REG0*/: add_reg="eax"; break; + case 1/*REG1*/: add_reg="ecx"; break; + case 2/*REG2*/: add_reg="edx"; break; + case 3/*REG3*/: add_reg="ebx"; break; + case 4/*REG4*/: add_reg="esp"; break; + case 5/*REG5*/: add_reg="ebp"; break; + case 6/*REG6*/: add_reg="esi"; break; + case 7/*REG7*/: add_reg="edi"; break; + default: + // no base register; + return; + } + } + else + { + jmp_reg=I5_reg; + if(!d4.getOperand(1)->isRegister()) + return; + add_reg=d4.getOperand(1)->getString(); + } + } + + assert(jmp_reg!="" && add_reg!="" && I4!=nullptr); + + + // backup and find the instruction that's an movsxd before I7 + if(!backup_until(string()+"(mov "+jmp_reg+"|mov "+add_reg+")", I3, I4)) + return; + + auto table_size = 0U; + if (!backup_until("cmp", Icmp, I3)) + { + cerr<<"pic32: could not find size of switch table"<<endl; + table_size=std::numeric_limits<int>::max(); + // set table_size to be very large, so we can still do pinning appropriately + } + else + { + //DISASM dcmp; + //Disassemble(Icmp,dcmp); + auto dcmp=DecodedInstruction_t::factory(Icmp); + table_size = dcmp->getImmediate(); //Instruction.Immediat; + if(table_size<=0) + table_size=std::numeric_limits<int>::max(); + } + + // grab the offset out of the lea. + const auto p_d2=DecodedInstruction_t::factory(I3); + const auto &d2=*p_d2; + + // get the offset from the thunk + auto table_offset=d2.getAddress(); + if(table_offset==0) + return; + + cout<<hex<<"Found switch dispatch at "<<I3->getAddress()->getVirtualOffset() + << " with table_offset="<<table_offset <<" and table_size="<<table_size<<endl; + + /* iterate over all thunk_bases/module_starts */ + for(auto thunk_base : thunk_bases) + { + VirtualOffset_t table_base=thunk_base+table_offset; + + // find the section with the data table + EXEIO::section *pSec=find_section(table_base,elfiop); + if(!pSec) + continue; + + // if the section has no data, abort + const char* secdata=pSec->get_data(); + if(!secdata) + continue; + + // get the base offset into the section + VirtualOffset_t offset=table_base-pSec->get_address(); + int i; + for(i=0;i<3;i++) + { + if((int)(offset+i*4+sizeof(int)) > (int)pSec->get_size()) + break; + + const int *table_entry_ptr=(const int*)&(secdata[offset+i*4]); + int table_entry=*table_entry_ptr; + + if(!is_possible_target(thunk_base+table_entry,table_base+i*4)) + break; + } + /* did we finish the loop or break out? */ + if(i==3) + { + set<Instruction_t *> ibtargets; + + if(getenv("IB_VERBOSE")!=0) + cout<<"Found switch table (thunk-relative) at "<<hex<<table_base+table_offset<<endl; + // finished the loop. + for(i=0;true;i++) + { + if((int)(offset+i*4+sizeof(int)) > (int)pSec->get_size()) + break; + + const int32_t *table_entry_ptr=(const int32_t*)&(secdata[offset+i*4]); + VirtualOffset_t table_entry=*table_entry_ptr; + + if(getenv("IB_VERBOSE")!=0) + cout<<"Found switch table (thunk-relative) entry["<<dec<<i<<"], "<<hex<<thunk_base+table_entry<<endl; + + if(!possible_target(thunk_base+table_entry,table_base+i*4,prov)) + break; + + auto ibtarget = lookupInstruction(firp, thunk_base+table_entry); + if (ibtarget && ibtargets.size() <= table_size) + { + ibtargets.insert(ibtarget); + } + } + + // valid switch table? may or may not have default: in the switch + // table size = 8, #entries: 9 b/c of default + cout << "pic32 (base pattern): table size: " << table_size << " ibtargets.size: " << ibtargets.size() << endl; + jmptables[I5].addTargets(ibtargets); + if (table_size == ibtargets.size() || table_size == (ibtargets.size()-1)) + { + cout << "pic32 (base pattern): valid switch table detected ibtp_switchtable_type1" << endl; + jmptables[I5].setAnalysisStatus(iasAnalysisComplete); + + } + } + else + { + if(getenv("IB_VERBOSE")!=0) + cout<<"Found that "<<hex<<table_base+table_offset<<endl; + } + + // now, try next thunk base + } +} + + + +void check_for_PIC_switch_table32_type2(FileIR_t *firp, Instruction_t* insn, const DecodedInstruction_t& disasm, EXEIO::exeio* elfiop, const set<VirtualOffset_t> &thunk_bases) +{ + ibt_provenance_t prov=ibt_provenance_t::ibtp_switchtable_type2; + auto ibtargets = InstructionSet_t(); +#if 0 + +/* here's typical code */ +I1: 0x8098ffc <text_handler+33>: cmp eax,0x8 +I2: 0x8098fff <text_handler+36>: ja 0x8099067 <text_handler+140> +I3: 0x8099001 <text_handler+38>: lea ecx,[ebx-0x21620] +I4: 0x8099007 <text_handler+44>: add ecx,DWORD PTR [ebx+eax*4-0x21620] +I5: 0x809900e <text_handler+51>: jmp ecx +#endif + + Instruction_t* I5=insn; + Instruction_t* I4=nullptr; +// Instruction_t* I3=nullptr; + // check if I5 is a jump + if(strstr(disasm.getMnemonic().c_str() /*disasm.Instruction.Mnemonic*/, "jmp")==nullptr) + return; + + // return if it's a jump to a constant address, these are common + if(disasm.getOperand(0)->isConstant() /*disasm.Argument1.ArgType&CONSTANT_TYPE*/) + return; + + // return if it's a jump to a memory address + //if(disasm.Argument1.ArgType&MEMORY_TYPE) + if(disasm.getOperand(0)->isMemory()) + return; + + // has to be a jump to a register now + + // backup and find the instruction that's an add before I8 + if(!backup_until("add", I4, I5)) + return; + + const auto d4=DecodedInstruction_t::factory(I4); + if(!d4->hasOperand(1) || !d4->getOperand(1)->isMemory()) + return; + + // found that sometimes I3 is set a different way, + // and that it's perfectly reasonable to just use I4's offsets. + // backup and find the instruction that's an movsxd before I7 +// if(!backup_until("lea", I3, I4)) +// return; + + // get the offset from the thunk + VirtualOffset_t table_offset=d4->getOperand(1)->getMemoryDisplacement(); + if(table_offset==0) + return; + + cout<<hex<<"Found (type2) switch dispatch at "<<I5->getAddress()->getVirtualOffset()<< " with table_offset="<<table_offset<<endl; + + /* iterate over all thunk_bases/module_starts */ + for(auto thunk_base : thunk_bases ) + { + auto table_base=thunk_base+table_offset; + + // find the section with the data table + auto pSec=find_section(table_base,elfiop); + if(!pSec) + continue; + + // if the section has no data, abort + const auto secdata=pSec->get_data(); + if(!secdata) + continue; + + // get the base offset into the section + VirtualOffset_t offset=table_base-pSec->get_address(); + int i; + for(i=0;i<3;i++) + { + if((int)(offset+i*4+sizeof(int)) > (int)pSec->get_size()) + break; + + const int32_t *table_entry_ptr=(const int32_t*)&(secdata[offset+i*4]); + VirtualOffset_t table_entry=*table_entry_ptr; + +// cout<<"Checking target base:" << std::hex << table_base+table_entry << ", " << table_base+i*4<<endl; + if(!is_possible_target(table_base+table_entry,table_base+i*4) && !is_possible_target(thunk_base+table_entry,table_base+i*4)) + break; + } + /* did we finish the loop or break out? */ + if(i==3) + { + if(getenv("IB_VERBOSE")!=0) + cout<<"Found switch table (pic3, type2) (thunk-relative) at "<<hex<<table_base+table_offset<<endl; + // finished the loop. + for(i=0;true;i++) + { + if((int)(offset+i*4+sizeof(int)) > (int)pSec->get_size()) + break; + + const int32_t *table_entry_ptr=(const int32_t*)&(secdata[offset+i*4]); + VirtualOffset_t table_entry=*table_entry_ptr; + + if(getenv("IB_VERBOSE")!=0) + cout<<"Found switch table (thunk-relative) entry["<<dec<<i<<"], "<<hex<<table_base+table_entry<<" or "<<thunk_base+table_entry<<endl; + auto t1=possible_target(table_base+table_entry,table_base+i*4,prov); + auto t2=possible_target(thunk_base+table_entry,table_base+i*4,prov); + if(!t1 && !t2) + break; + + auto ibtarget1 = lookupInstruction(firp, table_base+table_entry); + if (ibtarget1) + ibtargets.insert(ibtarget1); + auto ibtarget2 = lookupInstruction(firp, thunk_base+table_entry); + if (ibtarget2) + ibtargets.insert(ibtarget2); + } + } + else + { + if(getenv("IB_VERBOSE")!=0) + cout<<"Found that "<<hex<<table_base+table_offset<<endl; + } + + // now, try next thunk base + } + jmptables[I5].addTargets(ibtargets); +} + + +/* + * Detects this type of switch: + * + * 0x809900e <text_handler+51>: jmp [eax*4 + 0x8088208] + * + * nb: also works for 64-bit. + */ +void check_for_PIC_switch_table32_type3(FileIR_t* firp, Instruction_t* insn, const DecodedInstruction_t& disasm, EXEIO::exeio* elfiop, const set<VirtualOffset_t> &thunk_bases) +{ + uint32_t ptrsize=firp->getArchitectureBitWidth()/8; + ibt_provenance_t prov=ibt_provenance_t::ibtp_switchtable_type3; + + Instruction_t* I5=insn; + // check if I5 is a jump + if(strstr(disasm.getMnemonic().c_str(), "jmp")==nullptr) + return; + + // return if it's not a jump to a memory address + if(!(disasm.getOperand(0)->isMemory())) + return; + + /* return if there's no displacement */ + if(disasm.getOperand(0)->getMemoryDisplacement()==0) + return; + + if(!disasm.getOperand(0)->hasIndexRegister() || disasm.getOperand(0)->getScaleValue()!=ptrsize) + return; + + // grab the table base out of the jmp. + VirtualOffset_t table_base=disasm.getOperand(0)->getMemoryDisplacement(); + if(disasm.getOperand(0)->isPcrel()) + table_base+=insn->getDataBits().size()+insn->getAddress()->getVirtualOffset(); + + if(table_base==0) + return; + + // find the section with the data table + EXEIO::section *pSec=find_section(table_base,elfiop); + if(!pSec) + return; + + auto table_max=numeric_limits<uint32_t>::max(); + auto cmp_insn=(Instruction_t*)nullptr; + if(backup_until("cmp ", cmp_insn, insn)) + { + assert(cmp_insn); + const auto cmp_decode=DecodedInstruction_t::factory(cmp_insn); + table_max=cmp_decode->getImmediate(); + } + + + // if the section has no data, abort + const char* secdata=pSec->get_data(); + if(!secdata) + return; + + // get the base offset into the section + VirtualOffset_t offset=table_base-pSec->get_address(); + + + // check to see if stars already marked this complete. + // if so, just figure out the table size + if(jmptables[insn].getAnalysisStatus()==iasAnalysisComplete) + { + // we already know it's a type3, we can just record the type and table base. + jmptables[insn].AddSwitchType(prov); + jmptables[insn].SetTableStart(table_base); + + // try to determine the table size using the complete set of targets. + int i=0; + for(i=0;true;i++) + { + + if((int)(offset+i*ptrsize+ptrsize) > (int)pSec->get_size()) + return; + + const void *table_entry_ptr=(const int*)&(secdata[offset+i*ptrsize]); + + VirtualOffset_t table_entry=0; + switch(ptrsize) + { + case 4: + table_entry=(VirtualOffset_t)*(int*)table_entry_ptr; + break; + case 8: + table_entry=(VirtualOffset_t)*(int**)table_entry_ptr; + break; + default: + assert(0); + } + + Instruction_t* ibt=lookupInstruction(firp,table_entry); + // if we didn't find an instruction or the insn isn't in our set, stop looking, we've found the table size + if(ibt==nullptr || jmptables[insn].find(ibt) == jmptables[insn].end()) + break; + } + jmptables[insn].SetTableSize(i); + if(getenv("IB_VERBOSE")) + { + cout<<"Found type3 at "<<hex<<insn->getAddress()->getVirtualOffset() + <<" already complete, setting base to "<<hex<<table_base<<" and size to "<<dec<<i<<endl; + } + return; + } + + + auto i=0U; + for(i=0;i<3;i++) + { + if((int)(offset+i*ptrsize+ptrsize) > (int)pSec->get_size()) + return; + + const void *table_entry_ptr=(const int*)&(secdata[offset+i*ptrsize]); + + VirtualOffset_t table_entry=0; + switch(ptrsize) + { + case 4: + table_entry=(VirtualOffset_t)*(int*)table_entry_ptr; + break; + case 8: + table_entry=(VirtualOffset_t)*(int**)table_entry_ptr; + break; + default: + assert(0); + } + + if(getenv("IB_VERBOSE")!=0) + cout<<"Checking target base:" << std::hex << table_entry << ", " << table_base+i*ptrsize<<endl; + + /* if there's no base register and no index reg, */ + /* then this jmp can't have more than one valid table entry */ + if( !disasm.getOperand(0)->hasBaseRegister() && !disasm.getOperand(0)->hasIndexRegister()) + { + /* but the table can have 1 valid entry. */ + if(pSec->get_name()==".got.plt") + { + Instruction_t *ibtarget = lookupInstruction(firp, table_entry); + if(ibtarget) + { + jmptables[I5].insert(ibtarget); + jmptables[I5].setAnalysisStatus(iasAnalysisModuleComplete); + possible_target(table_entry,table_base+0*ptrsize, ibt_provenance_t::ibtp_gotplt); + if(getenv("IB_VERBOSE")!=0) + cout<<hex<<"Found plt dispatch ("<<disasm.getDisassembly()<<"') at "<<I5->getAddress()->getVirtualOffset()<< endl; + return; + } + } + if(pSec->isWriteable()) + possible_target(table_entry,table_base+0*ptrsize, ibt_provenance_t::ibtp_data); + else + possible_target(table_entry,table_base+0*ptrsize, ibt_provenance_t::ibtp_rodata); + if(getenv("IB_VERBOSE")!=0) + cout<<hex<<"Found constant-memory dispatch from non- .got.plt location ("<<disasm.getDisassembly()<<"') at " + <<I5->getAddress()->getVirtualOffset()<< endl; + return; + } + if(!is_possible_target(table_entry,table_base+i*ptrsize)) + { + if(getenv("IB_VERBOSE")!=0) + { + cout<<hex<<"Found (type3) candidate for switch dispatch for '"<<disasm.getDisassembly()<<"' at " + <<I5->getAddress()->getVirtualOffset()<< " with table_base="<<table_base<<endl; + cout<<"Found table_entry "<<hex<<table_entry<<" is not valid\n"<<endl; + } + return; + } + } + + + cout<<hex<<"Definitely found (type3) switch dispatch at "<<I5->getAddress()->getVirtualOffset()<< " with table_base="<<table_base<<endl; + + /* did we finish the loop or break out? */ + if(i==3) + { + if(getenv("IB_VERBOSE")!=0) + cout<<"Found switch table (type3) at "<<hex<<table_base<<endl; + jmptables[insn].AddSwitchType(prov); + jmptables[insn].SetTableStart(table_base); + // finished the loop. + for(i=0;true;i++) + { + if(i>table_max) + { + if(getenv("IB_VERBOSE")!=0) + { + cout<<hex<<"Switch dispatch at "<<I5->getAddress()->getVirtualOffset()<< " with table_base=" + <<table_base<<" is complete!"<<endl; + } + jmptables[insn].setAnalysisStatus(iasAnalysisComplete); + } + if((int)(offset+i*ptrsize+ptrsize) > (int)pSec->get_size() || i > table_max) + return; + + const void *table_entry_ptr=(const int*)&(secdata[offset+i*ptrsize]); + + VirtualOffset_t table_entry=0; + switch(ptrsize) + { + case 4: + table_entry=(VirtualOffset_t)*(int*)table_entry_ptr; + break; + case 8: + table_entry=(VirtualOffset_t)*(int**)table_entry_ptr; + break; + default: + assert(0); + } + + Instruction_t* ibt=lookupInstruction(firp,table_entry); + if(!possible_target(table_entry,table_base+i*ptrsize,prov) || ibt==nullptr) + return; + if(getenv("IB_VERBOSE")!=0) + cout<<"Found switch table (thunk-relative) entry["<<dec<<i<<"], "<<hex<<table_entry<<endl; + + // make table bigger. + jmptables[insn].SetTableSize(i+1);/* 0 index, and this index is determined valid. */ + jmptables[insn].insert(ibt); + } + } + else + { + if(getenv("IB_VERBOSE")!=0) + cout<<"Found that "<<hex<<table_base<<endl; + } +} + + + +/* check if this instruction is an indirect jump via a register, + * if so, see if we can trace back a few instructions to find a + * the start of the table. + */ +void check_for_PIC_switch_table64(FileIR_t* firp, Instruction_t* insn, const DecodedInstruction_t& p_disasm, EXEIO::exeio* elfiop) +{ + ibt_provenance_t prov=ibt_provenance_t::ibtp_switchtable_type4; +/* here's the pattern we're looking for */ +#if 0 +I1: 0x000000000044425a <+218>: cmp DWORD PTR [rax+0x8],0xd // bounds checking code, 0xd cases. switch(i) has i stored in [rax+8] in this e.g. +I2: 0x000000000044425e <+222>: jbe 0x444320 <_gedit_tab_get_icon+416> +<new bb> +I3: 0x0000000000444264 <+228>: mov rdi,rbp // default case, also jumped to via indirect branch below +<snip (doesnt fall through)> +I4: 0x0000000000444320 <+416>: mov edx,DWORD PTR [rax+0x8] # load from memory into index reg EDX. + +THIS ONE +I5: 0x0000000000444323 <+419>: lea rax,[rip+0x3e1b6] # 0x4824e0 +I6: 0x000000000044432a <+426>: movsxd rdx,DWORD PTR [rax+rdx*4] +I7: 0x000000000044432e <+430>: add rax,rdx // OR: lea rax, [rdx+rax] +I8: 0x0000000000444331 <+433>: jmp rax // relatively standard switch dispatch code + + +D1: 0x4824e0: .long 0x4824e0-L1 // L1-LN are labels in the code where case statements start. +D2: 0x4824e4: .long 0x4824e0-L2 +.. +DN: 0x4824XX: .long 0x4824e0-LN + + + + +Alternate version: + + 0x00000000000b939d <+25>: cmp DWORD PTR [rbp-0x4],0xf + 0x00000000000b93a1 <+29>: ja 0xb94a1 <worker_query+285> + 0x00000000000b93a7 <+35>: mov eax,DWORD PTR [rbp-0x4] + 0x00000000000b93aa <+38>: lea rdx,[rax*4+0x0] +I5-1 0x00000000000b93b2 <+46>: lea rax,[rip+0x1f347] # 0xd8700 +I6-2 0x00000000000b93b9 <+53>: mov eax,DWORD PTR [rdx+rax*1] +I6 0x00000000000b93bc <+56>: movsxd rdx,eax +I5-2 0x00000000000b93bf <+59>: lea rax,[rip+0x1f33a] # 0xd8700 + 0x00000000000b93c6 <+66>: add rax,rdx + 0x00000000000b93c9 <+69>: jmp rax + +Note: Since I6 doesnt access memory, do another backup until with to verify address format + +Alternate version 2: + + 0xdcf7 <+7>: mov r8,QWORD PTR [rdi+0xa0] + 0xdcfe <+14>: cmp r8,rax + 0xdd01 <+17>: jbe 0xdd5c <httpd_got_request+108> + 0xdd03 <+19>: mov r9,QWORD PTR [rdi+0x90] +I5 0xdd0a <+26>: lea rcx,[rip+0x2a427] # 0x38138 + 0xdd11 <+33>: cmp DWORD PTR [rdi+0xb0],0xb + 0xdd18 <+40>: movzx edx,BYTE PTR [r9+rax*1] + 0xdd1d <+45>: ja 0xdd4c <httpd_got_request+92> + 0xdd1f <+47>: mov esi,DWORD PTR [rdi+0xb0] +I6 0xdd25 <+53>: movsxd rsi,DWORD PTR [rcx+rsi*4] +I7 0xdd29 <+57>: add rsi,rcx +I8 0xdd2c <+60>: jmp rsi + +Note: Here the operands of the add are reversed, so lookup code was not finding I5 where it was expected.c + + +#endif + + + // for now, only trying to find I4-I8. ideally finding I1 would let us know the size of the + // jump table. We'll figure out N by trying targets until they fail to produce something valid. + + string table_index_str; + Instruction_t* I8=insn; + Instruction_t* I7=nullptr; + Instruction_t* I6=nullptr; + Instruction_t* I5=nullptr; + Instruction_t* I1=nullptr; + // check if I8 is a jump + if(strstr(p_disasm.getMnemonic().c_str(), "jmp")==nullptr) + return; + + // return if it's a jump to a constant address, these are common + if(p_disasm.getOperand(0)->isConstant()) + return; + // return if it's a jump to a memory address + if(p_disasm.getOperand(0)->isMemory()) + return; + + // has to be a jump to a register now + + /* + * This is the instruction that adds the table value + * to the base address of the table. The result is + * the target address of the jump. + * + * Backup and find the instruction that's an add or lea before I8. + */ + table_index_str = "(add "; + table_index_str += p_disasm.getOperand(0)->getString(); + table_index_str += "|lea "; + table_index_str += p_disasm.getOperand(0)->getString(); + table_index_str += ")"; + + const auto cmp_str = string("cmp ") + p_disasm.getOperand(0)->getString(); + + // this was completely broken because argument2 had a null mnemonic, which we found out because getOperand(1) threw an exception. + // i suspect it's attempting to find a compare of operand1 on the RHS of a compare, but i need better regex foo to get that. + // for now, repeat what was working. + const auto cmp_str2 = string("cmp "); + + if(!backup_until(table_index_str.c_str(), I7, I8)) + return; + + const auto d7=DecodedInstruction_t::factory(I7); + + // Check if lea instruction is being used as add (scale=1, disp=0) + if(strstr(d7->getMnemonic().c_str(), "lea")) + { + if(!(d7->getOperand(1)->isMemory() )) + return; + if(!(d7->getOperand(1)->getScaleValue() == 1 && d7->getOperand(1)->getMemoryDisplacement() == 0)) + return; + } + // backup and find the instruction that's an movsxd before I7 + /* + * This instruction will contain the register names for + * the index and the address of the base of the table + */ + if(!backup_until("movsxd", I6, I7)) + return; + + string lea_string="lea "; + + const auto d6=DecodedInstruction_t::factory(I6); + if( d6->getOperand(1)->isMemory() ) + { + // try to be smarter for memory types. + + // 64-bit register names are OK here, because this pattern already won't apply to 32-bit code. + /* + * base_reg is the register that holds the address + * for the base of the jump table. + */ + string base_reg=""; + if(!d6->getOperand(1)->hasBaseRegister() ) + return; + switch(d6->getOperand(1)->getBaseRegister() ) + { + case 0/*REG0*/: base_reg="rax"; break; + case 1/*REG1*/: base_reg="rcx"; break; + case 2/*REG2*/: base_reg="rdx"; break; + case 3/*REG3*/: base_reg="rbx"; break; + case 4/*REG4*/: base_reg="rsp"; break; + case 5/*REG5*/: base_reg="rbp"; break; + case 6/*REG6*/: base_reg="rsi"; break; + case 7/*REG7*/: base_reg="rdi"; break; + case 8/*REG8*/: base_reg="r8"; break; + case 9/*REG9*/: base_reg="r9"; break; + case 10/*REG10*/: base_reg="r10"; break; + case 11/*REG11*/: base_reg="r11"; break; + case 12/*REG12*/: base_reg="r12"; break; + case 13/*REG13*/: base_reg="r13"; break; + case 14/*REG14*/: base_reg="r14"; break; + case 15/*REG15*/: base_reg="r15"; break; + default: + // no base register; + return; + } + lea_string+=base_reg; + } + + /* + * This is the instruction that loads the address of the base + * of the table into a register. + * + * backup and find the instruction that's an lea before I6; + * make sure we match the register, + * and allow recursion in the search (last parameter as true). + * + */ + + /* + * Convert to return set + */ + + auto found_leas=InstructionSet_t(); + + + if (I6->getFunction()) + { + cout << "Using find_in_function method." << endl; + found_leas=find_in_function(lea_string,I6->getFunction()); + } + else + { + cout << "Using fallback method." << endl; + if (backup_until(lea_string.c_str(), I5, I6, "", true)) + { + found_leas.insert(I5); + } + } + if (found_leas.empty()) + { + /* + * TODO: Write this to warning.txt + */ + cout << "WARNING: No I5 candidates found!" << endl; + } + + /* + * Check each one that is returned. + */ + auto found_leas_it = found_leas.begin(); + for (; found_leas_it != found_leas.end(); found_leas_it++) + { + auto I5_cur = *found_leas_it; + auto d5p=DecodedInstruction_t::factory(I5_cur); + auto &d5=*d5p; + + if(!(d5.getOperand(1)->isMemory() )) + continue; + if(!(d5.getOperand(1)->isPcrel() )) + continue; + + // note that we'd normally have to add the displacement to the + // instruction address (and include the instruction's size, etc. + // but, fix_calls has already removed this oddity so we can relocate + // the instruction. + VirtualOffset_t D1=strtol(d5.getOperand(1)->getString().c_str(), nullptr, 0); + D1+=I5_cur->getAddress()->getVirtualOffset(); + + // find the section with the data table + auto pSec=find_section(D1,elfiop); + + // sanity check there's a section + if(!pSec) + continue; + + const char* secdata=pSec->get_data(); + + // if the section has no data, abort + if(!secdata) + continue; + + auto table_size = 0U; + if(backup_until(cmp_str.c_str(), I1, I8)) + { + auto d1=DecodedInstruction_t::factory(I1); + table_size = d1->getImmediate(); // Instruction.Immediat; + if (table_size <= 4) + { + cout<<"pic64: found I1 ('"<<d1->getDisassembly()<<"'), but could not find size of switch table"<<endl; + // set table_size to be very large, so we can still do pinning appropriately + table_size=std::numeric_limits<int>::max(); + } + } + else if(backup_until(cmp_str2.c_str(), I1, I8)) + { + auto d1=DecodedInstruction_t::factory(I1); + table_size = d1->getImmediate()/*Instruction.Immediat*/; + if (table_size <= 4) + { + // set table_size to be very large, so we can still do pinning appropriately + cout<<"pic64: found I1 ('"<<d1->getDisassembly()<<"'), but could not find size of switch table"<<endl; + table_size=std::numeric_limits<int>::max(); + } + } + else + { + cout<<"pic64: could not find size of switch table"<<endl; + + // we set the table_size variable to max_int so that we can still do pinning, + // but we won't do the switch identification. + table_size=std::numeric_limits<int>::max(); + } + + auto ibtargets=InstructionSet_t(); + auto offset=D1-pSec->get_address(); + auto entry=0U; + auto found_table_error = false; + do + { + // check that we can still grab a word from this section + if((int)(offset+sizeof(int)) > (int)pSec->get_size()) + { + found_table_error = true; + break; + } + + const int *table_entry_ptr=(const int*)&(secdata[offset]); + VirtualOffset_t table_entry=*table_entry_ptr; + + if(!possible_target(D1+table_entry, 0/* from addr unknown */,prov)) + { + found_table_error = true; + break; + } + + if(getenv("IB_VERBOSE")) + { + cout<<"Found possible table entry, at: "<< std::hex << I8->getAddress()->getVirtualOffset() + << " insn: " << d5.getDisassembly()<< " d1: " + << D1 << " table_entry:" << table_entry + << " target: "<< D1+table_entry << std::dec << endl; + } + + auto ibtarget = lookupInstruction(firp, D1+table_entry); + if (ibtarget && ibtargets.size() <= table_size) + { + if(getenv("IB_VERBOSE")) + cout << "jmp table [" << entry << "]: " << hex << table_entry << dec << endl; + ibtargets.insert(ibtarget); + } + else + { + if(getenv("IB_VERBOSE")) + cout << " INVALID target" << endl; + + found_table_error = true; + break; + } + offset+=sizeof(int); + entry++; + } while ( entry<=table_size); + + + // valid switch table? may or may not have default: in the switch + // table size = 8, #entries: 9 b/c of default + cout << "pic64: detected table size (max_int means no found): 0x"<< hex << table_size << " #entries: 0x" << entry << " ibtargets.size: " << ibtargets.size() << endl; + + jmptables[I8].addTargets(ibtargets); + // note that there may be an off-by-one error here as table size depends on whether instruction I2 is a jb or jbe. + if (!found_table_error) + { + cout << "pic64: valid switch table for "<<hex<<I8->getAddress()->getVirtualOffset() + <<"detected ibtp_switchtable_type4" << endl; + jmptables[I8].setAnalysisStatus(iasAnalysisComplete); + } + else + { + cout << "pic64: INVALID switch table detected for, " + <<hex<<I8->getAddress()->getVirtualOffset()<<"type=ibtp_switchtable_type4" << endl; + } + } +} + +/* + switch table pattern (non-PIC): + 40062a: 8d 40 ec lea eax,[rax-0x14] + I1: 40062d: 83 f8 08 cmp eax,0x8 'size + I2: 400630: 0f 87 98 00 00 00 ja 4006ce <main+0xbb> + 400636: 89 c0 mov eax,eax + I3: 400638: ff 24 c5 10 08 40 00 jmp QWORD PTR [rax*8+0x400810] 'branch + 40063f: bf a9 07 40 00 mov edi,0x4007a9 + 400644: e8 67 fe ff ff call 4004b0 <puts@plt> + 400649: e9 96 00 00 00 jmp 4006e4 <main+0xd1> + + nb: handles both 32 and 64 bit +*/ +void check_for_nonPIC_switch_table_pattern2(FileIR_t* firp, Instruction_t* insn, const DecodedInstruction_t& p_disasm, EXEIO::exeio* elfiop) +{ + ibt_provenance_t prov=ibt_provenance_t::ibtp_switchtable_type5; + Instruction_t *I1 = nullptr; + Instruction_t *IJ = insn; + + assert(IJ); + + // check if IJ is a jump + if(strstr(p_disasm.getMnemonic().c_str(), "jmp")==nullptr) + return; + + // look for a memory type + if(!(p_disasm.getOperand(0)->isMemory())) + return; + + // make sure there's a scaling factor + if (!p_disasm.getOperand(0)->hasIndexRegister() || p_disasm.getOperand(0)->getScaleValue() < 4) + return; + + // extract start of jmp table + VirtualOffset_t table_offset = p_disasm.getAddress(); // disasm.Instruction.AddrValue; + if(table_offset==0) + return; + + cout<<hex<<"(nonPIC-pattern2): Found switch dispatch at 0x"<<hex<<IJ->getAddress()->getVirtualOffset()<< " with table_offset="<<hex<<table_offset<<dec<<endl; + + if(!backup_until("cmp", I1, IJ)) + { + cout<<"(nonPIC): could not find size of switch table"<<endl; + return; + } + + // extract size off the comparison + // make sure not off by one + auto d1p=DecodedInstruction_t::factory(I1); + auto &d1=*d1p; + VirtualOffset_t table_size = d1.getImmediate()/*d1.Instruction.Immediat*/; + + if (table_size <= 0) return; + + cout<<"(nonPIC-pattern2): size of jmp table: "<< table_size << endl; + + // find the section with the data table + auto pSec=find_section(table_offset,elfiop); + if(!pSec) + { + return; + } + + // if the section has no data, abort + const char* secdata=pSec->get_data(); + if(!secdata) + return; + + // get the base offset into the section + auto offset=table_offset-pSec->get_address(); + auto i=0U; + + InstructionSet_t ibtargets; + for(i=0;i<table_size;++i) + { + if((int)(offset+i*arch_ptr_bytes()+sizeof(int)) > (int)pSec->get_size()) + { + cout << "jmp table outside of section range ==> invalid switch table" << endl; + return; + } + + const VirtualOffset_t *table_entry_ptr=(const VirtualOffset_t*)&(secdata[offset+i*arch_ptr_bytes()]); + VirtualOffset_t table_entry=*table_entry_ptr; + possible_target(table_entry,0,prov); + + Instruction_t *ibtarget = lookupInstruction(firp, table_entry); + if (!ibtarget) { + if(getenv("IB_VERBOSE")) + cout << "0x" << hex << table_entry << " is not an instruction, invalid switch table" << endl; + return; + } + + if(getenv("IB_VERBOSE")) + cout << "jmp table [" << i << "]: " << hex << table_entry << dec << endl; + ibtargets.insert(ibtarget); + } + + cout << "(non-PIC) valid switch table found - ibtp_switchtable_type5" << endl; + + jmptables[IJ].addTargets(ibtargets); + jmptables[IJ].setAnalysisStatus(iasAnalysisComplete); +} + +/* + Handles the following switch table pattern: + I1: 400518: 83 7d ec 0c cmpl $0xc,-0x14(%rbp) 'size + I2: 40051c: 0f 87 b7 00 00 00 ja 4005d9 <main+0xe5> + I3: 400522: 8b 45 ec mov -0x14(%rbp),%eax + I4: 400525: 48 8b 04 c5 20 07 40 mov 0x400720(,%rax,8),%rax 'start jump table + 40052c: 00 + IJ: 40052d: ff e0 jmpq *%rax 'indirect branch + 40052f: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%rbp) + 400536: c7 45 f8 03 00 00 00 movl $0x3,-0x8(%rbp) + + nb: handles both 32 and 64 bit +*/ +void check_for_nonPIC_switch_table(FileIR_t* firp, Instruction_t* insn, const DecodedInstruction_t& p_disasm, EXEIO::exeio* elfiop) +{ + ibt_provenance_t prov=ibt_provenance_t::ibtp_switchtable_type6; + Instruction_t *I1 = nullptr; + Instruction_t *I4 = nullptr; + Instruction_t *IJ = insn; + + if (!IJ) return; + + // check if IJ is a jump + if(strstr(p_disasm.getMnemonic().c_str()/*disasm.Instruction.Mnemonic*/, "jmp")==nullptr) + return; + + // return if it's a jump to a constant address, these are common + if(p_disasm.getOperand(0)->isConstant() /*disasm.Argument1.ArgType&CONSTANT_TYPE*/) + return; + + // return if it's a jump to a memory address + if(p_disasm.getOperand(0)->isMemory() /*disasm.Argument1.ArgType&MEMORY_TYPE*/) + return; + + // has to be a jump to a register now + + // backup and find the instruction that's a mov + if(!backup_until("mov", I4, IJ)) + return; + + // extract start of jmp table + // DISASM d4; + // Disassemble(I4,d4); + auto d4p=DecodedInstruction_t::factory(I4); + auto &d4=*d4p; + + // make sure there's a scaling factor + if (d4.getOperand(1)->isMemory() && d4.getOperand(1)->getScaleValue() < 4) + return; + + VirtualOffset_t table_offset=d4.getAddress(); + if(table_offset==0) + return; + + if(getenv("IB_VERBOSE")) + cout<<hex<<"(nonPIC): Found switch dispatch at 0x"<<hex<<I4->getAddress()->getVirtualOffset()<< " with table_offset="<<hex<<table_offset<<dec<<endl; + + if(!backup_until("cmp", I1, I4)) + { + cout<<"(nonPIC): could not find size of switch table"<<endl; + return; + } + + // extract size off the comparison + // make sure not off by one + auto d1p=DecodedInstruction_t::factory(I1); + auto &d1=*d1p; + auto table_size = d1.getImmediate(); // d1.Instruction.Immediat; + if (table_size <= 0) return; + + if(getenv("IB_VERBOSE")) + cout<<"(nonPIC): size of jmp table: "<< table_size << endl; + + // find the section with the data table + auto pSec=find_section(table_offset,elfiop); + if(!pSec) + { + cout<<hex<<"(nonPIC): could not find jump table in section"<<endl; + return; + } + + // if the section has no data, abort + const char* secdata=pSec->get_data(); + if(!secdata) + return; + + // get the base offset into the section + auto offset=table_offset-pSec->get_address(); + auto i=0U; + + if(getenv("IB_VERBOSE")) + cout << hex << "offset: " << offset << " arch bit width: " << dec << firp->getArchitectureBitWidth() << endl; + + InstructionSet_t ibtargets; + for(i=0;i<table_size;++i) + { + if((int)(offset+i*arch_ptr_bytes()+sizeof(int)) > (int)pSec->get_size()) + { + cout << "jmp table outside of section range ==> invalid switch table" << endl; + return; + } + + VirtualOffset_t table_entry=0; + if (firp->getArchitectureBitWidth()==32) + { + const int *table_entry_ptr=(const int*)&(secdata[offset+i*arch_ptr_bytes()]); + table_entry=*table_entry_ptr; + } + else if (firp->getArchitectureBitWidth()==64) + { + const VirtualOffset_t *table_entry_ptr=(const VirtualOffset_t*)&(secdata[offset+i*arch_ptr_bytes()]); + table_entry=*table_entry_ptr; + } + else + assert(0 && "Unknown arch size."); + + possible_target(table_entry, 0 /* from addr unknown */, prov); + auto ibtarget = lookupInstruction(firp, table_entry); + if (!ibtarget) { + if(getenv("IB_VERBOSE")) + cout << "0x" << hex << table_entry << " is not an instruction, invalid switch table" << endl; + return; + } + + if(getenv("IB_VERBOSE")) + cout << "jmp table [" << i << "]: " << hex << table_entry << dec << endl; + ibtargets.insert(ibtarget); + } + + cout << "(non-PIC) valid switch table found - prov=ibt_provenance_t::ibtp_switchtable_type6" << endl; + jmptables[IJ].addTargets(ibtargets); + jmptables[IJ].setAnalysisStatus(iasAnalysisComplete); +} + +void calc_preds(FileIR_t* firp) +{ + preds.clear(); + for(auto insn : firp->getInstructions()) + { + if(insn->getTarget()) + preds[insn->getTarget()].insert(insn); + if(insn->getFallthrough()) + preds[insn->getFallthrough()].insert(insn); + } +} + +void handle_takes_address_annot(FileIR_t* firp,Instruction_t* insn, MEDS_TakesAddressAnnotation* p_takes_address_annotation) +{ + const auto referenced_addr=p_takes_address_annotation->GetReferencedAddress(); + if(p_takes_address_annotation->isCode()) + { + const auto refd_addr=referenced_addr; + possible_target(refd_addr,insn->getAddress()->getVirtualOffset(), ibt_provenance_t::ibtp_text); + } + else + { + all_add_adrp_results[insn->getFunction()].insert(referenced_addr); + } +} + +void handle_ib_annot(FileIR_t* firp,Instruction_t* insn, MEDS_IBAnnotation* p_ib_annotation) +{ + if(p_ib_annotation->IsComplete()) + { + jmptables[insn].setAnalysisStatus(iasAnalysisComplete); + } +} +void handle_ibt_annot(FileIR_t* firp,Instruction_t* insn, MEDS_IBTAnnotation* p_ibt_annotation) +{ +/* + * ibt_prov reason codes + * static const provtype_t ibtp_stars_ret=1<<11; + * static const provtype_t ibtp_stars_switch=1<<12; + * static const provtype_t ibtp_stars_data=1<<13; + * static const provtype_t ibtp_stars_unknown=1<<14; + * static const provtype_t ibtp_stars_addressed=1<<15; + * static const provtype_t ibtp_stars_unreachable=1<<15; + */ +/* meds annotations + * typedef enum { SWITCH, RET, DATA, UNREACHABLE, ADDRESSED, UNKNOWN } ibt_reason_code_t; + */ + //cout<<"at handl_ibt with addr="<<hex<<insn->getAddress()->getVirtualOffset()<<" code="<<p_ibt_annotation->GetReason()<<endl; + switch(p_ibt_annotation->GetReason()) + { + case MEDS_IBTAnnotation::SWITCH: + case MEDS_IBTAnnotation::INDIRCALL: + { + possible_target((VirtualOffset_t)p_ibt_annotation->getVirtualOffset().getOffset(), + 0,ibt_provenance_t::ibtp_stars_switch); + auto addr=(VirtualOffset_t)p_ibt_annotation->GetXrefAddr(); + auto fromib=lookupInstruction(firp, addr); + auto ibt=lookupInstruction(firp, p_ibt_annotation->getVirtualOffset().getOffset()); + if(fromib && ibt) + { + if(getenv("IB_VERBOSE")!=nullptr) + cout<<hex<<"Adding call/switch icfs: "<<fromib->getAddress()->getVirtualOffset()<<"->"<<ibt->getAddress()->getVirtualOffset()<<endl; + jmptables[fromib].insert(ibt); + } + else + { + cout<<"Warning: cannot find source or dest for call/switch icfs."<<endl; + } + break; + } + case MEDS_IBTAnnotation::RET: + { + /* we are not going to mark return points as IBTs yet. that's fix-calls job */ + // possible_target((VirtualOffset_t)p_ibt_annotation->getVirtualOffset().getOffset(), + // 0,ibt_provenance_t::ibtp_stars_ret); + + + auto fromaddr=(VirtualOffset_t)p_ibt_annotation->GetXrefAddr(); + auto fromib=lookupInstruction(firp, fromaddr); + auto toaddr=p_ibt_annotation->getVirtualOffset().getOffset(); + auto ibt=lookupInstruction(firp, toaddr); + if(fromib && ibt) + { + if(getenv("IB_VERBOSE")!=nullptr) + cout<<hex<<"Adding ret icfs: "<<fromib->getAddress()->getVirtualOffset()<<"->"<<ibt->getAddress()->getVirtualOffset()<<endl; + jmptables[fromib].insert(ibt); + } + else + { + cout<<"Warning: cannot find source ("<<hex<<fromaddr<<") or dest ("<<hex<<toaddr<<") for ret icfs."<<endl; + } + break; + } + case MEDS_IBTAnnotation::DATA: + { + possible_target((VirtualOffset_t)p_ibt_annotation->getVirtualOffset().getOffset(), + 0,ibt_provenance_t::ibtp_stars_data); + if(getenv("IB_VERBOSE")!=nullptr) + cout<<hex<<"detected stars data ibt at"<<p_ibt_annotation->getVirtualOffset().getOffset()<<endl; + break; + } + case MEDS_IBTAnnotation::UNREACHABLE: + { + possible_target((VirtualOffset_t)p_ibt_annotation->getVirtualOffset().getOffset(), + 0,ibt_provenance_t::ibtp_stars_unreachable); + if(getenv("IB_VERBOSE")!=nullptr) + cout<<hex<<"detected stars unreachable ibt at"<<p_ibt_annotation->getVirtualOffset().getOffset()<<endl; + break; + } + case MEDS_IBTAnnotation::ADDRESSED: + { + possible_target((VirtualOffset_t)p_ibt_annotation->getVirtualOffset().getOffset(), + 0,ibt_provenance_t::ibtp_stars_addressed); + if(getenv("IB_VERBOSE")!=nullptr) + cout<<hex<<"detected stars addresssed ibt at"<<p_ibt_annotation->getVirtualOffset().getOffset()<<endl; + break; + } + case MEDS_IBTAnnotation::UNKNOWN: + { + possible_target((VirtualOffset_t)p_ibt_annotation->getVirtualOffset().getOffset(), + 0,ibt_provenance_t::ibtp_stars_unknown); + if(getenv("IB_VERBOSE")!=nullptr) + cout<<hex<<"detected stars unknown ibt at"<<p_ibt_annotation->getVirtualOffset().getOffset()<<endl; + break; + } + default: + { + assert(0); // unexpected ibt annotation. + } + } + + +} + +void read_stars_xref_file(FileIR_t* firp) +{ + + const auto BINARY_NAME=string("a.ncexe"); + const auto SHARED_OBJECTS_DIR=string("shared_objects"); + + const auto fileBasename = string(basename((char*)firp->getFile()->getURL().c_str())); + + auto annotationParser=MEDS_AnnotationParser(); + // need to map filename to integer annotation file produced by STARS + // this should be retrieved from the IRDB but for now, we use files to store annotations + // convention from within the peasoup subdirectory is: + // a.ncexe.infoannot + // shared_objects/<shared-lib-filename>.infoannot + const auto annotationFilename =(fileBasename==BINARY_NAME) ? BINARY_NAME : SHARED_OBJECTS_DIR + "/" + fileBasename ; + + try + { + annotationParser.parseFile(annotationFilename+".STARSxrefs"); + } + catch (const string &s) + { + cout<<"Warning: annotation parser reports error: "<<s<<endl; + } + + for(auto insn : firp->getInstructions()) + { + const auto irdb_vo = insn->getAddress()->getVirtualOffset(); + const auto vo=VirtualOffset_t(irdb_vo); + + /* find it in the annotations */ + const auto ret = annotationParser.getAnnotations().equal_range(vo); + + /* for each annotation for this instruction */ + for (auto ait = ret.first; ait != ret.second; ++ait) + { + /* is this annotation a funcSafe annotation? */ + const auto p_ib_annotation=dynamic_cast<MEDS_IBAnnotation*>(ait->second); + const auto p_ibt_annotation=dynamic_cast<MEDS_IBTAnnotation*>(ait->second); + const auto p_takes_address_annotation=dynamic_cast<MEDS_TakesAddressAnnotation*>(ait->second); + if(p_ib_annotation && p_ib_annotation->isValid()) + handle_ib_annot(firp,insn,p_ib_annotation); + else if(p_ibt_annotation && p_ibt_annotation->isValid()) + handle_ibt_annot(firp,insn,p_ibt_annotation); + else if(p_takes_address_annotation && p_takes_address_annotation->isValid()) + handle_takes_address_annot(firp,insn,p_takes_address_annotation); + } + } +} + +void process_dynsym(FileIR_t* firp) +{ + auto dynsymfile = popen("$PS_OBJDUMP -T readeh_tmp_file.exe | $PS_GREP '^[0-9]\\+' | $PS_GREP -v UND | awk '{print $1;}' | $PS_GREP -v '^$'", "r"); + if(!dynsymfile) + { + perror("Cannot open readeh_tmp_file.exe"); + exit(2); + } + auto target=(unsigned int)0; + while( fscanf(dynsymfile, "%x", &target) != -1) + { + possible_target((VirtualOffset_t)target,0,ibt_provenance_t::ibtp_dynsym); + } +} + + +ICFS_t* setup_hellnode(FileIR_t* firp, EXEIO::exeio* elfiop, ibt_provenance_t allowed) +{ + auto hn=firp->addNewICFS(nullptr, {}, iasAnalysisModuleComplete); + + for(auto insn: firp->getInstructions()) + { + auto prov=targets[insn->getAddress()->getVirtualOffset()]; + + if(prov.isEmpty()) + continue; + + if(prov.isPartiallySet(allowed)) + { + hn->insert(insn); + } + } + + if(hn->size() < 1000 && !elfiop->isDynamicallyLinked()) + hn->setAnalysisStatus(iasAnalysisComplete); + + return hn; +} + +ICFS_t* setup_call_hellnode(FileIR_t* firp, EXEIO::exeio* elfiop) +{ + ibt_provenance_t allowed= + ibt_provenance_t::ibtp_data | + ibt_provenance_t::ibtp_text | + ibt_provenance_t::ibtp_stars_addressed | + ibt_provenance_t::ibtp_unknown | + ibt_provenance_t::ibtp_stars_unreachable | + ibt_provenance_t::ibtp_dynsym | // symbol resolved to other module, this module should xfer directly, but could still plt + ibt_provenance_t::ibtp_rodata | + ibt_provenance_t::ibtp_initarray | // .init loops through the init_array, and calls them + ibt_provenance_t::ibtp_finiarray | // .fini loops through the fini_array, and calls them + ibt_provenance_t::ibtp_user; + + +// would like to sanity check better. +// ibt_provenance_t::ibtp_stars_data | // warn if stars reports it's in data, but !allowed. + + /* + * these aren't good enough reasons for a call instruction to transfer somewhere. + * ibt_provenance_t::ibtp_eh_frame // only libc should xfer. + * ibt_provenance_t::ibtp_gotplt // only an analyzed jump should xfer. + * ibt_provenance_t::ibtp_entrypoint // only ld.so or kernel should xfer. + * ibt_provenance_t::ibtp_texttoprintf // shouldn't xfer if addr passed to printf. + * ibt_provenance_t::ibtp_symtab // user info only. + * ibt_provenance_t::ibtp_stars_ret // stars says a return goes here, calls shouldn't. + * ibt_provenance_t::ibtp_stars_switch // stars says switch target. + * ibt_provenance_t::ibtp_switchtable_type1 // FII switch targets. + * ibt_provenance_t::ibtp_switchtable_type2 + * ibt_provenance_t::ibtp_switchtable_type3 + * ibt_provenance_t::ibtp_switchtable_type4 + * ibt_provenance_t::ibtp_switchtable_type5 + * ibt_provenance_t::ibtp_switchtable_type6 + * ibt_provenance_t::ibtp_switchtable_type7 + * ibt_provenance_t::ibtp_switchtable_type8 + * ibt_provenance_t::ibtp_switchtable_type9 + * ibt_provenance_t::ibtp_switchtable_type10 + */ + + auto ret=setup_hellnode(firp,elfiop,allowed); + + cout<<"# ATTRIBUTE fill_in_indtargs::call_hellnode_size="<<dec<<ret->size()<<endl; + return ret; + +} + +ICFS_t* setup_jmp_hellnode(FileIR_t* firp, EXEIO::exeio* elfiop) +{ + ibt_provenance_t allowed= + ibt_provenance_t::ibtp_data | + ibt_provenance_t::ibtp_text | + ibt_provenance_t::ibtp_stars_addressed | + ibt_provenance_t::ibtp_unknown | + ibt_provenance_t::ibtp_stars_unreachable | + ibt_provenance_t::ibtp_dynsym | // symbol resolved to other module, this module should xfer directly. but that's not true, may still plt. + ibt_provenance_t::ibtp_rodata | + ibt_provenance_t::ibtp_gotplt | + ibt_provenance_t::ibtp_user; + +// ibt_provenance_t::ibtp_stars_data | // warn if stars reports it's in data, but !allowed. + + /* + * these aren't good enough reasons for a jmp instruction to transfer somewhere. + * ibt_provenance_t::ibtp_eh_frame // only libc should xfer. + * ibt_provenance_t::ibtp_initarray // only ld.so should xfer. + * ibt_provenance_t::ibtp_finiarray // only ld.so should xfer. + * ibt_provenance_t::ibtp_entrypoint // only ld.so or kernel should xfer. + * ibt_provenance_t::ibtp_texttoprintf // shouldn't xfer if addr passed to printf. + * ibt_provenance_t::ibtp_symtab // user info only. + * ibt_provenance_t::ibtp_stars_ret // stars says a return goes here, calls shouldn't. + * ibt_provenance_t::ibtp_stars_switch // stars says switch target. + * ibt_provenance_t::ibtp_switchtable_type1 // FII switch targets. + * ibt_provenance_t::ibtp_switchtable_type2 + * ibt_provenance_t::ibtp_switchtable_type3 + * ibt_provenance_t::ibtp_switchtable_type4 + * ibt_provenance_t::ibtp_switchtable_type5 + * ibt_provenance_t::ibtp_switchtable_type6 + * ibt_provenance_t::ibtp_switchtable_type7 + * ibt_provenance_t::ibtp_switchtable_type8 + * ibt_provenance_t::ibtp_switchtable_type9 + * ibt_provenance_t::ibtp_switchtable_type10 + */ + + auto ret=setup_hellnode(firp,elfiop,allowed); + cout<<"# ATTRIBUTE fill_in_indtargs::jmp_hellnode_size="<<dec<<ret->size()<<endl; + return ret; + +} + + +ICFS_t* setup_ret_hellnode(FileIR_t* firp, EXEIO::exeio* elfiop) +{ + ibt_provenance_t allowed= + ibt_provenance_t::ibtp_stars_ret | // stars says a return goes here, and this return isn't analyzeable. + ibt_provenance_t::ibtp_unknown | + ibt_provenance_t::ibtp_stars_unreachable | + ibt_provenance_t::ibtp_ret | // instruction after a call + ibt_provenance_t::ibtp_user; + + +// would like to sanity check better. +// ibt_provenance_t::ibtp_stars_data | // warn if stars reports it's in data, but !allowed. + + + /* + * these aren't good enough reasons for a ret instruction to transfer somewhere. + * ibt_provenance_t::ibtp_eh_frame // only libc should xfer. + * ibt_provenance_t::ibtp_initarray // only ld.so should xfer. + * ibt_provenance_t::ibtp_finiarray // only ld.so should xfer. + * ibt_provenance_t::ibtp_entrypoint // only ld.so or kernel should xfer. + * ibt_provenance_t::ibtp_texttoprintf // shouldn't xfer if addr passed to printf. + * ibt_provenance_t::ibtp_dynsym // symbol resolved to other module, this module should xfer directly. + * ibt_provenance_t::ibtp_symtab // user info only. + * ibt_provenance_t::ibtp_stars_ret // stars says a return goes here, calls shouldn't. + * ibt_provenance_t::ibtp_stars_switch // stars says switch target. + * ibt_provenance_t::ibtp_switchtable_type1 // FII switch targets. + * ibt_provenance_t::ibtp_switchtable_type2 + * ibt_provenance_t::ibtp_switchtable_type3 + * ibt_provenance_t::ibtp_switchtable_type4 + * ibt_provenance_t::ibtp_switchtable_type5 + * ibt_provenance_t::ibtp_switchtable_type6 + * ibt_provenance_t::ibtp_switchtable_type7 + * ibt_provenance_t::ibtp_switchtable_type8 + * ibt_provenance_t::ibtp_switchtable_type9 + * ibt_provenance_t::ibtp_switchtable_type10 + * ibt_provenance_t::ibtp_data // returns likely shouldn't be used to jump to data or addressed text chunks. may need to relax later. + * ibt_provenance_t::ibtp_text + * ibt_provenance_t::ibtp_stars_addressed + * ibt_provenance_t::ibtp_rodata + * ibt_provenance_t::ibtp_gotplt + */ + + auto ret_hell_node=setup_hellnode(firp,elfiop,allowed); + cout<<"# ATTRIBUTE fill_in_indtargs::basicret_hellnode_size="<<dec<<ret_hell_node->size()<<endl; + + cout<<"# ATTRIBUTE fill_in_indtargs::fullret_hellnode_size="<<dec<<ret_hell_node->size()<<endl; + return ret_hell_node; +} + + +void mark_return_points(FileIR_t* firp) +{ + + // add unmarked return points. fix_calls will deal with whether they need to be pinned or not later. + for(auto insn : firp->getInstructions()) + { + auto d=DecodedInstruction_t::factory(insn); + if(string("call")==d->getMnemonic() && insn->getFallthrough()) + { + targets[insn->getFallthrough()->getAddress()->getVirtualOffset()].add(ibt_provenance_t::ibtp_ret); + } + } +} + + +void print_icfs(FileIR_t* firp) +{ + cout<<"Printing ICFS sets."<<endl; + for(auto insn : firp->getInstructions()) + { + auto icfs=insn->getIBTargets(); + + // not an IB + if(!icfs) + continue; + + cout<<hex<<insn->getAddress()->getVirtualOffset()<<" -> "; + + for(auto target : *icfs) + { + cout<<hex<<target->getAddress()->getVirtualOffset()<<" "; + } + cout<<endl; + } +} + +void setup_icfs(FileIR_t* firp, EXEIO::exeio* elfiop) +{ + int total_ibta_set=0; + + /* setup some IBT categories for warning checking */ + ibt_provenance_t non_stars_data= + ibt_provenance_t::ibtp_text | + ibt_provenance_t::ibtp_eh_frame | + ibt_provenance_t::ibtp_texttoprintf | + ibt_provenance_t::ibtp_gotplt | + ibt_provenance_t::ibtp_initarray | + ibt_provenance_t::ibtp_finiarray | + ibt_provenance_t::ibtp_data | + ibt_provenance_t::ibtp_dynsym | + ibt_provenance_t::ibtp_symtab | + ibt_provenance_t::ibtp_rodata | + ibt_provenance_t::ibtp_unknown; + ibt_provenance_t stars_data=ibt_provenance_t::ibtp_stars_data ; + + + + // setup calls, jmps and ret hell nodes. + auto call_hell = setup_call_hellnode(firp,elfiop); + auto jmp_hell = setup_jmp_hellnode(firp,elfiop); + auto ret_hell = setup_ret_hellnode(firp,elfiop); + + // for each instruction + for(auto insn : firp->getInstructions()) + { + + // if we already got it complete (via stars or FII) + if(insn->getIndirectBranchTargetAddress()!=nullptr) + total_ibta_set++; + + + // warning check + ibt_provenance_t prov=targets[insn->getAddress()->getVirtualOffset()]; + + // stars calls it data, but printw arning if we didn't find it in data or as a printf addr. + if(prov.isPartiallySet(stars_data) && !prov.isPartiallySet(non_stars_data)) + { + //ofstream fout("warning.txt", ofstream::out | ofstream::app); + cerr<<"STARS found an IBT in data that FII wasn't able to classify at "<<hex<<insn->getAddress()->getVirtualOffset()<<"."<<endl; + } + + // create icfs for complete jump tables. + if(jmptables[insn].isComplete()) + { + + // get the strcuture into the IRDB + /* + auto nn=new ICFS_t(jmptables[insn]); + firp->GetAllICFS().insert(nn); + insn->SetIBTargets(nn); + */ + auto nn=firp->addNewICFS(insn,jmptables[insn]); + + if(getenv("IB_VERBOSE")!=0) + { + cout<<"IB complete for "<<hex<<insn->getAddress()->getVirtualOffset() + <<":"<<insn->getDisassembly()<<" with "<<dec<<nn->size()<<" targets."<<endl; + } + + // that's all we need to do + continue; + } + + // disassemble the instruction, and figure out which type of hell node we need. + auto d=DecodedInstruction_t::factory(insn); + if(d->isReturn()) + { + if(getenv("IB_VERBOSE")!=0) + cout<<"using ret hell node for "<<hex<<insn->getAddress()->getVirtualOffset()<<endl; + insn->setIBTargets(ret_hell); + ret_hell->insert(ALLOF(jmptables[insn])); // insert any partially analyzed results from rets. + } + else if ( d->isCall() && (!d->getOperand(0)->isConstant())) + { + if(getenv("IB_VERBOSE")!=0) + cout<<"using call hell node for "<<hex<<insn->getAddress()->getVirtualOffset()<<endl; + // indirect call + insn->setIBTargets(call_hell); + call_hell->insert(ALLOF(jmptables[insn])); // insert any partially analyzed results from calls. + } + else if ( d->isUnconditionalBranch() && (!d->getOperand(0)->isConstant())) + { + if(getenv("IB_VERBOSE")!=0) + cout<<"using jmp hell node for "<<hex<<insn->getAddress()->getVirtualOffset()<<endl; + // indirect jmp + insn->setIBTargets(jmp_hell); + jmp_hell->insert(ALLOF(jmptables[insn])); // insert any partially analyzed results from jmps. + } + + } + + cout<<"# ATTRIBUTE fill_in_indtargs::total_ibtas_set="<<dec<<total_ibta_set<<endl; + + if(getenv("ICFS_VERBOSE")!=nullptr) + print_icfs(firp); +} + + +void unpin_elf_tables(FileIR_t *firp, int64_t do_unpin_opt) +{ + map<string,int> unpin_counts; + map<string,int> missed_unpins; + + for(auto scoop : firp->getDataScoops()) + { + // 4 or 8 + const auto ptrsize=firp->getArchitectureBitWidth()/8; + const char *scoop_contents=scoop->getContents().c_str(); + if(scoop->getName()==".init_array" || scoop->getName()==".fini_array" || scoop->getName()==".got.plt" || scoop->getName()==".got") + { + const auto start_offset= (scoop->getName()==".got.plt") ? 3*ptrsize : 0u; + for(auto i=start_offset; i+ptrsize <= scoop->getSize() ; i+=ptrsize) + { + const auto vo= + ptrsize==4 ? (VirtualOffset_t)*(uint32_t*)&scoop_contents[i] : + ptrsize==8 ? (VirtualOffset_t)*(uint64_t*)&scoop_contents[i] : + throw domain_error("Invalid ptr size"); + + + auto insn=lookupInstruction(firp,vo); + + // OK for .got scoop to miss, some entries are empty. + if(scoop->getName()==".got" && insn==nullptr) + { + if(getenv("UNPIN_VERBOSE")!=0) + cout<<"Skipping "<<scoop->getName()<<" unpin for "<<hex<<vo<<" due to no instruction at vo"<<endl; + continue; + } + if(vo==0) + { + // some segments may be null terminated. + assert(i+ptrsize==scoop->getSize()); + break; + } + + // these asserts are probably overkill, but want them for sanity checking for now. + assert(insn); + assert(targets.find(vo)!=targets.end()); + + if( targets[vo].areOnlyTheseSet( + ibt_provenance_t::ibtp_initarray | + ibt_provenance_t::ibtp_finiarray | + ibt_provenance_t::ibtp_gotplt | + ibt_provenance_t::ibtp_got | + ibt_provenance_t::ibtp_stars_data) + ) + { + total_unpins++; + auto allow_unpin=true; + if(do_unpin_opt != -1) + { + if(total_unpins > do_unpin_opt) + { + /* + cout<<"Aborting unpin process mid elf table."<<endl; + return; + */ + allow_unpin=false; + } + } + + // when/if they fail, convert to if and guard the reloc creation. + if(getenv("UNPIN_VERBOSE")!=0) + { + if(allow_unpin) + cout<<"Attempting unpin #"<<total_unpins<<"."<<endl; + else + cout<<"Eliding unpin #"<<total_unpins<<"."<<endl; + } + + if(allow_unpin || already_unpinned.find(insn)!=already_unpinned.end()) + { + // mark as unpinned + already_unpinned.insert(insn); + unpin_counts[scoop->getName()]++; + + // add reloc to IR. + auto nr=firp->addNewRelocation(scoop, i, "data_to_insn_ptr", insn); + assert(nr); + /* + Relocation_t* nr=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, i, "data_to_insn_ptr", insn); + firp->getRelocations().insert(nr); + scoop->getRelocations().insert(nr); + */ + + if(getenv("UNPIN_VERBOSE")!=0) + cout<<"Unpinning "+scoop->getName()+" entry at offset "<<dec<<i<<endl; + if(insn->getIndirectBranchTargetAddress()==nullptr) + { + // add ibta to mark as unpipnned + const auto fileid=insn->getAddress()->getFileID(); + /* + auto newaddr = new AddressID_t(BaseObj_t::NOT_IN_DATABASE,fileid,0); + assert(newaddr); + firp->getAddresses().insert(newaddr); + */ + auto newaddr=firp->addNewAddress(fileid,0); + insn->setIndirectBranchTargetAddress(newaddr); + } + else + { + // just mark as unpinned. + insn->getIndirectBranchTargetAddress()->setVirtualOffset(0); + } + } + } + else + { + if(getenv("UNPIN_VERBOSE")!=0) + cout<<"Skipping "<<scoop->getName()<<" unpin for "<<hex<<vo<<" due to other references at offset="<<dec<<i<<endl; + missed_unpins[scoop->getName()]++; + } + } + } + else if(scoop->getName()==".dynsym") + { + const auto ptrsize=firp->getArchitectureBitWidth()/8; + const auto scoop_contents=scoop->getContents().c_str(); + const auto symsize= + ptrsize==8 ? sizeof(Elf64_Sym) : + ptrsize==4 ? sizeof(Elf32_Sym) : + throw domain_error("Cannot detect ptr size -> ELF symbol mapping"); + + auto table_entry_no=0U; + for(auto i=0U;i+symsize<scoop->getSize(); i+=symsize, table_entry_no++) + { + int addr_offset=0; + VirtualOffset_t vo=0; + int st_info_field=0; + int shndx=0; + switch(ptrsize) + { + case 4: + { + auto sym32=(Elf32_Sym*)&scoop_contents[i]; + addr_offset=(uintptr_t)&(sym32->st_value)-(uintptr_t)sym32; + vo=sym32->st_value; + st_info_field=sym32->st_info; + shndx=sym32->st_shndx; + break; + } + case 8: + { + auto sym64=(Elf64_Sym*)&scoop_contents[i]; + addr_offset=(uintptr_t)&(sym64->st_value)-(uintptr_t)sym64; + vo=sym64->st_value; + st_info_field=sym64->st_info; + shndx=sym64->st_shndx; + break; + } + default: + throw domain_error("Invalid pointer size"); + } + + // this is good for both 32- and 64-bit. + int type=ELF32_ST_TYPE(st_info_field); + + if(shndx!=SHN_UNDEF && type==STT_FUNC) + { + auto insn=lookupInstruction(firp,vo); + + // these asserts are probably overkill, but want them for sanity checking for now. + assert(insn); + assert(targets.find(vo)!=targets.end()); + + // check that the ibt is only ref'd by .dynsym (and STARS, which is ambigulous + // about which section + if(targets[vo].areOnlyTheseSet( + ibt_provenance_t::ibtp_dynsym | ibt_provenance_t::ibtp_stars_data)) + { + total_unpins++; + if(do_unpin_opt != -1) + { + if(total_unpins > do_unpin_opt) + { + cout<<"Aborting unpin process mid elf table."<<endl; + return; + } + cout<<"Attempting unpin #"<<total_unpins<<"."<<endl; + } + + if(getenv("UNPIN_VERBOSE")!=0) + cout<<"Unpinning .dynsym entry no "<<dec<<table_entry_no<<". vo="<<hex<<vo<<endl; + + + // when/if these asserts fail, convert to if and guard the reloc creation. + + unpin_counts[scoop->getName()]++; + /* + auto nr=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, i+addr_offset, "data_to_insn_ptr", insn); + assert(nr); + + // add reloc to IR. + firp->getRelocations().insert(nr); + scoop->getRelocations().insert(nr); + */ + auto nr=firp->addNewRelocation(scoop, i+addr_offset, "data_to_insn_ptr", insn); + (void)nr; + + if(insn->getIndirectBranchTargetAddress()==nullptr) + { + /* + auto newaddr = new AddressID_t; + assert(newaddr); + newaddr->SetFileID(insn->getAddress()->getFileID()); + newaddr->setVirtualOffset(0); // unpinne + + firp->getAddresses().insert(newaddr); + */ + auto newaddr=firp->addNewAddress(insn->getAddress()->getFileID(),0); + insn->setIndirectBranchTargetAddress(newaddr); + } + else + { + insn->getIndirectBranchTargetAddress()->setVirtualOffset(0); + } + } + else + { + if(getenv("UNPIN_VERBOSE")!=0) + cout<<"Skipping .dynsm unpin for "<<hex<<vo<<" due to other references."<<dec<<i<<endl; + missed_unpins[scoop->getName()]++; + } + } + } + } + else + { + if(getenv("UNPIN_VERBOSE")!=0) + cout<<"Skipping unpin of section "<<scoop->getName()<<endl; + } + + } + + int total_elftable_unpins=0; + + // print unpin stats. + for(map<string,int>::iterator it=unpin_counts.begin(); it!=unpin_counts.end(); ++it) + { + string name=it->first; + int count=it->second; + cout<<"# ATTRIBUTE fill_in_indtargs::unpin_count_"<<name<<"="<<dec<<count<<endl; + total_elftable_unpins++; + } + for(map<string,int>::iterator it=missed_unpins.begin(); it!=missed_unpins.end(); ++it) + { + string name=it->first; + int count=it->second; + cout<<"# ATTRIBUTE fill_in_indtargs::hmissed_unpin_count_"<<name<<"="<<dec<<count<<endl; + } + cout<<"# ATTRIBUTE fill_in_indtargs::total_elftable_unpins="<<dec<<total_elftable_unpins<<endl; + +} + +DataScoop_t* find_scoop(FileIR_t *firp, const VirtualOffset_t &vo) +{ + for(auto s : firp->getDataScoops()) + { + if( s->getStart()->getVirtualOffset()<=vo && vo<s->getEnd()->getVirtualOffset() ) + return s; + } + return nullptr; +} + +// stats for unpinning. +int type3_unpins=0; +int type3_pins=0; + +void unpin_type3_switchtable(FileIR_t* firp,Instruction_t* insn,DataScoop_t* scoop, int64_t do_unpin_opt) +{ + + assert(firp && insn && scoop); + + set<Instruction_t*> switch_targs; + + if(getenv("UNPIN_VERBOSE")) + { + cout<<"Unpinning type3 switch, dispatch is "<<hex<<insn->getAddress()->getVirtualOffset()<<":" + <<insn->getDisassembly()<<" with tabSz="<<jmptables[insn].GetTableSize()<<endl; + } + + + // switch check + // could be dangerous if the IBT is found in rodata section, + // but then also used for a switch. this is unlikely. + ibt_provenance_t prov=ibt_provenance_t::ibtp_switchtable_type3 | // found as switch + ibt_provenance_t::ibtp_stars_switch | // found as stars switch + ibt_provenance_t::ibtp_rodata; // found in rodata. + + ibt_provenance_t newprov=ibt_provenance_t::ibtp_switchtable_type3 | // found as switch + ibt_provenance_t::ibtp_stars_switch ; // found as stars switch + + // ptr size + int ptrsize=firp->getArchitectureBitWidth()/8; + + // offset from start of scoop + VirtualOffset_t scoop_off=jmptables[insn].GetTableStart() - scoop->getStart()->getVirtualOffset(); + + // scoop contents + const char *scoop_contents=scoop->getContents().c_str(); + + + for(int i=0; i<jmptables[insn].GetTableSize(); i++) + { + + // grab the value out of the scoop + VirtualOffset_t table_entry=0; + switch(ptrsize) + { + case 4: + table_entry=(VirtualOffset_t)*(int*)&scoop_contents[scoop_off]; + break; + case 8: + table_entry=(VirtualOffset_t)*(int**)&scoop_contents[scoop_off]; + break; + default: + assert(0); + } + + // verify we have an instruction. + auto ibt=lookupInstruction(firp,table_entry); + if(ibt) + { + // which isn't otherwise addressed. + if(targets[table_entry].areOnlyTheseSet(prov)) + { + auto allow_new_unpins=true; + total_unpins++; + if(do_unpin_opt != -1 && total_unpins > do_unpin_opt) + { + allow_new_unpins=false; + + // don't abort early as we need to fully unpin the IBT once we've started. + //cout<<"Aborting unpin process mid switch table."<<endl; + // return; + } + + // if we are out of unpins, and we haven't unpinned this instruction yet, skip unpinning it. + if(!allow_new_unpins && already_unpinned.find(ibt)==already_unpinned.end()) + { + if(getenv("UNPIN_VERBOSE")) + cout<<"Eliding switch unpin for entry["<<dec<<i<<"] ibt="<<hex<<table_entry<<", scoop_off="<<scoop_off<<endl; + + // do nothing + } + else + { + if(getenv("UNPIN_VERBOSE")) + cout<<"Unpinning switch entry ["<<dec<<i<<"] for ibt="<<hex<<table_entry<<", scoop_off="<<scoop_off<<endl; + already_unpinned.insert(ibt); + + // add reloc to IR. + /* + auto nr=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, scoop_off, "data_to_insn_ptr", ibt); + assert(nr); + firp->getRelocations().insert(nr); + scoop->getRelocations().insert(nr); + */ + auto nr=firp->addNewRelocation(scoop,scoop_off, "data_to_insn_ptr", ibt); + (void)nr; + + + // remove rodata reference for hell nodes. + targets[table_entry]=newprov; + switch_targs.insert(ibt); + + if(ibt->getIndirectBranchTargetAddress()==nullptr) + { + /* + auto newaddr = new AddressID_t; + assert(newaddr); + newaddr->SetFileID(ibt->getAddress()->getFileID()); + newaddr->setVirtualOffset(0); // unpinne + + firp->getAddresses().insert(newaddr); + */ + auto newaddr=firp->addNewAddress(ibt->getAddress()->getFileID(),0); + ibt->setIndirectBranchTargetAddress(newaddr); + } + else + { + ibt->getIndirectBranchTargetAddress()->setVirtualOffset(0); + } + } + } + } + scoop_off+=ptrsize; + + + } + + type3_unpins+=switch_targs.size(); + type3_pins+=jmptables[insn].size(); + +} + +void unpin_switches(FileIR_t *firp, int do_unpin_opt) +{ + // re-init stats for this file. + type3_unpins=0; + type3_pins=0; + + // for each instruction + for( + set<Instruction_t*>::const_iterator it=firp->getInstructions().begin(); + it!=firp->getInstructions().end(); + ++it + ) + + { + // check for an insn. + Instruction_t* insn=*it; + assert(insn); + + // if we didn't find a jmptable for this insn, try again. + if(jmptables.find(insn) == jmptables.end()) + continue; + + // sanity check we have a good switch + if(insn->getIBTargets()==nullptr) continue; + + // sanity check we have a good switch + if(insn->getIBTargets()->getAnalysisStatus()!=iasAnalysisComplete) continue; + + // find the scoop, try next if we fail. + DataScoop_t* scoop=find_scoop(firp,jmptables[insn].GetTableStart()); + if(!scoop) continue; + + if(jmptables[insn].GetSwitchType().areOnlyTheseSet(ibt_provenance_t::ibtp_switchtable_type3)) + { + unpin_type3_switchtable(firp,insn,scoop, do_unpin_opt); + } + } + cout<<"# ATTRIBUTE fill_in_indtargs::switch_type3_pins="<<dec<<type3_pins<<endl; + cout<<"# ATTRIBUTE fill_in_indtargs::switch_type3_unpins="<<dec<<type3_unpins<<endl; +} + +void print_unpins(FileIR_t *firp) +{ + // don't print if not asked for this type of verbose + if(getenv("UNPIN_VERBOSE") == nullptr) + return; + + for(auto scoop : firp->getDataScoops()) + { + assert(scoop); + for(auto reloc : scoop->getRelocations()) + { + assert(reloc); + cout<<"Found relocation in "<<scoop->getName()<<" of type "<<reloc->getType()<<" at offset "<<hex<<reloc->getOffset()<<endl; + } + } +} + + +void unpin_well_analyzed_ibts(FileIR_t *firp, int64_t do_unpin_opt) +{ + unpin_elf_tables(firp, do_unpin_opt); + unpin_switches(firp, do_unpin_opt); + print_unpins(firp); +} + +bool find_arm_address_gen(Instruction_t* insn, const string& reg, VirtualOffset_t& address, bool& page_only) +{ + // init output args, just in case. + address=0; + page_only=true; + + auto adrp_insn=(Instruction_t*)nullptr; + if(backup_until(string()+"adrp "+reg+",", /* to find */ + adrp_insn, /* return insn here */ + insn, /* look before here */ + "^"+reg+"$", /* stop if reg is set */ + true)) /* try hard to find the other half, more expensive */ + { + assert(adrp_insn); + const auto adrp_disasm=DecodedInstruction_t::factory(adrp_insn); + const auto page_no=adrp_disasm->getOperand(1)->getConstant(); + + cout<<"Found spilled page_no at "<<hex<<insn->getAddress()->getVirtualOffset()<<" in: "<<endl; + cout<<"\t"<<adrp_disasm->getDisassembly()<<endl; + cout<<"\t"<<insn->getDisassembly()<<endl; + page_only=true; + address=page_no; + return true; + } + + auto add_insn=(Instruction_t*)nullptr; + if(backup_until(string()+"add "+reg+",", /* to find */ + add_insn, /* return insn here */ + insn, /* look before here */ + "^"+reg+"$", /* stop if reg is set */ + true)) /* try hard to find the other half, more expensive */ + { + assert(add_insn); + const auto add_disasm=DecodedInstruction_t::factory(add_insn); + const auto add_op1=add_disasm->getOperand(1); + const auto add_op2=add_disasm->getOperand(2); + if(!add_op1->isRegister()) return false; + if( add_op1->getString()=="x29") return false; // skip arm SP. + if(!add_op2->isConstant()) return false; + + const auto add_op1_reg=add_op1->getString(); + const auto add_op2_constant=add_op2->getConstant(); + + // try to find an adrp + auto adrp_insn=(Instruction_t*)nullptr; + if(!backup_until(string()+"adrp "+add_op1_reg+",", /* to find */ + adrp_insn, /* return insn here */ + add_insn, /* look before here */ + "^"+add_op1_reg+"$", /* stop if reg is set */ + true)) /* try hard to find the other half, more expensive */ + return false; + assert(adrp_insn); + + const auto adrp_disasm=DecodedInstruction_t::factory(adrp_insn); + const auto adrp_page=adrp_disasm->getOperand(1)->getConstant(); + const auto spilled_address=adrp_page+add_op2_constant; + cout<<"Found spilled address at "<<hex<<insn->getAddress()->getVirtualOffset()<<" in: "<<endl; + cout<<"\t"<<adrp_disasm->getDisassembly()<<endl; + cout<<"\t"<<add_disasm->getDisassembly()<<endl; + cout<<"\t"<<insn->getDisassembly()<<endl; + page_only=false; + address=spilled_address; + return true; + } + return false; +} + +void find_all_arm_unks(FileIR_t* firp) +{ + const auto reg_to_spilled_addr=[&](Instruction_t* insn, const string ®, const SpillPoint_t& spill_loc) + { + + auto page_only=true; + auto address=VirtualOffset_t(0); + if(find_arm_address_gen(insn,reg, address, page_only)) + { + if(page_only) + spilled_adrps[spill_loc].insert(address); + else + spilled_add_adrp_results[spill_loc].insert(address); + } + }; + const auto do_verbose=getenv("IB_VERBOSE"); + /* only valid for arm */ + if(firp->getArchitecture()->getMachineType() != admtAarch64) return; + + /* find adrps */ + for(auto insn : firp->getInstructions()) + { + const auto d=DecodedInstruction_t::factory(insn); + if(d->getMnemonic()!="adrp") continue; + const auto op1=d->getOperand(1); + const auto op1_constant=op1->getConstant(); + all_adrp_results[insn->getFunction()].insert(op1_constant); + } + + /* find add/adrp pairs */ + for(auto insn : firp->getInstructions()) + { + const auto d=DecodedInstruction_t::factory(insn); + if(d->getMnemonic()!="add") continue; + if(!d->hasOperand(1)) continue; + if(!d->hasOperand(2)) continue; + const auto op0=d->getOperand(1); + const auto op1=d->getOperand(1); + const auto op2=d->getOperand(2); + if(!op1->isRegister()) continue; + if(op1->getString()=="x29") continue; // skip arm SP. + if(!op2->isConstant()) continue; + + const auto op1_reg=op1->getString(); + const auto op2_constant=op2->getConstant(); + + // try to find an adrp + auto adrp_insn=(Instruction_t*)nullptr; + if(!backup_until(string()+"adrp "+op1_reg+",", /* to find */ + adrp_insn, /* return insn here */ + insn, /* look before here */ + "^"+op1_reg+"$", /* stop if reg is set */ + true)) /* try hard to find the other half, more expensive */ + continue; + assert(adrp_insn); + + const auto adrp_disasm=DecodedInstruction_t::factory(adrp_insn); + const auto adrp_page=adrp_disasm->getOperand(1)->getConstant(); + const auto unk_value=adrp_page+op2_constant; + + all_add_adrp_results [ insn->getFunction() ].insert(unk_value); + all_add_adrp_results [ adrp_insn->getFunction()].insert(unk_value); + per_reg_add_adrp_results [ op0->getString() ].insert(unk_value); + + /* check for scoops at the unk address. + * if found, we assume that the unk points at data. + * else, we mark it as a possible code target. + */ + if(firp->findScoop(unk_value)==nullptr) + possible_target(unk_value, 0, ibt_provenance_t::ibtp_text); + + /* verbose logging */ + if(do_verbose) + cout << "Detected ARM unk="<<hex<<unk_value<<" for "<<d->getDisassembly() + << " and "<<adrp_disasm->getDisassembly()<<endl; + + } + /* find spilled adrp's and add/adrp pairs + * looking for these patterns: + * + * adrp reg1, #page_no + * add reg2, reg1, #page_offset + * str reg2, [x29, #spill loc] ; or sp instead of x29 + * + * or + * + * adrp reg1, #page_no + * str reg1, [x29, #spill loc] ; or sp instead of x29 + * + * we record these later, in case we find a switch dispatch that has a spilled jump table address. + */ + for(auto insn : firp->getInstructions()) + { + // look for a spill of an address + const auto d=DecodedInstruction_t::factory(insn); + + // spills are str instructions + if(d->getMnemonic()!="str") continue; + + // spills of an address are writing an X register. + const auto spill_op0_reg=d->getOperand(0)->getString(); + if(spill_op0_reg[0]!='x') continue; + + // spills write to the stack with a constant offset. + const auto spill_op1=d->getOperand(1); + assert(spill_op1->isMemory()); + const auto spill_op1_string=spill_op1->getString(); + // needs to have a base reg, which is either sp or x29 + if(!spill_op1->hasBaseRegister()) continue; + if( spill_op1_string.substr(0,2)!="sp" && spill_op1_string.substr(0,3)!="x29" ) continue; + if(!spill_op1->hasMemoryDisplacement()) continue; + if( spill_op1->hasIndexRegister()) continue; + + const auto spill_disp=spill_op1->getMemoryDisplacement(); + + // found str <x-reg> [sp+const] + + reg_to_spilled_addr(insn, spill_op0_reg, SpillPoint_t({insn->getFunction(),spill_disp })); + + + } + for(auto insn : firp->getInstructions()) + { + // look for a spill of an address + const auto d=DecodedInstruction_t::factory(insn); + + // spills are str instructions + if(d->getMnemonic()!="stp") continue; + + // spills of an address are writing an X register. + const auto spill_op0_reg=d->getOperand(0)->getString(); + const auto spill_op1_reg=d->getOperand(1)->getString(); + if(spill_op0_reg[0]!='x') continue; + + // spills write to the stack with a constant offset. + const auto spill_op2=d->getOperand(2); + assert(spill_op2->isMemory()); + const auto spill_op2_string=spill_op2->getString(); + // needs to have a base reg, which is either sp or x29 + if(!spill_op2->hasBaseRegister()) continue; + if( spill_op2_string.substr(0,2)!="sp" && spill_op2_string.substr(0,3)!="x29" ) continue; + if(!spill_op2->hasMemoryDisplacement()) continue; + if( spill_op2->hasIndexRegister()) continue; + + const auto spill_disp=spill_op2->getMemoryDisplacement(); + + // found stp <xreg> <xreg> [sp+const] + + reg_to_spilled_addr(insn, spill_op0_reg, SpillPoint_t({insn->getFunction(),spill_disp })); + reg_to_spilled_addr(insn, spill_op1_reg, SpillPoint_t({insn->getFunction(),spill_disp+8})); + + + } + + // look for spilling an address into a d-register. + for(auto insn : firp->getInstructions()) + { + // look for moves to d-regs via fmov. + const auto d = DecodedInstruction_t::factory(insn); + if( d->getMnemonic()!="fmov" ) continue; + + // look for a spill of an address + const auto op0 = d->getOperand(0); + const auto op1 = d->getOperand(1); + const auto op0_str = op0->getString(); + const auto op1_str = op1->getString(); + + // spills to d-regs are fmov instructions with a d-reg dest and an xreg src. + if( op0_str[0] !='d' ) continue; + if( op1_str[0] !='x' ) continue; + + auto page_only=true; + auto address=VirtualOffset_t(0); + if(find_arm_address_gen(insn,op1_str, address, page_only)) + { + const auto spill_loc = DregSpillPoint_t({insn->getFunction(), op0_str}); + spilled_to_dreg[spill_loc].insert(address); + + } + } + +} + + +/* + * fill_in_indtargs - main driver routine for + */ +void fill_in_indtargs(FileIR_t* firp, exeio* elfiop, int64_t do_unpin_opt) +{ + calc_preds(firp); + + set<VirtualOffset_t> thunk_bases; + find_all_module_starts(firp,thunk_bases); + + // reset global vars + bounds.clear(); + ranges.clear(); + targets.clear(); + jmptables.clear(); + already_unpinned.clear(); + lookupInstruction_init(firp); + + + int secnum = elfiop->sections.size(); + int secndx=0; + + /* look through each section and record bounds */ + for (secndx=0; secndx<secnum; secndx++) + get_executable_bounds(firp, elfiop->sections[secndx]); + + /* import info from stars */ + read_stars_xref_file(firp); + + /* and find any unks ourselves, as stars is unreliable */ + find_all_arm_unks(firp); + + + /* look through each section and look for target possibilities */ + for (secndx=0; secndx<secnum; secndx++) + infer_targets(firp, elfiop->sections[secndx]); + + handle_scoop_scanning(firp); + + /* should move to separate function */ + for(auto pin : forced_pins ) + possible_target(pin, 0, ibt_provenance_t::ibtp_user); + + /* look through the instructions in the program for targets */ + get_instruction_targets(firp, elfiop, thunk_bases); + + /* mark the entry point as a target */ + possible_target(elfiop->get_entry(),0,ibt_provenance_t::ibtp_entrypoint); + + /* Read the exception handler frame so that those indirect branches are accounted for */ + /* then now process the ranges and mark IBTs as necessarthat have exception handling */ + read_ehframe(firp, elfiop); + process_ranges(firp); + + /* now, find the .GOT addr and process any pc-rel things for x86-32 ibts. */ + check_for_thunks(firp, thunk_bases); + + /* now deal with dynsym pins */ + process_dynsym(firp); + + /* mark any instructions after a call instruction */ + mark_return_points(firp); + + /* set the IR to have some instructions marked as IB targets, and deal with the ICFS */ + mark_targets(firp); + + + cout<<"========================================="<<endl; + cout<<"# ATTRIBUTE fill_in_indtargs::total_indirect_targets="<<std::dec<<targets.size()<<endl; + print_targets(); + cout<<"========================================="<<endl; + + // try to setup an ICFS for every IB. + setup_icfs(firp, elfiop); + + // do unpinning of well analyzed ibts. + if(do_unpin_opt!=(int64_t)-1) + unpin_well_analyzed_ibts(firp, do_unpin_opt); + +} + +bool split_eh_frame_opt=true; +int64_t do_unpin_opt=numeric_limits<int64_t>::max() ; +DatabaseID_t variant_id=BaseObj_t::NOT_IN_DATABASE; +set<VirtualOffset_t> forced_pins; + +int parseArgs(const vector<string> step_args) +{ + + if(step_args.size()<1) + { + cerr<<"Usage: <id> [--[no-]split-eh-frame] [--[no-]unpin] [addr,...]"<<endl; + exit(-1); + } + + variant_id=stoi(step_args[0]); + cout<<"Parsing parameters with argc= " << step_args.size()<<endl; + + // parse dash-style options. + unsigned int argc_iter = 1; + while(argc_iter < step_args.size() && step_args[argc_iter][0]=='-') + { + cout<<"Parsing parameter: "<< step_args[argc_iter] << endl; + if(step_args[argc_iter]=="--no-unpin") + { + do_unpin_opt=-1; + argc_iter++; + } + else if(step_args[argc_iter]=="--unpin") + { + do_unpin_opt = numeric_limits<decltype(do_unpin_opt)>::max() ; + argc_iter++; + } + else if(step_args[argc_iter]=="--max-unpin" || step_args[argc_iter]=="--max-unpins") + { + argc_iter++; + auto arg_as_str=step_args[argc_iter]; + argc_iter++; + + try { + do_unpin_opt = stoul(arg_as_str,nullptr,0); + } + catch (invalid_argument ia) + { + cerr<<"In --max-unpin, cannot convert "<<arg_as_str<<" to unsigned"<<endl; + exit(1); + } + + } + else if(step_args[argc_iter]=="--no-split-eh-frame") + { + split_eh_frame_opt=false; + argc_iter++; + } + else if(step_args[argc_iter]=="--split-eh-frame") + { + split_eh_frame_opt=true; + argc_iter++; + } + else + { + cerr<<"Unknown option: "<<step_args[argc_iter]<<endl; + return 2; + } + } + // parse addr argumnets + for (; argc_iter < step_args.size(); argc_iter++) + { + char *end_ptr; + VirtualOffset_t offset = strtol(step_args[argc_iter].c_str(), &end_ptr, 0); + if (*end_ptr == '\0') + { + cout << "force pinning: 0x" << std::hex << offset << endl; + forced_pins.insert(offset); + } + } + + cout<<"Setting unpin limit to: "<<dec<<do_unpin_opt<<endl; + return 0; +} + + +int executeStep(IRDBObjects_t *const irdb_objects) +{ + //VariantID_t *pidp=nullptr; + //FileIR_t * firp=nullptr; + + try + { + /* setup the interface to the sql server */ + const auto pqxx_interface=irdb_objects->getDBInterface(); + BaseObj_t::setInterface(pqxx_interface); + + auto pidp = irdb_objects->addVariant(variant_id); + assert(pidp); + + // pidp=new VariantID_t(atoi(argv[1])); + + + assert(pidp->isRegistered()==true); + + cout<<"New Variant, after reading registration, is: "<<*pidp << endl; + + for(const auto &this_file : pidp->getFiles()) + { + assert(this_file); + + cout<<"Analyzing file "<<this_file->getURL()<<endl; + + // read the db + auto firp = irdb_objects->addFileIR(variant_id, this_file->getBaseID()); + // firp=new FileIR_t(*pidp, this_file); + assert(firp); + + firp->setBaseIDS(); + firp->assembleRegistry(); + + // read the executeable file + int elfoid=firp->getFile()->getELFOID(); + pqxx::largeobject lo(elfoid); + lo.to_file(pqxx_interface->getTransaction(),"readeh_tmp_file.exe"); + auto elfiop=unique_ptr<EXEIO::exeio>(new EXEIO::exeio); + elfiop->load(string("readeh_tmp_file.exe")); + + // find all indirect branch targets + fill_in_indtargs(firp, elfiop.get(), do_unpin_opt); + if(split_eh_frame_opt) + split_eh_frame(firp); + } + + if(getenv("FII_NOUPDATE")!=nullptr) + return -1; + + } + catch (DatabaseError_t pnide) + { + cout<<"Unexpected database error: "<<pnide<<endl; + return -1; + } + catch(...) + { + cerr<<"Unexpected error"<<endl; + return -1; + } + + assert(getenv("SELF_VALIDATE")==nullptr || bounds.size() > 3 ); + assert(getenv("SELF_VALIDATE")==nullptr || targets.size() > 100 ); + assert(getenv("SELF_VALIDATE")==nullptr || ranges.size() > 1 ); + assert(getenv("SELF_VALIDATE")==nullptr || preds.size() > 100 ); + assert(getenv("SELF_VALIDATE")==nullptr || lookupInstructionMap.size() > 100 ); + + return 0; +} + +std::string getStepName(void) const override +{ + return std::string("fill_in_indtargs"); +} + + +}; + + +shared_ptr<TransformStep_t> curInvocation; + +bool possible_target(VirtualOffset_t p, VirtualOffset_t from_addr, ibt_provenance_t prov) +{ + assert(curInvocation); + return (dynamic_cast<PopulateIndTargs_t*>(curInvocation.get()))->possible_target(p,from_addr,prov); +} + +void range(VirtualOffset_t start, VirtualOffset_t end) +{ + assert(curInvocation); + return (dynamic_cast<PopulateIndTargs_t*>(curInvocation.get()))->range(start,end); +} + +extern "C" +shared_ptr<TransformStep_t> getTransformStep(void) +{ + curInvocation.reset(new PopulateIndTargs_t()); + return curInvocation; +} + + diff --git a/irdb-lib/ir_builders/fill_in_indtargs.hpp b/irdb-lib/ir_builders/fill_in_indtargs.hpp new file mode 100644 index 0000000000000000000000000000000000000000..dd0500d1f5ce03c7760387d5739c80d5cdbf1ad2 --- /dev/null +++ b/irdb-lib/ir_builders/fill_in_indtargs.hpp @@ -0,0 +1,223 @@ + +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <irdb-core> +#include <iostream> +#include <limits> +#include <stdlib.h> +#include <string.h> +#include <map> +#include <assert.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <regex.h> +#include <ctype.h> +#include <list> +#include <stdio.h> + +#include <exeio.h> +#include "check_thunks.hpp" + + +/* + * defines + */ +#define arch_ptr_bytes() (firp->getArchitectureBitWidth()/8u) + +/* + * global variables + */ + + +// +// data structures +// + + +class ibt_provenance_t; +static inline std::ostream& operator<<(std::ostream& out, const ibt_provenance_t& prov); + +class ibt_provenance_t +{ + public: + typedef uint32_t provtype_t; + + ibt_provenance_t() : value(0) { }; + + ibt_provenance_t(const provtype_t t) : value(t) { }; + + static const provtype_t ibtp_eh_frame=1<<0; + static const provtype_t ibtp_user=1<<1; // requested by user + static const provtype_t ibtp_gotplt=1<<2; + static const provtype_t ibtp_initarray=1<<3; + static const provtype_t ibtp_finiarray=1<<4; + static const provtype_t ibtp_entrypoint=1<<5; + static const provtype_t ibtp_data=1<<6; + static const provtype_t ibtp_text=1<<7; + static const provtype_t ibtp_texttoprintf=1<<8; + static const provtype_t ibtp_dynsym=1<<9; + static const provtype_t ibtp_symtab=1<<10; + static const provtype_t ibtp_stars_ret=1<<11; + static const provtype_t ibtp_stars_switch=1<<12; + static const provtype_t ibtp_stars_data=1<<13; + static const provtype_t ibtp_stars_unknown=1<<14; + static const provtype_t ibtp_stars_addressed=1<<15; + static const provtype_t ibtp_stars_unreachable=1<<16; + static const provtype_t ibtp_switchtable_type1=1<<17; + static const provtype_t ibtp_switchtable_type2=1<<18; + static const provtype_t ibtp_switchtable_type3=1<<19; + static const provtype_t ibtp_switchtable_type4=1<<20; + static const provtype_t ibtp_switchtable_type5=1<<21; + static const provtype_t ibtp_switchtable_type6=1<<22; + static const provtype_t ibtp_switchtable_type7=1<<23; + static const provtype_t ibtp_switchtable_type8=1<<24; + static const provtype_t ibtp_switchtable_type9=1<<25; + static const provtype_t ibtp_switchtable_type10=1<<26; + static const provtype_t ibtp_rodata=1<<27; + static const provtype_t ibtp_unknown=1<<28; // completely unknown + static const provtype_t ibtp_got=1<<29; // got is 0 init'd, shouldn't see this one. + static const provtype_t ibtp_ret=1<<30; // insn after a call + + void add(const provtype_t t) { value |=t; } + void add(const ibt_provenance_t t) { value |=t.value; } + bool isFullySet(const provtype_t t) const { return (value&t) == t; } + bool isFullySet(const ibt_provenance_t t) const { return (value&t.value) == t.value; } + bool isPartiallySet(const provtype_t t) const { return (value&t) != 0; } + bool isPartiallySet(const ibt_provenance_t t) const { return (value&t.value) != 0; } + + bool areOnlyTheseSet(const provtype_t t) const { return (value&~t) == 0; } + bool areOnlyTheseSet(const ibt_provenance_t t) const { return (value&~t.value) == 0; } + bool isEmpty() const { return value==0; } + + + private: + + provtype_t value; + friend std::ostream& operator<<(std::ostream& out, const ibt_provenance_t& prov); + +}; + +static inline std::ostream& operator<<(std::ostream& out, const ibt_provenance_t& prov) +{ +#define print_prov(a) \ +{ \ + if(prov.value&(ibt_provenance_t::a)) \ + { \ + const auto foo=std::string(#a); \ + out<<foo.substr(4,foo.length())<<","; \ + } \ +} + print_prov(ibtp_eh_frame); + print_prov(ibtp_user); + print_prov(ibtp_gotplt); + print_prov(ibtp_initarray); + print_prov(ibtp_finiarray); + print_prov(ibtp_entrypoint); + print_prov(ibtp_data); + print_prov(ibtp_text); + print_prov(ibtp_texttoprintf); + print_prov(ibtp_dynsym); + print_prov(ibtp_symtab); + print_prov(ibtp_stars_ret); + print_prov(ibtp_stars_switch); + print_prov(ibtp_stars_data); + print_prov(ibtp_stars_unknown); + print_prov(ibtp_stars_addressed); + print_prov(ibtp_stars_unreachable); + print_prov(ibtp_switchtable_type1); + print_prov(ibtp_switchtable_type2); + print_prov(ibtp_switchtable_type3); + print_prov(ibtp_switchtable_type4); + print_prov(ibtp_switchtable_type5); + print_prov(ibtp_switchtable_type6); + print_prov(ibtp_switchtable_type7); + print_prov(ibtp_switchtable_type8); + print_prov(ibtp_switchtable_type9); + print_prov(ibtp_switchtable_type10); + print_prov(ibtp_rodata); + print_prov(ibtp_unknown); + print_prov(ibtp_got); + print_prov(ibtp_ret); +#undef print_prov + + return out; +} + + +/* + * Forward prototypes + */ + +bool is_possible_target(IRDB_SDK::VirtualOffset_t p, IRDB_SDK::VirtualOffset_t addr); +bool possible_target(IRDB_SDK::VirtualOffset_t p, IRDB_SDK::VirtualOffset_t from_addr, ibt_provenance_t prov=ibt_provenance_t::ibtp_unknown); + + +class fii_icfs : public IRDB_SDK::InstructionSet_t +{ + public: + // get/set table start + IRDB_SDK::VirtualOffset_t GetTableStart() {return table_start; } + void SetTableStart(IRDB_SDK::VirtualOffset_t s) {table_start=s; } + + // get/set switch type + ibt_provenance_t GetSwitchType() { return switch_type; } + void AddSwitchType(const ibt_provenance_t& p) { switch_type.add(p); } + + // get/set table size + int GetTableSize() { return table_size; } + void SetTableSize(int s) { table_size=s; } + + void addTargets(const IRDB_SDK::InstructionSet_t &other) + { + insert(std::begin(other), std::end(other)); + } + bool isIncomplete() const { + return getAnalysisStatus() == IRDB_SDK::iasAnalysisIncomplete; + } + + bool isComplete() const { + return getAnalysisStatus() == IRDB_SDK::iasAnalysisComplete; + } + + bool isModuleComplete() const { + return getAnalysisStatus() == IRDB_SDK::iasAnalysisModuleComplete; + } + + void setAnalysisStatus(const IRDB_SDK::ICFSAnalysisStatus_t p_status) { + m_icfs_analysis_status = p_status; + } + + IRDB_SDK::ICFSAnalysisStatus_t getAnalysisStatus() const { + return m_icfs_analysis_status; + } + + + private: + + IRDB_SDK::VirtualOffset_t table_start; + ibt_provenance_t switch_type; + int table_size; + IRDB_SDK::ICFSAnalysisStatus_t m_icfs_analysis_status; + +}; + +void split_eh_frame(IRDB_SDK::FileIR_t* firp); + diff --git a/irdb-lib/ir_builders/find_strings.cpp b/irdb-lib/ir_builders/find_strings.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e1f7146d093f6f81d99ae6a029d99e919fef350b --- /dev/null +++ b/irdb-lib/ir_builders/find_strings.cpp @@ -0,0 +1,629 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + + +#include <libIRDB-core.hpp> +#include <irdb-cfg.hpp> +#include <iostream> +#include <stdlib.h> +#include <cctype> +#include <assert.h> +#include <stdlib.h> + + +#include <exeio.h> + +//#include <elf.h> +#include "targ-config.h" +#include "elfio/elfio.hpp" +//#include "elfio/elfio_dump.hpp" + +// elfio doesn't have this, and elf.h does, but including both is troublesome. +#ifndef SHT_GNU_HASH +#define SHT_GNU_HASH 0x6ffffff6 +#endif + + + +using namespace libIRDB; +using namespace std; +using namespace EXEIO; + +#define arch_ptr_bytes() (uintptr_t)(firp->GetArchitectureBitWidth()/8) + +bool is_string_character(char c) +{ + if(c=='\n') return true; + return isprint(c); +} + + +/* the stuff we need for reading an elf file */ +typedef struct elf_info { +#if 0 + ::Elf64_Off sec_hdr_off, sec_off; + ::Elf_Half secnum, strndx; + ::Elf_Word secsize; + ::Elf64_Addr got; +#endif + int secnum; + VirtualOffset_t got; + char const **sec_data; + exeio *elfiop; +} elf_info_t; + +void found_string(string s, void* addr) +{ + char *buff=(char*)malloc(s.length()+2); + char *old_p=buff, *p; + // use .data() instead of c_str(); can find multiple C-strings in one string + memcpy(buff,s.data(),s.length()); + buff[s.length()]=0; + + do { + // look for new lines in the string + // if found, split it up and print out each one as it's own thing. + while( ( p=strchr(old_p,'\n')) ) + { + *p=0; + if (*old_p != 0) + { + cout << "Found string: \""<<old_p<<"\" at "<<std::hex<<addr<<std::dec<<endl; + old_p=p+1; + } + } + + if (*old_p != 0) + cout << "Found string: \""<<old_p<<"\" at "<<std::hex<<addr<<std::dec<<endl; + old_p = p = old_p + strlen(old_p) + 1; + } while (p < buff + s.length()); +} + +void load_section(elf_info_t &ei, int i, bool alloc) +{ + if( alloc && !ei.elfiop->sections[i]->isLoadable()) // (ei.elfiop->sections[i]->get_flags() & SHF_ALLOC) != SHF_ALLOC) + { + cerr<<"Cannot load non-alloc section\n"; + assert(0); + } + + if(ei.sec_data[i]==NULL) + { + ei.sec_data[i]=ei.elfiop->sections[i]->get_data(); + // if(ei.elfiop->sections[i]->get_type()==SHT_NOBITS) + if(ei.elfiop->sections[i]->isBSS()) + { + /* no need to read anything for NOBITS sections */ + ei.sec_data[i]=(char*)calloc(ei.elfiop->sections[i]->get_size(),1); + } + } +} + +void check_for_string(const char* p, void* addr) +{ + assert(p); + if(!is_string_character(*p)) + return; + + string s; + while(*p) + { + if(!is_string_character(*p)) + return; + s+=*p; + p++; + } + found_string(s, addr); +} + +void is_string_pointer(void* addr, elf_info_t &ei) +{ + auto intaddr=(uintptr_t)(addr); + + for(int i=0;i<ei.secnum;i++) + { +//cout << "is_string_pointer(): address: " << std::hex << intaddr << std::dec << "looking at section number: " << i << endl; + /* only look at loaded sections */ + // if( (ei.elfiop->sections[i]->get_flags() & SHF_ALLOC) != SHF_ALLOC) + if( !ei.elfiop->sections[i]->isLoadable()) + continue; + + if(ei.elfiop->sections[i]->get_address() <= intaddr + && intaddr <= (ei.elfiop->sections[i]->get_address()+ei.elfiop->sections[i]->get_size())) + { + /* we found a pointer into a loadable segment */ + load_section(ei,i,true); + + check_for_string(ei.sec_data[i]+((long long int)addr-ei.elfiop->sections[i]->get_address()),addr); + } + } + +} + +void is_string_constant(const DecodedInstruction_t& disasm) +{ + void *addr; + + //if(disasm.Argument1.ArgType != MEMORY_TYPE || disasm.Argument2.ArgType == MEMORY_TYPE + // || disasm.Argument1.ArgSize != FileIR_t::GetArchitectureBitWidth() ) + if(!disasm.getOperand(0).isMemory() || + disasm.getOperand(1).isMemory() || + (uintptr_t)disasm.getOperand(0).getArgumentSizeInBits() != (uintptr_t)FileIR_t::GetArchitectureBitWidth() ) + return; + + // addr = (void*)disasm.Instruction.Immediat; + addr = (void*)disasm.getImmediate(); + + /* consider that this constant itself may be a string */ + unsigned char byte1=(((long long unsigned int)addr)>>24)&0xff; + unsigned char byte2=(((long long unsigned int)addr)>>16)&0xff; + unsigned char byte3=(((long long unsigned int)addr)>>8)&0xff; + unsigned char byte4=(long long unsigned int)addr&0xff; + + /* + mov reg, 0x6161 + addr = 0x00006161 + addr >> 24 = 0 byte1 + addr >> 16 = 0 byte2 + addr >> 8 = 61 byte3 + addr >> 0 = 61 byte4 + mov reg, 0x61616161 + + mov reg, 0x0000000061616161 + */ +// cout << "address: " << std::hex << addr << std::dec << byte1 << " " << byte2 << " " << byte3 << " " << byte4 << endl; + if( + (is_string_character(byte1) || byte1==0) && + (is_string_character(byte2) || byte2==0) && + (is_string_character(byte3) || byte3==0) && + (is_string_character(byte4) || byte4==0) + ) + { + char s[5]; + s[0]=byte4; + s[1]=byte3; + s[2]=byte2; + s[3]=byte1; + s[4]=0; + if(strlen(s)>0) // only find 2+ character strings this way. + found_string(s, addr); + } + + + +} + +void handle_argument(const DecodedOperand_t &arg, elf_info_t &ei, Instruction_t *insn) +{ + // if( (arg->ArgType & MEMORY_TYPE) == MEMORY_TYPE ) + if(arg.isMemory()) + { + /* Only check without GOT offset if type is executable */ + + // if( ((arg->ArgType & ABSOLUTE_) == ABSOLUTE_) && !ei.elfiop->isDLL() ) + if( !arg.isPcrel() && !ei.elfiop->isDLL() ) + // && ei.elfiop->get_type() == ET_EXEC ) -- checks for .so/.dll vrs .exe. + // is_string_pointer((void*)arg->Memory.Displacement,ei); + is_string_pointer((void*)arg.getMemoryDisplacement(),ei); + else + //is_string_pointer((void*)(arg->Memory.Displacement + insn->GetDataBits().size()), ei); + is_string_pointer((void*)(arg.getMemoryDisplacement() + insn->GetDataBits().size()), ei); + + /* Check with GOT offset if present */ + // if ( ei.got && arg->Memory.BaseRegister == REG3 /* ebx */ ) + if ( ei.got && arg.hasBaseRegister() && arg.getBaseRegister() == 3 /* ebx */ ) + // is_string_pointer((void*)(arg->Memory.Displacement + ei.got),ei); + is_string_pointer((void*)(arg.getMemoryDisplacement() + ei.got),ei); + } +} + + +void read_elf_info(elf_info_t &ei, FileIR_t* firp) +{ + + + /* Read ELF header */ +// ei.sec_hdr_off = ei.elfiop->get_sections_offset(); + ei.secnum = ei.elfiop->sections.size(); + assert(ei.secnum>0); +// ei.strndx = ei.elfiop->get_section_name_str_index(); + + ei.sec_data=(char const**)calloc(ei.secnum,sizeof(void*)); + + ei.got = 0; + /* Get .got or .got.plt address, if any */ +// if (ei.strndx != SHN_UNDEF) +// { +// int shstr_sec; +// if (ei.strndx < SHN_LORESERVE) +// shstr_sec = ei.strndx; +// else +// shstr_sec = ei.elfiop->sections[0]->get_link(); +// assert(shstr_sec < ei.secnum); +// load_section(ei,shstr_sec,false); +// IRDB_Elf_Shdr *shstr_sec_hdr = ei.sechdrs + shstr_sec; + for (int i=0;i<ei.secnum;i++) + { +// name works oddly here. we can just get the name safely using elfio +// assert(ei.sechdrs[i].sh_name < shstr_sec_hdr->sh_size); + if (ei.elfiop->sections[i]->get_name()==".got.plt") // !strcmp(ei.sec_data[shstr_sec]+ei.sechdrs[i].sh_name, ".got.plt")) + { + // Prefer .got.plt to .got + ei.got = ei.elfiop->sections[i]->get_address(); + break; + } + if (ei.elfiop->sections[i]->get_name()==".got") // if (!strcmp(ei.sec_data[shstr_sec]+ei.sechdrs[i].sh_name, ".got")) + ei.got = ei.elfiop->sections[i]->get_address(); + } +// } +} + +void free_elf_info(elf_info_t &ei) +{ + #define FREE_IF_NOT_NULL(a) { if(a) { free(a); a=NULL; } } + FREE_IF_NOT_NULL(ei.sec_data); +} + +void find_strings_in_instructions(FileIR_t* firp, elf_info_t& ei) +{ + set<Instruction_t*> visited_insns; + + // First pass; get strings from basic blocks, + // concatenating consecutive immediates stored to the stack + + // Loop over all functions + for( + set<Function_t*>::const_iterator fit=firp->GetFunctions().begin(); + fit!=firp->GetFunctions().end(); + ++fit + ) + { + if(!(*fit)->GetEntryPoint()) + continue; + ControlFlowGraph_t cfg = ControlFlowGraph_t(*fit) ; + // Loop over basic blocks in function + for( + set<BasicBlock_t*>::const_iterator bit=cfg.GetBlocks().begin(); + bit!=cfg.GetBlocks().end(); + ++bit + ) + { + // Loop over instructions in basic block + vector<Instruction_t*>::const_iterator iit=(*bit)->GetInstructions().begin(); + while(iit!=(*bit)->GetInstructions().end()) + { + Instruction_t *insn=*iit; + //DISASM disasm; + char *str = NULL; + + //int res=Disassemble(insn,disasm); + auto disasm=DecodedInstruction_t(insn); + int res=disasm.length(); + assert(res); + + // Concatenate printable strings from consecutive store immediates to SP-relative stack addresses + size_t size = 0; + unsigned int olddisp = 0; + unsigned int newdisp = 0; + unsigned int basereg = 0; + while(iit!=(*bit)->GetInstructions().end()) + { +// cout<<"Pass 1: Checking insn: "<<disasm.CompleteInstr<<" id: "<<(*iit)->GetBaseID()<<" category: " << (int) (disasm.Instruction.Category & 0xFFFF0000) << " ibta: " << (*iit)->GetIndirectBranchTargetAddress() << endl; + + // Break if not assignment of an immediate to an esp/ebp/eax offset +// if (disasm.Argument1.ArgType != MEMORY_TYPE +// || (disasm.Argument1.Memory.BaseRegister != REG4 /* esp */ +// && disasm.Argument1.Memory.BaseRegister != REG5 /* ebp */ +// && disasm.Argument1.Memory.BaseRegister != REG0 /* eax */) +// || (basereg && disasm.Argument1.Memory.BaseRegister != basereg) +// || disasm.Argument2.ArgType == MEMORY_TYPE +// || ((disasm.Instruction.Category & 0XFFFF0000) != GENERAL_PURPOSE_INSTRUCTION)) + if (!disasm.getOperand(0).isMemory() + || !disasm.getOperand(0).hasBaseRegister() + || (disasm.getOperand(0).getBaseRegister() != 4 /* esp */ + && disasm.getOperand(0).getBaseRegister() != 5 /* ebp */ + && disasm.getOperand(0).getBaseRegister() != 0 /* eax */) + || (basereg && disasm.getOperand(0).getBaseRegister() != basereg) + || disasm.getOperand(1).isMemory() + ) + { + // mark visited + visited_insns.insert(*iit); + is_string_constant(disasm); + break; + } + // basereg = disasm.Argument1.Memory.BaseRegister; + basereg = disasm.getOperand(0).getBaseRegister(); + unsigned int disp = disasm.getOperand(0).getMemoryDisplacement(); + // break if displacement moved backward + if (newdisp && (disp < newdisp || disp == olddisp)) + break; + // mark visited + visited_insns.insert(*iit); + // check for a printable argument + // unsigned int imm = disasm.Instruction.Immediat; + unsigned int imm = disasm.getImmediate(); + unsigned char byte1=(imm>>24)&0xff; + unsigned char byte2=(imm>>16)&0xff; + unsigned char byte3=(imm>>8)&0xff; + unsigned char byte4=imm&0xff; + // size_t argsize = disasm.Argument1.ArgSize / 8; + size_t argsize = disasm.getOperand(0).getArgumentSizeInBytes(); // .ArgSize / 8; + + if ( imm!=0 /* special case 0 which is likely from push <reg> insns, etc. */ && + (((is_string_character(byte1) || byte1==0) || argsize < 4) && + ((is_string_character(byte2) || byte2==0) || argsize < 4) && + ((is_string_character(byte3) || byte3==0) || argsize < 2) && + (is_string_character(byte4) || byte4==0))) + { + // printable, concatenate to built string + assert(str = (char *)realloc(str, size+argsize)); + size += argsize; + memcpy(str + size - argsize, (char *) (&imm), argsize); + } + else + { + // not printable, check for other strings + is_string_constant(disasm); + break; + } + ++iit; + if (iit == (*bit)->GetInstructions().end()) + { + break; + } + insn = *iit; + // break if none + if (insn == NULL) + break; + olddisp = disp; + // calculate expected displacement + if (newdisp) + newdisp += argsize; + else + newdisp = disp + argsize; + // res=Disassemble(insn,disasm); + disasm=DecodedInstruction_t(insn); + res=disasm.length(); + assert(res); + } + + // Handle string if one was found + if (size > 1) // only find 2+ character strings this way. + { + if (str[size-1] != 0) + { + assert(str = (char *)realloc(str, size+1)); + str[size] = 0; + size++; + } + std::string s(str, size); + found_string(s, str); + free(str); + } + // advance to next if we've visited this instruction + if (iit != (*bit)->GetInstructions().end() + && visited_insns.find(*iit) != visited_insns.end()) + ++iit; + } + } + } + + // second pass; grab any leftover stringy bits without chunking + for( + set<Instruction_t*>::const_iterator it=firp->GetInstructions().begin(); + it!=firp->GetInstructions().end(); + ++it + ) + { + Instruction_t *insn=*it; + + //DISASM disasm; + //int res=Disassemble(insn,disasm); + const auto disasm=DecodedInstruction_t(insn); + int res=disasm.length(); + assert(res); +// cout<<"Pass 2: Checking insn: "<<disasm.CompleteInstr<<" id: "<<insn->GetBaseID()<<endl; + + // check for immediate string pointers in non-PIC code + if ( !ei.elfiop->isDLL()) // ei.elfiop->get_type() == ET_EXEC ) + // is_string_pointer((void*)disasm.Instruction.Immediat,ei); + is_string_pointer((void*)disasm.getImmediate(),ei); + // always check for string pointers in memory argument displacements + + handle_argument(disasm.getOperand(0),ei, insn); + handle_argument(disasm.getOperand(1),ei, insn); + handle_argument(disasm.getOperand(2),ei, insn); + + // if not in a function, check for string in immediate + if (visited_insns.find(insn) != visited_insns.end()) + { + assert(insn->GetFunction()); + continue; + } + +// if (insn->GetFunction()) +// cerr << "Warning: instruction at address ID " << insn->GetOriginalAddressID() +// << " is in function " << insn->GetFunction()->GetName() << " but not in its CFG." << endl; + + is_string_constant(disasm); + } +} + + +void find_strings_in_data(FileIR_t* firp, elf_info_t& ei) +{ + ELFIO::elfio *the_elfiop=reinterpret_cast<ELFIO::elfio *>(ei.elfiop->get_elfio()); + if(!the_elfiop) + return; + for(int i=0;i<ei.secnum;i++) + { + /* skip executable, hash, string table, nonloadable, and tiny sections */ + if( (the_elfiop->sections[i]->get_flags() & SHF_EXECINSTR) + || the_elfiop->sections[i]->get_type() == SHT_HASH + || the_elfiop->sections[i]->get_type() == SHT_GNU_HASH + || the_elfiop->sections[i]->get_type() == SHT_STRTAB + || (the_elfiop->sections[i]->get_flags() & SHF_ALLOC) != SHF_ALLOC + || the_elfiop->sections[i]->get_size() < arch_ptr_bytes()) + continue; + + auto offset = 0U; + auto step = 0U; + /* step over relocation info */ + switch( the_elfiop->sections[i]->get_type() ) + { + case SHT_REL: + if(arch_ptr_bytes()==4) + step = sizeof(ELFIO::Elf32_Rel); + else + step = sizeof(ELFIO::Elf64_Rel); + break; + case SHT_RELA: + if(arch_ptr_bytes()==4) + step = sizeof(ELFIO::Elf32_Rela); + else + step = sizeof(ELFIO::Elf64_Rela); + break; + case SHT_SYMTAB: + case SHT_DYNSYM: + if(arch_ptr_bytes()==4) + { + offset = sizeof(ELFIO::Elf32_Word); + step = sizeof(ELFIO::Elf32_Sym); + } + else + { + offset = sizeof(ELFIO::Elf64_Word); + step = sizeof(ELFIO::Elf64_Sym); + } + break; + default: + step = 1; + } + + load_section(ei,i,true); + for(auto j=offset;(uintptr_t)(j+arch_ptr_bytes())<=(uintptr_t)(ei.elfiop->sections[i]->get_size());j+=step) + { + void* p; + if(arch_ptr_bytes()==4) + p=(void*)(uintptr_t)*((int*)(ei.sec_data[i]+j)); + else + p=*((void**)(ei.sec_data[i]+j)); + is_string_pointer(p,ei); + } + + + } + +} + +void find_strings(VariantID_t *pidp, FileIR_t* firp) +{ + + assert(firp && pidp); + + cout<<"Searching variant for strings"<<*pidp<< "." <<endl; + + /* get a handle to the binary file */ + int elfoid=firp->GetFile()->GetELFOID(); + pqxxDB_t* pqxx_interface=dynamic_cast<pqxxDB_t*>(BaseObj_t::GetInterface()); + + pqxx::largeobject lo(elfoid); + lo.to_file(pqxx_interface->GetTransaction(),"readeh_tmp_file.exe"); + EXEIO::exeio elfiop; + elfiop.load(string("readeh_tmp_file.exe")); + //EXEIO::dump::header(cout,elfiop); + //EXEIO::dump::section_headers(cout,elfiop); + + + + + elf_info_t ei; + ei.elfiop=&elfiop; + read_elf_info(ei,firp); + + find_strings_in_instructions(firp, ei); + find_strings_in_data(firp, ei); + + free_elf_info(ei); + + cout << "# ATTRIBUTE find_strings::filename="<<firp->GetFile()->GetURL()<<endl; +} + +int main(int argc, char* argv[]) +{ + + if(argc!=2) + { + cerr<<"Usage: ilr <id>"<<endl; + exit(-1); + } + + VariantID_t *pidp=NULL; + FileIR_t *firp=NULL; + + /* setup the interface to the sql server */ + pqxxDB_t pqxx_interface; + BaseObj_t::SetInterface(&pqxx_interface); + + cout<<"Reading variant "<<string(argv[1])<<" from database." << endl; + try + { + + pidp=new VariantID_t(atoi(argv[1])); + assert(pidp->IsRegistered()==true); + + + for(set<File_t*>::iterator it=pidp->GetFiles().begin(); + it!=pidp->GetFiles().end(); + ++it + ) + { + File_t* this_file=*it; + assert(this_file); + + // read the db + firp=new FileIR_t(*pidp,this_file); + + // do the finding. + find_strings(pidp, firp); + +// firp->WriteToDB(); + + delete firp; + } + + + pqxx_interface.Commit(); + + } + catch (DatabaseError_t pnide) + { + cout<<"Unexpected database error: "<<pnide<<endl; + exit(-1); + } + + cout<<"Done!"<<endl; + + delete pidp; + return 0; +} + diff --git a/irdb-lib/ir_builders/fix_calls.cpp b/irdb-lib/ir_builders/fix_calls.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b35c6f5098993cc18abfb1137cc0837508a46ca5 --- /dev/null +++ b/irdb-lib/ir_builders/fix_calls.cpp @@ -0,0 +1,1129 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +#include <irdb-core> +#include <irdb-cfg> +#include <algorithm> +#include <iostream> +#include <stdlib.h> +#include <assert.h> +#include <string.h> +#include <elf.h> +#include <set> +#include <exeio.h> + +#include "fill_in_indtargs.hpp" + + +using namespace std; +using namespace EXEIO; +using namespace IRDB_SDK; + +// macros +#define ALLOF(a) begin(a),end(a) + + +// externs +extern void read_ehframe(FileIR_t* firp, EXEIO::exeio* ); + +class FixCalls_t : public TransformStep_t +{ + +public: + +class Range_t +{ + public: + Range_t(VirtualOffset_t p_s, VirtualOffset_t p_e) : m_start(p_s), m_end(p_e) { } + Range_t() : m_start(0), m_end(0) { } + + virtual VirtualOffset_t getStart() const { return m_start; } + virtual VirtualOffset_t getEnd() const { return m_end; } + virtual void setStart(VirtualOffset_t s) { m_start=s; } + virtual void setEnd(VirtualOffset_t e) { m_end=e; } + + protected: + + VirtualOffset_t m_start, m_end; +}; + +struct Range_tCompare +{ + bool operator() (const Range_t &first, const Range_t &second) const + { + return first.getEnd() < second.getStart(); + } +}; + +using Rangeset_t = std::set<Range_t, Range_tCompare>; + + + +Rangeset_t eh_frame_ranges; +size_t no_target_insn=0; +size_t no_fallthrough_insn=0; +size_t target_not_in_function=0; +size_t call_to_not_entry=0; +size_t thunk_check=0; +size_t found_pattern=0; +size_t in_ehframe=0; +size_t no_fix_for_ib=0; +size_t no_fix_for_safefn=0; +size_t other_fixes=0; +size_t fixed_calls=0; +size_t not_fixed_calls=0; +size_t not_calls=0; + +bool opt_fix_icalls = false; +bool opt_fix_safefn = true; + +bool check_entry(bool &found, ControlFlowGraph_t* cfg) +{ + + auto entry=cfg->getEntry(); + found=false; + + for(auto insn : entry->getInstructions()) + { + auto disasmp = DecodedInstruction_t::factory(insn); + auto &disasm = *disasmp; + if(disasm.setsStackPointer()) { + return false; + } else { + if(getenv("VERBOSE_FIX_CALLS")) + { + VirtualOffset_t addr = 0; + if (insn->getAddress()) + addr = insn->getAddress()->getVirtualOffset(); + cout<<"check_entry: does not set stack pointer?"<< " address=" + <<hex<<addr<<": "<<insn->getDisassembly()<<endl; + } + } + + if(strstr(disasm.getDisassembly().c_str(), "[esp]")) + { + found=true; + if(getenv("VERBOSE_FIX_CALLS")) + { + VirtualOffset_t addr = 0; + if (insn->getAddress()) + addr = insn->getAddress()->getVirtualOffset(); + cout<<"Needs fix (check_entry): [esp]"<< " address=" + <<hex<<addr<<": "<<insn->getDisassembly()<<endl; + } + return true; + } + } + + return false; +} + +using ControlFlowGraphMap_t = map<Function_t*, shared_ptr<ControlFlowGraph_t> >; +ControlFlowGraphMap_t cfg_optimizer; + +bool call_needs_fix(Instruction_t* insn) +{ + + for(auto reloc : insn->getRelocations()) + { + if(string("safefr") == reloc->getType()) + return false; + } + + auto target=insn->getTarget(); + auto fallthru=insn->getFallthrough(); + + string pattern; + +// this used to work because fill_in_indirects would mark IBTs +// while reading the ehframe, which perfectly corresponds to when +// we need to fix calls due to eh_frame. However, now STARS also marks +// return points as IBTs, so we need to re-parse the ehframe and use that instead. + + /* no fallthrough instruction, something is odd here */ + if(!fallthru) + { + if(getenv("VERBOSE_FIX_CALLS")) + { + VirtualOffset_t addr = 0; + if (insn->getAddress()) + addr = insn->getAddress()->getVirtualOffset(); + cout<<"Needs fix: No fallthrough"<< " address=" + <<hex<<addr<<": "<<insn->getDisassembly()<<endl; + } + no_fallthrough_insn++; + return true; + } + + auto addr=fallthru->getAddress()->getVirtualOffset(); + auto rangeiter=eh_frame_ranges.find(Range_t(addr,addr)); + if(rangeiter != eh_frame_ranges.end()) // found an eh_frame addr entry for this call + { + in_ehframe++; + return true; + } + + if (!opt_fix_icalls && insn->getIBTargets() && insn->getIBTargets()->size() > 0) + { + /* do not fix indirect calls */ + no_fix_for_ib++; + return false; + } + + /* if the target isn't in the IR */ + if(!target) + { + /* call 0's aren't to real locations */ + auto disasm=DecodedInstruction_t::factory(insn); + if(disasm->getOperand(0)->isConstant() && disasm->getAddress()==0) + { + return false; + } + no_target_insn++; + + if(getenv("VERBOSE_FIX_CALLS")) + { + VirtualOffset_t addr = 0; + if (insn->getAddress()) + addr = insn->getAddress()->getVirtualOffset(); + cout<<"Needs fix: No target instruction"<< " address=" + <<hex<<addr<<": "<<insn->getDisassembly()<<endl; + } + /* then we need to fix it */ + return true; + } + + + /* if the location after the call is marked as an IBT, then + * this location might be used for walking the stack + */ + + + auto func=target->getFunction(); + + /* if there's no function for this instruction */ + if(!func) + { + if(getenv("VERBOSE_FIX_CALLS")) + { + VirtualOffset_t addr = 0; + if (insn->getAddress()) + addr = insn->getAddress()->getVirtualOffset(); + cout<<"Needs fix: Target not in a function"<< " address=" + <<hex<<addr<<": "<<insn->getDisassembly()<<endl; + } + target_not_in_function++; + /* we need to fix it */ + return true; + } + + + + const auto is_found_it=cfg_optimizer.find(func); + const auto is_found=(is_found_it!=end(cfg_optimizer)); + + if(!is_found) + /* build a cfg for this function */ + cfg_optimizer[func]=shared_ptr<ControlFlowGraph_t>(move(ControlFlowGraph_t::factory(func))); + + auto cfg=cfg_optimizer[func].get(); + + + + assert(cfg->getEntry()); + + /* if the call instruction isn't to a function entry point */ + if(cfg->getEntry()->getInstructions()[0]!=target) + { + call_to_not_entry++; + /* then we need to fix it */ + return true; + } + + + /* check the entry block for thunks, etc. */ + auto found=false; + bool ret=check_entry(found,cfg); + // delete cfg; + if(found) + { + if(ret) + { + if(getenv("VERBOSE_FIX_CALLS")) + { + VirtualOffset_t addr = 0; + if (insn->getAddress()) + addr = insn->getAddress()->getVirtualOffset(); + cout<<"Needs fix: (via check_entry) Thunk detected"<< " address=" + <<hex<<addr<<": "<<insn->getDisassembly()<<endl; + } + thunk_check++; + } + + return ret; + } + + + /* otherwise, we think it's safe */ + return false; + +} + +/* + * - adjust_esp_offset - take newbits, and determine if it has an esp+K type offset in a memory address. + * if so, adjust k by offset, and return the new string. + */ +string adjust_esp_offset(string newbits, int offset) +{ + + /* + * call has opcodes of: + * E8 cw call near, relative, displacement relative to next instruction + * E8 cd call near, relative, displacement relative to next instruction + * FF /2 call near, absolute indirect, address given in r/m16 + * FF /2 call near, absolute indirect, address given in r/m32 + * 9a cd call far, absolute, address given in operand + * 9a cp call far, absolute, address given in operand + * FF /3 call far, absolute indirect, address given in m16:16 + * FF /3 call far, absolute indirect, address given in m16:32 + * + * FF /4 jmp near, absolute indirect, address given in r/m16 + * FF /4 jmp near, absolute indirect, address given in r/m32 + * FF /5 jmp near, absolute indirect, address given in r/m16 + * FF /5 jmp near, absolute indirect, address given in r/m32 + * + * /digit indicates that the Reg/Opcode field (bits 3-5) of the ModR/M byte (opcode[1]) + * contains that value as an opcode instead of a register operand indicator. The instruction only + * uses the R/M field (bits 0-2) as an operand. + * + * cb,cw,cd,cp indicates a 1,2,4,6-byte following the opcode is used to specify a + * code offset and possibly a new code segment + * + * I believe we only care about these this version: + * FF /3 call far, absolute indirect, address given in m16:32 + * as we're looking for an address on the stack. + * + * The ModR/M byte must be Mod=10, Reg/Op=010, R/M=100 aka 0x94 or possibly + * Mod=01, Reg/Op=100, R/M=100 aka 0x64 or possibly + * Mod=10, Reg/Op=100, R/M=100 aka 0xa4 or possibly + * Mod=01, Reg/Op=010, R/M=100 aka 0x54 or possibly + * R/M=100 indicates to read the SIB (see below) + * Mod=10 indicates an 32-bit displacement after the SIB byte + * Mod=01 indicates an 8-bit displacement after the SIB byte + * Reg/Op=010 indicates an opcode that has a /3 after it + * Reg/Op=100 indicates an opcode that has a /5 after it + * + * The SIB byte (opcode[2]) needs to be scale=00, index=100, base=100, or 0x24 + * indicating that the addresing mode is 0*%esp+%esp. + * + * I believe that the SIB byte could also be 0x64, 0xA4, or 0xE4, but that + * these are very rarely used as they are redundant. + * + * + * + * + */ + /* non-negative offsets please */ + assert(offset>=0); + + int sib_byte=(unsigned char)newbits[2]; + int sib_base=(unsigned char)sib_byte&0x7; + //int sib_ss=(sib_byte>>3)&0x7; + //int sib_index=(sib_byte>>3)&0x7; + + + /* 32-bit offset */ + if ( (unsigned char)newbits[0] == 0xff && /* ff */ + ((unsigned char)newbits[1] == 0x94 || (unsigned char)newbits[1] == 0x64 ) && /* /2 or /4*/ + sib_base == 0x4 ) /* base==esp */ + { + // reconstruct the old 32-bit value + int oldval=((unsigned char)newbits[6]<<24)+((unsigned char)newbits[5]<<16)+((unsigned char)newbits[4]<<8)+((unsigned char)newbits[3]); + + // add the offset + int newval=oldval+offset; + + // break it back apart to store in the string. + newbits[3]=(char)(newval>>0)&0xff; + newbits[4]=(char)(newval>>8)&0xff; + newbits[5]=(char)(newval>>16)&0xff; + newbits[6]=(char)(newval>>24)&0xff; + } + + /* 8-bit offset */ + else if ( (unsigned char)newbits[0] == 0xff && /* ff */ + ((unsigned char)newbits[1] == 0x54 || (unsigned char)newbits[1]==0xa4) && /* /3 or /5 */ + sib_base == 0x4 ) /* base==esp */ + { + /* We need to add 4 to the offset, but this may overflow an 8-bit quantity + * (note: there's no 16-bit offset for this insn. Only 8-bit or 32-bit offsets exist for this instr) + * if the const offset is over (0x7f-offset), adding offset will overflow it to be negative instead + * of positive + */ + if((unsigned char)newbits[3]>=(0x7f-offset)) + { + /* Careful, adding 4 to this will cause an overflow. + * We need to convert it to a 32-bit displacement + */ + /* first, change addressing mode from 8-bit to 32-bit. */ + newbits[1]&=0x3f; /* remove upper 2 bits */ + newbits[1]|=0x80; /* make them 10 to indicate a 32-bit offset */ + + // sign-extend to 32-bit int + int oldval=(char)newbits[3]; + + // add the offset + int newval=oldval+offset; + + // break it back apart to store in the string. + assert(newbits.length() == 4); + newbits[3]=(char)(newval>>0)&0xff; + // 3 most significant bytes extend the instruction + newbits+=(char)(newval>>8)&0xff; + newbits+=(char)(newval>>16)&0xff; + newbits+=(char)(newval>>24)&0xff; + + } + else + + newbits[3] += (char)offset; + } + return newbits; +} + + + +/* + * convert_to_jump - assume newbits is a call insn, convert newbits to a jump, and return it. + * Also: if newbits is a call [esp+k], add "offset" to k. + */ +void convert_to_jump(Instruction_t* insn, int offset) +{ + string newbits=insn->getDataBits(); + auto dp=DecodedInstruction_t::factory(insn); + auto &d=*dp; + + /* this case is odd, handle it specially (and more easily to understand) */ + if(strcmp(d.getDisassembly().c_str(), "call qword [rsp]")==0) + { + char buf[100]; + sprintf(buf,"jmp qword [rsp+%d]", offset); + insn->assemble(buf); + return; + } + + + /* skip over any prefixes */ + int op_index=d.getPrefixCount(); // d.Prefix.Number; + + // on the opcode. assume no prefix here + switch((unsigned char)newbits[op_index]) + { + // opcodes: ff /2 and ff /3 + case 0xff: + { + // opcode: ff /2 + // call r/m32, call near, absolute indirect, address given in r/m32 + if(((((unsigned char)newbits[op_index+1])&0x38)>>3) == 2) + { + newbits=adjust_esp_offset(newbits,offset); + // convert to jmp r/m32 + // opcode: FF /4 + newbits[op_index+1]&=0xC7; // remove old bits + newbits[op_index+1]|=(0x4<<3); // set r/m field to 4 + } + // opcode: ff /3 + // call m16:32, call far, absolute indirect, address given in m16:32 + else if(((((unsigned char)newbits[op_index+1])&0x38)>>3) == 3) + { + // convert to jmp m16:32 + // opcode: FF /5 + newbits[op_index+1]&=0xC7; // remove old bits + newbits[op_index+1]|=(0x5<<3); // set r/m field to 5 + } + else + assert(0); + break; + } + // opcode: 9A cp + // call ptr16:32, call far, absolute, address given in operand + case 0x9A: + { + // convert to jmp ptr16:32 + // opcode: EA cp + newbits[op_index+0]=0xEA; + break; + } + + // opcode: E8 cd + // call rel32, call near, relative, displacement relative to next insn. + case 0xE8: + { + // convert to jmp rel32 + // opcode: E9 cd + newbits[op_index+0]=0xE9; + break; + } + + // not a call + default: + assert(0); + } + + /* set the instruction's bits */ + insn->setDataBits(newbits); + return; +} + + +/* + * fix_call - convert call to push/jump. + */ +void fix_call(Instruction_t* insn, FileIR_t *firp, bool can_unpin) +{ + if(firp->getArchitecture()->getMachineType()==admtAarch64) + return; + + /* record the possibly new indirect branch target if this call gets fixed */ + Instruction_t* newindirtarg=insn->getFallthrough(); + + /* Disassemble the instruction */ + auto disasmp=DecodedInstruction_t::factory (insn); + auto &disasm=*disasmp; + + /* if this instruction is an inserted call instruction than we don't need to + * convert it for correctness' sake. + */ + if(insn->getAddress()->getVirtualOffset()==0) + return; + + /* if the first byte isn't a call opcode, there's some odd prefixing and we aren't handling it. + * this comes up most frequently in a call gs:0x10 instruction where an override prefix specifes the gs: part. + */ + if((insn->getDataBits()[0]&0x40)==0x40) + { + // ignore rex prefixes + } + else if( (insn->getDataBits()[0]!=(char)0xff) && + (insn->getDataBits()[0]!=(char)0xe8) && + (insn->getDataBits()[0]!=(char)0x9a) ) + { + cout<<"Found odd prefixing.\n Not handling **********************************************"<<endl; + assert(0); + return; + } + + if(getenv("VERBOSE_FIX_CALLS")) + { + cout<<"Doing a fix_call on "<<std::hex<<insn->getAddress()->getVirtualOffset()<< " which is "<<disasm.getDisassembly() /*.CompleteInstr*/<<endl; + } + + + VirtualOffset_t next_addr=insn->getAddress()->getVirtualOffset() + insn->getDataBits().length(); + + /* create a new instruction and a new addresss for it that do not correspond to any original program address */ + /* + Instruction_t *callinsn=new Instruction_t(); + firp->getInstructions().insert(callinsn); + */ + auto callinsn=firp->addNewInstruction(); + /* + AddressID_t *calladdr=new AddressID_t; + firp->getAddresses().insert(calladdr); + calladdr->setFileID(insn->getAddress()->getFileID()); + */ + auto calladdr=firp->addNewAddress(insn->getAddress()->getFileID(),0); + + /* set the fields in the new instruction */ + callinsn->setAddress(calladdr); + callinsn->setTarget(insn->getTarget()); + callinsn->setFallthrough(NULL); + callinsn->setFunction(insn->getFunction()); + callinsn->setComment(insn->getComment()+" Jump part"); + + /* handle ib targets */ + callinsn->setIBTargets(insn->getIBTargets()); + insn->setIBTargets(NULL); + + // We need the control transfer instruction to be from the orig program because + // if for some reason it's fallthrough/target isn't in the DB, we need to correctly + // emit fallthrough/target rules + callinsn->setOriginalAddressID(insn->getOriginalAddressID()); + insn->setOriginalAddressID(BaseObj_t::NOT_IN_DATABASE); + + /* set the new instruction's data bits to be a jmp instead of a call */ + string newbits=""; + + /* add 4 (8) if it's an esp(rsp) indirect branch for x86-32 (-64) */ + callinsn->setDataBits(insn->getDataBits()); + convert_to_jump(callinsn,firp->getArchitectureBitWidth()/8); + + /* the jump instruction should NOT be indirectly reachable. We should + * land at the push + */ + fix_other_pcrel(firp, callinsn, insn->getAddress()->getVirtualOffset()); + callinsn->setIndirectBranchTargetAddress(NULL); + + /* add the new insn and new address into the list of valid calls and addresses */ + + + /* Convert the old call instruction into a push return_address instruction */ + insn->setFallthrough(callinsn); + insn->setTarget(NULL); + newbits=string(""); + newbits.resize(5); + newbits[0]=0x68; /* assemble an instruction push next_addr */ + newbits[1]=(next_addr>>0) & 0xff; + newbits[2]=(next_addr>>8) & 0xff; + newbits[3]=(next_addr>>16) & 0xff; + newbits[4]=(next_addr>>24) & 0xff; + insn->setDataBits(newbits); + insn->setComment(insn->getComment()+" Push part"); + + /* create a relocation for this instruction */ + /* + Relocation_t* reloc=new Relocation_t; + insn->getRelocations().insert(reloc); + firp->getRelocations().insert(reloc); + */ + auto reloc= firp->getArchitectureBitWidth()==32 ? firp->addNewRelocation(insn, 1, "32-bit") : + /* + reloc->setOffset(1); + reloc->setType("32-bit"); + */ + firp->getArchitectureBitWidth()==64 ? firp->addNewRelocation(insn, 0, "push64") : + /* + reloc->setOffset(0); + reloc->setType("push64"); + */ + throw invalid_argument("odd bit width?"); + + + + /* If the fallthrough is not marked as indirectly branchable-to, then mark it so */ + if(newindirtarg && !newindirtarg->getIndirectBranchTargetAddress()) + { + /* create a new address for the IBTA */ + /* + AddressID_t* newaddr = new AddressID_t; + assert(newaddr); + newaddr->setFileID(newindirtarg->getAddress()->getFileID()); + newaddr->setVirtualOffset(newindirtarg->getAddress()->getVirtualOffset()); + firp->getAddresses().insert(newaddr); + */ + auto newaddr=firp->addNewAddress(newindirtarg->getAddress()->getFileID(), newindirtarg->getAddress()->getVirtualOffset()); + + /* set the instruction and include this address in the list of addrs */ + newindirtarg->setIndirectBranchTargetAddress(newaddr); + + // if we're marking this as an IBTA, determine whether we can unpin it or not + if(can_unpin) + { + if(getenv("VERBOSE_FIX_CALLS")) + { + cout<<"setting unpin for type="<< reloc->getType()<< " address=" + <<hex<<insn->getBaseID()<<":"<<insn->getDisassembly()<<endl; + } + // set newindirtarg as unpinned + newindirtarg->getIndirectBranchTargetAddress()->setVirtualOffset(0); + reloc->setWRT(newindirtarg); + } + } + + + // mark in the IR what the fallthrough of this insn is. + /* + Relocation_t* fix_call_reloc=new Relocation_t(); + callinsn->getRelocations().insert(fix_call_reloc); + firp->getRelocations().insert(fix_call_reloc); + */ + auto fix_call_reloc=firp->addNewRelocation(callinsn, 0, "fix_call_fallthrough", newindirtarg); + (void)fix_call_reloc; // not used, just give to IR + /* + fix_call_reloc->setOffset(0); + fix_call_reloc->setType("fix_call_fallthrough"); + fix_call_reloc->setWRT(newindirtarg); + */ +} + + +// +// return true if insn is a call +// +bool is_call(Instruction_t* insn) +{ + /* Disassemble the instruction */ + auto disasm=DecodedInstruction_t::factory (insn); + return disasm->isCall(); +} + +bool can_skip_safe_function(Instruction_t *call_insn) +{ + if (!call_insn) + return false; + if (!is_call(call_insn)) + return false; + Instruction_t *target=call_insn->getTarget(); + if (!target) + return false; + auto func=target->getFunction(); + if (!func) + return false; + + /* if the call instruction isn't to a function entry point */ + if(func->getEntryPoint()!=target) + { + return false; + } + + if (func->isSafe()) + { + cout << "Function " << func->getName() << " is safe" << endl; + } + + return func->isSafe(); +} + + +template <class T> struct insn_less : binary_function <T,T,bool> { + bool operator() (const T& x, const T& y) const { + return x->getBaseID() < y->getBaseID() ;} +}; + + +// +// Mark ret_point as an unpinned IBT. +// +void mark_as_unpinned_ibt(FileIR_t* firp, Instruction_t* ret_point) +{ + if( ret_point == NULL ) return; + if( ret_point->getIndirectBranchTargetAddress() != NULL ) return; + + /* + auto newaddr = new AddressID_t; + assert(newaddr); + newaddr->setFileID(ret_point->getAddress()->getFileID()); + newaddr->setVirtualOffset(0); // unpinne + + firp->getAddresses().insert(newaddr); + */ + auto newaddr=firp->addNewAddress(ret_point->getAddress()->getFileID(),0); + ret_point->setIndirectBranchTargetAddress(newaddr); + +} + +// +// fix_all_calls - convert calls to push/jump pairs in the IR. if fix_all is true, all calls are converted, +// else we attempt to detect the calls it is safe to convert. +// +void fix_all_calls(FileIR_t* firp, bool fix_all) +{ + + auto sorted_insns = set<Instruction_t*,insn_less<Instruction_t*> >(ALLOF(firp->getInstructions())); + + for(auto insn : sorted_insns) + { + if(getenv("STOP_FIX_CALLS_AT") && fixed_calls>=(size_t)atoi(getenv("STOP_FIX_CALLS_AT"))) + break; + + if(is_call(insn)) + { + if( call_needs_fix(insn) ) // fixing is necessary + unpinning not possible. + { + fixed_calls++; + fix_call(insn, firp, false); + } + // we've been asked to fix all calls for funsies/cfi + // (and a bit about debugging fix-calls that's not important for anyone but jdh. + else if ( fix_all || (getenv("FIX_CALL_LIMIT") && not_fixed_calls>=(size_t)atoi(getenv("FIX_CALL_LIMIT")))) + { + auto fix_me = true; + if (!opt_fix_safefn && can_skip_safe_function(insn)) + { + fix_me = false; + no_fix_for_safefn++; + } + + if(fix_me) + { + // if we make it here, we know that it was not 100% necessary to fix the call + // but we've been asked to anyhow. + fixed_calls++; + fix_call(insn, firp, true /* true here indicates that the call can have an unpin reloc -- anh to add option in 3 minutes */); + } + else + { + not_fixed_calls++; + } + } + else + { + if(getenv("VERBOSE_FIX_CALLS")) + cout<<"No fix needed, marking ret site IBT, for "<<insn->getAddress()->getVirtualOffset()<<":"<<insn->getDisassembly()<<endl; + mark_as_unpinned_ibt(firp, insn->getFallthrough()); + not_fixed_calls++; + } + } + + else + { + if(getenv("VERBOSE_FIX_CALLS")) + cout<<"Not a call "<<insn->getAddress()->getVirtualOffset()<<":"<<insn->getDisassembly()<<endl; + not_calls++; + } + } + + cout << "# ATTRIBUTE fix_calls::fixed_calls="<<std::dec<<fixed_calls<<endl; + cout << "# ATTRIBUTE fix_calls::no_fix_needed_calls="<<std::dec<<not_fixed_calls<<endl; + cout << "# ATTRIBUTE fix_calls::other_instructions="<<std::dec<<not_calls<<endl; + cout << "# ATTRIBUTE fix_calls::fixed_pct="<<std::fixed<<(((float)fixed_calls)/((float)(not_fixed_calls+fixed_calls+not_calls)))*100.00<<"%"<<endl; + cout << "# ATTRIBUTE fix_calls::remaining_ratio="<<std::fixed<<((float)not_fixed_calls/((float)(not_fixed_calls+fixed_calls+not_calls)))*100.00<<"%"<<endl; + cout << "# ATTRIBUTE fix_calls::other_insts_ratio="<<std::fixed<<((float)not_calls/((float)(not_fixed_calls+fixed_calls+not_calls)))*100.00<<"%"<<endl; + cout << "# ATTRIBUTE fix_calls::no_target_insn="<<std::dec<< no_target_insn << endl; + cout << "# ATTRIBUTE fix_calls::no_fallthrough_insn="<<std::dec<< no_fallthrough_insn << endl; + cout << "# ATTRIBUTE fix_calls::target_not_in_function="<<std::dec<< target_not_in_function << endl; + cout << "# ATTRIBUTE fix_calls::call_to_not_entry="<<std::dec<< call_to_not_entry << endl; + cout << "# ATTRIBUTE fix_calls::thunk_check="<<std::dec<< thunk_check << endl; + cout << "# ATTRIBUTE fix_calls::found_pattern="<<std::dec<< found_pattern << endl; + cout << "# ATTRIBUTE fix_calls::in_ehframe="<<std::dec<< in_ehframe << endl; + cout << "# ATTRIBUTE fix_calls::no_fix_for_ib="<<std::dec<< no_fix_for_ib << endl; + cout << "# ATTRIBUTE fix_calls::no_fix_for_safefn="<<std::dec<< no_fix_for_safefn << endl; +} + + +// +// fix_other_pcrel - add relocations to other instructions that have pcrel bits +// +void fix_other_pcrel(FileIR_t* firp, Instruction_t *insn, uintptr_t virt_offset) +{ + auto disasm=DecodedInstruction_t::factory(insn); + const auto &operands=disasm->getOperands(); + const auto relop_it=find_if(ALLOF(operands),[](const shared_ptr<DecodedOperand_t>& op) + { return op->isPcrel() ; } ); + const bool is_rel= relop_it!=operands.end(); + + /* if this has already been fixed, we can skip it */ + if(virt_offset==0 || virt_offset==(uintptr_t)-1) + return; + + if(is_rel) + { + const auto &the_arg=*(relop_it->get()); + const auto mt=firp->getArchitecture()->getMachineType(); + if(mt==admtAarch64) + { + // figure out how to rewrite pcrel arm insns, then change the virt addr + // insn->getAddress()->setVirtualOffset(0); + } + else if(mt==admtX86_64 || mt==admtI386) + { + assert(the_arg.isMemory()); + auto offset=disasm->getMemoryDisplacementOffset(&the_arg, insn); + assert(offset>=0 && offset <=15); + auto size=the_arg.getMemoryDisplacementEncodingSize(); + assert(size==1 || size==2 || size==4 || size==8); + + if(getenv("VERBOSE_FIX_CALLS")) + { + cout<<"Found insn with pcrel memory operand: "<<disasm->getDisassembly() + <<" Displacement="<<std::hex<<the_arg.getMemoryDisplacement() << dec + <<" size="<<the_arg.getMemoryDisplacementEncodingSize() <<" Offset="<<offset; + } + + /* convert [rip_pc+displacement] addresssing mode into [rip_0+displacement] where rip_pc is the actual PC of the insn, + * and rip_0 is means that the PC=0. AKA, we are relocating this instruction to PC=0. Later we add a relocation to undo this transform at runtime + * when we know the actual address. + */ + + /* get the data */ + string data=insn->getDataBits(); + char cstr[20]={}; + memcpy(cstr,data.c_str(), data.length()); + void *offsetptr=&cstr[offset]; + + uintptr_t disp=the_arg.getMemoryDisplacement(); + uintptr_t oldpc=virt_offset; + uintptr_t newdisp=disp+oldpc; + + assert((uintptr_t)(offset+size)<=(uintptr_t)(data.length())); + + switch(size) + { + case 4: + assert( (uintptr_t)(int)newdisp == (uintptr_t)newdisp); + *(int*)offsetptr=newdisp; + break; + case 1: + case 2: + case 8: + default: + assert(0); + //assert(("Cannot handle offset of given size", 0)); + } + + /* put the data back into the insn */ + data.replace(0, data.length(), cstr, data.length()); + insn->setDataBits(data); + + other_fixes++; + + disasm=DecodedInstruction_t::factory(insn); + if(getenv("VERBOSE_FIX_CALLS")) + cout<<" Converted to: "<<disasm->getDisassembly() << endl; + + // and it's important to set the VO to 0, so that the pcrel-ness is calculated correctly. + insn->getAddress()->setVirtualOffset(0); + } + + // now that we've done the rewriting, go ahead and add the reloc. + /* + auto reloc=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, 0,"pcrel"); + insn->getRelocations().insert(reloc); + firp->getRelocations().insert(reloc); + */ + auto reloc=firp->addNewRelocation(insn,0,"pcrel"); + (void)reloc; // not used, only given to the IR + + } +} + +void fix_safefr(FileIR_t* firp, Instruction_t *insn, uintptr_t virt_offset) +{ + /* if this has already been fixed, we can skip it */ + if(virt_offset==0 || virt_offset==(uintptr_t)-1) + return; + + for(auto reloc : insn->getRelocations()) + { + assert(reloc); + if( reloc->getType() == "safefr" ) + { + /* + auto addr=new AddressID_t(BaseObj_t::NOT_IN_DATABASE, insn->getAddress()->getFileID(), 0); + firp->getAddresses().insert(addr); + */ + auto addr=firp->addNewAddress(insn->getAddress()->getFileID(), 0); + insn->setAddress(addr); + } + } +} + + +void fix_other_pcrel(FileIR_t* firp) +{ + + for(auto insn : firp->getInstructions()) + { + fix_other_pcrel(firp,insn, insn->getAddress()->getVirtualOffset()); + fix_safefr(firp,insn, insn->getAddress()->getVirtualOffset()); + } + cout << "# ATTRIBUTE fix_calls::other_fixes="<<std::dec<<other_fixes<<endl; +} + +// +// main rountine; convert calls into push/jump statements +// +// int main(int argc, char* argv[]) + + +bool fix_all=false; +bool do_eh_frame=true; + + +int parseArgs(const vector<string> step_args) +{ + + if(step_args.size()<1) + { + cerr<<"Usage: <id> [--fix-all | --no-fix-all ] [--eh-frame | --no-ehframe] "<<endl; + cerr<<" --eh-frame " << endl; + cerr<<" --no-eh-frame Use (or dont) the eh-frame section to be compatible with exception handling." << endl; + cerr<<" --fix-all " << endl; + cerr<<" --no-fix-all Convert (or don't) all calls to push/jmp pairs."<<endl; + cerr<<" --fix-icalls Convert (or don't) indirect calls."<<endl; + cerr<<" --no-fix-icalls Convert (or don't) indirect calls."<<endl; + exit(-1); + } + + for(unsigned int argc_iter=1; argc_iter<step_args.size(); argc_iter++) + { + if("--fix-all"==step_args[argc_iter]) + { + fix_all=true; + } + else if("--no-fix-all"==step_args[argc_iter]) + { + fix_all=false; + } + else if("--eh-frame"==step_args[argc_iter]) + { + do_eh_frame=true; + } + else if("--no-eh-frame"==step_args[argc_iter]) + { + do_eh_frame=false; + } + else if("--fix-icalls"==step_args[argc_iter]) + { + opt_fix_icalls = true; + } + else if("--no-fix-icalls"==step_args[argc_iter]) + { + opt_fix_icalls = false; + } + else if("--fix-safefn"==step_args[argc_iter]) + { + opt_fix_safefn = true; + } + else if("--no-fix-safefn"==step_args[argc_iter]) + { + opt_fix_safefn = false; + } + else + { + cerr<<"Unrecognized option: "<<step_args[argc_iter]<<endl; + return -1; + } + } + if(getenv("FIX_CALLS_FIX_ALL_CALLS")) + fix_all=true; + + variant_id=stoi(step_args[0]); + return 0; +} + +DatabaseID_t variant_id=BaseObj_t::NOT_IN_DATABASE; + + +int executeStep(IRDBObjects_t *const irdb_objects) +{ + + cout<<"Reading variant "<<variant_id<<" from database." << endl; + try + { + /* setup the interface to the sql server */ + const auto pqxx_interface=irdb_objects->getDBInterface(); + BaseObj_t::setInterface(pqxx_interface); + + auto pidp = irdb_objects->addVariant(variant_id); + cout<<"Fixing calls->push/jmp in variant "<<*pidp<< "." <<endl; + + assert(pidp->isRegistered()==true); + + for(const auto &this_file : pidp->getFiles()) + { + assert(this_file); + + // read the db + auto firp = irdb_objects->addFileIR(variant_id, this_file->getBaseID()); + + assert(firp && pidp); + + eh_frame_ranges.clear(); + int elfoid=firp->getFile()->getELFOID(); + pqxx::largeobject lo(elfoid); + lo.to_file(pqxx_interface->getTransaction(),"readeh_tmp_file.exe"); + EXEIO::exeio* elfiop=new EXEIO::exeio; + elfiop->load(string("readeh_tmp_file.exe")); + EXEIO::dump::header(cout,*elfiop); + EXEIO::dump::section_headers(cout,*elfiop); + // do eh_frame reading as required. + if(do_eh_frame) + read_ehframe(firp, elfiop); + + fix_all_calls(firp,fix_all); + fix_other_pcrel(firp); + + cout<<"Done!"<<endl; + + } + } + catch (DatabaseError_t pnide) + { + cout<<"Unexpected database error: "<<pnide<<endl; + return -1; + } + catch(...) + { + cerr<<"Unexpected error"<<endl; + return -1; + } + + assert(getenv("SELF_VALIDATE")==nullptr || (fixed_calls + other_fixes) > 5); + assert(getenv("SELF_VALIDATE")==nullptr || fix_all || not_fixed_calls > 5); + + return 0; +} + +void range(VirtualOffset_t a, VirtualOffset_t b) +{ + // we've found examples of ranges being 0 sized, and it's a bit weird what that means. + // it applies to 0 instructions? + // skip it, it's likely an invalid FDE. + if(a==b) + return; + // non-zero sized fde + assert(a<b); + + const auto rangeiter=eh_frame_ranges.find(Range_t(a+1,a+1)); + assert(rangeiter==eh_frame_ranges.end()); + + eh_frame_ranges.insert(Range_t(a+1,b)); // ranges are interpreted as (a,b] +} + +bool possible_target(uintptr_t p, uintptr_t at, ibt_provenance_t prov) +{ + // used for LDSA + return false; +} + + +std::string getStepName(void) const override +{ + return std::string("fix_calls"); +} + +}; // end class FixCalls_t + +shared_ptr<TransformStep_t> curInvocation; + +bool possible_target(VirtualOffset_t p, VirtualOffset_t from_addr, ibt_provenance_t prov) +{ + assert(curInvocation); + return (dynamic_cast<FixCalls_t*>(curInvocation.get()))->possible_target(p,from_addr,prov); +} + +void range(VirtualOffset_t start, VirtualOffset_t end) +{ + assert(curInvocation); + return (dynamic_cast<FixCalls_t*>(curInvocation.get()))->range(start,end); +} + +extern "C" +shared_ptr<TransformStep_t> getTransformStep(void) +{ + curInvocation.reset(new FixCalls_t()); + return curInvocation; + + //return shared_ptr<Transform_SDK::TransformStep_t>(new FixCalls_t()); +} + + diff --git a/irdb-lib/ir_builders/generate_spri.cpp b/irdb-lib/ir_builders/generate_spri.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6c60fa7deeb3e331c9583b9de58d02832ba1ea7f --- /dev/null +++ b/irdb-lib/ir_builders/generate_spri.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + + +#include <libIRDB-core.hpp> +#include <utils.hpp> // to_string function from libIRDB +#include <iostream> +#include <fstream> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +using namespace libIRDB; +using namespace std; + +// +// main routine to generate spri rules for a variant. +// +int main(int argc, char* argv[]) +{ + if(argc!=3 && argc!=4) + { + cerr<<"Usage: generate_spri.exe <is shared object> <variant id> [<output_file>]"<<endl; + exit(-1); + } + + int with_ilr=!atoi(argv[1]); + assert(with_ilr==!!with_ilr); + + string filename; + ostream *fout; + if(argc==4) + fout=new ofstream(argv[3], ios::out); + else + fout=&cout; + + + VariantID_t *varidp=NULL; + FileIR_t *firp=NULL; + + /* setup the interface to the sql server */ + pqxxDB_t pqxx_interface; + BaseObj_t::SetInterface(&pqxx_interface); + + try + { + + cerr<<"Looking up variant "<<string(argv[2])<<" from database." << endl; + varidp=new VariantID_t(atoi(argv[2])); + + assert(varidp->IsRegistered()==true); + + + for(set<File_t*>::iterator it=varidp->GetFiles().begin(); + it!=varidp->GetFiles().end(); + ++it + ) + { + File_t* this_file=*it; + assert(this_file); + cerr<<"Reading variant "<<string(argv[2])<<":"<<this_file->GetURL() + <<" from database." << endl; + + // read the db + firp=new FileIR_t(*varidp,this_file); + + // ILR only for the main file. + firp->GenerateSPRI(*fout, with_ilr && this_file==varidp->GetMainFile()); + delete firp; + } + + } + catch (DatabaseError_t pnide) + { + cerr<<"Unexpected database error: "<<pnide<<endl; + exit(-1); + } + + cerr<<"Done!"<<endl; + + if(fout!=&cout) + ((ofstream*)fout)->close(); + + + delete varidp; + return 0; +} + + diff --git a/irdb-lib/ir_builders/ilr.cpp b/irdb-lib/ir_builders/ilr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a42c1282cba5aba8e8304dea1c20de7a602513ee --- /dev/null +++ b/irdb-lib/ir_builders/ilr.cpp @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + + +#include <libIRDB-core.hpp> +#include <iostream> +#include <stdlib.h> + +using namespace libIRDB; +using namespace std; + +template <class T> struct insn_less : binary_function <T,T,bool> { + bool operator() (const T& x, const T& y) const { + return x->GetBaseID() < y->GetBaseID() ;} +}; + +void do_ilr(VariantID_t *pidp, FileIR_t* firp) +{ + + assert(firp && pidp); + + cout<<"Applying ILR to variant "<<*pidp<< "." <<endl; + + long long unmoved_instr=0, moved_instr=0; + + set<Instruction_t*,insn_less<Instruction_t*> > sorted_insns; + + set<AddressID_t*> newaddressset; + for( + set<Instruction_t*>::const_iterator it=firp->GetInstructions().begin(); + it!=firp->GetInstructions().end(); + ++it + ) + { + Instruction_t* insn=*it; + sorted_insns.insert(insn); + } + + int ilrd_instructions=0; + + + + for( + set<Instruction_t*,insn_less<Instruction_t*> >::const_iterator it=sorted_insns.begin(); + it!=sorted_insns.end(); + ++it + ) + { + Instruction_t* insn=*it; + ilrd_instructions++; + + if(getenv("ILR_NUMINSNSTOTRANSFORM") && ilrd_instructions==atoi(getenv("ILR_NUMINSNSTOTRANSFORM"))) + { + //DISASM d; + //Disassemble(insn,d); + const auto d=DecodedInstruction_t(insn); + cout<<"Aborting after insn #"<<std::dec<<ilrd_instructions<<": "<<d.getDisassembly() << " at " + <<std::hex<<insn->GetAddress()->GetVirtualOffset()<<std::dec<<endl; + } + if(getenv("ILR_NUMINSNSTOTRANSFORM") && ilrd_instructions>=atoi(getenv("ILR_NUMINSNSTOTRANSFORM"))) + { + newaddressset.insert(insn->GetAddress()); + if (insn->GetIndirectBranchTargetAddress()) + newaddressset.insert(insn->GetIndirectBranchTargetAddress()); + continue; + } + + + AddressID_t *newaddr=new AddressID_t; + newaddr->SetFileID(insn->GetAddress()->GetFileID()); + insn->SetAddress(newaddr); + + if (insn->GetIndirectBranchTargetAddress()) + { + unmoved_instr++; + newaddressset.insert(insn->GetIndirectBranchTargetAddress()); + } + else + moved_instr++; + + newaddressset.insert(newaddr); + } + + for( + DataScoopSet_t::const_iterator it=firp->GetDataScoops().begin(); + it!=firp->GetDataScoops().end(); + ++it + ) + { + newaddressset.insert((*it)->GetStart()); + newaddressset.insert((*it)->GetEnd()); + } + + firp->GetAddresses()=newaddressset; + + + cout << "# ATTRIBUTE ilr::filename="<<firp->GetFile()->GetURL()<<endl; + cout << "# ATTRIBUTE ilr::unmoved_instructions="<<std::dec<<unmoved_instr<<endl; + cout << "# ATTRIBUTE ilr::moved_instructions="<<std::dec<<moved_instr<<endl; + cout << "# ATTRIBUTE ilr::moved_insts_pct="<<std::fixed<<((float)moved_instr/(moved_instr+unmoved_instr))*100.00<<"%"<<endl; + + cout<<"Writing variant "<<*pidp<<" back to database." << endl; + firp->WriteToDB(); +} +int main(int argc, char* argv[]) +{ + + if(argc!=2) + { + cerr<<"Usage: ilr <id>"<<endl; + exit(-1); + } + + VariantID_t *pidp=NULL; + FileIR_t *firp=NULL; + + /* setup the interface to the sql server */ + pqxxDB_t pqxx_interface; + BaseObj_t::SetInterface(&pqxx_interface); + + cout<<"Reading variant "<<string(argv[1])<<" from database." << endl; + try + { + + pidp=new VariantID_t(atoi(argv[1])); + assert(pidp->IsRegistered()==true); + + + for(set<File_t*>::iterator it=pidp->GetFiles().begin(); + it!=pidp->GetFiles().end(); + ++it + ) + { + File_t* this_file=*it; + assert(this_file); + + // ilr isnt working for shared libs yet. + // if(this_file!=pidp->GetMainFile()) + // continue; + + // read the db + firp=new FileIR_t(*pidp,this_file); + + // do the ILRing. + do_ilr(pidp, firp); + + delete firp; + } + + + pqxx_interface.Commit(); + + } + catch (DatabaseError_t pnide) + { + cout<<"Unexpected database error: "<<pnide<<endl; + exit(-1); + } + + cout<<"Done!"<<endl; + + delete pidp; + return 0; +} + diff --git a/irdb-lib/ir_builders/list_programs.cpp b/irdb-lib/ir_builders/list_programs.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ede92ba86e328b0b14c9f85f6e1a1b170cc1fcae --- /dev/null +++ b/irdb-lib/ir_builders/list_programs.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + + +#include <libIRDB-core.hpp> +#include <iostream> +#include <stdlib.h> + +using namespace libIRDB; +using namespace std; + +int main(int argc, char* argv[]) +{ + + if(argc!=1) + { + cerr<<"Usage: list_tests)"<<endl; + exit(-1); + } + + + /* setup the interface to the sql server */ + pqxxDB_t pqxx_interface; + BaseObj_t::SetInterface(&pqxx_interface); + + for(int i=1; true ; i++) + { + try + { + /* try to load the program ID */ + VariantID_t pid(i); + cout<<pid<<endl; + } + catch (DatabaseError_t pnide) + { + if(pnide.GetErrorCode()==DatabaseError_t::VariantNotInDatabase) + break; + else + { + cout<<"Unexpected database error: "<<pnide<<endl; + exit(-1); + } + }; + } + return 0; +} diff --git a/irdb-lib/ir_builders/mark_functions_safe.cpp b/irdb-lib/ir_builders/mark_functions_safe.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7e27bd7b85cd61fbb6cd36249c8fa51c12c35e8a --- /dev/null +++ b/irdb-lib/ir_builders/mark_functions_safe.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2014-2015 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + + +#include <libIRDB-core.hpp> +#include <iostream> +#include <fstream> +#include <stdlib.h> + +using namespace libIRDB; +using namespace std; + +Function_t* findFunction(FileIR_t* firp, string funcName) +{ + assert(firp); + + for( + set<Function_t*>::iterator it=firp->GetFunctions().begin(); + it!=firp->GetFunctions().end(); + ++it + ) + { + Function_t* func=*it; + if (!func) continue; + if (func->GetName() == funcName) + { + return func; + } + } + + return NULL; +} + +void mark_function_safe(FileIR_t* firp, const std::string& function_file) +{ + assert(firp); + + std::ifstream ffile(function_file); + std::string fn; + while (std::getline(ffile, fn)) + { + cerr << "Want to mark: " << fn << " as safe" << endl; + Function_t *f = findFunction(firp, fn); + if (f) + { + cerr << "Found in IRDB: Marking " << f->GetName() << " as safe" << endl; + f->SetSafe(true); + } + } + + firp->WriteToDB(); +} + +int main(int argc, char* argv[]) +{ + if(argc!=3) + { + cerr<<"Usage: mark_function_safe <id> <file_with_functions_to_mark_safe>"<<endl; + exit(-1); + } + + VariantID_t *pidp=NULL; + FileIR_t *firp=NULL; + string function_files(argv[2]); + + /* setup the interface to the sql server */ + pqxxDB_t pqxx_interface; + BaseObj_t::SetInterface(&pqxx_interface); + + cout<<"Reading variant "<<string(argv[1])<<" from database." << endl; + try + { + pidp=new VariantID_t(atoi(argv[1])); + assert(pidp->IsRegistered()==true); + + for(set<File_t*>::iterator it=pidp->GetFiles().begin(); it!=pidp->GetFiles().end(); ++it) + { + File_t* this_file=*it; + assert(this_file); + + // only do main file for now + if(this_file!=pidp->GetMainFile()) + continue; + + // read the db + firp=new FileIR_t(*pidp,this_file); + + // mark as safe + mark_function_safe(firp, function_files); + + delete firp; + } + pqxx_interface.Commit(); + + } + catch (DatabaseError_t pnide) + { + cout<<"Unexpected database error: "<<pnide<<endl; + exit(-1); + } + + cout<<"Done!"<<endl; + + delete pidp; + return 0; +} + diff --git a/irdb-lib/ir_builders/pin_address.cpp b/irdb-lib/ir_builders/pin_address.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dc4fc637433461632f9c32a659205d5590232dc3 --- /dev/null +++ b/irdb-lib/ir_builders/pin_address.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <libIRDB-core.hpp> +#include <iostream> +#include <stdlib.h> +#include <string.h> +#include <cstring> +#include <cstdlib> + +using namespace libIRDB; +using namespace std; + +/* + * Prefix-aware (pa) string to unsigned + * long conversion function. + */ +unsigned long pa_strtoul(const char * const number) +{ + unsigned long result = 0l; + char *end = NULL; + int base = 10; + int number_len = strlen(number); + + /* + * Determine the base. + */ + if (number_len >= 2 && number[0] == '0' && + ((number[1] == 'x') || (number[1] == 'X'))) + base = 16; + else if (number_len >= 1 && number[0] == '0') + base = 8; + + result = strtoul(number, &end, base); + if (end == &number[number_len]) + { + return result; + } + else + { + return 0; + } +} + +int main(int argc, char* argv[]) +{ + VariantID_t *pidp=NULL; + FileIR_t * firp=NULL; + unsigned long address_to_pin = 0; + bool did_pin = false; + + if(argc != 3) + { + cerr<<"Usage: pin_address.exe <id> <address>" << endl; + exit(-1); + } + + address_to_pin = pa_strtoul(argv[2]); + try + { + /* setup the interface to the sql server */ + pqxxDB_t pqxx_interface; + BaseObj_t::SetInterface(&pqxx_interface); + + pidp=new VariantID_t(atoi(argv[1])); + + assert(pidp->IsRegistered()==true); + + for(set<File_t*>::iterator it=pidp->GetFiles().begin(); + it!=pidp->GetFiles().end(); + ++it) + { + File_t* this_file=*it; + assert(this_file); + + + // read the db + firp=new FileIR_t(*pidp, this_file); + /* + * put the two nested loops here. + */ + for( + set<Function_t*>::const_iterator itf=firp->GetFunctions().begin(); + itf!=firp->GetFunctions().end(); + ++itf + ) + { + Function_t* func=*itf; + for( + set<Instruction_t*>::const_iterator it=func->GetInstructions().begin(); + it!=func->GetInstructions().end(); + ++it) + { + Instruction_t* insn = *it; + if (insn->GetAddress()->GetVirtualOffset() == address_to_pin) + { + insn->SetIndirectBranchTargetAddress(insn->GetAddress()); + did_pin = true; + } + } + } + firp->WriteToDB(); + delete firp; + + if (did_pin) { + cout <<"Pinned 0x" << hex << address_to_pin + << " in file " << this_file->GetURL()<<endl; + break; + } + } + + pqxx_interface.Commit(); + if (!did_pin) { + cerr << "Oops: Could not find an instruction at 0x" << hex + << address_to_pin << " to pin." << endl; + } + } + catch (DatabaseError_t pnide) + { + cout<<"Unexpected database error: "<<pnide<<endl; + exit(-1); + } + + assert(firp && pidp); + + delete pidp; + return 0; +} diff --git a/irdb-lib/ir_builders/print_variant.cpp b/irdb-lib/ir_builders/print_variant.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b45f283fb732bed65efb8e2e97886c7b4a6dcc90 --- /dev/null +++ b/irdb-lib/ir_builders/print_variant.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + + +#include <libIRDB-core.hpp> +#include <iostream> +#include <stdlib.h> + +using namespace libIRDB; +using namespace std; + + +int main(int argc, char* argv[]) +{ + + if(argc!=2) + { + cerr<<"Usage: simple (<pid>)"<<endl; + exit(-1); + } + + + /* setup the interface to the sql server */ + pqxxDB_t pqxx_interface; + BaseObj_t::SetInterface(&pqxx_interface); + + + VariantID_t *pidp=NULL; + try + { + pidp=new VariantID_t(atoi(argv[1])); + } + catch (DatabaseError_t pnide) + { + if(pnide.GetErrorCode()==DatabaseError_t::VariantNotInDatabase) + { + cout<<"Variant "<< argv[1]<< " not found in db"<<endl; + exit(-2); + } + else + { + cout<<"Unexpected database error: "<<pnide<<endl; + exit(-1); + } + } + + cout<<"Variant "<< argv[1]<< " found in db: "<<*pidp << endl; + + delete pidp; + return 0; +} diff --git a/irdb-lib/ir_builders/read_ehframe.cpp b/irdb-lib/ir_builders/read_ehframe.cpp new file mode 100644 index 0000000000000000000000000000000000000000..17dd5f8c673ec71a17105a50bee17d77e7a79ce9 --- /dev/null +++ b/irdb-lib/ir_builders/read_ehframe.cpp @@ -0,0 +1,998 @@ + + +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + + +#include <irdb-core> +#include <iostream> +#include <algorithm> +#include <stdlib.h> +#include <assert.h> +#include <string.h> + +#include <exeio.h> + +// disable sign compare warnings in 3rd party code +#pragma GCC diagnostic ignored "-Wsign-compare" +#include "elfio/elfio.hpp" +#include "elfio/elfio_dump.hpp" +#pragma GCC diagnostic pop + + +#include "fill_in_indtargs.hpp" + + +using namespace std; +using namespace IRDB_SDK; + + + + + + +uint32_t ptrsize=0; +ELFIO::elfio *elfiop=NULL; +void* eh_frame_addr=0; +char* eh_frame_data=0; +int eh_frame_data_total_size; +intptr_t eh_offset=0; + + + +typedef int sword; +typedef unsigned int uword; +typedef unsigned int uaddr; +typedef int saddr; +typedef unsigned char ubyte; +typedef struct dwarf_fde fde; +typedef uintptr_t _Unwind_Ptr; + +union unaligned +{ + void *p; + unsigned u2 __attribute__ ((mode (HI))); + unsigned u4 __attribute__ ((mode (SI))); + unsigned u8 __attribute__ ((mode (DI))); + signed s2 __attribute__ ((mode (HI))); + signed s4 __attribute__ ((mode (SI))); + signed s8 __attribute__ ((mode (DI))); +} __attribute__ ((packed)); + + +#define DW_EH_PE_absptr 0x00 +#define DW_EH_PE_omit 0xff + +#define DW_EH_PE_uleb128 0x01 +#define DW_EH_PE_udata2 0x02 +#define DW_EH_PE_udata4 0x03 +#define DW_EH_PE_udata8 0x04 +#define DW_EH_PE_sleb128 0x09 +#define DW_EH_PE_sdata2 0x0A +#define DW_EH_PE_sdata4 0x0B +#define DW_EH_PE_sdata8 0x0C +#define DW_EH_PE_signed 0x08 + +#define DW_EH_PE_pcrel 0x10 +#define DW_EH_PE_textrel 0x20 +#define DW_EH_PE_datarel 0x30 +#define DW_EH_PE_funcrel 0x40 +#define DW_EH_PE_aligned 0x50 + +#define DW_EH_PE_indirect 0x80 + +#if __SIZEOF_LONG__ >= __SIZEOF_POINTER__ + typedef long _sleb128_t; + typedef unsigned long _uleb128_t; +#elif __SIZEOF_LONG_LONG__ >= __SIZEOF_POINTER__ + typedef long long _sleb128_t; + typedef unsigned long long _uleb128_t; +#else +# error "What type shall we use for _sleb128_t?" +#endif + + +struct dwarf_cie +{ + uword length; + sword CIE_id; + ubyte version; + unsigned char augmentation[1]; +} __attribute__ ((packed, aligned (__alignof__ (void* )))); + + + +struct dwarf_fde +{ + uword length; + sword CIE_delta; + unsigned char pc_begin[1]; +} __attribute__ ((packed, aligned (__alignof__ (void* )))); + + +struct fde_vector +{ + void *orig_data; + size_t count; + struct dwarf_fde *array[1]; +}; + +struct object +{ + void *pc_begin; + void *tbase; + void *dbase; + union { + struct dwarf_fde *single; + struct dwarf_fde **array; + struct fde_vector *sort; + } u; + + union { + struct { + unsigned long sorted : 1; + unsigned long from_array : 1; + unsigned long mixed_encoding : 1; + unsigned long encoding : 8; + /* ??? Wish there was an easy way to detect a 64-bit host here; + we've got 32 bits left to play with... */ + unsigned long count : 21; + } b; + size_t i; + } s; +#ifdef DWARF2_OBJECT_END_PTR_EXTENSION + char *fde_end; +#endif + + struct object *next; + +}; + +void * ptr_to_data_to_addr(uintptr_t data_addr); +void * addr_to_ptr_to_data(uintptr_t to_deref); +intptr_t addr_to_p_offset(uintptr_t addr); + + +#include "unwind-pe.h" + +void * ptr_to_data_to_addr(uintptr_t data_addr) +{ + int i; + if(eh_frame_data<=(void*)data_addr && + (uintptr_t)data_addr <= (uintptr_t)eh_frame_data+(uintptr_t)eh_frame_data_total_size) + { + intptr_t offset=((uintptr_t)data_addr-(uintptr_t)eh_frame_data); + const char* data=(const char*)(uintptr_t)eh_frame_addr; + return (void*)&data[offset]; + } + for(i=0; i<elfiop->sections.size();i++) + { + // skip sections that aren't loaded. + if((elfiop->sections[i]->get_flags() & SHF_ALLOC) != SHF_ALLOC) + continue; + if(elfiop->sections[i]->get_data()<=(void*)data_addr && + (uintptr_t)data_addr < (uintptr_t)elfiop->sections[i]->get_data() + (uintptr_t)elfiop->sections[i]->get_size() ) + { + intptr_t offset=((uintptr_t)data_addr-(uintptr_t)elfiop->sections[i]->get_data()); + const char* data=(const char*)(uintptr_t)elfiop->sections[i]->get_address(); + return (void*)&data[offset]; + } + } + assert(0); +} + + +intptr_t addr_to_p_offset(uintptr_t to_deref) +{ + int i; + for(i=0; i<elfiop->sections.size();i++) + { + // skip sections that aren't loaded. + if((elfiop->sections[i]->get_flags() & SHF_ALLOC) != SHF_ALLOC) + continue; + if(elfiop->sections[i]->get_address()<=to_deref && + to_deref < elfiop->sections[i]->get_address() + elfiop->sections[i]->get_size() ) + { + intptr_t offset=((uintptr_t)to_deref-(uintptr_t)elfiop->sections[i]->get_address()); + const char* data=elfiop->sections[i]->get_data(); + return (intptr_t)(to_deref-(uintptr_t)&data[offset]); + } + } + assert(0); +} + +void * addr_to_ptr_to_data(uintptr_t to_deref) +{ + int i; + for(i=0; i<elfiop->sections.size();i++) + { + // skip sections that aren't loaded. + if((elfiop->sections[i]->get_flags() & SHF_ALLOC) != SHF_ALLOC) + continue; + if(elfiop->sections[i]->get_address()<=to_deref && + to_deref < elfiop->sections[i]->get_address() + elfiop->sections[i]->get_size() ) + { + intptr_t offset=((uintptr_t)to_deref-(uintptr_t)elfiop->sections[i]->get_address()); + const char* data=elfiop->sections[i]->get_data(); + return (void*)&data[offset]; + } + } + assert(0); +} + +_Unwind_Internal_Ptr deref_unwind_ptr(uintptr_t to_deref) +{ + int i; + for(i=0; i<elfiop->sections.size();i++) + { + // skip sections that aren't loaded. + if((elfiop->sections[i]->get_flags() & SHF_ALLOC) != SHF_ALLOC) + continue; + if(elfiop->sections[i]->get_address()<=to_deref && + to_deref + ptrsize <= elfiop->sections[i]->get_address() + elfiop->sections[i]->get_size() ) + { + intptr_t offset=(to_deref-elfiop->sections[i]->get_address()); + const char* data=elfiop->sections[i]->get_data(); + return deref_unwind_ptr_in_memory(&data[offset]); + } + } + assert(0); +} + +struct lsda_header_info +{ + _Unwind_Ptr Start; + _Unwind_Ptr LPStart; + _Unwind_Ptr ttype_base; + unsigned char *TType; + unsigned char *action_table; + unsigned char ttype_encoding; + unsigned char call_site_encoding; +}; + + + +struct object *all_objects=NULL; + +void register_frame_info(void *begin, struct object *ob) +{ + memset(ob,0,sizeof(struct object)); + + ob->pc_begin = (void *)-1; + ob->tbase = 0; + ob->dbase = 0; + ob->u.single = (struct dwarf_fde *)begin; + ob->s.i = 0; + ob->s.b.encoding = DW_EH_PE_omit; +#ifdef DWARF2_OBJECT_END_PTR_EXTENSION + ob->fde_end = NULL; +#endif + + ob->next = all_objects; + all_objects = ob; + +} + +struct dwarf_cie * get_cie (struct dwarf_fde *f) +{ + return (struct dwarf_cie*)((long long)&f->CIE_delta - (long long)f->CIE_delta); +} + +fde * next_fde (fde *f) +{ + return (fde *) ((char *) f + f->length + sizeof (f->length)); +} + +int last_fde (struct object *obj __attribute__ ((__unused__)), fde *f) +{ +#ifdef DWARF2_OBJECT_END_PTR_EXTENSION + return (char *)f == obj->fde_end || f->length == 0; +#else + return f->length == 0; +#endif +} + +static _Unwind_Ptr +base_from_object (unsigned char encoding, struct object *ob) +{ + if (encoding == DW_EH_PE_omit) + return 0; + + switch (encoding & 0x70) + { + case DW_EH_PE_absptr: + case DW_EH_PE_pcrel: + case DW_EH_PE_aligned: + return 0; + + case DW_EH_PE_textrel: + return (_Unwind_Ptr) ob->tbase; + case DW_EH_PE_datarel: + return (_Unwind_Ptr) ob->dbase; + default: + assert(0); + } +} + +int get_cie_encoding (struct dwarf_cie *cie) +{ + unsigned char *aug, *p; + _Unwind_Ptr dummy; + _uleb128_t utmp; + _sleb128_t stmp; + + aug = cie->augmentation; + if (aug[0] != 'z') + return DW_EH_PE_absptr; + + p = aug + strlen ((char *)aug) + 1; /* Skip the augmentation string. */ + p = read_uleb128 (p, &utmp); /* Skip code alignment. */ + p = read_sleb128 (p, &stmp); /* Skip data alignment. */ + if (cie->version == 1) /* Skip return address column. */ + p++; + else + p = read_uleb128 (p, &utmp); + + aug++; /* Skip 'z' */ + p = read_uleb128 (p, &utmp); /* Skip augmentation length. */ + while (1) + { + /* This is what we're looking for. */ + if (*aug == 'R') + return *p; + /* Personality encoding and pointer. */ + else if (*aug == 'P') + { + /* ??? Avoid dereferencing indirect pointers, since we're + faking the base address. Gotta keep DW_EH_PE_aligned + intact, however. */ + p = read_encoded_value_with_base (*p & 0x7F, 0, p + 1, &dummy); + } + /* LSDA encoding. */ + else if (*aug == 'L') + p++; + /* Otherwise end of string, or unknown augmentation. */ + else + return DW_EH_PE_absptr; + aug++; + } +} + + + + +void * read_pointer (void *p) { union unaligned *up = (union unaligned*)p; return (void*)up->p; } + + +unsigned char * +extract_cie_info (struct dwarf_cie *cie, + int *saw_z, + int *lsda_encoding, + int *fde_encoding) +{ + unsigned char *aug = cie->augmentation; + unsigned char *p = aug + strlen ((char *)aug) + 1; + unsigned char *ret = NULL; + _uleb128_t utmp=0; + _sleb128_t stmp=0; + + /* g++ v2 "eh" has pointer immediately following augmentation string, + so it must be handled first. */ + if (aug[0] == 'e' && aug[1] == 'h') + { + void* eh_ptr = read_pointer (p); + if(getenv("EH_VERBOSE")) + cout<<"eh_ptr: "<< std::dec << eh_ptr<<endl; + p += ptrsize; + aug += 2; + } + + /* Immediately following the augmentation are the code and + * data alignment and return address column. */ + p = read_uleb128 (p, &utmp); + if(getenv("EH_VERBOSE")) + cout<<"code align: "<< std::dec << utmp<<endl; + p = read_sleb128 (p, &stmp); + if(getenv("EH_VERBOSE")) + cout<<"data align: "<< std::dec << stmp<<endl; + if (cie->version == 1) + { + int ret_col= *p++; + if(getenv("EH_VERBOSE")) + cout<<"ret_col: "<< std::dec << ret_col<<endl; + } + else + { + p = read_uleb128 (p, &utmp); + if(getenv("EH_VERBOSE")) + cout<<"ret_col: "<< std::dec << utmp<<endl; + } + + /* If the augmentation starts with 'z', then a uleb128 immediately + follows containing the length of the augmentation field following + the size. */ + if (*aug == 'z') + { + p = read_uleb128 (p, &utmp); + ret = p + utmp; + *saw_z=1; + if(getenv("EH_VERBOSE")) + cout<<"Saw z, length: "<<utmp<<endl; + ++aug; + } + + /* Iterate over recognized augmentation subsequences. */ + while (*aug != '\0') + { + /* "L" indicates a byte showing how the LSDA pointer is encoded. */ + if (aug[0] == 'L') + { + *lsda_encoding = *p++; + if(getenv("EH_VERBOSE")) + cout<<"lsda encoding "<<std::hex<<*lsda_encoding<<endl; + aug += 1; + } + + /* "R" indicates a byte indicating how FDE addresses are encoded. */ + else if (aug[0] == 'R') + { + *fde_encoding = *p++; + if(getenv("EH_VERBOSE")) + cout<<"fde encoding "<<std::hex<<*fde_encoding<<endl; + aug += 1; + } + + /* "P" indicates a personality routine in the CIE augmentation. */ + else if (aug[0] == 'P') + { + _Unwind_Ptr personality=0; + int personality_encoding=*p; + + + p = read_encoded_value_with_base(*p, 0, p + 1, &personality); + + if(getenv("EH_VERBOSE")) + { + cout << "encoding personality = " << std::hex << personality_encoding << endl; + cout << "fs->personality = " << std::hex << personality << endl; + } + possible_target(personality, 0, ibt_provenance_t::ibtp_eh_frame); + aug += 1; + } + + /* "S" indicates a signal frame. */ + else if (aug[0] == 'S') + { + if(getenv("EH_VERBOSE")) + cout << "fs->signal_frame = 1 " << endl; + aug += 1; + } + + /* Otherwise we have an unknown augmentation string. + Bail unless we saw a 'z' prefix. */ + else + return ret; + } + + return ret ? ret : p; +} + + + +static size_t +classify_object_over_fdes (struct object *ob, fde *this_fde) +{ + struct dwarf_cie *last_cie = 0; + size_t count = 0; + int encoding = DW_EH_PE_absptr; + _Unwind_Ptr base = 0; + + for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde)) + { +// printf("analysis addr=%p\n", this_fde); +// printf("pgm addr=%p\n", (uintptr_t)this_fde+(uintptr_t)eh_offset); +// printf("offset=%p\n", (uintptr_t)this_fde+(uintptr_t)eh_offset-(uintptr_t)eh_frame_addr); + struct dwarf_cie *this_cie; + _Unwind_Ptr mask, pc_begin; + + /* Skip CIEs. */ + if (this_fde->CIE_delta == 0) + continue; + + /* Determine the encoding for this FDE. Note mixed encoded + objects for later. */ + this_cie = get_cie (this_fde); + if (this_cie != last_cie) + { + last_cie = this_cie; + encoding = get_cie_encoding (this_cie); + base = base_from_object (encoding, ob); + if (ob->s.b.encoding == DW_EH_PE_omit) + ob->s.b.encoding = encoding; + else if (ob->s.b.encoding != encoding) + ob->s.b.mixed_encoding = 1; + } + + read_encoded_value_with_base (encoding, base, this_fde->pc_begin, + &pc_begin); + + /* Take care to ignore link-once functions that were removed. + In these cases, the function address will be NULL, but if + the encoding is smaller than a pointer a true NULL may not + be representable. Assume 0 in the representable bits is NULL. */ + mask = size_of_encoded_value (encoding); + if (mask < ptrsize) + mask = (((_Unwind_Ptr) 1) << (mask << 3)) - 1; + else + mask = -1; + + if ((pc_begin & mask) == 0) + continue; + + count += 1; + if ((void *) pc_begin < ob->pc_begin) + ob->pc_begin = (void *) pc_begin; + } + + + if(getenv("EH_VERBOSE")) + cout<<"Count is "<<count<<endl; + + return count; +} + +void print_lsda_handlers(lsda_header_info* info, unsigned char* p) +{ + // change to lsda section; + uintptr_t p_addr=((uintptr_t)p+(uintptr_t)eh_offset); + + // if the action table is size 0, avoid calling addr_to_ptr_to_data on it, because it may assert, + // and we wouldn't do anything (except 0 iterations of the loop below) with the results anyhow. + if(p_addr == (uintptr_t)info->action_table) + return; + + p=(unsigned char*)addr_to_ptr_to_data((uintptr_t)p_addr); + // use -1 in case info->action table represents the end of a section. + uintptr_t action_table_in_data=(uintptr_t)addr_to_ptr_to_data((uintptr_t)info->action_table-1); +// intptr_t p_offset=(intptr_t)p-(intptr_t)ptr_to_addr_to_data_to_addr((uintptr_t)p); + // Search the call-site table for the action associated with this IP. + while ( + // use <= because we we used -1 3 lines above. + ((uintptr_t)p) <= (uintptr_t)action_table_in_data + ) + { + _Unwind_Ptr cs_start=0, cs_len=0, cs_lp=0; + _uleb128_t cs_action=0; + + // Note that all call-site encodings are "absolute" displacements. + p = read_encoded_value (0, info->call_site_encoding, p, &cs_start); + p = read_encoded_value (0, info->call_site_encoding, p, &cs_len); + p = read_encoded_value (0, info->call_site_encoding, p, &cs_lp); + p = read_uleb128 (p, &cs_action); + + if(cs_lp!=0) + { + + if(getenv("EH_VERBOSE")) + { + cout <<"cs_start: "<< cs_start << "\t" + <<"cs_len: "<< cs_len << "\t" + <<"cs_lp: "<< cs_lp << "\t" + <<"cs_action: "<< cs_action << endl; + cout <<"cs_start+info->Start: "<< cs_start+info->Start << "\t" + <<"cs_len+cs_start+info->Start: "<< cs_len+cs_start+info->Start << "\t" + <<"cs_lp+info->LPstart: "<< cs_lp +info->LPStart<< "\t" + <<"cs_action: "<< cs_action << endl; + } + +#ifndef TEST + + /* the landing pad is a possible target if an exception is thrown */ + possible_target(cs_lp+info->Start, 0, ibt_provenance_t::ibtp_eh_frame); + + /* and the return address is a possible oddity if it's used for walking the stack */ + possible_target(cs_len+cs_start+info->Start, 0, ibt_provenance_t::ibtp_eh_frame); + +#endif + } + } +} + +int get_fde_encoding (struct dwarf_fde *f) +{ + return get_cie_encoding (get_cie (f)); +} + +unsigned char * parse_lsda_header (unsigned char *p, lsda_header_info *info, struct object *ob, fde* f) +{ + _uleb128_t tmp=0; + unsigned char lpstart_encoding=0; + _Unwind_Ptr func=0; + + info->Start = 0; +/* +fixme + + needs to be info->Start=context->bases->func + + +which is set here: +*/ + unsigned char encoding = ob->s.b.encoding; + if (ob->s.b.mixed_encoding) + encoding = get_fde_encoding (f); + read_encoded_value_with_base (encoding, base_from_object (encoding, ob), + f->pc_begin, (_Unwind_Ptr*)&func); + + info->Start=func; + if(getenv("EH_VERBOSE")) + cout<<"info->Start set to "<<std::hex << (uintptr_t)info->Start << endl; + + + // Find @LPStart, the base to which landing pad offsets are relative. + lpstart_encoding = *p++; + if (lpstart_encoding != DW_EH_PE_omit) + p = read_encoded_value_with_base (lpstart_encoding, 0, p, &info->LPStart); + else + info->LPStart = info->Start; + + if(getenv("EH_VERBOSE")) + cout<<"LPStart : "<<std::hex<<info->LPStart<<endl; + + // Find @TType, the base of the handler and exception spec type data. + info->ttype_encoding = *p++; + if (info->ttype_encoding != DW_EH_PE_omit) + { + p = read_uleb128 (p, &tmp); + // this doesn't work + //info->TType = (unsigned char*)ptr_to_data_to_addr((uintptr_t)(p + tmp)); + info->TType = p + tmp + eh_offset; + } + else + info->TType = 0; + + if(getenv("EH_VERBOSE")) + cout<<"ttype : "<<std::hex<<((uintptr_t)(info->TType))<<endl; + + // The encoding and length of the call-site table; the action table + // immediately follows. + info->call_site_encoding = *p++; + + if(getenv("EH_VERBOSE")) + cout<<"Call site encoding " << std::hex << (uintptr_t)info->call_site_encoding << endl; + + p = read_uleb128 (p, &tmp); + info->action_table = p + tmp + eh_offset; + //info->action_table = (unsigned char*)ptr_to_data_to_addr((uintptr_t)(p + tmp)); + if(getenv("EH_VERBOSE")) + cout<<"Action table: "<<std::hex<<(uintptr_t)info->action_table<<endl; + + return p; +} + + + + + +void linear_search_fdes (struct object *ob, fde *this_fde, int offset) +{ + struct dwarf_cie *last_cie = 0; + int encoding = ob->s.b.encoding; + cout<<"encoding="<<encoding<<endl; + _Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob); + int saw_z=0; + int lsda_encoding=DW_EH_PE_omit; + int fde_encoding=0; + int count=0; + + for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde)) + { + count++; + if(getenv("EH_VERBOSE")) + { + cout<<"Examining FDE #"<<std::dec<<count<<" at offset "<<hex<<(uintptr_t)this_fde-(uintptr_t)eh_frame_data<<endl; + cout<<"FDE (in memory) addr is: "<<std::hex<<this_fde<<endl; + cout<<"FDE (in file) addr is: "<<std::hex<<(uintptr_t)this_fde-(uintptr_t)eh_frame_data+(uintptr_t)eh_frame_addr<<endl; + } + struct dwarf_cie *this_cie=NULL; + _Unwind_Ptr pc_begin=0, pc_range=0; + + /* Skip CIEs. */ + if (this_fde->CIE_delta == 0) + { + if(getenv("EH_VERBOSE")) + cout<<"Skipping FDE because it's a CIE"<<endl; + continue; + } + + this_cie = get_cie (this_fde); + + saw_z=0; + lsda_encoding=DW_EH_PE_omit; + fde_encoding=0; + extract_cie_info(this_cie, &saw_z, &lsda_encoding, &fde_encoding); + + /* Locate augmentation for the fde. */ + unsigned char* aug = (unsigned char *) this_fde + 8; /* 4-bytes for FDE len, 4-bytes for FDE id. */ + + // 2x size of fde_encoding for pc_begin and pc_range */ + aug += 2 * size_of_encoded_value (fde_encoding); + if (saw_z) + { + _uleb128_t i=0; + aug = read_uleb128 (aug, &i); + } + if (lsda_encoding != DW_EH_PE_omit) + { + _Unwind_Ptr lsda; + + aug = read_encoded_value_with_base (lsda_encoding, 0, aug, &lsda); + cout<<"lsda at "<<std::hex << lsda <<endl; + lsda_header_info info; + memset(&info, 0, sizeof(info)); + cout.flush(); + + // lsda might be 0, which means we shouldn't load it! + if(lsda != 0 ) + { + // change sections; + uintptr_t save_eh_offset=eh_offset; + eh_offset=addr_to_p_offset(lsda); + unsigned char* lsda_p=parse_lsda_header ( + (unsigned char*)addr_to_ptr_to_data(lsda) + , &info, ob, this_fde); + print_lsda_handlers(&info, lsda_p); + eh_offset=save_eh_offset; + cout.flush(); + } + } + + + + if (ob->s.b.mixed_encoding) + { + /* Determine the encoding for this FDE. Note mixed encoded + objects for later. */ + this_cie = get_cie (this_fde); + if (this_cie != last_cie) + { + last_cie = this_cie; + encoding = get_cie_encoding (this_cie); + base = base_from_object (encoding, ob); + if(getenv("EH_VERBOSE")) + cout<<"Base from object (mixed encoding?)="<<std::hex<<base<<endl; + } + } + + if (encoding == DW_EH_PE_absptr) + { + //pc_begin = ((_Unwind_Ptr *) this_fde->pc_begin)[0]; + auto my_pc_begin=(_Unwind_Ptr*)(this_fde->pc_begin); + memcpy(&pc_begin, my_pc_begin, sizeof(_Unwind_Ptr)); + //pc_range = ((_Unwind_Ptr *) this_fde->pc_begin)[1]; + memcpy(&pc_range, my_pc_begin+1, sizeof(_Unwind_Ptr)); + + if(getenv("EH_VERBOSE")) + { + cout<<"absptr pc_begin 0x"<<std::hex<<(pc_begin+offset)<<"\t"; + cout<<"absptr pc_end 0x"<<std::hex<<(pc_begin+pc_range+offset)<<endl; + } +#ifndef TEST + extern void range(VirtualOffset_t, VirtualOffset_t); + range(pc_begin,pc_begin+pc_range); +#endif + if (pc_begin == 0) + continue; + } + else + { + _Unwind_Ptr mask=0; + unsigned char *p=0; + + p = read_encoded_value_with_base (encoding, base, + this_fde->pc_begin, &pc_begin); + read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range); + + if(getenv("EH_VERBOSE")) + { + cout<<"!absptr pc_begin 0x"<<std::hex<<(pc_begin)<<"\t"; + cout<<"!absptr pc_end 0x"<<std::hex<<(pc_begin+pc_range)<<endl; + } + +#ifndef TEST + extern void range(VirtualOffset_t, VirtualOffset_t); + range(pc_begin,pc_begin+pc_range); +#endif + + /* Take care to ignore link-once functions that were removed. + In these cases, the function address will be NULL, but if + the encoding is smaller than a pointer a true NULL may not + be representable. Assume 0 in the representable bits is NULL. */ + mask = size_of_encoded_value (encoding); + if (mask < ptrsize) + mask = (((_Unwind_Ptr) 1) << (mask << 3)) - 1; + else + mask = -1; + + if ((pc_begin & mask) == 0) + continue; + } + } + + if(getenv("EH_VERBOSE")) + cout<<"Found "<<std::dec<<count<< " FDE's"<<endl; + + return; +} + +void read_ehframe(FileIR_t* virp, EXEIO::exeio* exeiop) +{ + + ptrsize=virp->getArchitectureBitWidth()/(8*sizeof(char)); + // 64/8 = 8 + // 32/8 = 4 + + assert(exeiop); + elfiop=reinterpret_cast<ELFIO::elfio*>(exeiop->get_elfio()); + if(!elfiop) + return; // skip entire analysis for non-elf files as eh-frame is way different. + + const auto eh_frame_it=find_if(virp->getDataScoops().begin(), virp->getDataScoops().end(), + [](const DataScoop_t* scoop) { return scoop->getName()==".eh_frame"; }); + + // either no eh_frame in the elf file, or fill_in_indtargs removed it because + // it was asked to import the EH IR. + if(eh_frame_it==virp->getDataScoops().end()) + return; + + int secndx=0; + int secnum=elfiop->sections.size(); + + /* Locate desired section */ + bool found=false; + int eh_frame_index; + for (secndx=1; secndx<secnum; secndx++) + { + // cout<<"sechdrs["<<i<<"] name index="<<sechdrs[secndx].sh_name<<endl; + const char *p=elfiop->sections[secndx]->get_name().c_str(); + if (strcmp(".eh_frame",p)==0) + { + found = true; + eh_frame_index=secndx; + break; + }; + } + + if(!found) + { + cout<<"Cannot find .eh_frame section\n"; + return; + } + cout<<"Found .eh_frame is section "<<std::dec<<eh_frame_index<<endl; + + eh_frame_addr=(void*)elfiop->sections[eh_frame_index]->get_address(); + cout<<"Found .eh_frame section addr is "<<std::dec<<eh_frame_addr<<endl; + int total_size=0; + + const char *p=elfiop->sections[secndx+1]->get_name().c_str(); + if (strcmp(".gcc_except_table",p)!=0) + { + cout<<"Did not find .gcc_except_table immediately after .eh_frame\n"; + total_size=elfiop->sections[eh_frame_index]->get_size()+1; + } + else + { + total_size= + (elfiop->sections[eh_frame_index+1]->get_address()+ + elfiop->sections[eh_frame_index+1]->get_size() ) - (uintptr_t)eh_frame_addr; + } + eh_frame_data_total_size=total_size; + + + // calc the size needed to safely walk the EH frame data. apparently walking assumes a null value in memory + // after the section is loaded (or properly using eh_frame_hdr, which we aren't doing) + //eh_frame_data=(char*)elfiop->sections[eh_frame_index]->get_data(); + int newsize=elfiop->sections[eh_frame_index]->get_size()+4; + eh_frame_data=(char*)calloc(1,newsize); + memcpy(eh_frame_data, (void*)elfiop->sections[eh_frame_index]->get_data(), elfiop->sections[eh_frame_index]->get_size()); + + uintptr_t offset; +// careful with offset and eh_offset as it can only be used for eh_frame_data offsetting, not offsetting into other addrs. + eh_offset=offset=(uintptr_t)eh_frame_addr-(uintptr_t)eh_frame_data; + + + struct object ob; + register_frame_info( eh_frame_data, &ob); + classify_object_over_fdes(&ob,ob.u.single); + linear_search_fdes (&ob,ob.u.single,offset); + + /* clean up memory */ + +} + +#ifdef TEST +// +// main rountine; convert calls into push/jump statements +// +main(int argc, char* argv[]) +{ + + bool fix_all=false; + + if(argc!=2 && argc !=3) + { + cerr<<"Usage: fix_calls <id> (--fix-all) "<<endl; + exit(-1); + } + + if(argc==3) + { + if(strcmp("--fix-all", argv[2])!=0) + { + cerr<<"Unrecognized option: "<<argv[2]<<endl; + exit(-1); + } + else + fix_all=true; + } + + VariantID_t *pidp=NULL; + FileIR_t *virp=NULL; + + /* setup the interface to the sql server */ + pqxxDB_t pqxx_interface; + BaseObj_t::SetInterface(&pqxx_interface); + + cout<<"Reading variant "<<string(argv[1])<<" from database." << endl; + try + { + + pidp=new VariantID_t(atoi(argv[1])); + + assert(pidp->IsRegistered()==true); + + // read the db + virp=new FileIR_t(*pidp); + + + } + catch (DatabaseError_t pnide) + { + cout<<"Unexpected database error: "<<pnide<<endl; + exit(-1); + } + + assert(virp && pidp); + + cout<<"Reading EH frame and gcc except table in variant "<<*pidp<< "." <<endl; + + read_ehframe(virp,pqxx_interface); + + cout<<"Writing variant "<<*pidp<<" back to database." << endl; +// virp->WriteToDB(); + +// pqxx_interface.Commit(); + cout<<"Done!"<<endl; + + delete virp; + delete pidp; +} +#endif diff --git a/irdb-lib/ir_builders/read_variantir.cpp b/irdb-lib/ir_builders/read_variantir.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ac24333965063027e38482406f51709aefa00cb5 --- /dev/null +++ b/irdb-lib/ir_builders/read_variantir.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + + +#include <libIRDB-core.hpp> +#include <iostream> +#include <algorithm> +#include <stdlib.h> + +using namespace libIRDB; +using namespace std; + +int main(int argc, char* argv[]) +{ + + if(argc!=2) + { + cerr<<"Usage: read_variantir <id>"<<endl; + exit(-1); + } + + + VariantID_t *pidp=NULL; + try + { + /* setup the interface to the sql server */ + pqxxDB_t pqxx_interface; + BaseObj_t::SetInterface(&pqxx_interface); + + pidp=new VariantID_t(atoi(argv[1])); + + assert(pidp->IsRegistered()==true); + + cout<<"New Variant, after reading registration, is: "<<*pidp << endl; + for(set<File_t*>::iterator it=pidp->GetFiles().begin(); + it!=pidp->GetFiles().end(); + ++it + ) + { + File_t* this_file=*it; + assert(this_file); + + cout<<"... Analyzing file "<<this_file->GetURL()<<endl; + + // read the db + FileIR_t* firp=new FileIR_t(*pidp, this_file); + assert(firp); + + for(auto fn : firp->GetFunctions()) + if (!fn) return; + cout<<"Function: " << fn->GetName(); + cout<<" NumArgs: " << fn->GetNumArguments(); + cout<<" FP: " << fn->GetUseFramePointer(); + cout<<" StackFrameSize: " << fn->GetStackFrameSize(); + cout<<" OutArgsRegionSize: " << fn->GetOutArgsRegionSize(); + cout<<endl; + }; + + for( + set<Instruction_t*>::const_iterator it=firp->GetInstructions().begin(); + it!=firp->GetInstructions().end(); + ++it + ) + { + Instruction_t* insn=*it; + cout<<"Found insn at addr:" << std::hex << insn->GetAddress()->GetVirtualOffset() << " " << insn->getDisassembly(); + + ICFS_t* ibtargets = insn->GetIBTargets(); + if (ibtargets) + cout << " ibtargets_id: " << dec << ibtargets->GetBaseID() << endl; + else + cout << endl; + } + + for(ICFSSet_t::const_iterator it=firp->GetAllICFS().begin(); + it != firp->GetAllICFS().end(); + ++it) + { + ICFS_t *icfs = *it; + cout << "icfs set id: " << dec << icfs->GetBaseID() << " analysis status: " << icfs->GetAnalysisStatus() << " #ibtargets: " << icfs->size() << " | "; + int count = 0; + for(ICFS_t::const_iterator it2=icfs->begin(); + it2!=icfs->end(); ++it2, ++count) + { + Instruction_t* insn = *it2; + assert(insn); + cout<< std::hex << insn->GetAddress()->GetVirtualOffset() << " "; + if (count >= 10) { + cout << "..."; + break; + } + } + cout << endl; + } + delete firp; + } + delete pidp; + } + catch (DatabaseError_t pnide) + { + cout<<"Unexpected database error: "<<pnide<<endl; + exit(-1); + } + + return 0; +} diff --git a/irdb-lib/ir_builders/rename_function.cpp b/irdb-lib/ir_builders/rename_function.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4ec9fdf38b23d499a705f538b8b7396242929d0a --- /dev/null +++ b/irdb-lib/ir_builders/rename_function.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2014-2015 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + + +#include <libIRDB-core.hpp> +#include <iostream> +#include <stdlib.h> + +using namespace libIRDB; +using namespace std; + +void rename_function(FileIR_t* firp, string oldfn, string newfn) +{ + + assert(firp); + + for( + set<Function_t*>::iterator it=firp->GetFunctions().begin(); + it!=firp->GetFunctions().end(); + ++it + ) + { + Function_t* func=*it; + if (!func) continue; + if (func->GetName() == oldfn) + { + cout<<"Renaming function " << oldfn << " to " << newfn << endl; + func->SetName(newfn); + } + } + + firp->WriteToDB(); +} + +main(int argc, char* argv[]) +{ + if(argc!=4) + { + cerr<<"Usage: rename_function <id> <oldfn> <newfn>"<<endl; + exit(-1); + } + + VariantID_t *pidp=NULL; + FileIR_t *firp=NULL; + string oldfn(argv[2]); + string newfn(argv[3]); + + assert(oldfn.size() > 0 && newfn.size() > 0); + + /* setup the interface to the sql server */ + pqxxDB_t pqxx_interface; + BaseObj_t::SetInterface(&pqxx_interface); + + cout<<"Reading variant "<<string(argv[1])<<" from database." << endl; + try + { + pidp=new VariantID_t(atoi(argv[1])); + assert(pidp->IsRegistered()==true); + + for(set<File_t*>::iterator it=pidp->GetFiles().begin(); it!=pidp->GetFiles().end(); ++it) + { + File_t* this_file=*it; + assert(this_file); + + // only do main file for now + if(this_file!=pidp->GetMainFile()) + continue; + + // read the db + firp=new FileIR_t(*pidp,this_file); + + // rename the function + rename_function(firp, oldfn, newfn); + + delete firp; + } + pqxx_interface.Commit(); + + } + catch (DatabaseError_t pnide) + { + cout<<"Unexpected database error: "<<pnide<<endl; + exit(-1); + } + + cout<<"Done!"<<endl; + + delete pidp; +} + diff --git a/irdb-lib/ir_builders/split_eh_frame.cpp b/irdb-lib/ir_builders/split_eh_frame.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dcd7adb752d4c5c9ab7c7d4cec0ea6d73edacf63 --- /dev/null +++ b/irdb-lib/ir_builders/split_eh_frame.cpp @@ -0,0 +1,630 @@ +#include <irdb-core> +#include <iostream> +#include <iomanip> +#include <fstream> +#include <limits> +#include <stdlib.h> +#include <string.h> +#include <map> +#include <assert.h> +#include <elf.h> +#include <algorithm> +#include <memory> +#include <tuple> +#include <functional> + +#include <exeio.h> + +#include "split_eh_frame.hpp" +#include "ehp.hpp" + +using namespace std; +using namespace EXEIO; +using namespace IRDB_SDK; +using namespace EHP; + +#define ALLOF(s) begin(s), end(s) + + +struct EhProgramPlaceHolder_t +{ + uint8_t caf; + int8_t daf; + int8_t rr; + uint8_t ptrsize; // needed for interpreting programs + IRDB_SDK::EhProgramListing_t cie_program; + IRDB_SDK::EhProgramListing_t fde_program; + + //IRDB_SDK::EhProgramListing_t& getCIEProgram() { return cie_program; } + //IRDB_SDK::EhProgramListing_t& getFDEProgram() { return fde_program; } + const IRDB_SDK::EhProgramListing_t& getCIEProgram() const { return cie_program; } + const IRDB_SDK::EhProgramListing_t& getFDEProgram() const { return fde_program; } + uint8_t getCodeAlignmentFactor() const { return caf; } + int8_t getDataAlignmentFactor() const { return daf; } + int8_t getReturnRegNumber() const { return rr; } + uint8_t getPointerSize() const { return ptrsize; } + +}; + +template <int ptrsize> +bool split_eh_frame_impl_t<ptrsize>::lsda_call_site_appliesTo(const LSDACallSite_t& cs, const Instruction_t* insn) const +{ + assert(insn && insn->getAddress()); + auto insn_addr=insn->getAddress()->getVirtualOffset(); + + const auto call_site_addr=cs.getCallSiteAddress(); + const auto call_site_end_addr=cs.getCallSiteEndAddress(); + + return ( call_site_addr <=insn_addr && insn_addr<call_site_end_addr ); +} + +template <int ptrsize> +void split_eh_frame_impl_t<ptrsize>::lsda_call_site_build_ir + ( + const LSDACallSite_t& cs, + Instruction_t* insn, + const /*vector<lsda_type_table_entry_t <ptrsize> > &*/ std::shared_ptr<EHP::TypeTableVector_t> type_table_ptr, + const uint8_t& tt_encoding + ) const +{ + const auto &type_table=*type_table_ptr; + const auto &om=offset_to_insn_map; + const auto landing_pad_addr=cs.getLandingPadAddress(); + const auto action_table_ptr=cs.getActionTable(); + const auto &action_table=*action_table_ptr; + assert(lsda_call_site_appliesTo(cs,insn)); + + // find landing pad instruction. + auto lp_insn=(IRDB_SDK::Instruction_t*)NULL; + auto lp_it=om.find(landing_pad_addr); + if(lp_it!=om.end()) + lp_insn=lp_it->second; + + // create the callsite. + auto new_ehcs = firp->addEhCallSite_t(insn, tt_encoding, lp_insn); + + //cout<<"landing pad addr : 0x"<<hex<<landing_pad_addr<<endl; + if(action_table.size() == 0 ) + { + new_ehcs->setHasCleanup(); + // cout<<"Destructors to call, but no exceptions to catch"<<endl; + } + else + { + for(auto p : action_table) + { + const auto action=p->getAction(); + if(action==0) + { + auto new_ttov=new_ehcs->getTTOrderVector(); + new_ttov.push_back(action); + new_ehcs->setTTOrderVector(new_ttov); + //cout<<"Cleanup only (no catches) ."<<endl; + } + else if(action>0) + { + auto new_ttov=new_ehcs->getTTOrderVector(); + new_ttov.push_back(action); + new_ehcs->setTTOrderVector(new_ttov); + // new_ehcs->getTTOrderVector().push_back(action); + const auto index=action - 1; + //cout<<"Catch for type: "; + // the type table reveral was done during parsing, type table is right-side-up now. + //type_table.at(index).print(); + auto wrt=(DataScoop_t*)NULL; + if(type_table.at(index)->getTypeInfoPointer()!=0) + { + wrt=firp->findScoop(type_table.at(index)->getTypeInfoPointer()); + assert(wrt); + } + const auto offset=index*type_table.at(index)->getTTEncodingSize(); + auto addend=0; + if(wrt!=NULL) + addend=type_table.at(index)->getTypeInfoPointer()-wrt->getStart()->getVirtualOffset(); + /* + auto newreloc=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, offset, "type_table_entry", wrt, addend); + new_ehcs->getRelocations().insert(newreloc); + firp->getRelocations().insert(newreloc); + */ + auto newreloc=firp->addNewRelocation(new_ehcs,offset, "type_table_entry", wrt, addend); + (void)newreloc; // just give it to the ir + + //if(wrt==NULL) + // cout<<"Catch all in type table"<<endl; + //else + // cout<<"Catch for type at "<<wrt->getName()<<"+0x"<<hex<<addend<<"."<<endl; + } + else if(action<0) + { + static auto already_warned=false; + if(!already_warned) + { + ofstream fout("warning.txt"); + fout<<"Dynamic exception specification in eh_frame not fully supported."<<endl; + already_warned=true; + } + + // this isn't right at all, but pretend it's a cleanup! + new_ehcs->setHasCleanup(); + //cout<<"Cleanup only (no catches) ."<<endl; + } + else + { + cout<<"What? :"<< action <<endl; + exit(1); + } + }; + } +} + +template <int ptrsize> +void split_eh_frame_impl_t<ptrsize>::lsda_build_ir(const LSDA_t& lsda, Instruction_t* insn) const +{ + const auto call_site_table_ptr=lsda.getCallSites(); + const auto& call_site_table=*call_site_table_ptr; + const auto& type_table_ptr=lsda.getTypeTable(); + + const auto cs_ptr_it=find_if(ALLOF(call_site_table), [&](const shared_ptr<LSDACallSite_t> &p) + { + return lsda_call_site_appliesTo(*p, insn); + }); + + if(cs_ptr_it!= call_site_table.end()) + { + const auto cs_ptr=*cs_ptr_it; + lsda_call_site_build_ir(*cs_ptr,insn, type_table_ptr, lsda.getTTEncoding()); + } + else + { + // no call site table entry for this instruction. + } +} + +template <int ptrsize> +bool split_eh_frame_impl_t<ptrsize>::fde_contents_appliesTo(const FDEContents_t& fde, const Instruction_t* insn) const +{ + assert(insn && insn->getAddress()); + auto insn_addr=insn->getAddress()->getVirtualOffset(); + const auto fde_start_addr=fde.getStartAddress(); + const auto fde_end_addr=fde.getEndAddress(); + return ( fde_start_addr<=insn_addr && insn_addr<fde_end_addr ); +} + +template <int ptrsize> +void split_eh_frame_impl_t<ptrsize>::fde_contents_build_ir(const FDEContents_t& fde, Instruction_t* insn) const +{ + const auto fde_start_addr=fde.getStartAddress(); + const auto fde_end_addr=fde.getEndAddress(); + const auto lsda_ptr=fde.getLSDA(); + const auto &lsda=*lsda_ptr; + const auto lsda_addr=fde.getLSDAAddress(); + + // assert this is the right FDE. + assert( fde_start_addr<= insn->getAddress()->getVirtualOffset() && insn->getAddress()->getVirtualOffset() <= fde_end_addr); + + //eh_pgm.print(fde_start_addr); + if(lsda_addr!=0) + lsda_build_ir(lsda,insn); +} + +template <int ptrsize> +bool split_eh_frame_impl_t<ptrsize>::init_offset_map() +{ + for(const auto i : firp->getInstructions()) + { + offset_to_insn_map[i->getAddress()->getVirtualOffset()]=i; + }; + return false; +} + + +template <int ptrsize> +void split_eh_frame_impl_t<ptrsize>::build_ir() const +{ + class whole_pgm_t + { + public: + whole_pgm_t(EhProgramPlaceHolder_t& _pgm, EhProgram_t* cp, uint64_t _personality) + : hashcode(hashPgm(_pgm)), pgm(_pgm), cached_pgm(cp), personality(_personality) + { + } + void setCachedProgram(EhProgram_t* cp) { cached_pgm=cp; } + EhProgram_t* getCachedProgram() const { return cached_pgm; } + uint64_t getPersonality() const { return personality; } + private: + static uint64_t hashPgm(const EhProgramPlaceHolder_t& vec) + { + auto seed = vec.getCIEProgram().size() + vec.getFDEProgram().size(); + auto hash_fn=hash<string>(); + + for(const auto& i : vec.getCIEProgram()) + seed ^= hash_fn(i) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + for(const auto& i : vec.getFDEProgram()) + seed ^= hash_fn(i) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + return seed; + }; + uint64_t hashcode; + EhProgramPlaceHolder_t pgm; + EhProgram_t* cached_pgm; + uint64_t personality; + + friend struct EhProgramComparator_t; + }; + + //const auto fdes_ptr=eh_frame_parser->getFDEs(); + //const auto &fdes=*fdes_ptr; + + auto reusedpgms=size_t(0); + struct EhProgramComparator_t + { + bool operator() (const whole_pgm_t& lhs, const whole_pgm_t& rhs) + { + const auto &a=(lhs.pgm); + const auto &b=(rhs.pgm); + if(lhs.hashcode == rhs.hashcode) + return + make_tuple( + a.getCIEProgram(), + a.getFDEProgram(), + a.getCodeAlignmentFactor(), + a.getDataAlignmentFactor(), + a.getReturnRegNumber(), + a.getPointerSize(), + lhs.personality + ) + < + make_tuple( + b.getCIEProgram(), + b.getFDEProgram(), + b.getCodeAlignmentFactor(), + b.getDataAlignmentFactor(), + b.getReturnRegNumber(), + b.getPointerSize(), + rhs.personality + ); + else + return lhs.hashcode < rhs.hashcode; +// return tie(*a.first, a.second) < tie(*b.first,b.second); + } + }; + + // this is used to avoid adding duplicate entries to the program's IR, it allows a lookup by value + // instead of the IR's set which allows duplicates. + auto eh_program_cache = set<whole_pgm_t, EhProgramComparator_t>(); + + // find the right cie and fde, and build the IR from those for this instruction. + auto build_ir_insn=[&](Instruction_t* insn) -> void + { + const auto find_addr=insn->getAddress()->getVirtualOffset(); + static auto fie_ptr=shared_ptr<FDEContents_t>(); + static auto cie_instructions=shared_ptr<EHProgramInstructionVector_t>(); + static auto fde_instructions=shared_ptr<EHProgramInstructionVector_t>(); + + if (fie_ptr && fie_ptr->getStartAddress() <= find_addr && find_addr < fie_ptr->getEndAddress()) + { + // fie_ptr already points at right thing, do nothing + } + else + { + fie_ptr=eh_frame_parser->findFDE(find_addr); + if(fie_ptr) + { + cie_instructions=fie_ptr->getCIE().getProgram().getInstructions(); + fde_instructions=fie_ptr->getProgram().getInstructions(); + } + } + + if(fie_ptr != nullptr ) + { + // const auto fie_ptr=*fie_ptr_it; + + if(getenv("EHIR_VERBOSE")!=NULL) + { + cout<<hex<<insn->getAddress()->getVirtualOffset()<<":" + <<insn->getBaseID()<<":"<<insn->getDisassembly()<<" -> "<<endl; + fie_ptr->print(); + } + + const auto fde_addr=fie_ptr->getStartAddress(); + const auto caf=(uint8_t)fie_ptr->getCIE().getCAF(); + const auto daf=(int8_t)fie_ptr->getCIE().getDAF(); + const auto return_reg=(int8_t)fie_ptr->getCIE().getReturnRegister(); + const auto personality=fie_ptr->getCIE().getPersonality(); + const auto insn_addr=insn->getAddress()->getVirtualOffset(); + + auto import_pgm = [&](EhProgramListing_t& out_pgm_final, const shared_ptr<EHProgramInstructionVector_t> &in_pgm_instructions_ptr) -> void + { + auto out_pgm=vector<shared_ptr<EHProgramInstruction_t> >(); + auto cur_addr=fde_addr; + const auto in_pgm_instructions=*in_pgm_instructions_ptr; + for(const auto & insn_ptr : in_pgm_instructions) + { + const auto & insn=*insn_ptr; + if(insn.advance(cur_addr, caf)) + { + if(cur_addr > insn_addr) + break; + } + else if(insn.isNop()) + { + // skip nops + } + else if(insn.isRestoreState()) + { + // if a restore state happens, pop back out any instructions until + // we find the corresponding remember_state + while(1) + { + if(out_pgm.size()==0) + { + // unmatched remember state + cerr<<"Error in CIE/FDE program: unmatched restore_state command"<<endl; + break; + } + const auto back_insn=out_pgm.back(); + out_pgm.pop_back(); + //const auto back_insn=eh_program_insn_t<ptrsize>(back_str); + if(back_insn->isRememberState()) + break; + } + } + else + { + out_pgm.push_back(insn_ptr); + } + + } + if(getenv("EHIR_VERBOSE")!=NULL) + { + cout<<"\tPgm has insn_count="<<out_pgm.size()<<endl; + } + transform + ( + ALLOF(out_pgm), + back_inserter(out_pgm_final), + [](const shared_ptr<EHProgramInstruction_t>& p){ return string(ALLOF(p->getBytes()));} + ); + }; + + + // build an eh program on the stack; + // + auto ehpgm=EhProgramPlaceHolder_t({caf,daf,return_reg, ptrsize, {}, {}}); + import_pgm(ehpgm.cie_program, cie_instructions); + import_pgm(ehpgm.fde_program, fde_instructions); + + + //if(getenv("EHIR_VERBOSE")!=NULL) + // ehpgm.print(); + // see if we've already built this one. + auto ehpgm_it = eh_program_cache.find(whole_pgm_t(ehpgm, nullptr, personality)) ; + if(ehpgm_it != eh_program_cache.end()) + { + // yes, use the cached program. + insn->setEhProgram(ehpgm_it->getCachedProgram()); + if(getenv("EHIR_VERBOSE")!=NULL) + cout<<"Re-using existing Program!"<<endl; + reusedpgms++; + } + else /* doesn't yet exist! */ + { + + if(getenv("EHIR_VERBOSE")!=NULL) + cout<<"Allocating new Program!"<<endl; + + // allocate a new pgm in the heap so we can give it to the IR. + /* + auto newehpgm=new EhProgram_t(ehpgm); // copy constructor + assert(newehpgm); + firp->getAllEhPrograms().insert(newehpgm); + insn->setEhProgram(newehpgm); + */ + auto newehpgm=firp->addEhProgram(insn, ehpgm.caf, ehpgm.daf,ehpgm.rr, ehpgm.ptrsize, ehpgm.cie_program, ehpgm.fde_program); + + // allocate a relocation for the personality and give it to the IR. + auto personality_scoop=firp->findScoop(personality); + auto personality_insn_it=offset_to_insn_map.find(personality); + auto personality_insn=personality_insn_it==offset_to_insn_map.end() ? (Instruction_t*)NULL : personality_insn_it->second; + auto personality_obj = personality_scoop ? (BaseObj_t*)personality_scoop : (BaseObj_t*)personality_insn; + auto addend= personality_scoop ? personality - personality_scoop->getStart()->getVirtualOffset() : 0; + assert(personality==0 || personality_obj!=NULL); + + if(personality_obj==NULL) + { + if(getenv("EHIR_VERBOSE")!=NULL) + cout<<"Null personality obj: 0x"<<hex<<personality<<endl; + } + else if(personality_scoop) + { + if(getenv("EHIR_VERBOSE")!=NULL) + cout<<"Found personality scoop: 0x"<<hex<<personality<<" -> " + <<personality_scoop->getName()<<"+0x"<<hex<<addend<<endl; + } + else if(personality_insn) + { + if(getenv("EHIR_VERBOSE")!=NULL) + cout<<"Found personality insn: 0x"<<hex<<personality<<" -> " + <<personality_insn->getBaseID()<<":"<<personality_insn->getDisassembly()<<endl; + } + else + assert(0); + + /* + auto newreloc=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, 0, "personality", personality_obj, addend); + assert(newreloc); + newehpgm->getRelocations().insert(newreloc); + firp->getRelocations().insert(newreloc); + */ + auto newreloc=firp->addNewRelocation(newehpgm,0, "personality", personality_obj, addend); + (void)newreloc; // not used, just give it to the IR + + // update cache. + eh_program_cache.insert( whole_pgm_t(ehpgm,newehpgm,personality)); + } + + // build the IR from the FDE. + fde_contents_build_ir(*fie_ptr.get(), insn); + } + else + { + if(getenv("EHIR_VERBOSE")!=NULL) + { + cout<<hex<<insn->getAddress()->getVirtualOffset()<<":" + <<insn->getBaseID()<<":"<<insn->getDisassembly()<<" has no FDE "<<endl; + } + } + + }; + +#if 0 + auto remove_reloc=[&](Relocation_t* r) -> void + { + firp->getRelocations().erase(r); + delete r; + }; + + auto remove_address=[&](AddressID_t* a) -> void + { + firp->getAddresses().erase(a); + for(auto &r : a->getRelocations()) remove_reloc(r); + for(auto &r : firp->getRelocations()) assert(r->getWRT() != a); + delete a; + }; + + auto remove_scoop=[&] (DataScoop_t* s) -> void + { + if(s==NULL) + return; + firp->getDataScoops().erase(s); + remove_address(s->getStart()); + remove_address(s->getEnd()); + for(auto &r : s->getRelocations()) remove_reloc(r); + for(auto &r : firp->getRelocations()) assert(r->getWRT() != s); + delete s; + }; +#endif + + for(Instruction_t* i : firp->getInstructions()) + { + build_ir_insn(i); + } + + cout<<"# ATTRIBUTE Split_Exception_Handler::total_eh_programs_created="<<dec<<firp->getAllEhPrograms().size()<<endl; + cout<<"# ATTRIBUTE Split_Exception_Handler::total_eh_programs_reused="<<dec<<reusedpgms<<endl; + cout<<"# ATTRIBUTE Split_Exception_Handler::total_eh_programs="<<dec<<firp->getAllEhPrograms().size()+reusedpgms<<endl; + cout<<"# ATTRIBUTE Split_Exception_Handler::pct_eh_programs="<<std::fixed + <<((float)firp->getAllEhPrograms().size()/((float)firp->getAllEhPrograms().size()+reusedpgms))*100.00 + <<"%" <<endl; + cout<<"# ATTRIBUTE Split_Exception_Handler::pct_eh_programs_reused="<<std::fixed + <<((float)reusedpgms/((float)firp->getAllEhPrograms().size()+reusedpgms))*100.00 + <<"%"<<endl; + + firp->removeScoop(eh_frame_scoop); + firp->removeScoop(eh_frame_hdr_scoop); + firp->removeScoop(gcc_except_table_scoop); + +} + +template <int ptrsize> +Instruction_t* split_eh_frame_impl_t<ptrsize>::find_lp(Instruction_t* i) const +{ + const auto find_addr=i->getAddress()->getVirtualOffset(); + const auto fde_ptr=eh_frame_parser->findFDE(find_addr); + + if(fde_ptr==nullptr) + return nullptr; + + const auto &the_fde=*fde_ptr; + const auto &the_lsda_ptr=the_fde.getLSDA(); + const auto &the_lsda=*the_lsda_ptr; + const auto &cstab_ptr = the_lsda.getCallSites(); + const auto &cstab = *cstab_ptr; + + const auto cstab_it=find_if(ALLOF(cstab), [&](const shared_ptr<LSDACallSite_t>& cs) + { return lsda_call_site_appliesTo(*cs,i); }); + + if(cstab_it==cstab.end()) + return nullptr; + + const auto &the_cstab_entry_ptr=*cstab_it; + const auto &the_cstab_entry=*the_cstab_entry_ptr; + const auto lp_addr= the_cstab_entry.getLandingPadAddress(); + + const auto om_it=offset_to_insn_map.find(lp_addr); + + if(om_it==offset_to_insn_map.end()) + return nullptr; + + auto lp=om_it->second; + return lp; +} + +template <int ptrsize> +void split_eh_frame_impl_t<ptrsize>::print() const +{ + eh_frame_parser->print(); +} + +template <int ptrsize> +split_eh_frame_impl_t<ptrsize>::split_eh_frame_impl_t(FileIR_t* p_firp) + : firp(p_firp), + eh_frame_scoop(NULL), + eh_frame_hdr_scoop(NULL), + gcc_except_table_scoop(NULL) +{ + assert(firp!=NULL); + + // function to find a scoop by name. + auto lookup_scoop_by_name=[&](const string &the_name) -> DataScoop_t* + { + const auto scoop_it=find_if( + firp->getDataScoops().begin(), + firp->getDataScoops().end(), + [the_name](DataScoop_t* scoop) + { + return scoop->getName()==the_name; + }); + + if(scoop_it!=firp->getDataScoops().end()) + return *scoop_it; + return NULL; + }; + auto scoop_address=[&](const DataScoop_t* p) -> uint64_t { return p==NULL ? 0 : p->getStart()->getVirtualOffset(); }; + auto scoop_contents=[&](const DataScoop_t* p) -> string { return p==NULL ? "" : p->getContents(); }; + + eh_frame_scoop=lookup_scoop_by_name(".eh_frame"); + eh_frame_hdr_scoop=lookup_scoop_by_name(".eh_frame_hdr"); + gcc_except_table_scoop=lookup_scoop_by_name(".gcc_except_table"); + + eh_frame_parser=EHFrameParser_t::factory + ( + ptrsize, + scoop_contents(eh_frame_scoop), scoop_address(eh_frame_scoop), + scoop_contents(eh_frame_hdr_scoop), scoop_address(eh_frame_hdr_scoop), + scoop_contents(gcc_except_table_scoop), scoop_address(gcc_except_table_scoop) + ); + + if(eh_frame_parser!=NULL) + fdes=eh_frame_parser->getFDEs(); + + (void)init_offset_map(); +} + +unique_ptr<split_eh_frame_t> split_eh_frame_t::factory(FileIR_t *firp) +{ + if( firp->getArchitectureBitWidth()==64) + return unique_ptr<split_eh_frame_t>(new split_eh_frame_impl_t<8>(firp)); + else + return unique_ptr<split_eh_frame_t>(new split_eh_frame_impl_t<4>(firp)); + +} + +void split_eh_frame(FileIR_t* firp) +{ + auto found_err=false; + //auto eh_frame_splitter=(unique_ptr<split_eh_frame_t>)NULL; + const auto eh_frame_splitter=split_eh_frame_t::factory(firp); + eh_frame_splitter->build_ir(); + + assert(!found_err); +} diff --git a/irdb-lib/ir_builders/split_eh_frame.hpp b/irdb-lib/ir_builders/split_eh_frame.hpp new file mode 100644 index 0000000000000000000000000000000000000000..2e1a2b08eb507eb17a802009b8033e6cb31d887f --- /dev/null +++ b/irdb-lib/ir_builders/split_eh_frame.hpp @@ -0,0 +1,95 @@ +#ifndef eh_frame_hpp +#define eh_frame_hpp + +#include <irdb-core> +#include <iostream> +#include <iomanip> +#include <fstream> +#include <limits> +#include <stdlib.h> +#include <string.h> +#include <map> +#include <assert.h> +#include <elf.h> +#include <algorithm> +#include <memory> + +#include <exeio.h> +#include <ehp.hpp> + + + + +using OffsetMap_t = std::map<IRDB_SDK::VirtualOffset_t, IRDB_SDK::Instruction_t*>; + +class split_eh_frame_t +{ + public: + + virtual void build_ir() const =0; + virtual void print() const=0; + virtual IRDB_SDK::Instruction_t* find_lp(IRDB_SDK::Instruction_t*) const =0; + + static std::unique_ptr<split_eh_frame_t> factory(IRDB_SDK::FileIR_t *firp); + +}; + +template <int ptrsize> +class split_eh_frame_impl_t : public split_eh_frame_t +{ + private: + + IRDB_SDK::FileIR_t* firp; + IRDB_SDK::DataScoop_t* eh_frame_scoop; + IRDB_SDK::DataScoop_t* eh_frame_hdr_scoop; + IRDB_SDK::DataScoop_t* gcc_except_table_scoop; + OffsetMap_t offset_to_insn_map; + + std::unique_ptr<const EHP::EHFrameParser_t> eh_frame_parser; + std::shared_ptr<const EHP::FDEVector_t> fdes; + + bool init_offset_map(); + + bool lsda_call_site_appliesTo + ( + const EHP::LSDACallSite_t& cs, + const IRDB_SDK::Instruction_t* insn + ) const; + void lsda_call_site_build_ir + ( + const EHP::LSDACallSite_t& cs, + IRDB_SDK::Instruction_t* insn, + /* const std::vector<lsda_type_table_entry_t <ptrsize> > &*/ std::shared_ptr<EHP::TypeTableVector_t> type_table_ptr, + const uint8_t& tt_encoding + ) const; + void lsda_build_ir + ( + const EHP::LSDA_t& lsda, + IRDB_SDK::Instruction_t* insn + ) const; + bool fde_contents_appliesTo + ( + const EHP::FDEContents_t& fde, + const IRDB_SDK::Instruction_t* insn + ) const; + void fde_contents_build_ir + ( + const EHP::FDEContents_t& fde, + IRDB_SDK::Instruction_t* insn + ) const; + + public: + + split_eh_frame_impl_t(IRDB_SDK::FileIR_t* p_firp); + + + void print() const; + + void build_ir() const; + + IRDB_SDK::Instruction_t* find_lp(IRDB_SDK::Instruction_t*) const ; +}; + +void split_eh_frame(IRDB_SDK::FileIR_t* firp); + +#endif diff --git a/irdb-lib/ir_builders/tests/ibtarget/Makefile b/irdb-lib/ir_builders/tests/ibtarget/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..3b0ad3b1ac0436e951c1793ca7c4d21f4db9eb67 --- /dev/null +++ b/irdb-lib/ir_builders/tests/ibtarget/Makefile @@ -0,0 +1,38 @@ +INCLUDES= -I../../../../include -I../../../include/ -I../../../../beaengine/include +#LIBS=-L ../../../lib/ -lIRDB-core -lIRDB-cfg -lIRDB-util -lpqxx -L ../../../../beaengine/lib/Linux.gnu.Debug -lBeaEngine_s_d +#OPT=-fPIE -fPIC -O +#OPT=-g -fPIE -fPIC +OPT=-O +.SUFFIXES: .exe .cpp .protected + +PROGS=jmp1.exe jmp2.exe jmp.shared.exe icall.exe +PEASOUP_PROGS=jmp1.protected jmp2.protected jmp.shared.protected icall.protected + +all: $(PROGS) +protected: $(PEASOUP_PROGS) + +$(PROGS): ../../../../lib/* + +.exe.protected: $< +# FIX_CALLS_FIX_ALL_CALLS=1 LD_LIBRARY_PATH="$(LD_LIBRARY_PATH):." $(PEASOUP_HOME)/tools/ps_analyze.sh $< $@ --backend zipr --step selective_cfi=on +# FIX_CALLS_FIX_ALL_CALLS=1 LD_LIBRARY_PATH="$(LD_LIBRARY_PATH):." $(PEASOUP_HOME)/tools/ps_analyze.sh $< $@ --backend zipr --step selective_cfi=on --step-option selective_cfi:--color + FIX_CALLS_FIX_ALL_CALLS=1 LD_LIBRARY_PATH="$(LD_LIBRARY_PATH):." $(PEASOUP_HOME)/tools/ps_analyze.sh $< $@ --backend zipr +# LD_LIBRARY_PATH="$(LD_LIBRARY_PATH):." $(PEASOUP_HOME)/tools/ps_analyze.sh $< $@ --backend zipr --stop_after pdb_register + +.o.exe: $< ../lib/libIRDB-core.a ../lib/libIRDB-cfg.a + g++ $< $(INCLUDES) $(LIBS) $(OPT) -o $@ + +.cpp.o: $< + g++ $< $(INCLUDES) $(LIBS) $(OPT) -o $@ -c + +jmp.shared.so: jmp.shared.cpp jmp2.shared.cpp + g++ -fPIC -c jmp.shared.cpp + g++ -fPIC -c jmp2.shared.cpp + g++ -shared -Wl,-soname,libjmp.so -o libjmp.so jmp.shared.o jmp2.shared.o + +jmp.shared.exe: jmp.shared.so jmp.main.cpp + g++ -c jmp.main.cpp + g++ jmp.main.o -L. -ljmp -o $@ + +clean: + rm -fr $(PROGS) *.o *.so peasoup_executable* *.protected *.tmp.orig diff --git a/irdb-lib/ir_builders/tests/ibtarget/README b/irdb-lib/ir_builders/tests/ibtarget/README new file mode 100644 index 0000000000000000000000000000000000000000..4e563b9edb039d8ecd20f094b554d1f534c1a7f2 --- /dev/null +++ b/irdb-lib/ir_builders/tests/ibtarget/README @@ -0,0 +1,21 @@ +to test: + +[x] 32,nonPIC,nonOptimized +[x] 32,nonPIC,optimized +[x] 32,PIC,nonOptimized +[x] 32,PIC,optimized +[x] 32,shared lib, nonOpt +[x] 32,shared lib, optimized +[x] verify GetIBTargets() off Instruction_t* + +[x] 64,nonPIC,nonOptimized +[x] 64,nonPIC,optimized +[x] 64,PIC,nonOptimized +[x] 64,PIC,optimized +[x] 64,shared lib, nonOpt +[x] 64,shared lib, optimized +[x] verify GetIBTargets() off Instruction_t* + +[ ] make sure fix_calls copies the indirect branch targets +[ ] induce head-merge, and tail-merge in switch case + diff --git a/irdb-lib/ir_builders/tests/ibtarget/icall.cpp b/irdb-lib/ir_builders/tests/ibtarget/icall.cpp new file mode 100644 index 0000000000000000000000000000000000000000..41c87bad0c97fe4a223de3a80b6b31ca068d62a3 --- /dev/null +++ b/irdb-lib/ir_builders/tests/ibtarget/icall.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014-2015 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <stdio.h> +#include <stdlib.h> + +int add(int a, int b) +{ + printf("%d + %d = %d\n", a, b, a+b); + return a + b; +} + +int sub(int a, int b) +{ + printf("%d - %d = %d\n", a, b, a-b); + return a - b; +} + +int mul(int a, int b) +{ + printf("%d * %d = %d\n", a, b, a*b); + return a * b; +} + +int main(int argc, char**argv) +{ + int (*fn)(int,int); + + if (argc % 2) + fn = &add; + else + fn = ⊂ + + int result = (*fn)(argc, argc+1); + printf("result = %d\n", result); +} diff --git a/irdb-lib/ir_builders/tests/ibtarget/jmp.main.cpp b/irdb-lib/ir_builders/tests/ibtarget/jmp.main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bf97bed9c68359a174efe9641c777e8994303d49 --- /dev/null +++ b/irdb-lib/ir_builders/tests/ibtarget/jmp.main.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2014-2015 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <stdio.h> + +extern int switch_table(int, char**); +extern int switch_table_2(int, char**); + +int main(int argc, char** argv) +{ + printf("testing switch tables in shared library\n"); + switch_table(argc, argv); + switch_table_2(argc, argv); +} diff --git a/irdb-lib/ir_builders/tests/ibtarget/jmp.shared.cpp b/irdb-lib/ir_builders/tests/ibtarget/jmp.shared.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eccfeb5e892431dcd1109f769e7ca2415aedcab5 --- /dev/null +++ b/irdb-lib/ir_builders/tests/ibtarget/jmp.shared.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2014-2015 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <stdlib.h> +#include <stdio.h> + +int add(int a, int b) +{ + int x = a + b; + printf("add(): %d + %d = %d\n", a, b, x); + return x; +} + +int switch_table(int argc, char **argv) +{ + int i = atoi(argv[1]); + + switch(i) + { + case 20: + printf("i = 20\n"); + break; + case 22: + printf("i = 22\n"); + break; + case 23: + printf("hello: "); + printf("i = 23\n"); + break; + case 24: + printf("i = 24\n"); + break; + case 25: + printf("i = 25\n"); + break; + case 26: + printf("bar: "); + printf("i = 26\n"); + break; + case 27: + printf("i = 27\n"); + break; + case 28: + printf("i = 28\n"); + break; + default: + printf("i = %d\n", i); + } + + int val = add(i,i); + printf("main(): %d + %d = %d\n", i, i, val); +} diff --git a/irdb-lib/ir_builders/tests/ibtarget/jmp1.cpp b/irdb-lib/ir_builders/tests/ibtarget/jmp1.cpp new file mode 100644 index 0000000000000000000000000000000000000000..aa11e16c0aeff900b190724195f0194cc09311aa --- /dev/null +++ b/irdb-lib/ir_builders/tests/ibtarget/jmp1.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2014-2015 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <stdlib.h> +#include <stdio.h> + +int add(int a, int b) +{ + int x = a + b; + printf("add(): %d + %d = %d\n", a, b, x); + return x; +} + +int main(int argc, char **argv) +{ + int i = atoi(argv[1]); + + switch(i) + { + case 20: + printf("i = 20\n"); + break; + case 22: + printf("i = 22\n"); + break; + case 23: + printf("hello: "); + printf("i = 23\n"); + break; + case 24: + printf("i = 24\n"); + break; + case 25: + printf("i = 25\n"); + break; + case 26: + printf("bar: "); + printf("i = 26\n"); + break; + case 27: + printf("i = 27\n"); + break; + case 28: + printf("i = 28\n"); + break; + default: + printf("i = %d\n", i); + } + + int val = add(i,i); + printf("main(): %d + %d = %d\n", i, i, val); +} diff --git a/irdb-lib/ir_builders/tests/ibtarget/jmp2.cpp b/irdb-lib/ir_builders/tests/ibtarget/jmp2.cpp new file mode 100644 index 0000000000000000000000000000000000000000..83244e7f2d070a00c8abb0a692d049afec214415 --- /dev/null +++ b/irdb-lib/ir_builders/tests/ibtarget/jmp2.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2014-2015 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <stdlib.h> +#include <stdio.h> + +int add(int a, int b) +{ + int x = a + b; + printf("add(): %d + %d = %d\n", a, b, x); + return x; +} + +int main(int argc, char **argv) +{ + int i = atoi(argv[1]); + + switch(i) + { + case 20: + printf("i = 20\n"); + break; + case 22: + printf("i = 22\n"); + break; + case 23: + printf("hello: "); + printf("i = 23\n"); + break; + case 24: + printf("i = 24\n"); + break; + case 25: + printf("i = 25\n"); + break; + case 26: + printf("bar: "); + printf("i = 26\n"); + break; + case 27: + printf("i = 27\n"); + break; + case 28: + printf("i = 28\n"); + break; + default: + printf("i = %d\n", i); + } + + int val = add(i,i); + printf("main(): %d + %d = %d\n", i, i, val); + + switch(val) + { + case 20: + val = 35; + printf("a\n"); + break; + case 22: + val = add(21,31); + printf("36\n"); + break; + case 23: + val = add(val, val); + printf("37\n"); + break; + case 24: + val = add(val, 34); + printf("38\n"); + break; + case 25: + val = 38; + printf("39\n"); + break; + case 26: + val = 45; + printf("45\n"); + break; + case 27: + val = 55; + printf("55\n"); + break; + case 28: + val = 69; + printf("69\n"); + break; + case 29: + val = 72; + break; + case 31: + val = 82; + printf("82\n"); + break; + default: + val = 99; + } + + printf("val = %d\n", val); + +} diff --git a/irdb-lib/ir_builders/tests/ibtarget/jmp2.shared.cpp b/irdb-lib/ir_builders/tests/ibtarget/jmp2.shared.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a6bb2d9fce89013d28087b66c8e1e898e485bb82 --- /dev/null +++ b/irdb-lib/ir_builders/tests/ibtarget/jmp2.shared.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2014-2015 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <stdlib.h> +#include <stdio.h> + +extern int add(int, int); + +int switch_table_2(int argc, char **argv) +{ + int i = atoi(argv[1]); + + switch(i) + { + case 20: + printf("i = 20\n"); + break; + case 22: + printf("i = 22\n"); + break; + case 23: + printf("hello: "); + printf("i = 23\n"); + break; + case 24: + printf("i = 24\n"); + break; + case 25: + printf("i = 25\n"); + break; + case 26: + printf("bar: "); + printf("i = 26\n"); + break; + case 27: + printf("i = 27\n"); + break; + case 28: + printf("i = 28\n"); + break; + default: + printf("i = %d\n", i); + } + + int val = add(i,i); + printf("main(): %d + %d = %d\n", i, i, val); + + switch(val) + { + case 20: + val = 35; + printf("a\n"); + break; + case 22: + val = add(21,31); + printf("36\n"); + break; + case 23: + val = add(val, val); + printf("37\n"); + break; + case 24: + val = add(val, 34); + printf("38\n"); + break; + case 25: + val = 38; + printf("39\n"); + break; + case 26: + val = 45; + printf("45\n"); + break; + case 27: + val = 55; + printf("55\n"); + break; + case 28: + val = 69; + printf("69\n"); + break; + case 29: + val = 72; + break; + case 31: + val = 82; + printf("82\n"); + break; + default: + val = 99; + } + + printf("val = %d\n", val); + +} diff --git a/irdb-lib/ir_builders/tests/ibtarget/validate_ibts.sh b/irdb-lib/ir_builders/tests/ibtarget/validate_ibts.sh new file mode 100755 index 0000000000000000000000000000000000000000..f95b2cd9d31c532561d403ac2000b9411c94c28e --- /dev/null +++ b/irdb-lib/ir_builders/tests/ibtarget/validate_ibts.sh @@ -0,0 +1,38 @@ +# build original and protected test programs +make clean all protected +if [ ! $? -eq 0 ]; then + echo "failed to compile test programs" + exit 1 +fi + +export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:." + +ALL_PASS_STATUS=0 +# compare output +for i in `ls *.exe` +do + orig=$i + base=$(basename $orig .exe) + protected=${base}.protected + + echo $orig $base $protected + ./$orig 1 2 > $$.tmp.orig + ./$protected 1 2 > $$.tmp.protected + diff $$.tmp.orig $$.tmp.protected + if [ ! $? -eq 0 ]; then + echo "FAIL: Protected program ${base}.protected does not match original program" + ALL_PASS_STATUS=1 + else + echo "PASS: $orig vs. $protected" + fi + + rm $$.tmp.orig $$.tmp.protected +done + +echo +if [ $ALL_PASS_STATUS -eq 0 ]; then + echo "PASS: all tests passed" +else + echo "FAIL: one or more test failed" +fi + diff --git a/irdb-lib/ir_builders/unfix_calls.cpp b/irdb-lib/ir_builders/unfix_calls.cpp new file mode 100644 index 0000000000000000000000000000000000000000..65ed56dfa103341f771dc2d7fdc14e8ee4d6d47a --- /dev/null +++ b/irdb-lib/ir_builders/unfix_calls.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + + +#include <libIRDB-core.hpp> +#include <libIRDB-cfg.hpp> +#include <iostream> +#include <stdlib.h> +#include <assert.h> +#include <string.h> + + + +using namespace libIRDB; +using namespace std; + +void unfix_call(Instruction_t* insn, FileIR_t *virp); +bool is_push(Instruction_t* insn); + +void unfix_calls(FileIR_t* virp) +{ + for( + set<Instruction_t*>::const_iterator it=virp->GetInstructions().begin(); + it!=virp->GetInstructions().end(); + ++it + ) + { + + Instruction_t* insn=*it; + unfix_call(insn, virp); + } +} + +void unfix_call(Instruction_t* insn, FileIR_t *virp) +{ + /* we need a push instruction */ + assert(insn); + if(!is_push(insn)) + return; + /* that has a fallthrough */ + Instruction_t* nextinsn=insn->GetFallthrough(); + if(!nextinsn) + return; + + /* to a jump */ + Instruction_t* target=nextinsn->GetTarget(); + if(!target) + return; + + /* that isn't conditional */ + Instruction_t* fallthrough=nextinsn->GetFallthrough(); + if(fallthrough) + return; + + /* and the target has a function */ + Function_t *target_func=target->GetFunction(); + if(!target_func) + return; + + /* more checks? that the value pushed is an original program address? and one that originally follows the call? */ + + /* it seems that this instruction has met its prereqs. for converting to a call*/ + ControlFlowGraph_t *target_cfg=new ControlFlowGraph_t(target_func); + + cout<<"Built CFG for func "<< target_func->GetName() << endl; + + cout<<*target_cfg<<endl; + + /* cleanup */ + delete target_cfg; + +} + + +// +// return true if insn is a call +// +bool is_push(Instruction_t* insn) +{ + return insn->GetDataBits()[0]==0x68; +} + + +// +// main rountine; convert calls into push/jump statements +// +main(int argc, char* argv[]) +{ + + if(argc!=2) + { + cerr<<"Usage: ilr <id>"<<endl; + exit(-1); + } + + VariantID_t *pidp=NULL; + FileIR_t *virp=NULL; + + /* setup the interface to the sql server */ + pqxxDB_t pqxx_interface; + BaseObj_t::SetInterface(&pqxx_interface); + + cout<<"Reading variant "<<string(argv[1])<<" from database." << endl; + try + { + + pidp=new VariantID_t(atoi(argv[1])); + + assert(pidp->IsRegistered()==true); + + // read the db + virp=new FileIR_t(*pidp); + + + } + catch (DatabaseError_t pnide) + { + cout<<"Unexpected database error: "<<pnide<<endl; + exit(-1); + } + + assert(virp && pidp); + + cout<<"Adjusting push/jmp -> call in variant "<<*pidp<< "." <<endl; + + unfix_calls(virp); + + cout<<"Writing variant "<<*pidp<<" back to database." << endl; + virp->WriteToDB(); + + pqxx_interface.Commit(); + cout<<"Done!"<<endl; + + delete virp; + delete pidp; +} diff --git a/irdb-lib/ir_builders/unwind-pe.h b/irdb-lib/ir_builders/unwind-pe.h new file mode 100644 index 0000000000000000000000000000000000000000..a3c41963ff4bc878fe7492bccf2b766cf8246ca6 --- /dev/null +++ b/irdb-lib/ir_builders/unwind-pe.h @@ -0,0 +1,313 @@ +/* Exception handling and frame unwind runtime interface routines. + Copyright (C) 2001, 2002, 2003, 2004, 2008, 2009 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +/* @@@ Really this should be out of line, but this also causes link + compatibility problems with the base ABI. This is slightly better + than duplicating code, however. */ + +#ifndef GCC_UNWIND_PE_H +#define GCC_UNWIND_PE_H + +/* If using C++, references to abort have to be qualified with std::. */ +#if __cplusplus +#define __gxx_abort std::abort +#else +#define __gxx_abort abort +#endif + +/* Pointer encodings, from dwarf2.h. */ +#define DW_EH_PE_absptr 0x00 +#define DW_EH_PE_omit 0xff + +#define DW_EH_PE_uleb128 0x01 +#define DW_EH_PE_udata2 0x02 +#define DW_EH_PE_udata4 0x03 +#define DW_EH_PE_udata8 0x04 +#define DW_EH_PE_sleb128 0x09 +#define DW_EH_PE_sdata2 0x0A +#define DW_EH_PE_sdata4 0x0B +#define DW_EH_PE_sdata8 0x0C +#define DW_EH_PE_signed 0x08 + +#define DW_EH_PE_pcrel 0x10 +#define DW_EH_PE_textrel 0x20 +#define DW_EH_PE_datarel 0x30 +#define DW_EH_PE_funcrel 0x40 +#define DW_EH_PE_aligned 0x50 + +#define DW_EH_PE_indirect 0x80 + + +#ifndef NO_SIZE_OF_ENCODED_VALUE + +/* Given an encoding, return the number of bytes the format occupies. + This is only defined for fixed-size encodings, and so does not + include leb128. */ + +static unsigned int +size_of_encoded_value (unsigned char encoding) __attribute__ ((unused)); + +static unsigned int +size_of_encoded_value (unsigned char encoding) +{ + if (encoding == DW_EH_PE_omit) + return 0; + + switch (encoding & 0x07) + { + case DW_EH_PE_absptr: + return ptrsize; + case DW_EH_PE_udata2: + return 2; + case DW_EH_PE_udata4: + return 4; + case DW_EH_PE_udata8: + return 8; + } + __gxx_abort (); +} + +#endif + +#ifndef NO_BASE_OF_ENCODED_VALUE + +/* Given an encoding and an _Unwind_Context, return the base to which + the encoding is relative. This base may then be passed to + read_encoded_value_with_base for use when the _Unwind_Context is + not available. */ + +static _Unwind_Ptr +base_of_encoded_value (unsigned char encoding, struct _Unwind_Context *context) +{ + if (encoding == DW_EH_PE_omit) + return 0; + + switch (encoding & 0x70) + { + case DW_EH_PE_absptr: + case DW_EH_PE_pcrel: + case DW_EH_PE_aligned: + return 0; + +assert(0); +#if 0 + case DW_EH_PE_textrel: + return _Unwind_GetTextRelBase (context); + case DW_EH_PE_datarel: + return _Unwind_GetDataRelBase (context); + case DW_EH_PE_funcrel: + return _Unwind_GetRegionStart (context); +#endif + } + __gxx_abort (); +} + +#endif + +/* Read an unsigned leb128 value from P, store the value in VAL, return + P incremented past the value. We assume that a word is large enough to + hold any value so encoded; if it is smaller than a pointer on some target, + pointers should not be leb128 encoded on that target. */ + +static unsigned char * +read_uleb128 (unsigned char *p, _uleb128_t *val) +{ + unsigned int shift = 0; + unsigned char byte; + _uleb128_t result; + + result = 0; + do + { + byte = *p++; + result |= ((_uleb128_t)byte & 0x7f) << shift; + shift += 7; + } + while (byte & 0x80); + + *val = result; + return p; +} + +/* Similar, but read a signed leb128 value. */ + +static unsigned char * +read_sleb128 (unsigned char *p, _sleb128_t *val) +{ + unsigned int shift = 0; + unsigned char byte; + _uleb128_t result; + + result = 0; + do + { + byte = *p++; + result |= ((_uleb128_t)byte & 0x7f) << shift; + shift += 7; + } + while (byte & 0x80); + + /* Sign-extend a negative value. */ + if (shift < 8 * sizeof(result) && (byte & 0x40) != 0) + result |= -(((_uleb128_t)1L) << shift); + + *val = (_sleb128_t) result; + return p; +} + +typedef unsigned _Unwind_Internal_Ptr __attribute__((__mode__(__pointer__))); + +_Unwind_Internal_Ptr deref_unwind_ptr(uintptr_t to_deref); + + + +/* Load an encoded value from memory at P. The value is returned in VAL; + The function returns P incremented past the value. BASE is as given + by base_of_encoded_value for this encoding in the appropriate context. */ + +static unsigned char * +read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base, + unsigned char *p, _Unwind_Ptr *val) +{ + union unaligned + { + void *ptr; + unsigned u2 __attribute__ ((mode (HI))); + unsigned u4 __attribute__ ((mode (SI))); + unsigned u8 __attribute__ ((mode (DI))); + signed s2 __attribute__ ((mode (HI))); + signed s4 __attribute__ ((mode (SI))); + signed s8 __attribute__ ((mode (DI))); + } __attribute__((__packed__)); + + union unaligned *u = (union unaligned *) p; + _Unwind_Internal_Ptr result; + + +#define deref_unwind_ptr_in_memory(a) \ + ( ptrsize==4 ? (*(int32_t*)(a)) : (*(int64_t*)(a)) ) + + if (encoding == DW_EH_PE_aligned) + { + _Unwind_Internal_Ptr a = (_Unwind_Internal_Ptr) p; + a = (a + ptrsize - 1) & - ptrsize; + result = *(_Unwind_Internal_Ptr *) a; + result = deref_unwind_ptr_in_memory(a); + p = (unsigned char *) (_Unwind_Internal_Ptr) (a + ptrsize); + } + else + { + switch (encoding & 0x0f) + { + case DW_EH_PE_absptr: + if(ptrsize==4) + result = (_Unwind_Internal_Ptr) u->u4; + else if(ptrsize==8) + result = (_Unwind_Internal_Ptr) u->u8; + else + assert(0); + p += ptrsize; + break; + + case DW_EH_PE_uleb128: + { + _uleb128_t tmp; + p = read_uleb128 (p, &tmp); + result = (_Unwind_Internal_Ptr) tmp; + } + break; + + case DW_EH_PE_sleb128: + { + _sleb128_t tmp; + p = read_sleb128 (p, &tmp); + result = (_Unwind_Internal_Ptr) tmp; + } + break; + + case DW_EH_PE_udata2: + result = u->u2; + p += 2; + break; + case DW_EH_PE_udata4: + result = u->u4; + p += 4; + break; + case DW_EH_PE_udata8: + result = u->u8; + p += 8; + break; + + case DW_EH_PE_sdata2: + result = u->s2; + p += 2; + break; + case DW_EH_PE_sdata4: + result = u->s4; + p += 4; + break; + case DW_EH_PE_sdata8: + result = u->s8; + p += 8; + break; + + default: + __gxx_abort (); + } + + if (result != 0) + { + result += ((encoding & 0x70) == DW_EH_PE_pcrel + ? (_Unwind_Internal_Ptr) ptr_to_data_to_addr((uintptr_t)u) : base); +// ? (_Unwind_Internal_Ptr) ((uintptr_t)u+(uintptr_t)eh_offset) : base); + + if (encoding & DW_EH_PE_indirect) + { + result=deref_unwind_ptr(result); + //result = *(_Unwind_Internal_Ptr *) ((uintptr_t)result-(uintptr_t)eh_offset); + } + } + } + + *val = result; + return p; +} + +#ifndef NO_BASE_OF_ENCODED_VALUE + +/* Like read_encoded_value_with_base, but get the base from the context + rather than providing it directly. */ + +static inline unsigned char * +read_encoded_value (struct _Unwind_Context *context, unsigned char encoding, + unsigned char *p, _Unwind_Ptr *val) +{ + return read_encoded_value_with_base (encoding, + base_of_encoded_value (encoding, context), + p, val); +} + +#endif + +#endif /* unwind-pe.h */ diff --git a/irdb-lib/lib/.ignore b/irdb-lib/lib/.ignore new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/irdb-lib/libEXEIO/SConscript b/irdb-lib/libEXEIO/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..4b924974526de19e32967a8f64104b68348ed8b1 --- /dev/null +++ b/irdb-lib/libEXEIO/SConscript @@ -0,0 +1,9 @@ +import os + +Import('env') + +lib1=SConscript("src/SConscript") +lib2=SConscript("test/SConscript") + +ret=[lib1, lib2] +Return ('ret') diff --git a/irdb-lib/libEXEIO/SConstruct b/irdb-lib/libEXEIO/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..b5b7b78c5f88640c7e8877a9df76dc9191af7498 --- /dev/null +++ b/irdb-lib/libEXEIO/SConstruct @@ -0,0 +1,8 @@ + + + +env=Environment() +Export('env') +lib=SConscript("SConscript") + +Return('lib') diff --git a/irdb-lib/libEXEIO/include/exeio.h b/irdb-lib/libEXEIO/include/exeio.h new file mode 100644 index 0000000000000000000000000000000000000000..f27c8556d7af114c2759766074643f751156ea5d --- /dev/null +++ b/irdb-lib/libEXEIO/include/exeio.h @@ -0,0 +1,150 @@ +#ifndef EXEIO_H +#define EXEIO_H + +#include <ostream> +#include <vector> +#include <stddef.h> +#include <stdint.h> +#include <assert.h> + + +namespace EXEIO +{ + class exeio_t; // forward decl + + typedef enum { ELF64, ELF32, PE32, PE64 } execlass_t; + typedef enum { mtX86_64, mtI386, mtArm32, mtAarch64 } MachineType_t; + + typedef uintptr_t virtual_offset_t; + + + // create type to match elfio + class exeio_section_t + { + public: + virtual ~exeio_section_t() {} + virtual bool isLoadable() const =0; + virtual bool isExecutable() const =0; + virtual bool isWriteable() const =0; + virtual bool isReadable() const =0; + virtual bool isBSS() const =0; + virtual bool isThreadLocal() const { return false; } + virtual const char* get_data() const =0; + virtual std::string get_name() const =0; + virtual int get_size() const =0; + virtual int get_type() const =0; + virtual EXEIO::virtual_offset_t get_address() const =0; + virtual bool mightContainStrings() const =0; + }; + + // break naming rule for elfio compatibility + typedef exeio_section_t section; + + class exeio_backend_t + { + public: + virtual ~exeio_backend_t() { } + virtual void dump_header(std::ostream& stream) =0; + virtual void dump_section_headers(std::ostream& stream) =0; + virtual void load(exeio_t* main, const char* filename) =0; + virtual execlass_t get_class() =0; + virtual MachineType_t getMachineType() const =0; + virtual virtual_offset_t get_entry() =0; + virtual void* get_elfio() { return NULL; } + virtual bool isDLL() =0; + virtual bool isDynamicallyLinked() { return true; } + + }; + + class exeio_sections_t + { + public: + exeio_section_t* operator[](int i) { return the_sections[i]; } + exeio_section_t* operator[](const std::string& name) + { + for(auto s: the_sections) + if(s->get_name()==name) + return s; + return NULL; + } + exeio_section_t* findByAddress(const uint64_t addr) + { + for(auto s: the_sections) + { + if(s->get_address() <= addr && addr < (s->get_address()+s->get_size())) + return s; + } + return NULL; + } + int size() const { return (int)the_sections.size(); } + + void add_section(exeio_section_t* sec) + { + the_sections.push_back(sec); + } + private: + + std::vector<exeio_section_t*> the_sections; + + friend class exeio_backend_t; + + }; + + + class exeio_t + { + public: + // constructors + exeio_t() { Init(); } + exeio_t(const char* filename) { Init(); load(filename); } + exeio_t(const std::string& filename) { Init(); load(filename.c_str()); } + virtual ~exeio_t() { delete backend; } + + virtual void load(const std::string filename) { load((char*)filename.c_str()); } + + // load the file + virtual void load(const char* fn); + + // trying to do minimal rewriting of code that uses + // ELFIO namespace. + // This slightly odd construction of classes + // is used by ELFIO because it makes for nice looking code when using ELFIO. + // I quite like the results and there's a lot of code, so I'm mimicking it here. + // Unfortunately it means a less-than-clean interface for the class writer, + // but we'll manage. + exeio_sections_t sections; + + virtual virtual_offset_t get_entry() { assert(backend); return backend->get_entry(); } + + virtual void dump_header(std::ostream& stream) { assert(backend); backend->dump_header(stream); } + virtual void dump_section_headers(std::ostream& stream) { assert(backend); backend->dump_section_headers(stream); } + virtual execlass_t get_class() { assert(backend); return backend->get_class(); } + virtual MachineType_t getMachineType() const { assert(backend); return backend->getMachineType(); } + virtual void* get_elfio() { assert(backend); return backend->get_elfio(); } + virtual bool isDLL() { assert(backend); return backend->isDLL(); } + virtual bool isDynamicallyLinked() { assert(backend); return backend->isDynamicallyLinked(); } + + private: + void Init() { backend=NULL; } + + exeio_backend_t* backend; + + friend class exeio_backend; + + }; + + // intentionally breaking _t rule for ELFIO compatibility. + typedef exeio_t exeio; + + // breaking _t rule for ELFIO compatibility + class dump_t + { + public: + static void header(std::ostream& stream, EXEIO::exeio_t &to_print) { to_print.dump_header(stream); } + static void section_headers(std::ostream& stream, EXEIO::exeio_t &to_print) { to_print.dump_section_headers(stream); } + }; + + typedef dump_t dump; + +} +#endif diff --git a/irdb-lib/libEXEIO/src/SConscript b/irdb-lib/libEXEIO/src/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..3a81a1b36c99bf204a68e16461c9c9633d0dc950 --- /dev/null +++ b/irdb-lib/libEXEIO/src/SConscript @@ -0,0 +1,29 @@ +import os + +Import('env') +myenv=env.Clone() +myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) + + +libname="EXEIO" +files= ''' + exeio_src.cpp + ''' + +cpppath=''' + . + $SECURITY_TRANSFORMS_HOME/include/ + $SECURITY_TRANSFORMS_HOME/libEXEIO/include + $SECURITY_TRANSFORMS_HOME/pebliss/trunk/pe_lib/ + $SECURITY_TRANSFORMS_HOME/third_party/elfio-code + ''' + + +myenv=myenv.Clone(CPPPATH=Split(cpppath)) +myenv.Append(CXXFLAGS=" -std=c++11 -Wall -Werror ") +lib=myenv.SharedLibrary(libname, Split(files), LIBS=Split("irdb-core pebliss"), LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" ) + +install=myenv.Install("$SECURITY_TRANSFORMS_HOME/lib/", lib) +Default(install) + +Return('install') diff --git a/irdb-lib/libEXEIO/src/SConstruct b/irdb-lib/libEXEIO/src/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..b5b7b78c5f88640c7e8877a9df76dc9191af7498 --- /dev/null +++ b/irdb-lib/libEXEIO/src/SConstruct @@ -0,0 +1,8 @@ + + + +env=Environment() +Export('env') +lib=SConscript("SConscript") + +Return('lib') diff --git a/irdb-lib/libEXEIO/src/exeio_elf.h b/irdb-lib/libEXEIO/src/exeio_elf.h new file mode 100644 index 0000000000000000000000000000000000000000..cd2230b757b674a77aff6ab723d9ccdd1327a76d --- /dev/null +++ b/irdb-lib/libEXEIO/src/exeio_elf.h @@ -0,0 +1,145 @@ +#ifndef EXEIO_ELF_H +#define EXEIO_ELF_H + +#include <iostream> +#include <vector> +#include <assert.h> + +#pragma GCC diagnostic ignored "-Wsign-compare" +#include "elfio/elfio.hpp" +#include "elfio/elfio_dump.hpp" +#include "elf.h" +#pragma GCC diagnostic pop + +class exeio_backend; +class exeio_section; + +namespace EXEIO +{ + class exeio_elf_section_t : public exeio_section_t + { + public: + exeio_elf_section_t(ELFIO::section *the_s) : s(the_s) { assert(s); } + + bool isLoadable() const { return (s->get_flags() & SHF_ALLOC) == SHF_ALLOC; } + bool isExecutable() const { return (s->get_flags() & SHF_EXECINSTR) == SHF_EXECINSTR; } + bool isWriteable() const { return (s->get_flags() & SHF_WRITE) == SHF_WRITE; } + bool isThreadLocal() const { return (s->get_flags() & SHF_TLS) == SHF_TLS; } + bool isReadable() const { return isLoadable(); } + bool isBSS() const { return (s->get_type() == SHT_NOBITS); } + + const char* get_data() const { return s->get_data(); } + std::string get_name() const { return s->get_name(); } + int get_size() const { return s->get_size(); } + int get_type() const { return s->get_type(); } + EXEIO::virtual_offset_t get_address() const { return s->get_address(); } + bool mightContainStrings() const { assert(0); } + + private: + ELFIO::section *s; + }; + + class exeio_elf_backend_t : public exeio_backend_t + { + public: + exeio_elf_backend_t() : e(NULL), main(NULL) {} + virtual ~exeio_elf_backend_t() + { + if(!main) + return; + // remove subclasses. + for(int i=0;i<e->sections.size(); ++i) + { + // copy each section into the main class' structure. + EXEIO::exeio_elf_section_t* sec=dynamic_cast<EXEIO::exeio_elf_section_t*>(main->sections[i]); + delete sec; + } + + // remove the elfio class. + delete e; + } + void load(exeio* the_main, const char* filename) + { + main=the_main; + e=new ELFIO::elfio; + int res=e->load(filename); + assert(res); + + // resize the sections. + for(int i=0;i<e->sections.size(); ++i) + { + // copy each section into the main class' structure. + main->sections.add_section(new EXEIO::exeio_elf_section_t(e->sections[i])); + } + + } + virtual void dump_header(std::ostream& stream) + { + assert(e); + ELFIO::dump::header(stream,*e); + } + virtual void dump_section_headers(std::ostream& stream) + { + assert(e); + ELFIO::dump::section_headers(stream,*e); + } + virtual execlass_t get_class() + { + assert(e); + switch(e->get_class()) + { + case ELFCLASS64: return ELF64; + case ELFCLASS32: return ELF32; + default: assert(0); + }; + } + virtual MachineType_t getMachineType() const + { + assert(e); + switch(e->get_machine()) + { + case EM_ARM : return mtArm32; + case EM_AARCH64 : return mtAarch64; + case EM_386 : return mtI386; + case EM_X86_64 : return mtX86_64; + default: assert(0); + } + assert(0); + } + + // get entry point of function. + virtual virtual_offset_t get_entry() + { + assert(e); + return (virtual_offset_t)e->get_entry(); + } + + virtual void* get_elfio() { return (void*)e; } + + virtual bool isDLL() { return e->get_type()!=ET_EXEC; } + + virtual bool isDynamicallyLinked() + { + assert(e); + for(int i=0;i<e->segments.size(); ++i) + { + if( e->segments[i]->get_type()==PT_INTERP || e->segments[i]->get_type()==PT_DYNAMIC) + return true; + + } + return false; + + } + + + + + private: + ELFIO::elfio* e; + EXEIO::exeio* main; + }; + + +} + +#endif diff --git a/irdb-lib/libEXEIO/src/exeio_pe.h b/irdb-lib/libEXEIO/src/exeio_pe.h new file mode 100644 index 0000000000000000000000000000000000000000..868ddeec9e26f2bd578b7e81b12130baa2394b3f --- /dev/null +++ b/irdb-lib/libEXEIO/src/exeio_pe.h @@ -0,0 +1,169 @@ +#ifndef EXEIO_PE_H +#define EXEIO_PE_H + +#ifndef SOLARIS +#include <iostream> +#include <vector> +#include <assert.h> +#include <fstream> + +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#include <pe_bliss.h> +#pragma GCC diagnostic pop + + +class exeio_backend; +class exeio_section; + + +namespace EXEIO +{ + class exeio_pe_section_t : public exeio_section_t + { + public: + exeio_pe_section_t(const pe_bliss::section *the_s, const pe_bliss::pe_base *the_b) + : s(the_s),b(the_b) { assert(s); assert(b);} + + bool isLoadable() const { return s->readable(); } + bool isExecutable() const { return s->executable(); } + bool isWriteable() const { return s->writeable(); } + bool isReadable() const { return s->readable(); } + bool isBSS() const { return s->empty(); } + const char* get_data() const { return s->get_raw_data().c_str(); } + std::string get_name() const { return s->get_name(); } + int get_size() const { return s->get_virtual_size(); } + int get_type() const { assert(0); } // not imp'd yet + EXEIO::virtual_offset_t get_address() const { + EXEIO::virtual_offset_t base = b->get_image_base_64(); + return base + s->get_virtual_address(); + } + bool mightContainStrings() const { assert(0); } + + private: + const pe_bliss::section *s; + const pe_bliss::pe_base *b; + }; + + class exeio_pe_backend_t : public exeio_backend_t + { + public: + exeio_pe_backend_t() + : + e(NULL), + pe_sections(NULL), + main(NULL) + { + } + + ~exeio_pe_backend_t() + { + if(!main) + return; + // remove subclasses. + for(int i=0;i<main->sections.size(); ++i) + { + // copy each section into the main class' structure. + EXEIO::exeio_pe_section_t* sec=dynamic_cast<EXEIO::exeio_pe_section_t*>(main->sections[i]); + delete sec; + } + + // remove the pe_bliss class. + delete e; + } + void load(exeio* the_main, const char* filename) + { + main=the_main; + + std::ifstream pe_file(filename, std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cerr << "Cannot open " << filename << std::endl; + assert(0); + exit(1); + } + + + e=new pe_bliss::pe_base(pe_bliss::pe_factory::create_pe(pe_file)); + assert(e); + + pe_sections=new pe_bliss::section_list(e->get_image_sections()); + + for(pe_bliss::section_list::const_iterator it = pe_sections->begin(); + it != pe_sections->end(); ++it) + { + const pe_bliss::section& s = *it; + main->sections.add_section(new EXEIO::exeio_pe_section_t(&s,e)); + } + + + } + virtual void dump_header(std::ostream& stream) + { + assert(e); + + std::cout << "EP : " <<std::hex<< e->get_ep() << std::endl; + std::cout << "EP section name: " << e->section_from_rva(e->get_ep()).get_name() << std::endl; + std::cout << "EP section data length: " << + e->section_data_length_from_rva(e->get_ep()) << std::endl; + + if(e->has_imports()) + { + std::cout << "Import section name: " << + e->section_from_directory(pe_bliss::pe_win + ::image_directory_entry_import).get_name() + << std::endl; + } + } + virtual void dump_section_headers(std::ostream& stream) + { + assert(e); + for(pe_bliss::section_list::const_iterator it = pe_sections->begin(); + it != pe_sections->end(); ++it) + { + const pe_bliss::section& s = *it; //Ð¡ÐµÐºÑ†Ð¸Ñ + std::cout << "Section [" << s.get_name() << "]" << std::endl //Ð˜Ð¼Ñ Ñекции + << "Characteristics: " << s.get_characteristics() << std::endl + << "Size of raw data: " << s.get_size_of_raw_data() << std::endl + << "Virtual address: " << s.get_virtual_address() << std::endl + << "Virtual size: " << s.get_virtual_size() << std::endl + << std::endl; + } + + } + virtual MachineType_t getMachineType() const + { + assert(0); + } + + virtual execlass_t get_class() + { + assert(e); + if(e->get_pe_type() == pe_bliss::pe_type_32) + return PE32; + if(e->get_pe_type() == pe_bliss::pe_type_64) + return PE64; + assert(0); + } + + // get entry point of function. + virtual virtual_offset_t get_entry() + { + assert(e); + return (virtual_offset_t)e->get_ep(); + } + + + virtual bool isDLL() { assert(0); } + + + + private: + pe_bliss::pe_base* e; + pe_bliss::section_list* pe_sections; + EXEIO::exeio* main; + }; + + +} +#endif // solaris +#endif // exeio_pe_h diff --git a/irdb-lib/libEXEIO/src/exeio_src.cpp b/irdb-lib/libEXEIO/src/exeio_src.cpp new file mode 100644 index 0000000000000000000000000000000000000000..58ec9f58b794f6402db38942f3d6c0bc6cde3ac2 --- /dev/null +++ b/irdb-lib/libEXEIO/src/exeio_src.cpp @@ -0,0 +1,51 @@ + + +#include <istream> +#include <fstream> +#include <exeio.h> +#include <exeio_elf.h> +#include <exeio_pe.h> + + + +using namespace EXEIO; +using namespace std; +#ifndef SOLARIS +using namespace pe_bliss; +#endif + +void exeio::load(const char* filename) +{ + + ifstream instream(filename); + + if(!instream) + assert(0 && "Cannot open file"); + + int c0=instream.get(); + int c1=instream.get(); + int c2=instream.get(); + int c3=instream.get(); + + // check for elf magic number + if(c0 == '\177' && c1=='E' && c2=='L' && c3=='F') + { + backend=new exeio_elf_backend_t; + } + // check for CGC magic number + else if(c0 == '\177' && c1=='C' && c2=='G' && c3=='C') + { + backend=new exeio_elf_backend_t; + } + else +#ifndef SOLARIS + // we assume it's PE. + backend=new exeio_pe_backend_t; +#else + // don't build win support on solaris. + assert(0); +#endif + + backend->load(this, filename); + +} diff --git a/irdb-lib/libEXEIO/test/SConscript b/irdb-lib/libEXEIO/test/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..3982cf59c158574c0fe45309c02730d326d285b5 --- /dev/null +++ b/irdb-lib/libEXEIO/test/SConscript @@ -0,0 +1,38 @@ +import os + +Import('env') +myenv=env.Clone() +myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) + +(sysname, nodename, release, version, machine)=os.uname() + + +libname="exeio_test" +files= ''' + main.cpp + ''' + +cpppath=''' + . + $SECURITY_TRANSFORMS_HOME/include/ + $SECURITY_TRANSFORMS_HOME/libEXEIO/include + $SECURITY_TRANSFORMS_HOME/libEXEIO/include + ''' +libpath=''' + $SECURITY_TRANSFORMS_HOME/lib/ + ''' + +libs= ''' + EXEIO + pebliss + ''' +if "CYGWIN" in sysname: + libs = libs + " iconv" + +myenv=myenv.Clone(CPPPATH=Split(cpppath), LIBS=Split(libs), LIBPATH=Split(libpath)) +myenv.Append(CXXFLAGS=" -Wall -Werror -std=c++11 ") +pgm=myenv.Program(libname, Split(files)) + +install=myenv.Install("$SECURITY_TRANSFORMS_HOME/bin/", pgm) +Default(install) +Return('install') diff --git a/irdb-lib/libEXEIO/test/SConstruct b/irdb-lib/libEXEIO/test/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..b3bd01322f2b78089fd86e0e9b0ae01897c9c8a5 --- /dev/null +++ b/irdb-lib/libEXEIO/test/SConstruct @@ -0,0 +1,7 @@ + + + +env=Environment() +Export('env') +lib=SConscript("SConscript") +Return('lib') diff --git a/irdb-lib/libEXEIO/test/main.cpp b/irdb-lib/libEXEIO/test/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..041d395f36ece81ab882115d7f097c0b19b200e7 --- /dev/null +++ b/irdb-lib/libEXEIO/test/main.cpp @@ -0,0 +1,23 @@ +#include <iostream> +#include <exeio.h> + +using namespace std; +using namespace EXEIO; + + +int main(int argc, char* argv[]) +{ + if(argc!=2) + { + cout<<"Usage: "<<argv[0]<<": <exe>"<<endl; + } + + exeio *exep=new exeio; + + exep->load(argv[1]); + + EXEIO::dump::header(cout,*exep); + EXEIO::dump::section_headers(cout,*exep); + + return 0; +} diff --git a/irdb-lib/libIRDB-cfg/include/BasicBlock.hpp b/irdb-lib/libIRDB-cfg/include/BasicBlock.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d2059b22eca8bf27a7df1c8991de15116ede1822 --- /dev/null +++ b/irdb-lib/libIRDB-cfg/include/BasicBlock.hpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +namespace libIRDB +{ + using namespace std; + + class BasicBlock_t : public IRDB_SDK::BasicBlock_t + { + + public: + BasicBlock_t(); + virtual ~BasicBlock_t() { } + + bool getIsExitBlock() const { return is_exit_block; } + void setIsExitBlock(bool is_exit) { is_exit_block=is_exit; } + + IRDB_SDK::InstructionVector_t& GetInstructions() { return instructions; } + IRDB_SDK::BasicBlockSet_t& GetPredecessors() { return predecessors; } + IRDB_SDK::BasicBlockSet_t& GetSuccessors() { return successors; } + IRDB_SDK::BasicBlockSet_t& GetIndirectTargets() { return indirect_targets; } + + // for const correctness if you aren't modifying. + const IRDB_SDK::InstructionVector_t& getInstructions() const { return instructions; } + const IRDB_SDK::BasicBlockSet_t& getPredecessors() const { return predecessors; } + const IRDB_SDK::BasicBlockSet_t& getSuccessors() const { return successors; } + const IRDB_SDK::BasicBlockSet_t& getIndirectTargets() const { return indirect_targets; } +// IRDB_SDK::BasicBlock_t * getFallthrough() const ; +// IRDB_SDK::BasicBlock_t * getTarget() const ; + + bool endsInBranch() const; + bool endsInIndirectBranch() const; + bool endsInConditionalBranch() const; + IRDB_SDK::Instruction_t* getBranchInstruction() const; + void dump(ostream &os=cout) const ; + + protected: + + void BuildBlock( IRDB_SDK::Instruction_t* insn, + const map<IRDB_SDK::Instruction_t*,BasicBlock_t*> &insn2block_map + ); + + + private: + + IRDB_SDK::InstructionVector_t instructions; + IRDB_SDK::BasicBlockSet_t predecessors; + IRDB_SDK::BasicBlockSet_t successors; + IRDB_SDK::BasicBlockSet_t indirect_targets; + bool is_exit_block; + + friend ostream& operator<<(ostream& os, const BasicBlock_t& block); + friend class ControlFlowGraph_t; + }; + + +} diff --git a/irdb-lib/libIRDB-cfg/include/CFG.hpp b/irdb-lib/libIRDB-cfg/include/CFG.hpp new file mode 100644 index 0000000000000000000000000000000000000000..2499b994eea66f87fe85f49cd85dffaaa056489e --- /dev/null +++ b/irdb-lib/libIRDB-cfg/include/CFG.hpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +namespace libIRDB +{ + using namespace std; + + class ControlFlowGraph_t : public IRDB_SDK::ControlFlowGraph_t + { + public: + ControlFlowGraph_t(IRDB_SDK::Function_t* func); + virtual ~ControlFlowGraph_t() { } + IRDB_SDK::BasicBlock_t* getEntry() const { return entry; } + IRDB_SDK::Function_t* getFunction() const { return function; } + IRDB_SDK::BasicBlockSet_t& GetBlocks() { return blocks; } + const IRDB_SDK::BasicBlockSet_t& getBlocks() const { return blocks; } + void dump(ostream &os=cout) const; + bool hasEdge(IRDB_SDK::BasicBlock_t *p_src, IRDB_SDK::BasicBlock_t *p_tgt) const; + IRDB_SDK::CFGEdgeType_t getEdgeType(const IRDB_SDK::BasicBlock_t *p_src, const IRDB_SDK::BasicBlock_t *p_tgt) const; + + private: + // methods + void Build(IRDB_SDK::Function_t *func); + void alloc_blocks(const IRDB_SDK::InstructionSet_t &starts, map<IRDB_SDK::Instruction_t*,BasicBlock_t*>& insn2block_map); + void build_blocks(const map<IRDB_SDK::Instruction_t*,BasicBlock_t*>& insn2block_map); + void find_unblocked_instructions(InstructionSet_t &starts, IRDB_SDK::Function_t* func); + + // data + IRDB_SDK::BasicBlockSet_t blocks; + IRDB_SDK::BasicBlock_t* entry; + IRDB_SDK::Function_t* function; + + }; + +} diff --git a/irdb-lib/libIRDB-cfg/include/callgraph.hpp b/irdb-lib/libIRDB-cfg/include/callgraph.hpp new file mode 100644 index 0000000000000000000000000000000000000000..bc5f383923e2e686c9c08325aa175a7b008db8b4 --- /dev/null +++ b/irdb-lib/libIRDB-cfg/include/callgraph.hpp @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2014-2015 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef irdb_cfg_callgraph_h +#define irdb_cfg_callgraph_h + +namespace libIRDB +{ + + using namespace std; + + // only one type of hell node for now, but leave + // open the possibilty for multiple hell nodes + typedef enum { DEFAULT_HELL_NODE = 0 } HellNodeType; + + class CallGraphNode_t : public IRDB_SDK::CallGraphNode_t + { + public: + virtual ~CallGraphNode_t(){ } + CallGraphNode_t(IRDB_SDK::Function_t* f = NULL) { + if (f) { + SetFunction(f); + } else { + m_isHellNode = true; + m_node.hellNodeType = DEFAULT_HELL_NODE; + } + } + + bool isHellnode() const { return m_isHellNode; } + + IRDB_SDK::Function_t* getFunction() const { + assert(!m_isHellNode); + if (m_isHellNode) + return NULL; + else + return m_node.func; + } + + HellNodeType GetHellNodeType() const { + assert(m_isHellNode); + return m_node.hellNodeType; + } + + bool operator==(const CallGraphNode_t &other) const { + if (this == &other) return true; + if (m_isHellNode) + { + return m_node.hellNodeType == other.m_node.hellNodeType; + } + else + return m_node.func == other.m_node.func; + } + void dump(ostream& os=cout) const; + + private: + void SetFunction(IRDB_SDK::Function_t* const f) { + assert(f); + m_node.func = f; + m_isHellNode = false; + } + + private: + bool m_isHellNode; + union { + IRDB_SDK::Function_t* func; + HellNodeType hellNodeType; + } m_node; + }; + + + class Callgraph_t : public IRDB_SDK::CallGraph_t + { + public: + Callgraph_t(); + virtual ~Callgraph_t(); + void addFile(IRDB_SDK::FileIR_t* const firp); + + bool edgeExists(const IRDB_SDK::CallGraphEdge_t& edge) const + { + const auto from = dynamic_cast<CallGraphNode_t*>(edge.first); + const auto to = dynamic_cast<CallGraphNode_t*>(edge.second); + + const auto caller_it = callers.find(from); + if(caller_it==callers.end()) + return false; + + const auto &calleeSet = caller_it->second; + return calleeSet.find(to)!=calleeSet.end(); + } + bool edgeExists(IRDB_SDK::CallGraphNode_t& n1, IRDB_SDK::CallGraphNode_t& n2) const + { return edgeExists(IRDB_SDK::CallGraphEdge_t(&n1,&n2));} + + IRDB_SDK::CallGraphNodeSet_t& GetCallersOfNode(IRDB_SDK::CallGraphNode_t* const node) + { return callers[node]; } + IRDB_SDK::CallGraphNodeSet_t& GetCalleesOfNode(IRDB_SDK::CallGraphNode_t* const node) + { return callees[node]; } + + const IRDB_SDK::CallGraphNodeSet_t& getCallersOfNode(IRDB_SDK::CallGraphNode_t* const node) const + { + static const auto empty = IRDB_SDK::CallGraphNodeSet_t(); + const auto it=callers.find(node); + return (it==callers.end()) ? empty : it->second; + } + const IRDB_SDK::CallGraphNodeSet_t& getCalleesOfNode(IRDB_SDK::CallGraphNode_t* const node) const + { + static const auto empty = IRDB_SDK::CallGraphNodeSet_t(); + const auto it=callees.find(node); + return (it==callees.end()) ? empty : it->second; + } + + void GetAncestors(IRDB_SDK::Function_t* const fn, IRDB_SDK::CallGraphNodeSet_t& ancestors, bool skipHellNode = false) const; + void GetAncestors(IRDB_SDK::CallGraphNode_t* const node, IRDB_SDK::CallGraphNodeSet_t& ancestors, bool skipHellNode = false) const; + + const IRDB_SDK::CallSiteSet_t& GetCallSites(IRDB_SDK::CallGraphNode_t* const n1) const + { + static const auto empty = IRDB_SDK::CallSiteSet_t(); + const auto it=call_sites.find(n1); + return (it==call_sites.end()) ? empty : it->second; + } + + + IRDB_SDK::CallSiteSet_t& getCallSites(IRDB_SDK::CallGraphNode_t* const n1) + { return call_sites[n1]; } + + void dump(ostream& fout) const; + + string GetNodeName(const IRDB_SDK::CallGraphNode_t* const p_n1) const { + auto n1=dynamic_cast<CallGraphNode_t const*>(p_n1); + assert(n1); + if (n1->isHellnode()) { + ostringstream s; + s << "HELLNODE" << n1->GetHellNodeType(); + return s.str(); + } else { + assert(n1->getFunction()); + return n1->getFunction()->getName(); + } + } + + string GetCallsiteDisassembly(const IRDB_SDK::CallSite_t &c) const + { return c ? c->getDisassembly() : "NOFROMFUNC"; } + + bool isReachable(IRDB_SDK::CallGraphNode_t* const from, IRDB_SDK::CallGraphNode_t* const to, bool skipHellNode = false) const; + + CallGraphNode_t& GetDefaultHellNode() { return default_hellnode; } + const CallGraphNode_t& getDefaultHellNode() const { return default_hellnode; } + + IRDB_SDK::CallGraphNode_t* findNode(IRDB_SDK::Function_t* const fn) const; + + private: + // create nodes from functions + void CreateNodes(IRDB_SDK::FileIR_t *firp); + + // mark the given insn as a call site. + void MarkCallSite(IRDB_SDK::Instruction_t* const insn); + + // traverse graph to retrieve all ancestors + void _GetAncestors(IRDB_SDK::CallGraphNode_t* const node, IRDB_SDK::CallGraphNodeSet_t &ancestors, IRDB_SDK::CallGraphNodeSet_t &visited, bool skipHellNode) const; + + using CGNodeToCGNodeSetMap_t = map<IRDB_SDK::CallGraphNode_t*, IRDB_SDK::CallGraphNodeSet_t > ; + using NodeToCallSiteSetMap_t = map<IRDB_SDK::CallGraphNode_t*, IRDB_SDK::CallSiteSet_t > ; + using FunctionToCGNodeMap_t = map<IRDB_SDK::Function_t* , IRDB_SDK::CallGraphNode_t* > ; +; + CGNodeToCGNodeSetMap_t callers; // map a callee to its callees + CGNodeToCGNodeSetMap_t callees; // map a caller to its callers + NodeToCallSiteSetMap_t call_sites; + CallGraphNode_t default_hellnode; // default hell node + FunctionToCGNodeMap_t nodes; // maps functions to call graph nodes + }; + +} +#endif diff --git a/irdb-lib/libIRDB-cfg/include/criticaledge.hpp b/irdb-lib/libIRDB-cfg/include/criticaledge.hpp new file mode 100644 index 0000000000000000000000000000000000000000..244e68347ab77f4e565bb300fc98e8a6b4e81911 --- /dev/null +++ b/irdb-lib/libIRDB-cfg/include/criticaledge.hpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +namespace libIRDB +{ + using namespace std; + + class CriticalEdgeAnalyzer_t : public IRDB_SDK::CriticalEdges_t + { + public: + CriticalEdgeAnalyzer_t(const ControlFlowGraph_t *p_cfg, const bool p_conservative=true); + virtual ~CriticalEdgeAnalyzer_t() { } + const IRDB_SDK::BasicBlockEdgeSet_t& getAllCriticalEdges() const { return criticals; } + + private: + void init(); + const IRDB_SDK::ControlFlowGraph_t *m_cfg; + const bool m_conservative; + IRDB_SDK::BasicBlockEdgeSet_t criticals; + + }; +} diff --git a/irdb-lib/libIRDB-cfg/include/domgraph.hpp b/irdb-lib/libIRDB-cfg/include/domgraph.hpp new file mode 100644 index 0000000000000000000000000000000000000000..db37459ae80730a03cc2a15e599ba5b8003d5a72 --- /dev/null +++ b/irdb-lib/libIRDB-cfg/include/domgraph.hpp @@ -0,0 +1,75 @@ +#include <ostream> +namespace libIRDB +{ + using namespace std; + + using DominatorMap_t = map<IRDB_SDK::BasicBlock_t*, IRDB_SDK::BasicBlockSet_t>; + using BlockToBlockMap_t = map<IRDB_SDK::BasicBlock_t*, IRDB_SDK::BasicBlock_t*>; + + + + + + class DominatorGraph_t : public IRDB_SDK::DominatorGraph_t + { + public: + DominatorGraph_t(const ControlFlowGraph_t* p_cfg, bool needs_postdoms=false, bool needs_idoms=false); + virtual ~DominatorGraph_t() { } + + + // get the (post) dominators for a node + IRDB_SDK::BasicBlockSet_t& GetDominators(IRDB_SDK::BasicBlock_t* node) { return dom_graph[node]; } + IRDB_SDK::BasicBlockSet_t& GetPostDominators(IRDB_SDK::BasicBlock_t* node) { return post_dom_graph[node]; } + + const IRDB_SDK::BasicBlockSet_t& getDominators(const IRDB_SDK::BasicBlock_t* node) const { return dom_graph.at(const_cast<IRDB_SDK::BasicBlock_t*>(node)); } + const IRDB_SDK::BasicBlockSet_t& getDominated (const IRDB_SDK::BasicBlock_t* node) const { return dominated_graph.at(const_cast<IRDB_SDK::BasicBlock_t*>(node)); } +// const IRDB_SDK::BasicBlockSet_t& getPostDominators(const IRDB_SDK::BasicBlock_t* node) const { assert(0); } +// const IRDB_SDK::BasicBlockSet_t& getPostDominated (const IRDB_SDK::BasicBlock_t* node) const { assert(0); } + + bool hasWarnings() const { return warn; } + + + // get the immeidate (post) dominators for a node + const IRDB_SDK::BasicBlock_t* getImmediateDominator (const IRDB_SDK::BasicBlock_t* node) const + { + auto it=idom_graph.find(const_cast<IRDB_SDK::BasicBlock_t*>(node)); + return (it!=idom_graph.end()) ? it->second : nullptr; + } + const IRDB_SDK::BasicBlockSet_t& getImmediateDominated (const IRDB_SDK::BasicBlock_t* node) const + { + const static IRDB_SDK::BasicBlockSet_t empty; + auto it=idominated_graph.find(const_cast<IRDB_SDK::BasicBlock_t*>(node)); + return (it!=idominated_graph.end()) ? it->second : empty; } +// const IRDB_SDK::BasicBlock_t* getImmediatePostDominator(const IRDB_SDK::BasicBlock_t* node) const { assert(0); } +// const IRDB_SDK::BasicBlockSet_t& getImmediatePostDominated(const IRDB_SDK::BasicBlock_t* node) const { assert(0); } + + void dump(ostream& os=cout) const; + + + private: + void Dominated_Compute(); + + using pred_func_ptr_t = const IRDB_SDK::BasicBlockSet_t& (*) (const IRDB_SDK::BasicBlock_t* node); + + DominatorMap_t Dom_Comp(const IRDB_SDK::BasicBlockSet_t& N, pred_func_ptr_t pred_func, IRDB_SDK::BasicBlock_t* r); + BlockToBlockMap_t Idom_Comp(const IRDB_SDK::BasicBlockSet_t& N, const DominatorMap_t &Domin, IRDB_SDK::BasicBlock_t* r); + + + DominatorMap_t dom_graph; + BlockToBlockMap_t idom_graph; + + DominatorMap_t dominated_graph; + DominatorMap_t idominated_graph; + + DominatorMap_t post_dom_graph; + BlockToBlockMap_t post_idom_graph; + + const ControlFlowGraph_t& cfg; // a reference to our cfg. + + bool warn; + + }; + + + +} diff --git a/irdb-lib/libIRDB-cfg/include/libIRDB-cfg.hpp b/irdb-lib/libIRDB-cfg/include/libIRDB-cfg.hpp new file mode 100644 index 0000000000000000000000000000000000000000..003113796c76bed60fd626b097b7ad11b00bef7d --- /dev/null +++ b/irdb-lib/libIRDB-cfg/include/libIRDB-cfg.hpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef libIRDB_cfg +#define libIRDB_cfg + + +/* Building a CFG depends on core functionality */ +#include <irdb-cfg> +#include <libIRDB-core.hpp> + +#include <vector> +#include <set> +#include <map> +#include <ostream> + +#include <BasicBlock.hpp> +#include <CFG.hpp> +#include <callgraph.hpp> +#include <domgraph.hpp> +#include <criticaledge.hpp> + + +#endif diff --git a/irdb-lib/libIRDB-cfg/src/BasicBlock.cpp b/irdb-lib/libIRDB-cfg/src/BasicBlock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e89e6664e805291a2ffc4674957353cdae319fb9 --- /dev/null +++ b/irdb-lib/libIRDB-cfg/src/BasicBlock.cpp @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +#include <map> +#include <libIRDB-core.hpp> +#include <libIRDB-cfg.hpp> +#include <irdb-util> +#include <algorithm> + +using namespace libIRDB; +using namespace std; + + +#define ALLOF(a) begin((a)), end((a)) + +/* + * is_in_container - a handle template function returning whether key S is contained in container T. + */ +template <class T, class S> +inline bool is_in_container(const T& container, const S& key) +{ + bool is_in=container.find(key) != container.end(); + return is_in; +} + +template <class S> +inline bool is_in_set(const std::set<S>& container, const S& key) +{ + return std::find(container.begin(), container.end(), key) != container.end(); +} +/* + * find_map_object - without modifying the object, return the element + */ +template <class T, class S> +inline S const& find_map_object( const std::map< T , S > &a_map, const T& key) +{ + const auto it=a_map.find(key); + assert(it!=a_map.end()); + + return (*it).second; +} + + + +BasicBlock_t::BasicBlock_t() + : is_exit_block(false) +{ +} + + + +void BasicBlock_t::BuildBlock + ( + IRDB_SDK::Instruction_t* insn, + const map<IRDB_SDK::Instruction_t*,BasicBlock_t*> &insn2block_map + ) +{ + const auto &func=insn->getFunction(); + assert(insn); + /* loop through the instructions for this block */ + while(insn) + { + const auto d = DecodedInstruction_t::factory(insn); + + /* insert this instruction */ + instructions.push_back(insn); + + auto target_insn=insn->getTarget(); + auto ft_insn=insn->getFallthrough(); + + /* determine if there's a target block */ + BasicBlock_t* target_block=nullptr; + const auto include_target = (!d->isCall()); + if (include_target && target_insn && is_in_container(insn2block_map,target_insn)) + target_block=find_map_object(insn2block_map,target_insn); + + /* determine if there's a ft block */ + BasicBlock_t* ft_block=nullptr; + if(ft_insn && is_in_container(insn2block_map,ft_insn)) + ft_block=find_map_object(insn2block_map,ft_insn); + + /* if there's a target block, insert it into the appropriate sets */ + if(target_block) + { + target_block->GetPredecessors().insert(this); + successors.insert(target_block); + } + + /* This is also the end of the block if this is a function exit instruction */ + if(insn->isFunctionExit()) + { + is_exit_block=true; + } + + // handle fixed-call fallthroughs. + // for_each(ALLOF(insn->getRelocations()), [this,&insn2block_map](IRDB_SDK::Relocation_t* reloc) + for(auto reloc : insn->getRelocations()) + { + // and has a reloc that's a pcrel with a WRT object + // possible for a call to have a null fallthrouth (and consequently null WRT) + // becauase the call may be the last insn in a section, etc. + if( reloc->getType()==string("fix_call_fallthrough") && reloc->getWRT()!=nullptr) + { + assert(reloc->getWRT()!=nullptr); + auto fix_call_fallthrough_insn=dynamic_cast<Instruction_t*>(reloc->getWRT()); + assert(fix_call_fallthrough_insn); + + // this block has a fallthrough to the return block. + if(is_in_container(insn2block_map,fix_call_fallthrough_insn)) + { + BasicBlock_t* fix_call_fallthrough_blk=find_map_object(insn2block_map,static_cast<IRDB_SDK::Instruction_t*>(fix_call_fallthrough_insn)); + successors.insert(fix_call_fallthrough_blk); + fix_call_fallthrough_blk->GetPredecessors().insert(this); + } + + is_exit_block=false; + } + }; + + + /* if there's a fallthrough block, insert it into the appropriate sets */ + if(ft_block) + { + ft_block->GetPredecessors().insert(this); + successors.insert(ft_block); + } + + /* this is the end of the block if there's a target instruction */ + if(target_insn) + break; + + /* or if there is a fallthrough block already built */ + if(ft_block) + break; + + /* check for a fallthrough out of the function */ + if(ft_insn && ft_insn->getFunction() != func) + break; + + + /* otherwise, move to the fallthrough */ + insn=ft_insn; + } + + + // deal with IB targets for the end of the block + + insn=instructions[instructions.size()-1]; // get last instruction. + assert(insn); + const auto icfs = insn->getIBTargets(); + const auto d = DecodedInstruction_t::factory(insn); + const auto include_icfs = !(d->isReturn() || d->isCall() ) ; + + + if(icfs != nullptr && include_icfs) + { + for(const auto target : *icfs) + { + if(is_in_container(insn2block_map,target) && target!=func->getEntryPoint()) // don't link calls to the entry block. + { + BasicBlock_t* target_block=find_map_object(insn2block_map,target); + target_block->GetPredecessors().insert(this); + successors.insert(target_block); + } + }; + } + +} + + + +bool BasicBlock_t::endsInBranch() const +{ + const auto branch=instructions[instructions.size()-1]; + assert(branch); + + const auto d=DecodedInstruction_t::factory(branch); + return d->isBranch(); + + +} +bool BasicBlock_t::endsInIndirectBranch() const +{ + const auto *branch=instructions[instructions.size()-1]; + assert(branch); + + const auto p_d=DecodedInstruction_t::factory(branch); + const auto &d =*p_d; + + if(d.isReturn()) + return true; + if(d.isUnconditionalBranch() || d.isCall()) + { + if(!d.getOperand(0)->isConstant()) + /* not a constant type */ + return true; + return false; + + } + return false; +} +bool BasicBlock_t::endsInConditionalBranch() const +{ + if(!endsInBranch()) + return false; + const auto branch=instructions[instructions.size()-1]; + assert(branch); + const auto d=DecodedInstruction_t::factory(branch); + + return d->isConditionalBranch(); +} + +IRDB_SDK::Instruction_t* BasicBlock_t::getBranchInstruction() const + +{ + if(!endsInBranch()) + return nullptr; + + auto branch=instructions[instructions.size()-1]; + return branch; +} + + +std::ostream& IRDB_SDK::operator<<(std::ostream& os, const IRDB_SDK::BasicBlock_t& block) +{ + block.dump(os); + return os; +} +void BasicBlock_t::dump(std::ostream& os) const +{ + os<<getIsExitBlock(); + os<<"\t ---- Starting block print -----" <<endl; + for(auto i=0U;i<getInstructions().size();i++) + { + const auto insn=getInstructions()[i]; + os<<"\t Instruction "<<std::dec<<i<<" at " << std::hex << insn->getAddress()->getVirtualOffset() << " with id " << std::dec << insn->getBaseID() << " " << insn->getComment() << endl; + } + os<<"\t ---- done block print -----" <<endl; + os<<endl; +} + diff --git a/irdb-lib/libIRDB-cfg/src/CFG.cpp b/irdb-lib/libIRDB-cfg/src/CFG.cpp new file mode 100644 index 0000000000000000000000000000000000000000..33b9b56ac5b1c5fb96214aa910ecd53fa6bbef93 --- /dev/null +++ b/irdb-lib/libIRDB-cfg/src/CFG.cpp @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +#include <libIRDB-cfg.hpp> +#include <irdb-util> +#include <algorithm> + +using namespace std; +using namespace libIRDB; + +#define ALLOF(a) begin((a)), end((a)) + +/* + * is_in_container - a handle template function returning whether key S is contained in container T. + */ +template <class T, class S> +inline bool is_in_container(const T& container, const S& key) +{ + bool is_in=container.find(key) != container.end(); + return is_in; +} + +template <class S> +inline bool is_in_set(const std::set<S>& container, const S& key) +{ + return std::find(container.begin(), container.end(), key) != container.end(); +} +/* + * find_map_object - without modifying the object, return the element + */ +template <class T, class S> +inline S const& find_map_object( const std::map< T , S > &a_map, const T& key) +{ + const auto it=a_map.find(key); + assert(it!=a_map.end()); + + return (*it).second; +} + + +/* + * FindTargets - locate all possible instructions that are the target of a jump instruction + */ +static InstructionSet_t FindBlockStarts(IRDB_SDK::Function_t* func) +{ + + InstructionSet_t targets; + InstructionSet_t found_fallthrough_to; + + if(func->getEntryPoint()) + /* the entry point of the function is a target instruction for this CFG */ + targets.insert(func->getEntryPoint()); + + /* for each instruction, decide if it's a block start based on whether or not + * it can be indirectly branched to. Also mark direct targets as block starts. + */ + for(auto insn : func->getInstructions()) + { + /* If this instruction might be an indirect branch target, then mark it as a block start */ + if(insn->getIndirectBranchTargetAddress()) + { + targets.insert(insn); + } + + /* get target and fallthrough */ + auto target=insn->getTarget(); + auto ft=insn->getFallthrough(); + + /* if this instruction has a target, and the target is in this function, mark the target as a block start */ + if(target && is_in_container(func->getInstructions(), target)) + targets.insert(target); + + /* there is a target, and a failthrough, and the fallthrough is in this function */ + if(target && ft && is_in_container(func->getInstructions(), ft)) + targets.insert(ft); + + // we already found a fallthrough to ft, so we have 2+ fallthroughs to ft. mark it as a control flow merge. + if( ft && is_in_container(found_fallthrough_to, ft)) + targets.insert(ft); + + // if there is a ft, mark that we've seen it now. + if(ft) + found_fallthrough_to.insert(ft); + + } + + return targets; +} + +ControlFlowGraph_t::ControlFlowGraph_t(IRDB_SDK::Function_t* func) : + entry(NULL), function(dynamic_cast<Function_t*>(func)) +{ + Build(func); +} + + +void ControlFlowGraph_t::alloc_blocks(const IRDB_SDK::InstructionSet_t &starts, map<IRDB_SDK::Instruction_t*,BasicBlock_t*>& insn2block_map) +{ + /* create a basic block for each instruction that starts a block */ + for(const auto &insn : starts) + { + if(is_in_container(insn2block_map,insn)) // already allocated + continue; + + auto newblock=new BasicBlock_t; + + assert( insn && newblock ); + + blocks.insert(newblock); + insn2block_map[insn]=newblock; + } +} + +void ControlFlowGraph_t::build_blocks(const map<IRDB_SDK::Instruction_t*,BasicBlock_t*>& insn2block_map) +{ + + /* Ask the basic block to set the fields for each block that need to be set */ + for(const auto &it : insn2block_map) + { + const auto insn=it.first; + const auto block=it.second; + + if(block->getInstructions().size()>0) // already built + continue; + + assert(insn && block); + + block->BuildBlock(insn, insn2block_map); + + } + +} + +void ControlFlowGraph_t::find_unblocked_instructions(IRDB_SDK::InstructionSet_t &starts, IRDB_SDK::Function_t* func) +{ + auto mapped_instructions=InstructionSet_t(); + auto missed_instructions=InstructionSet_t(); + for(const auto block : GetBlocks()) + mapped_instructions.insert(ALLOF(block->getInstructions())); + + auto my_inserter=inserter(missed_instructions,missed_instructions.end()); + set_difference(ALLOF(func->getInstructions()), ALLOF(mapped_instructions), my_inserter); + starts.insert(ALLOF(missed_instructions)); +} + + + +void ControlFlowGraph_t::Build(IRDB_SDK::Function_t* func) +{ + auto starts=FindBlockStarts(func); + + auto insn2block_map=map<IRDB_SDK::Instruction_t*,BasicBlock_t*> (); + + alloc_blocks(starts, insn2block_map); + build_blocks(insn2block_map); + /* record the entry block */ + if(func->getEntryPoint()) + entry=insn2block_map[func->getEntryPoint()]; + + /* most functions are done now. */ + /* however, if a function has a (direct) side entrance, + * some code may appear unreachable and not be placed in + * a block -- here, we detect that code and create a + * new basic block for every instruction, as any may have a side entrance + */ + /* note: side entrances may miss a block start */ + /* in code that appears reachable from the entrance?! */ + find_unblocked_instructions(starts, func); + alloc_blocks(starts, insn2block_map); + build_blocks(insn2block_map); +} + +// returns true iff there's an edge from <p_src> to <p_tgt> in the CFG +bool ControlFlowGraph_t::hasEdge(IRDB_SDK::BasicBlock_t *p_src, IRDB_SDK::BasicBlock_t *p_tgt) const +{ + const auto src_exists = blocks.find(p_src) != blocks.end(); + const auto tgt_exists = blocks.find(p_tgt) != blocks.end(); + + if (!src_exists || !tgt_exists) return false; + + const auto successors = p_src->getSuccessors(); + return successors.find(p_tgt) != successors.end(); +} + +IRDB_SDK::CFGEdgeType_t ControlFlowGraph_t::getEdgeType(const IRDB_SDK::BasicBlock_t *p_src, const IRDB_SDK::BasicBlock_t *p_tgt) const +{ + const auto last_in_src = p_src->getInstructions()[p_src->getInstructions().size()-1]; + const auto first_in_tgt = p_tgt->getInstructions()[0]; + + auto edgeType = IRDB_SDK::CFGEdgeType_t(); + + if (last_in_src->getFallthrough() == first_in_tgt) + { + edgeType.insert(IRDB_SDK::cetFallthroughEdge); + } + + if (last_in_src->getTarget() == first_in_tgt) + { + edgeType.insert(IRDB_SDK::cetTargetEdge); + } + + if (edgeType.size() == 0) + { + edgeType.insert(IRDB_SDK::cetIndirectEdge); + } + + return edgeType; +} + +/* + * output operator + */ +ostream& IRDB_SDK::operator<<(ostream& os, const IRDB_SDK::ControlFlowGraph_t& cfg) +{ + cfg.dump(os); + return os; +} + +void ControlFlowGraph_t::dump(ostream& os) const +{ + int i=0; + + auto blk_numbers = map<IRDB_SDK::BasicBlock_t*,int>(); + for(auto blk : getBlocks() ) + { + blk_numbers[blk]=i++; + } + + + for(auto block : getBlocks()) + { + if(block==getEntry()) + os<<"**** Entry "; + else + os<<"---- NotEntry "; + os<<"block "<<std::dec<<blk_numbers[block]<<endl; + os<<"Successors: "; + for(auto succ : block->getSuccessors()) + { + os<<blk_numbers[succ]<<", "; + + }; + os<<endl; + os<<"Predecessors: "; + for(auto pred : block->getPredecessors()) + { + os<<blk_numbers[pred]<<", "; + }; + os<<endl; + os << *block; + } + +} + +unique_ptr<IRDB_SDK::ControlFlowGraph_t> IRDB_SDK::ControlFlowGraph_t::factory(IRDB_SDK::Function_t* func) +{ + return unique_ptr<IRDB_SDK::ControlFlowGraph_t>(new libIRDB::ControlFlowGraph_t(func)); +} + diff --git a/irdb-lib/libIRDB-cfg/src/Makefile b/irdb-lib/libIRDB-cfg/src/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..1554e4568c28be8e1ed93df0374692ad10825ff9 --- /dev/null +++ b/irdb-lib/libIRDB-cfg/src/Makefile @@ -0,0 +1,15 @@ + +LIB=../../lib/libIRDB-cfg.a + +OBJS=BasicBlock.o CFG.o callgraph.o + +all: $(OBJS) + +$(OBJS): ../../include/core/*.hpp ../../include/cfg/*.hpp ../../include/*.hpp + +clean: + rm -f $(OBJS) + +.cpp.o: + $(CXX) -fPIC -g -c -I. -I../../include -I../../../beaengine/include $< + ar rc $(LIB) $@ diff --git a/irdb-lib/libIRDB-cfg/src/SConscript b/irdb-lib/libIRDB-cfg/src/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..cb08c53f8c8a1a5c37f4e1c1247a591fdda427e5 --- /dev/null +++ b/irdb-lib/libIRDB-cfg/src/SConscript @@ -0,0 +1,31 @@ +import os + +Import('env') + +myenv=env.Clone() +myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) + + +libname="irdb-cfg" +files= ''' + BasicBlock.cpp callgraph.cpp CFG.cpp domgraph.cpp criticaledge.cpp + ''' +cpppath=''' + $IRDB_SDK/include/ + $SECURITY_TRANSFORMS_HOME/include/ + $SECURITY_TRANSFORMS_HOME/libIRDB-core/include/ + $SECURITY_TRANSFORMS_HOME/libIRDB-cfg/include/ + ''' +libpath=''' + $SECURITY_TRANSFORMS_HOME/lib + ''' + +myenv.Append(CCFLAGS=" -Wall -std=c++11 -fmax-errors=2 ") + +myenv=myenv.Clone(CPPPATH=Split(cpppath)) +lib=myenv.SharedLibrary(libname, Split(files), LIBS=Split("irdb-core"), LIBPATH=Split(libpath)) + +install=myenv.Install("$SECURITY_TRANSFORMS_HOME/lib/", lib) +Default(install) + +Return('install') diff --git a/irdb-lib/libIRDB-cfg/src/SConstruct b/irdb-lib/libIRDB-cfg/src/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..b3bd01322f2b78089fd86e0e9b0ae01897c9c8a5 --- /dev/null +++ b/irdb-lib/libIRDB-cfg/src/SConstruct @@ -0,0 +1,7 @@ + + + +env=Environment() +Export('env') +lib=SConscript("SConscript") +Return('lib') diff --git a/irdb-lib/libIRDB-cfg/src/callgraph.cpp b/irdb-lib/libIRDB-cfg/src/callgraph.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fe35a0105a294f1971f6003828827de5994f3c0a --- /dev/null +++ b/irdb-lib/libIRDB-cfg/src/callgraph.cpp @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2014-2015 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +#include <map> +#include <ostream> +#include <libIRDB-core.hpp> +#include <libIRDB-cfg.hpp> +#include <irdb-util> + +using namespace libIRDB; +using namespace std; + + +Callgraph_t::Callgraph_t() : + default_hellnode(NULL) +{ +} + +unique_ptr<IRDB_SDK::CallGraph_t> IRDB_SDK::CallGraph_t::factory(FileIR_t* const firp) +{ + auto ret=unique_ptr<IRDB_SDK::CallGraph_t>(new libIRDB::Callgraph_t()); + if(firp != nullptr) + ret->addFile(firp); + return ret; +} + + +Callgraph_t::~Callgraph_t() +{ + for (auto p : nodes) + { + delete p.second; + } + nodes.clear(); +} + +static bool IsCallSite(Instruction_t* insn) +{ + const auto d=DecodedInstruction_t::factory(insn); + return d->isCall(); +} + +static bool IsTailJmpSite(Instruction_t* insn) +{ + const auto d=DecodedInstruction_t::factory(insn); + if(d->isBranch()) + return false; + + if(insn->getTarget()==NULL) + return true; + + if(insn->getFunction() != insn->getTarget()->getFunction()) + return true; + return false; +} + +static bool IsPushJmpSite(Instruction_t* insn) +{ + const auto d=DecodedInstruction_t::factory(insn); + if(d->getMnemonic()!="push" || insn->getFallthrough()==NULL) + return false; + + if(insn->getRelocations().size()==0) + return false; + + const auto d2=DecodedInstruction_t::factory(insn->getFallthrough()); + if(!d2->isBranch()) + return false; + + return true; +} + +void Callgraph_t::MarkCallSite(IRDB_SDK::Instruction_t* insn) +{ + auto from_func=insn->getFunction(); + auto to_insn=insn->getTarget(); + auto to_func= to_insn==NULL? NULL : to_insn->getFunction(); + + auto from_node = findNode(from_func); + auto to_node = findNode(to_func); + + if (!from_node) + from_node = &GetDefaultHellNode(); + + if (!to_node) + to_node = &GetDefaultHellNode(); + + call_sites[from_node].insert(insn); + callees[from_node].insert(to_node); + callers[to_node].insert(from_node); +} + +void Callgraph_t::CreateNodes(IRDB_SDK::FileIR_t *firp) +{ + const FunctionSet_t &fns=firp->getFunctions(); + for(auto it=fns.begin(); fns.end() != it; ++it) + { + auto fn=*it; + if (fn) { + auto newnode = new CallGraphNode_t(fn); + nodes[fn] = newnode; +// cout << "Added CGNode: " << GetNodeName(newnode) << endl; + } + } +} + +void Callgraph_t::addFile(IRDB_SDK::FileIR_t* const firp) +{ + // Create CG Nodes from functions + CreateNodes(firp); + + // for each instruction + auto &insns=firp->getInstructions(); + + for(auto it=insns.begin(); insns.end() != it; ++it) + { + auto insn=dynamic_cast<Instruction_t*>(*it); + if(IsCallSite(insn) || IsTailJmpSite(insn)) + MarkCallSite(insn); + if(IsPushJmpSite(insn)) + MarkCallSite(dynamic_cast<Instruction_t*>(insn->getFallthrough())); + + if(insn->getFunction() && insn->getFunction()->getEntryPoint()==insn + && insn->getIndirectBranchTargetAddress()) + { + auto node = findNode(insn->getFunction()); + assert(node); + callees[&GetDefaultHellNode()].insert(node); + callers[node].insert(&GetDefaultHellNode()); + } + } +} + + +void Callgraph_t::_GetAncestors(IRDB_SDK::CallGraphNode_t* const node, IRDB_SDK::CallGraphNodeSet_t &ancestors, IRDB_SDK::CallGraphNodeSet_t &visited, bool skipHellNode) const +{ + if (!node || visited.count(node) > 0) + return; + + cerr << "visiting node: " << GetNodeName(node) << " visited(size):" << visited.size() << endl; + + // ancestor-traversal(node X) + // mark X visited + // get parents P of X + // if P[i] not visited: + // add P[i] to ancestors + // ancestor-traversal(P[i]) + + visited.insert(node); + + const auto &directPredecessors = getCallersOfNode(node); + for (const auto pred : directPredecessors ) // it = directPredecessors.begin(); it != directPredecessors.end(); ++it) + { + if (visited.count(pred) == 0) + { + assert(pred); + if (pred->isHellnode() && skipHellNode) continue; + + cerr << "adding " << GetNodeName(pred) << " to ancestor list " << hex << pred << dec << endl; + ancestors.insert(pred); + _GetAncestors(pred, ancestors, visited, skipHellNode); + } + } +} + +IRDB_SDK::CallGraphNode_t* Callgraph_t::findNode(IRDB_SDK::Function_t* const fn) const +{ + auto node_it=nodes.find(fn); + return (node_it==nodes.end()) ? nullptr : node_it->second; +} + +void Callgraph_t::GetAncestors(IRDB_SDK::Function_t* const fn, IRDB_SDK::CallGraphNodeSet_t &ancestors, bool skipHellNode) const +{ + auto node = findNode(fn); + if (node) + GetAncestors(node, ancestors, skipHellNode); +} + +void Callgraph_t::GetAncestors(IRDB_SDK::CallGraphNode_t* const node, IRDB_SDK::CallGraphNodeSet_t &ancestors, bool skipHellNode) const +{ + auto visited=IRDB_SDK::CallGraphNodeSet_t(); + _GetAncestors(node, ancestors, visited, skipHellNode); +} + +bool Callgraph_t::isReachable(IRDB_SDK::CallGraphNode_t* const from, IRDB_SDK::CallGraphNode_t* const to, bool skipHellNode) const +{ + auto ancestors=IRDB_SDK::CallGraphNodeSet_t(); + GetAncestors(to, ancestors, skipHellNode); + return (ancestors.count(from) > 0); +} + +void Callgraph_t::dump(std::ostream& fout) const +{ + + fout<<"Dumping callgraph ..."<<endl; + + fout<<"Mapping one way ..."<<endl; + for(const auto p : callees) // it=callees.begin(); callees.end()!=it; ++it) + { + // CallGraphNode_t* node = it->first; + // CallGraphNodeSet_t &node_callers=it->second; + const auto node =p.first; + const auto &node_callers=p.second; + + fout<<"Function "<<GetNodeName(node)<<" calls: "; + for(const auto &the_callee : node_callers) // auto it2=node_callers.begin(); node_callers.end()!=it2; ++it2) + { + // CallGraphNode_t* the_callee=*it2; + fout<<GetNodeName(the_callee)<<", "; + } + fout<<endl; + for(const auto the_call_site : GetCallSites(node)) // auto it2=GetCallSites(node).begin(); GetCallSites(node).end() != it2; ++it2) + { + // CallSite_t the_call_site=*it2; + fout<<"\t"<<GetCallsiteDisassembly(the_call_site)<<endl; + } + } + + fout<<"Mapping the other way ..."<<endl; + for(const auto p : callers) // auto it=callers.begin(); callers.end()!=it; ++it) + { + // CallGraphNode_t* n=it->first; + const auto n =p.first; + const auto &node_callees=p.second; + + fout<<"Function "<<GetNodeName(n)<<" called by: "; + for(auto the_caller : node_callees) // CallGraphNodeSet_t::iterator it2=node_callees.begin(); node_callees.end()!=it2; ++it2) + { + // CallGraphNode_t* the_caller=*it2; + fout<<GetNodeName(the_caller)<<", "; + + } + fout<<endl; + } + + + fout<<"Printing call sites..."<<endl; + for(const auto p : call_sites) // auto it=call_sites.begin(); call_sites.end()!=it; ++it) + { + const auto from_node=p.first; + const auto &call_sites_for_func=p.second; + + fout<<"Call Sites for "<<GetNodeName(from_node)<<": "; + + for(const auto the_call_site : call_sites_for_func) // auto it2=call_sites_for_func.begin(); call_sites_for_func.end() != it2; ++it2) + { + // auto the_call_site=*it2; + fout<<GetCallsiteDisassembly(the_call_site)<<", "; + } + fout<<endl; + } + + fout<<"Done!"<<endl; +} + +void CallGraphNode_t::dump(std::ostream& fout) const +{ + if (isHellnode()) + { + fout << "HELLNODE" << GetHellNodeType(); + } + else + { + assert(getFunction()); + fout << getFunction()->getName(); + } +} + +ostream& IRDB_SDK::operator<<(ostream& os, const IRDB_SDK::CallGraph_t& cg) +{ + cg.dump(os); + return os; +} +ostream& IRDB_SDK::operator<<(ostream& os, const IRDB_SDK::CallGraphNode_t& cgn) +{ + cgn.dump(os); + return os; +} + diff --git a/irdb-lib/libIRDB-cfg/src/criticaledge.cpp b/irdb-lib/libIRDB-cfg/src/criticaledge.cpp new file mode 100644 index 0000000000000000000000000000000000000000..82e5dd67edee08cfc8744ab42e7a57bc40dabbda --- /dev/null +++ b/irdb-lib/libIRDB-cfg/src/criticaledge.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2019 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +#include <libIRDB-cfg.hpp> +#include <irdb-util> +#include <algorithm> + +using namespace std; +using namespace libIRDB; + +#define ALLOF(a) begin(a),end(a) + +CriticalEdgeAnalyzer_t::CriticalEdgeAnalyzer_t(const ControlFlowGraph_t* p_cfg, const bool p_conservative) : + m_cfg(p_cfg), + m_conservative(p_conservative) +{ + init(); +} + +/* +* Critical edge between two nodes is where the source node has multiple successsors, +* and the target node has multiple predecessors +*/ +void CriticalEdgeAnalyzer_t::init() +{ + for (const auto &src : m_cfg->getBlocks()) + { + auto num_successors = src->getSuccessors().size(); + if (!m_conservative) + { + // in aggressive (non conservative) mode, ignore indirect edges + // when counting number of successors + num_successors = count_if + ( + ALLOF(src->getSuccessors()), + [&] (const IRDB_SDK::BasicBlock_t* bb_tgt) + { + auto myEdgeType = m_cfg->getEdgeType(src, bb_tgt); + return myEdgeType.find(IRDB_SDK::cetTargetEdge)!=myEdgeType.end() || + myEdgeType.find(IRDB_SDK::cetFallthroughEdge)!=myEdgeType.end(); + } + ); + } + + if (num_successors <= 1) continue; + + for (const auto &tgt : src->getSuccessors()) + { + auto num_predecessors = tgt->getPredecessors().size(); + if (!m_conservative) + { + // in aggressive (non conservative) mode, ignore indirect edges + // when counting number of predecessors + num_predecessors = count_if + ( + ALLOF(tgt->getPredecessors()), + [&] (const IRDB_SDK::BasicBlock_t* bb_pred) + { + auto myEdgeType = m_cfg->getEdgeType(bb_pred, tgt); + return myEdgeType.find(IRDB_SDK::cetTargetEdge)!=myEdgeType.end() || + myEdgeType.find(IRDB_SDK::cetFallthroughEdge)!=myEdgeType.end(); + } + ); + } + + if (num_predecessors > 1) + { + auto e=IRDB_SDK::BasicBlockEdge_t(src, tgt); + criticals.insert(e); + } + } + } +} + +unique_ptr<IRDB_SDK::CriticalEdges_t> IRDB_SDK::CriticalEdges_t::factory( + const IRDB_SDK::ControlFlowGraph_t &p_cfg, + const bool p_conservative) +{ + auto real_cfg = dynamic_cast<const libIRDB::ControlFlowGraph_t*>(&p_cfg); + return unique_ptr<IRDB_SDK::CriticalEdges_t>(new libIRDB::CriticalEdgeAnalyzer_t( + real_cfg, p_conservative)); +} diff --git a/irdb-lib/libIRDB-cfg/src/domgraph.cpp b/irdb-lib/libIRDB-cfg/src/domgraph.cpp new file mode 100644 index 0000000000000000000000000000000000000000..36a10b4ced1dca25f7a867d268b8032bdaf44584 --- /dev/null +++ b/irdb-lib/libIRDB-cfg/src/domgraph.cpp @@ -0,0 +1,400 @@ + +#include <libIRDB-cfg.hpp> +#include <algorithm> +#include <irdb-util> +#include <irdb-cfg> +#include <memory> + + +using namespace std; +using namespace libIRDB; + +#define ALLOF(a) begin((a)), end((a)) + +/* + * is_in_container - a handle template function returning whether key S is contained in container T. + */ +template <class T, class S> +inline bool is_in_container(const T& container, const S& key) +{ + bool is_in=container.find(key) != container.end(); + return is_in; +} + +template <class S> +inline bool is_in_set(const std::set<S>& container, const S& key) +{ + return std::find(container.begin(), container.end(), key) != container.end(); +} +/* + * find_map_object - without modifying the object, return the element + */ +template <class T, class S> +inline S const& find_map_object( const std::map< T , S > &a_map, const T& key) +{ + const auto it=a_map.find(key); + assert(it!=a_map.end()); + + return (*it).second; +} + + + +// constructor +DominatorGraph_t::DominatorGraph_t(const ControlFlowGraph_t* p_cfg, bool needs_postdoms, bool needs_idoms) + : cfg(*p_cfg), warn(false) +{ + auto &blocks=p_cfg->getBlocks(); + + + assert(needs_postdoms==false); + assert(needs_idoms==false); + + + pred_func_ptr_t func_get_predecessors=[](const IRDB_SDK::BasicBlock_t* node) -> const IRDB_SDK::BasicBlockSet_t& + { + return node->getPredecessors(); + }; + + dom_graph=Dom_Comp(blocks, func_get_predecessors, p_cfg->getEntry()); + idom_graph=Idom_Comp(blocks, dom_graph, p_cfg->getEntry()); + + Dominated_Compute(); + +// a func may have multiple exit nodes. how do we deal with that? +// psuedo-block? invoke this for each exit block? +// pred_func_ptr_t func_get_successors=[](const BasicBlock_t* node) -> const BasicBlockSet_t& +// { +// return node->GetSuccessors(); +// }; +// post_dom_graph=Dom_Comp(p_cfg->GetBlocks(), func_get_successors, p_cfg->GetEntry()); +// post_idom_graph=IDom_Comp(p_cfg->GetBlocks(), post_dom_graph, p_cfg->GetEntry()); +} + + + + +/* + +algorithm from advanced compiler design & impelmentation, Mucnick, 2nd edition page 18 + +procedure Dom_Comp(N,Pred,r) returns Node-> set of Node + N: in set of Node + Pred: in Node -> set of Node + r: in Node + D, T: set of Node + n, p: Node + change := true: boolean + Domin: Node -> set of Node + Domin(r) := { r } + + for each n \in N - {r} do + Domin(n)={N} + od + repeat + change := false + for each n \in N - {r} do + + T := N + for each p \in Pred(n) do + T = T intersect Domin(p) + done + D = {n} union T + if D != Domin(n) then + change := true + Domin(n) := D + fi + done + until ! change + return Domin +end || Dom_Comp + +*/ + +DominatorMap_t DominatorGraph_t::Dom_Comp(const IRDB_SDK::BasicBlockSet_t& N, pred_func_ptr_t get_preds, IRDB_SDK::BasicBlock_t* r) +{ +/* + D, T: set of Node + n, p: Node + change := true: boolean + Domin: Node -> set of Node + Domin(r) := { r } +*/ + IRDB_SDK::BasicBlockSet_t D, T; + bool change=true; + DominatorMap_t Domin; + Domin[r].insert(r); + + IRDB_SDK::BasicBlockSet_t NminusR=N; + NminusR.erase(r); + +/* + for each n \in N - {r} do + Domin(n)={N} + od +*/ + for( auto n : NminusR) + { + Domin[n]=N; + }; + +/* + repeat +*/ + do + { + change = false; + /* + for each n \in N - {r} do + */ + for( auto n : NminusR) + { + /* T := N */ + T=N; +/* + + for each p \in Pred(n) do + T = T intersect Domin(p) + done +*/ + for(auto p : get_preds(n) ) + { + IRDB_SDK::BasicBlockSet_t tmp; + set_intersection(T.begin(), T.end(), Domin[p].begin(), Domin[p].end(), inserter(tmp,tmp.begin())); + T=tmp; + + }; + /* + D = {n} union T + */ + D=T; + D.insert(n); + + /* + if D != Domin(n) then + change := true + Domin(n) := D + fi + */ + if(D != Domin[n]) + { + change=true; // keep trying + Domin[n]=D; + } + }; +/* + done + until ! change +*/ + } + while ( change ); + + +// log output +#if 0 + + for_each(N.begin(), N.end(), [&](const BasicBlock_t* blk) + { + assert(blk); + const BasicBlockSet_t& blk_dominates=Domin[blk]; + Instruction_t* first_insn=*(blk->getInstructions().begin()); + assert(first_insn); +#if 1 + cout<<"\tBlock " <<endl<<*blk<<endl; + +#endif + cout<<"\t Dominated by:"<<endl; + for_each(blk_dominates.begin(), blk_dominates.end(), [&](const BasicBlock_t* dom_blk) + { + cout<<*dom_blk<<endl; + }); + }); +#endif + return Domin; +} + + + +/* algorith for constructing immediate dominators from Muchnick, page 184. + +procedure Idom_Comp(N,Domin,r) returns Node -> Node + N: in set of Node + Domin: in Node -> set of Node + r: in Node +begin + n, s, t: Node + Tmp: Node -> set of Node + IDom: Node->Node + for each n \in N do + Tmp(n) := Domin(n) - {n} + od + + for each n \in N - {r} do + for each s \in Tmp(n) do + for each t \in Tmp(n) - {s} do + if t \in Tmp(s) then + Tmp(n) -= {t} + fi + od + od + od + + for each n \in N-{r} do + IDom(n) = <only element in>Tmp(n) + od + return IDdom +end || IDom_Comp +*/ + + + +BlockToBlockMap_t DominatorGraph_t::Idom_Comp(const IRDB_SDK::BasicBlockSet_t& N, const DominatorMap_t &Domin, IRDB_SDK::BasicBlock_t* r) +{ + // n, s, t: Node + //BasicBlock_t* n=NULL, *s=NULL, *t=NULL; + + // Tmp: Node -> set of Node + DominatorMap_t Tmp; + + // IDom: Node->Node + BlockToBlockMap_t IDom; + + + // calculate this set as we use it several times + IRDB_SDK::BasicBlockSet_t NminusR = N; + NminusR.erase(r); + + + // for each n \in N do + for(auto n : N) + { + //Tmp(n) := Domin(n) - {n} + Tmp[n] = Domin.at(n); + Tmp[n].erase(n); + // od + }; + + + //for each n \in N - {r} do + for(auto n : NminusR) + { + // for each s \in Tmp(n) do + auto Tmp_n=Tmp[n]; + // for_each( Tmp_n.begin(), Tmp_n.end(), [&]( BasicBlock_t* s) + for (auto s : Tmp_n) + { + + //for each t \in Tmp(n) - {s} do + // for_each( Tmp_n.begin(), Tmp_n.end(), [&]( BasicBlock_t* t) + for (auto t : Tmp_n) + { + // quickly do Tmp(n)-s + if(t != s) + { + //if t \in Tmp(s) then + if( is_in_container(Tmp[s],t)) + { + //Tmp(n) -= {t} + Tmp[n].erase(t); + } + } + }; + }; + }; + + + //for each n \in N-{r} do + for (auto n : NminusR) + { + //IDom(n) = <only element in>Tmp(n) + IDom[n]= *(Tmp[n].begin()); + if(Tmp[n].size()!=1) // should only be one idominator. + warn=true; + }; + return IDom; +} // IDom_Comp + + +void DominatorGraph_t::Dominated_Compute() +{ + for(auto p : dom_graph) + { + auto dominates = p.first; + auto dominated_set = p.second; + + for(auto dominated : dominated_set) + dominated_graph[dominated].insert(dominates); + } + for(auto p : idom_graph) + { + auto dominates = p.first; + auto dominated = p.second; + idominated_graph[dominated].insert(dominates); + } + +} + + + + +ostream& IRDB_SDK::operator<<(ostream& os, const DominatorGraph_t& dg) +{ + dg.dump(os); + return os; +} + +void DominatorGraph_t::dump(ostream& os) const +{ + for(auto blk : cfg.getBlocks()) + { + assert(blk); + const auto& blk_dominators=getDominators(blk); + auto first_insn=*(blk->getInstructions().begin()); + assert(first_insn); + + os<<"\tBlock entry id:" <<dec<<blk->getInstructions()[0]->getBaseID()<<endl; + os<<"\t\tBlocks that (eventually) dominate me: "; + for(auto blk : blk_dominators) + { + os<<blk->getInstructions()[0]->getBaseID()<<", "; + }; + os<<endl; + + const IRDB_SDK::BasicBlock_t* idom=getImmediateDominator(blk); + if(idom) + os<<"\t\tMy Immediate Dominator: "<<dec<<idom->getInstructions()[0]->getBaseID()<<endl; + else + os<<"\t\tNo Immed Dominator."<<endl; + + + os<<"\t\tBlocks I (eventually) Dominate: "; + const auto& dominated_blocks=getDominated(blk); + for(auto blk : dominated_blocks) + { + os<<blk->getInstructions()[0]->getBaseID()<<", "; + }; + os<<endl; + + os<<"\t\tBlocks I Immediately Dominate: "; + const auto& imm_dominated_blocks=getImmediateDominated(blk); + for(auto blk : imm_dominated_blocks) + { + os<<blk->getInstructions()[0]->getBaseID()<<", "; + }; + os<<endl; + }; + +} + +// constructor +unique_ptr<IRDB_SDK::DominatorGraph_t> +IRDB_SDK::DominatorGraph_t::factory(const ControlFlowGraph_t* p_cfg, const bool needs_postdoms, const bool needs_idoms) +{ + const auto real_cfg=dynamic_cast<const libIRDB::ControlFlowGraph_t*>(p_cfg); + return unique_ptr<IRDB_SDK::DominatorGraph_t>(new libIRDB::DominatorGraph_t(real_cfg, needs_postdoms, needs_idoms)); +} + + + + + diff --git a/irdb-lib/libIRDB-core/include/IRDB_Objects.hpp b/irdb-lib/libIRDB-core/include/IRDB_Objects.hpp new file mode 100644 index 0000000000000000000000000000000000000000..aaa34b8abebcf01c0e43be4a2025c9122828aea4 --- /dev/null +++ b/irdb-lib/libIRDB-core/include/IRDB_Objects.hpp @@ -0,0 +1,76 @@ +#ifndef IRDB_Objects_h +#define IRDB_Objects_h + +namespace libIRDB +{ + +// TODO: Should really use unordered maps but was getting build errors + + +// *** A toolchain step should NOT delete pointers to any variant, file IR, or file object stored +// in a IRFiles_t object. I have made pointers shared where possible to communicate this. *** +class IRDBObjects_t : virtual public IRDB_SDK::IRDBObjects_t +{ + public: + IRDBObjects_t() + { + pqxx_interface = std::unique_ptr<pqxxDB_t>(new pqxxDB_t()); + // set up interface to the sql server + BaseObj_t::setInterface(pqxx_interface.get()); + }; + virtual ~IRDBObjects_t(); + + // Add/delete file IRs for a variant. + // Step does not have ownership of fileIR (can't make assumptions about its + // lifetime!), and a call to DeleteFileIR will render any pointers to that fileIR dangling. + // AddFileIR returns the added IR or the preexistent IR if it was already added. + IRDB_SDK::FileIR_t* addFileIR(const IRDB_SDK::DatabaseID_t variant_id, const IRDB_SDK::DatabaseID_t file_id); // Returns NULL if no such file exists + void deleteFileIR(const IRDB_SDK::DatabaseID_t file_id); + // Add or delete a variant + // Step does not have ownership of variant (can't make assumptions about its lifetime!), and a call to DeleteVariant will render any pointers to that variant dangling. + // Deleting a variant does NOT write its files' IRs, but DOES delete them! + // AddVariant returns the added variant or the preexistent variant if it was already added. + IRDB_SDK::VariantID_t* addVariant(const IRDB_SDK::DatabaseID_t variant_id); + void deleteVariant(IRDB_SDK::DatabaseID_t variant_id); + + // Get DB interface + IRDB_SDK::pqxxDB_t* getDBInterface() const; + IRDB_SDK::pqxxDB_t* resetDBInterface(); + + // Write back variants and file IRs. Does NOT commit changes. + int writeBackFileIR(const IRDB_SDK::DatabaseID_t file_id, std::ostream *verbose_logging=nullptr); + int writeBackVariant(const IRDB_SDK::DatabaseID_t variant_id); // Does NOT write back its files' IRs + int writeBackAll(std::ostream* verbose_logging=nullptr); // Returns -1 if any writes fail. + + void deleteAll(void); + + void tidyIR(); + + private: + std::unique_ptr<pqxxDB_t> pqxx_interface; + // type aliases of maps. maps allow speed of finding needed files, file IRs + // and/or variants that have already been read from the DB + using IdToVariantMap_t = std::map<IRDB_SDK::DatabaseID_t, std::unique_ptr<VariantID_t>>; + struct FileIRInfo_t + { + File_t * file; + std::unique_ptr<FileIR_t> fileIR; + + FileIRInfo_t() : file(nullptr), fileIR(nullptr) + { + } + + }; + using IdToFileIRInfoMap_t = std::map<IRDB_SDK::DatabaseID_t, FileIRInfo_t>; + + IdToVariantMap_t variant_map; + IdToFileIRInfoMap_t file_IR_map; + + // minor helper + bool filesAlreadyPresent(const FileSet_t&) const; + +}; + + +} +#endif diff --git a/irdb-lib/libIRDB-core/include/address.hpp b/irdb-lib/libIRDB-core/include/address.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f6b341b56c76e902a82f2a1a2a64e329e422d919 --- /dev/null +++ b/irdb-lib/libIRDB-core/include/address.hpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +namespace libIRDB +{ + + +// +// An address in a variant. +// +using virtual_offset_t = IRDB_SDK::VirtualOffset_t; +class AddressID_t : virtual public IRDB_SDK::AddressID_t, public BaseObj_t +{ + public: + virtual ~AddressID_t() {} + AddressID_t() : BaseObj_t(NULL), fileID(NOT_IN_DATABASE), virtual_offset(0) + { setBaseID(NOT_IN_DATABASE); } + AddressID_t(db_id_t myid, db_id_t myfileID, virtual_offset_t voff) : BaseObj_t(NULL), fileID(myfileID), virtual_offset(voff) + { setBaseID(myid); } + + AddressID_t& operator=(const AddressID_t &rhs) { + if (this != &rhs) + { + this->fileID = rhs.fileID; + this->virtual_offset = rhs.virtual_offset; + } + + return *this; + } + + db_id_t getFileID() const { return fileID; } + void setFileID(db_id_t thefileID) { fileID=thefileID; } + + virtual_offset_t getVirtualOffset() const { return virtual_offset; } + void setVirtualOffset(virtual_offset_t voff) { virtual_offset=voff; } + + std::vector<std::string> WriteToDB(File_t *vid, db_id_t newid, bool p_withHeader); + + bool operator<(const AddressID_t& cmp) const + { return fileID < cmp.fileID || (fileID == cmp.fileID && virtual_offset < cmp.virtual_offset);} + + bool operator!=(const AddressID_t& cmp) const + { return fileID != cmp.fileID || virtual_offset != cmp.virtual_offset; } + + + private: + db_id_t fileID; // The ID of the file + virtual_offset_t virtual_offset; // the virtual address(offset) into the file. + // May be 0 if this insn doesn't exist + // within a file. + + void Register(VariantID_t *vid); + +}; +} diff --git a/irdb-lib/libIRDB-core/include/archdesc.hpp b/irdb-lib/libIRDB-core/include/archdesc.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e7299d450190a189b6929b41a957db00170aba93 --- /dev/null +++ b/irdb-lib/libIRDB-core/include/archdesc.hpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +namespace libIRDB +{ + + +using ADFileType_t = IRDB_SDK::ADFileType_t; +using ADMachineType_t = IRDB_SDK::ADMachineType_t; + +class ArchitectureDescription_t : virtual public IRDB_SDK::ArchitectureDescription_t +{ + public: + + virtual ~ArchitectureDescription_t() {} + ArchitectureDescription_t() : bits(0), ft(IRDB_SDK::adftNone), mt(IRDB_SDK::admtNone) {} + + int getBitWidth() const { return bits; } + void setBitWidth(const int _bits) { bits=_bits; } + + ADFileType_t getFileType() const { return ft; } + void setFileType(const ADFileType_t t) { ft=t; } + + ADMachineType_t getMachineType() const { return mt; } + void setMachineType(const ADMachineType_t t) { mt=t; } + + private: + + size_t bits; + ADFileType_t ft; + ADMachineType_t mt; +}; + +} diff --git a/irdb-lib/libIRDB-core/include/baseobj.hpp b/irdb-lib/libIRDB-core/include/baseobj.hpp new file mode 100644 index 0000000000000000000000000000000000000000..00abd21a166fbd056a3dd73b026e90be7a24d4da --- /dev/null +++ b/irdb-lib/libIRDB-core/include/baseobj.hpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + + +namespace libIRDB +{ +using virtual_offset_t = IRDB_SDK::VirtualOffset_t; +using db_id_t = IRDB_SDK::DatabaseID_t; +using RelocationSet_t = IRDB_SDK::RelocationSet_t; + + +// A base class for something that all objects have, for now just a DOIP. +// see .cpp file for method descriptions. +class BaseObj_t : virtual public IRDB_SDK::BaseObj_t +{ + public: + virtual ~BaseObj_t() {} + BaseObj_t(doip_t* doip); + + // static void SetInterface(DBinterface_t *dbintr); + static DBinterface_t* GetInterface() {return dbintr;} + + // get and set the ID + db_id_t getBaseID() const {return base_id; } + db_id_t getDoipID() const { return doip ? doip->GetBaseID() : NOT_IN_DATABASE; } + void setDoipID(IRDB_SDK::Doip_t *dp) { doip=dynamic_cast<doip_t*>(dp); if(dp) assert(doip); } + void setBaseID(db_id_t id) {base_id=id; } + + virtual RelocationSet_t& GetRelocations() { return relocs; } + virtual const RelocationSet_t& getRelocations() const { return relocs; } + virtual void setRelocations(const RelocationSet_t& rels) { relocs=rels; } + + + protected: + static DBinterface_t *dbintr; + + private: + doip_t* doip; + db_id_t base_id; // -1 means not yet in the DB. + RelocationSet_t relocs; + + friend class IRDB_SDK::BaseObj_t; +}; + +} diff --git a/irdb-lib/libIRDB-core/include/basetypes.hpp b/irdb-lib/libIRDB-core/include/basetypes.hpp new file mode 100644 index 0000000000000000000000000000000000000000..16cd27493835113a7569bd0514fd22da7f8f8860 --- /dev/null +++ b/irdb-lib/libIRDB-core/include/basetypes.hpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +namespace libIRDB +{ + using virtual_offset_t = IRDB_SDK::VirtualOffset_t; + using db_id_t = IRDB_SDK::DatabaseID_t; + using schema_version_t = IRDB_SDK::SchemaVersionID_t; + + // forward decls + class AddressID_t; + class ArchitectureDescription_t; + class BaseObj_t; + class DatabaseError_t; + class DBinterface_t; + class Doip_t; + class EhProgram_t; + class EhCallSite_t; + class File_t; + class FileIR_t; + class Function_t; + class ICFS_t; + class Instruction_t; + class IRDBObjects_t; + class pqxxDB_t; + class Relocation_t; + class DataScoop_t; + class Type_t; + class BasicType_t; + class PointerType_t; + class AggregateType_t; + class FuncType_t; + class VariantID_t; + class DecodedInstructionDispatcher_t; + class DecodedOperandDispatcher_t; + +} diff --git a/irdb-lib/libIRDB-core/include/dbinterface.hpp b/irdb-lib/libIRDB-core/include/dbinterface.hpp new file mode 100644 index 0000000000000000000000000000000000000000..fb4836ab16fc3cc460de37d18ae189d90ef55d92 --- /dev/null +++ b/irdb-lib/libIRDB-core/include/dbinterface.hpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +namespace libIRDB +{ +using DatabaseErrorType_t = IRDB_SDK::DatabaseErrorType_t; + +class DatabaseError_t : virtual public IRDB_SDK::DatabaseError_t +{ + public: + virtual ~DatabaseError_t() { } + DatabaseError_t(DatabaseErrorType_t the_err) : err(the_err) {} + DatabaseErrorType_t GetErrorCode() const { return err; } + private: + DatabaseError_t::DatabaseErrorType_t err; +}; + +std::ostream& operator<<(std::ostream& output, const DatabaseError_t& p); + + +// an interface to a database +class DBinterface_t : virtual public IRDB_SDK::DBinterface_t +{ + public: + DBinterface_t() {}; + virtual ~DBinterface_t() {}; + virtual void issueQuery(std::string query)=0; + virtual void moveToNextRow()=0; + virtual std::string getResultColumn(std::string colname)=0; + virtual bool isDone()=0; + virtual void commit()=0; + +}; + +} diff --git a/irdb-lib/libIRDB-core/include/decode.hpp b/irdb-lib/libIRDB-core/include/decode.hpp new file mode 100644 index 0000000000000000000000000000000000000000..79bd8617f47f14d06db59b03894423b09e31c651 --- /dev/null +++ b/irdb-lib/libIRDB-core/include/decode.hpp @@ -0,0 +1,10 @@ + +namespace libIRDB +{ + +using DecodedInstruction_t = IRDB_SDK::DecodedInstruction_t; +using DecodedOperand_t = IRDB_SDK::DecodedOperand_t; +using DecodedOperandVector_t = IRDB_SDK::DecodedOperandVector_t; + +} + diff --git a/irdb-lib/libIRDB-core/include/decode_base.hpp b/irdb-lib/libIRDB-core/include/decode_base.hpp new file mode 100644 index 0000000000000000000000000000000000000000..5cbbcee821ef04a9cd55e5784b3e512eeb5d27c6 --- /dev/null +++ b/irdb-lib/libIRDB-core/include/decode_base.hpp @@ -0,0 +1,50 @@ +#if 0 +namespace libIRDB +{ + +using namespace libIRDB; +using namespace std; + +class DecodedOperandCapstone_t; + +class DecodedInstructionCapstone_t : virtual public IRDB_SDK::DecodedInstruction_t +{ + public: + virtual ~DecodedInstructionCapstone_t(){} + virtual string getDisassembly() const =0; + virtual bool valid() const =0; + virtual uint32_t length() const =0; + virtual bool isBranch() const =0; + virtual bool isCall() const =0; + virtual bool isUnconditionalBranch() const =0; + virtual bool isConditionalBranch() const =0; + virtual bool isReturn() const =0; + virtual string getMnemonic() const =0; + virtual int64_t getImmediate() const =0; + virtual virtual_offset_t getAddress() const =0; + virtual bool setsStackPointer() const =0; + virtual uint32_t getPrefixCount() const =0; + virtual bool hasRelevantRepPrefix() const =0; + virtual bool hasRelevantRepnePrefix() const =0; + virtual bool hasRelevantOperandSizePrefix() const =0; + virtual bool hasRexWPrefix() const =0; + virtual bool hasImplicitlyModifiedRegs() const =0; + virtual virtual_offset_t getMemoryDisplacementOffset(const IRDB_SDK::DecodedOperand_t& t, const Instruction_t* insn) const =0; + + // 0-based. first operand is numbered 0. + virtual bool hasOperand(const int op_num) const =0; + virtual shared_ptr<IRDB_SDK::DecodedOperand_t> getOperand(const int op_num) const =0; + virtual DecodedOperandVector_t getOperands() const =0; + + private: + + // static unique_ptr<DecodedInstructionCapstone_t> factory(const Instruction_t* i); + // static unique_ptr<DecodedInstructionCapstone_t> factory(const IRDB_SDK::VirtualOffset_t start_addr, const void *data, uint32_t max_len); + // static unique_ptr<DecodedInstructionCapstone_t> factory(const IRDB_SDK::VirtualOffset_t start_addr, const void *data, const void* endptr); + // friend class DecodedInstructionDispatcher_t; + +}; + +} + +#endif diff --git a/irdb-lib/libIRDB-core/include/decode_csarm.hpp b/irdb-lib/libIRDB-core/include/decode_csarm.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b517d7d04b0708e317ee4a3809680866ff67bfff --- /dev/null +++ b/irdb-lib/libIRDB-core/include/decode_csarm.hpp @@ -0,0 +1,72 @@ + +namespace libIRDB +{ + +using namespace libIRDB; +using namespace std; + +class DecodedOperandCapstoneARM64_t; +class DecodedInstructionCapstoneARM64_t : virtual public IRDB_SDK::DecodedInstruction_t +{ + public: + DecodedInstructionCapstoneARM64_t()=delete; + DecodedInstructionCapstoneARM64_t& operator=(const DecodedInstructionCapstoneARM64_t& copy); + + virtual ~DecodedInstructionCapstoneARM64_t(); + + virtual string getDisassembly() const override; + virtual bool valid() const override; + virtual uint32_t length() const override; + virtual bool isBranch() const override; + virtual bool isCall() const override; + virtual bool isUnconditionalBranch() const override; + virtual bool isConditionalBranch() const override; + virtual bool isReturn() const override; + virtual string getMnemonic() const override; + virtual int64_t getImmediate() const override; + virtual virtual_offset_t getAddress() const override; + virtual bool setsStackPointer() const override; + virtual uint32_t getPrefixCount() const override; + virtual bool hasRelevantRepPrefix() const override; + virtual bool hasRelevantRepnePrefix() const override; + virtual bool hasRelevantOperandSizePrefix() const override; + virtual bool hasRexWPrefix() const override; + virtual bool hasImplicitlyModifiedRegs() const override; + virtual IRDB_SDK::VirtualOffset_t getMemoryDisplacementOffset(const DecodedOperand_t* t, const IRDB_SDK::Instruction_t* insn) const override; + + // 0-based. first operand is numbered 0. + virtual bool hasOperand(const int op_num) const override; + virtual std::shared_ptr<DecodedOperand_t> getOperand(const int op_num) const override; + virtual DecodedOperandVector_t getOperands() const override; + + private: + + void Disassemble(const virtual_offset_t start_addr, const void *data, const uint32_t max_len); + + shared_ptr<void> my_insn; + + class CapstoneHandle_t + { + public: + CapstoneHandle_t(FileIR_t* firp=NULL); + inline unsigned long getHandle() { return handle; } + + private: + // csh handle; // this is the real type, but it's an alias and I don't want to export capstone values. + unsigned long handle; + }; + static CapstoneHandle_t *cs_handle; + + + friend class IRDB_SDK::DecodedInstruction_t; + friend class DecodedOperandCapstoneARM64_t; + + DecodedInstructionCapstoneARM64_t(const shared_ptr<void> &my_insn); + DecodedInstructionCapstoneARM64_t(const Instruction_t*); + DecodedInstructionCapstoneARM64_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len); + DecodedInstructionCapstoneARM64_t(const virtual_offset_t start_addr, const void *data, const void* endptr); + DecodedInstructionCapstoneARM64_t(const DecodedInstructionCapstoneARM64_t& copy); +}; + +} + diff --git a/irdb-lib/libIRDB-core/include/decode_csx86.hpp b/irdb-lib/libIRDB-core/include/decode_csx86.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c7e85d91bb308db2b3d637c5a1d5cc28dcff73ee --- /dev/null +++ b/irdb-lib/libIRDB-core/include/decode_csx86.hpp @@ -0,0 +1,72 @@ + +namespace libIRDB +{ + +using namespace libIRDB; +using namespace std; + +class DecodedOperandCapstoneX86_t; +class DecodedInstructionCapstoneX86_t : virtual public DecodedInstruction_t +{ + public: + DecodedInstructionCapstoneX86_t()=delete; + DecodedInstructionCapstoneX86_t& operator=(const DecodedInstructionCapstoneX86_t& copy); + + virtual ~DecodedInstructionCapstoneX86_t(); + + virtual string getDisassembly() const override; + virtual bool valid() const override; + virtual uint32_t length() const override; + virtual bool isBranch() const override; + virtual bool isCall() const override; + virtual bool isUnconditionalBranch() const override; + virtual bool isConditionalBranch() const override; + virtual bool isReturn() const override; + virtual string getMnemonic() const override; + virtual int64_t getImmediate() const override; + virtual virtual_offset_t getAddress() const override; + virtual bool setsStackPointer() const override; + virtual uint32_t getPrefixCount() const override; + virtual bool hasRelevantRepPrefix() const override; + virtual bool hasRelevantRepnePrefix() const override; + virtual bool hasRelevantOperandSizePrefix() const override; + virtual bool hasRexWPrefix() const override; + virtual bool hasImplicitlyModifiedRegs() const override; + virtual IRDB_SDK::VirtualOffset_t getMemoryDisplacementOffset(const DecodedOperand_t* t, const IRDB_SDK::Instruction_t* insn) const override; + + // 0-based. first operand is numbered 0. + virtual bool hasOperand(const int op_num) const override; + virtual std::shared_ptr<DecodedOperand_t> getOperand(const int op_num) const override; + virtual DecodedOperandVector_t getOperands() const override; + + private: + + void Disassemble(const virtual_offset_t start_addr, const void *data, const uint32_t max_len); + + shared_ptr<void> my_insn; + + class CapstoneHandle_t + { + public: + CapstoneHandle_t(FileIR_t* firp=NULL); + inline unsigned long getHandle() { return handle; } + + private: + // csh handle; // this is the real type, but it's an alias and I don't want to export capstone values. + unsigned long handle; + }; + static CapstoneHandle_t *cs_handle; + + + friend class DecodedInstruction_t; + friend class DecodedOperandCapstoneX86_t; + + DecodedInstructionCapstoneX86_t(const shared_ptr<void> &my_insn); + DecodedInstructionCapstoneX86_t(const Instruction_t*); + DecodedInstructionCapstoneX86_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len); + DecodedInstructionCapstoneX86_t(const virtual_offset_t start_addr, const void *data, const void* endptr); + DecodedInstructionCapstoneX86_t(const DecodedInstructionCapstoneX86_t& copy); +}; + +} + diff --git a/irdb-lib/libIRDB-core/include/decode_dispatch.hpp b/irdb-lib/libIRDB-core/include/decode_dispatch.hpp new file mode 100644 index 0000000000000000000000000000000000000000..491df5ca2ce2ff7daff7069a1a62cd23dee4f339 --- /dev/null +++ b/irdb-lib/libIRDB-core/include/decode_dispatch.hpp @@ -0,0 +1,55 @@ + +namespace libIRDB +{ + +using namespace libIRDB; +using namespace std; + +class DecodedOperandDispatcher_t; +typedef std::vector<DecodedOperandDispatcher_t> DecodedOperandMetaVector_t; + +class DecodedInstructionDispatcher_t : virtual public IRDB_SDK::DecodedInstruction_t +{ + public: + DecodedInstructionDispatcher_t()=delete; + DecodedInstructionDispatcher_t(const Instruction_t*); + DecodedInstructionDispatcher_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len); + DecodedInstructionDispatcher_t(const virtual_offset_t start_addr, const void *data, const void* endptr); + DecodedInstructionDispatcher_t(const DecodedInstructionDispatcher_t& copy); + DecodedInstructionDispatcher_t& operator=(const DecodedInstructionDispatcher_t& copy); + + virtual ~DecodedInstructionDispatcher_t(); + + string getDisassembly() const; + bool valid() const; + uint32_t length() const; + bool isBranch() const; + bool isCall() const; + bool isUnconditionalBranch() const; + bool isConditionalBranch() const; + bool isReturn() const; + string getMnemonic() const; + int64_t getImmediate() const; + virtual_offset_t getAddress() const; + bool setsStackPointer() const; + uint32_t getPrefixCount() const; + bool hasRelevantRepPrefix() const; + bool hasRelevantRepnePrefix() const; + bool hasRelevantOperandSizePrefix() const; + bool hasRexWPrefix() const; + bool hasImplicitlyModifiedRegs() const; + IRDB_SDK::VirtualOffset_t getMemoryDisplacementOffset(const IRDB_SDK::DecodedOperand_t* t, const IRDB_SDK::Instruction_t* insn) const; + + // 0-based. first operand is numbered 0. + bool hasOperand(const int op_num) const; + shared_ptr<IRDB_SDK::DecodedOperand_t> getOperand(const int op_num) const; + IRDB_SDK::DecodedOperandVector_t getOperands() const; + + private: + + std::shared_ptr<DecodedInstructionCapstone_t> cs; + +}; + +} + diff --git a/irdb-lib/libIRDB-core/include/doip.hpp b/irdb-lib/libIRDB-core/include/doip.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e379150cd7f9e00507714c5bab40f4166bf2a36b --- /dev/null +++ b/irdb-lib/libIRDB-core/include/doip.hpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +namespace libIRDB +{ + + +// The Digital Object Identifier for Peasoup. +class doip_t : virtual public IRDB_SDK::Doip_t +{ + public: + virtual ~doip_t(){} + doip_t(db_id_t did, int conf, std::string tool_name , std::string comment); + + db_id_t GetBaseID() const { return did; } + + private: + db_id_t did; + int confidence; + std::string tool_name; + std::string comment; +}; +} diff --git a/irdb-lib/libIRDB-core/include/eh.hpp b/irdb-lib/libIRDB-core/include/eh.hpp new file mode 100644 index 0000000000000000000000000000000000000000..77082ae522f1dcafd68ba4080ec539266f9f1f17 --- /dev/null +++ b/irdb-lib/libIRDB-core/include/eh.hpp @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2017 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +namespace libIRDB +{ +using EhProgramInstruction_t = IRDB_SDK::EhProgramInstruction_t; +using EhProgramListing_t = IRDB_SDK::EhProgramListing_t; +using EhProgramSet_t = IRDB_SDK::EhProgramSet_t; +using TTOrderVector_t = IRDB_SDK::TTOrderVector_t; +using EhCallSiteSet_t = IRDB_SDK::EhCallSiteSet_t; + +class EhProgram_t : public BaseObj_t, virtual public IRDB_SDK::EhProgram_t +{ + public: + + virtual ~EhProgram_t(){} + EhProgram_t(const EhProgram_t& orig) + : + BaseObj_t(NULL) + { + cie_program=orig.cie_program; + fde_program=orig.fde_program; + code_alignment_factor=orig.code_alignment_factor; + data_alignment_factor=orig.data_alignment_factor; + return_register=orig.return_register; + ptrsize=orig.ptrsize; + setBaseID(BaseObj_t::NOT_IN_DATABASE); + GetRelocations()=orig.getRelocations(); + + } + EhProgram_t(db_id_t id, const uint64_t caf, const int64_t daf, const uint8_t rr, const uint8_t p_ptrsize, + const EhProgramListing_t& ciep, const EhProgramListing_t& fdep) + : + BaseObj_t(NULL), + code_alignment_factor(caf), + data_alignment_factor(daf), + return_register(rr), + ptrsize(p_ptrsize) , + cie_program(ciep), + fde_program(fdep) + { + setBaseID(id); + } + + + EhProgramListing_t& GetCIEProgram() { return cie_program; } + const EhProgramListing_t& getCIEProgram() const { return cie_program; } + + EhProgramListing_t& GetFDEProgram() { return fde_program; } + const EhProgramListing_t& getFDEProgram() const { return fde_program; } + void setCIEProgram(const EhProgramListing_t& p) { cie_program=p; } + void setFDEProgram(const EhProgramListing_t& p) { fde_program=p; } + + + uint64_t getCodeAlignmentFactor() const { return code_alignment_factor; } + void setCodeAlignmentFactor(const uint64_t caf) + { + if ( ((uint8_t)caf) != caf ) throw std::logic_error(std::string()+"Invalid code alignment factor in call to "+__FUNCTION__); + code_alignment_factor=(uint8_t)caf; + } + + int64_t getDataAlignmentFactor() const { return data_alignment_factor; } + void setDataAlignmentFactor(const int64_t daf) + { + if ( (( int8_t)daf) != daf ) throw std::logic_error(std::string()+"Invalid datat alignment factor in call to "+__FUNCTION__); + data_alignment_factor=(int8_t)daf; + } + + int64_t getReturnRegNumber() const { return return_register; } + void setReturnRegNumber(const uint8_t rr) { return_register=rr; } + + std::vector<std::string> WriteToDB(File_t* fid); // writes to DB, ID is not -1. + + uint8_t getPointerSize() const { return ptrsize; } + + + friend bool operator<(const EhProgram_t&a, const EhProgram_t&b); + + void print() const; + + private: + + uint8_t code_alignment_factor; + int8_t data_alignment_factor; + int8_t return_register; + uint8_t ptrsize; // needed for interpreting programs + EhProgramListing_t cie_program; + EhProgramListing_t fde_program; + +}; +bool operator<(const EhProgram_t&a, const EhProgram_t&b); + + +class EhCallSite_t : public BaseObj_t, virtual public IRDB_SDK::EhCallSite_t +{ + public: + + virtual ~EhCallSite_t(){} + EhCallSite_t(const db_id_t id, const uint64_t enc=0, IRDB_SDK::Instruction_t* lp=NULL) : + BaseObj_t(NULL), + tt_encoding(enc), + landing_pad(lp) + { setBaseID(id); } + + uint64_t getTTEncoding() const { return tt_encoding; } + void setTTEncoding(const uint64_t p_tt) { tt_encoding=p_tt; } + + IRDB_SDK::Instruction_t* getLandingPad() const { return landing_pad; } + void setLandingPad(IRDB_SDK::Instruction_t* lp) { landing_pad=dynamic_cast<Instruction_t*>(lp); if(lp) assert(landing_pad); } + + bool getHasCleanup() const ; + void setHasCleanup(bool p_has_cleanup=true) ; + + TTOrderVector_t& GetTTOrderVector() { return ttov; } + const TTOrderVector_t& getTTOrderVector() const { return ttov; } + void setTTOrderVector(const TTOrderVector_t& p_ttov) { ttov=p_ttov; } + + std::string WriteToDB(File_t* fid); // writes to DB, ID is not -1. + + + private: + + uint64_t tt_encoding; + IRDB_SDK::Instruction_t* landing_pad; + TTOrderVector_t ttov; +}; + +} diff --git a/irdb-lib/libIRDB-core/include/file.hpp b/irdb-lib/libIRDB-core/include/file.hpp new file mode 100644 index 0000000000000000000000000000000000000000..da3db353a3bdd86e4a1d49ca3da90c1ed38fd2ca --- /dev/null +++ b/irdb-lib/libIRDB-core/include/file.hpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2014-2015 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +namespace libIRDB +{ +// An ELF file as represented by the DB +class File_t : public BaseObj_t, virtual public IRDB_SDK::File_t +{ + public: + virtual ~File_t(){} + // create new item. + File_t( const db_id_t &file_id, const db_id_t &orig_fid, const std::string &url, + const std::string &hash, const std::string &arch, const int &elfoid, + const std::string &atn, const std::string &ftn, const std::string &itn, + const std::string &icfs, const std::string &icfs_map, + const std::string &rtn, const std::string &typ, const std::string &scoop, + const std::string &ehpgms, const std::string &ehcss, + const db_id_t &doipid); + + File_t(db_id_t file_id) : BaseObj_t(NULL) { (void)file_id; assert(0);} // read from DB + void WriteToDB() { assert(0); } // writes to DB ID is not -1. + + std::string getAddressTableName() const { return address_table_name; } + std::string getFunctionTableName() const { return function_table_name; } + std::string getInstructionTableName() const { return instruction_table_name; } + std::string getICFSTableName() const { return icfs_table_name; } + std::string getICFSMapTableName() const { return icfs_map_table_name; } + std::string getRelocationsTableName() const { return relocs_table_name; } + std::string getTypesTableName() const { return types_table_name; } + std::string getScoopTableName() const { return scoop_table_name; } + std::string getEhProgramTableName() const { return ehpgm_table_name; } + std::string getEhCallSiteTableName() const { return ehcss_table_name; } + std::string getURL() const { return url; } + + void CreateTables(); + + int getELFOID() const { return elfoid; }; + db_id_t getFileID() const {return orig_fid; }; + + friend class FileIR_t; + friend class Function_t; + friend class AddressID_t; + friend class Instruction_t; + friend class VariantID_t; + friend class Relocation_t; + friend class Type_t; + friend class BasicType_t; + friend class PointerType_t; + friend class AggregateType_t; + friend class FuncType_t; + friend class ICFS_t; + friend class DataScoop_t; +// friend class IBTargets; + + private: + db_id_t orig_fid; + std::string url; + std::string hash; + std::string arch; + std::string address_table_name; + std::string function_table_name; + std::string instruction_table_name; + std::string icfs_table_name; + std::string icfs_map_table_name; + std::string relocs_table_name; + std::string types_table_name; + std::string scoop_table_name; + std::string ehpgm_table_name; + std::string ehcss_table_name; + int elfoid; +}; +} diff --git a/irdb-lib/libIRDB-core/include/fileir.hpp b/irdb-lib/libIRDB-core/include/fileir.hpp new file mode 100644 index 0000000000000000000000000000000000000000..17b9a9c5fb4d0c753cbbcd1881ac26da57fd8e02 --- /dev/null +++ b/irdb-lib/libIRDB-core/include/fileir.hpp @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +namespace libIRDB +{ + +using namespace std; +using FunctionSet_t = IRDB_SDK::FunctionSet_t; +using AddressSet_t = IRDB_SDK::AddressSet_t ; + +// A variant of a problem, this +// may be an original variant +// (i.e., and unmodified Variant) or a modified variant. +class FileIR_t : public BaseObj_t, virtual public IRDB_SDK::FileIR_t +{ + public: + + // Create a Variant from the database + FileIR_t(const VariantID_t &newprogid, File_t* fid=NULL); + virtual ~FileIR_t(); + + // DB operations + void writeToDB(std::ostream *verbose_logging=&std::cerr); + + // accessors and mutators in one + FunctionSet_t& GetFunctions() { return funcs; } + const FunctionSet_t& getFunctions() const { return funcs; } + + InstructionSet_t& GetInstructions() { return insns; } + const InstructionSet_t& getInstructions() const { return insns; } + + AddressSet_t& GetAddresses() { return addrs; } + const AddressSet_t& getAddresses() const { return addrs; } + + RelocationSet_t& GetRelocations() { return relocs; } + const RelocationSet_t& getRelocations() const { return relocs; } + + DataScoopSet_t& GetDataScoops() { return scoops; } + const DataScoopSet_t& getDataScoops() const { return scoops; } + + ICFSSet_t& GetAllICFS() { return icfs_set; } + const ICFSSet_t& getAllICFS() const { return icfs_set; } + + EhProgramSet_t& GetAllEhPrograms() { return eh_pgms; } + const EhProgramSet_t& getAllEhPrograms() const { return eh_pgms; } + + EhCallSiteSet_t& GetAllEhCallSites() { return eh_css; } + const EhCallSiteSet_t& getAllEhCallSites() const { return eh_css; } + + // generate the spri rules into the output file, fout. + void GenerateSPRI(std::ostream &fout, bool with_ilr=false); + + // generate spri, assume that orig_varirp is the original variant. + void GenerateSPRI(FileIR_t *orig_varirp, std::ostream &fout, bool with_ilr=false); + + void setBaseIDS(); + IRDB_SDK::DatabaseID_t getMaxBaseID() const; + + File_t* getFile() const { return fileptr; } + + // Used for modifying a large number of instructions. AssembleRegistry + // assembles the assembly isntructions for each registered instruction + // and clears the registry. RegisterAssembly registers the instruction + // to be assembled later. + void assembleRegistry(); + void registerAssembly(IRDB_SDK::Instruction_t *instr, string assembly); + void unregisterAssembly(IRDB_SDK::Instruction_t *instr); + string lookupAssembly(IRDB_SDK::Instruction_t *instr); + + //Needed for inserting assembly before an instruction. + //if orig is not registered, the function returns, otherwise + //the instruction/assembly mapping of orig->assembly is altered to + //updated->assembly + //removes the mapping for orig->assembly from the map. + void changeRegistryKey(IRDB_SDK::Instruction_t* orig, IRDB_SDK::Instruction_t* updated); + + void setArchitecture(); + + static void setArchitecture(const int width, const IRDB_SDK::ADMachineType_t mt); + // static const IRDB_SDK::ArchitectureDescription_t* getArchitecture() { return archdesc; } + + // Lookup a scoop by address + IRDB_SDK::DataScoop_t* findScoop(const IRDB_SDK::VirtualOffset_t &addr) const; + + void splitScoop(IRDB_SDK::DataScoop_t *tosplit, const IRDB_SDK::VirtualOffset_t &addr, size_t size, + IRDB_SDK::DataScoop_t* &before, IRDB_SDK::DataScoop_t* &containing, IRDB_SDK::DataScoop_t* &after, IRDB_SDK::DatabaseID_t *max_id=NULL); + + virtual IRDB_SDK::EhCallSite_t* addEhCallSite_t(IRDB_SDK::Instruction_t* for_insn, const uint64_t enc=0, IRDB_SDK::Instruction_t* lp=nullptr) ; + + virtual IRDB_SDK::Relocation_t* addNewRelocation( + IRDB_SDK::BaseObj_t* from_obj, + int32_t _offset, + string _type, + IRDB_SDK::BaseObj_t* p_wrt_obj=nullptr, + int32_t p_addend=0) ; + virtual EhProgram_t* addEhProgram( + IRDB_SDK::Instruction_t* insn=nullptr, + const uint64_t caf=1, + const int64_t daf=1, + const uint8_t rr=1, + const uint8_t p_ptrsize=8, + const EhProgramListing_t& p_cie_program={}, + const EhProgramListing_t& p_fde_program={} + ) ; + virtual IRDB_SDK::AddressID_t* addNewAddress(const IRDB_SDK::DatabaseID_t& myfileID, const IRDB_SDK::VirtualOffset_t& voff=0) ; + virtual IRDB_SDK::ICFS_t* addNewICFS ( + IRDB_SDK::Instruction_t* insn=nullptr, + const IRDB_SDK::InstructionSet_t& targets={}, + const IRDB_SDK::ICFSAnalysisStatus_t& status=IRDB_SDK::iasAnalysisIncomplete); + virtual IRDB_SDK::Instruction_t* addNewInstruction( + IRDB_SDK::AddressID_t* addr=nullptr, + IRDB_SDK::Function_t* func=nullptr, + const string& bits="", + const string& comment="user-added", + IRDB_SDK::AddressID_t* indTarg=nullptr); + + virtual IRDB_SDK::DataScoop_t* addNewDataScoop( + const string& p_name="user-added", + IRDB_SDK::AddressID_t* p_start=nullptr, + IRDB_SDK::AddressID_t* p_end=nullptr, + IRDB_SDK::Type_t* p_type=nullptr, + uint8_t p_permissions=0, + bool p_is_relro=false, + const string &p_contents="", + IRDB_SDK::DatabaseID_t id=BaseObj_t::NOT_IN_DATABASE); + + virtual void removeScoop(IRDB_SDK::DataScoop_t* s) ; + virtual void moveRelocation(IRDB_SDK::Relocation_t* reloc, IRDB_SDK::Instruction_t* from, IRDB_SDK::Instruction_t* to) ; + virtual IRDB_SDK::EhProgram_t* copyEhProgram(const IRDB_SDK::EhProgram_t& orig); + + virtual void setAllEhPrograms(const EhProgramSet_t& new_pgms) { eh_pgms=new_pgms; } + + + + + + + + private: + + static ArchitectureDescription_t *archdesc; + + #define ASM_REG_MAX_SIZE 500000 + + typedef std::map<Instruction_t*,string> registry_type; + + // a pointer to the original variants IR, NULL means not yet loaded. + FileIR_t* orig_variant_ir_p; + + registry_type assembly_registry; + + void ReadFromDB(); //accesses DB + + FunctionSet_t funcs; + InstructionSet_t insns; + AddressSet_t addrs; + RelocationSet_t relocs; + TypeSet_t types; + DataScoopSet_t scoops; + VariantID_t& progid; // Not owned by fileIR + ICFSSet_t icfs_set; + File_t* fileptr; // Owned by variant, not fileIR + EhProgramSet_t eh_pgms; + EhCallSiteSet_t eh_css; + + map<db_id_t,AddressID_t*> ReadAddrsFromDB(); + map<db_id_t,EhProgram_t*> ReadEhPgmsFromDB(); + + map<db_id_t,EhCallSite_t*> ReadEhCallSitesFromDB + ( + map<EhCallSite_t*,db_id_t> &unresolvedEhCssLandingPads + ); + + map<db_id_t,Function_t*> ReadFuncsFromDB + ( + map<db_id_t,AddressID_t*> &addrMap, + map<db_id_t,Type_t*> &typeMap, + map<Function_t*,db_id_t> &entry_points + ); + + map<db_id_t,DataScoop_t*> ReadScoopsFromDB + ( + map<db_id_t,AddressID_t*> &addrMap, + map<db_id_t,Type_t*> &typeMap + ); + + map<db_id_t,Instruction_t*> ReadInsnsFromDB + ( + const map<db_id_t,Function_t*> &funcMap, + const map<db_id_t,AddressID_t*> &addrMap, + const map<db_id_t,EhProgram_t*> &ehpgmMap, + const map<db_id_t,EhCallSite_t*> &ehcsMap, + map<db_id_t,Instruction_t*> &addressToInstructionMap, + map<Instruction_t*, db_id_t> &unresolvedICFS + ); + + void ReadRelocsFromDB + ( + map<db_id_t,BaseObj_t*> &insnMap + ); + + map<db_id_t, Type_t*> ReadTypesFromDB(TypeSet_t& types); + void ReadAllICFSFromDB(map<db_id_t,Instruction_t*> &addr2insnMap, + map<Instruction_t*, db_id_t> &unresolvedICFS); + + void CleanupICFS(ostream *verbose_logging=&cerr); + void GarbageCollectICFS(ostream *verbose_logging=&cerr); + void DedupICFS(ostream *verbose_logging=&cerr); + + + clock_t ReadIRDB_start; + clock_t ReadIRDB_end; + + friend IRDB_SDK::FileIR_t; + +}; + +} diff --git a/irdb-lib/libIRDB-core/include/function.hpp b/irdb-lib/libIRDB-core/include/function.hpp new file mode 100644 index 0000000000000000000000000000000000000000..50731fd873e70a9d116a535d0d108ec92299155a --- /dev/null +++ b/irdb-lib/libIRDB-core/include/function.hpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +namespace libIRDB +{ +// The basic Function of a variant. +class Function_t : public BaseObj_t, virtual public IRDB_SDK::Function_t +{ + public: + + virtual ~Function_t() {} + Function_t() : BaseObj_t(NULL) {} // create a new function not in the db + + // create a function that's already in the DB + Function_t(db_id_t id, std::string name, int size, int oa_size, bool use_fp, bool is_safe, IRDB_SDK::FuncType_t *, IRDB_SDK::Instruction_t *entry); + + InstructionSet_t& GetInstructions() { return my_insns; } + const InstructionSet_t& getInstructions() const { return my_insns; } + + const int getStackFrameSize() const { return stack_frame_size; } + const std::string& getName() const { return name; } + uint32_t getOutArgsRegionSize() const { return out_args_region_size; } + + void setStackFrameSize(int size) { stack_frame_size=size; } + void setName(std::string newname) { name=newname; } + void setOutArgsRegionSize(uint32_t oa_size) {out_args_region_size=oa_size;} + + void setEntryPoint(IRDB_SDK::Instruction_t *insn) { entry_point=dynamic_cast<Instruction_t*>(insn); if(insn) assert(entry_point); } + IRDB_SDK::Instruction_t* getEntryPoint() const { return entry_point;} + + std::string WriteToDB(File_t *fid, db_id_t newid); + + bool getUseFramePointer() const { return use_fp; } + void setUseFramePointer(bool useFP) { use_fp = useFP; } + + void setSafe(bool safe) { is_safe = safe; } + bool isSafe() const { return is_safe; } + + void setType(IRDB_SDK::FuncType_t *t) ; // { function_type = dynamic_cast<FuncType_t*>(t); if(t) assert(function_type); } + IRDB_SDK::FuncType_t* getType() const ; // { return function_type; } + + int getNumArguments() const; + + private: + Instruction_t *entry_point; + InstructionSet_t my_insns; + int stack_frame_size; + std::string name; + uint32_t out_args_region_size; + bool use_fp; + bool is_safe; + FuncType_t *function_type; +}; + +} diff --git a/irdb-lib/libIRDB-core/include/icfs.hpp b/irdb-lib/libIRDB-core/include/icfs.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c18efe782582386561d1a9b17df9156599367773 --- /dev/null +++ b/irdb-lib/libIRDB-core/include/icfs.hpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2014-2015 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +namespace libIRDB +{ +using InstructionSet_t = IRDB_SDK::InstructionSet_t; +using ICFS_Analysis_Status_t = IRDB_SDK::ICFSAnalysisStatus_t; +using ICFSSet_t = IRDB_SDK::ICFSSet_t; + +// these must match the allowed values for type icfs_analysis_result in Postgres DB +#define ICFS_ANALYSIS_INCOMPLETE_STR "icfs_analysis_incomplete" +#define ICFS_ANALYSIS_MODULE_COMPLETE_STR "icfs_analysis_module_complete" +#define ICFS_ANALYSIS_COMPLETE_STR "icfs_analysis_complete" + +// Keep track of instruction control flow sets +class ICFS_t : virtual public InstructionSet_t, public BaseObj_t, virtual public IRDB_SDK::ICFS_t +{ + public: + virtual ~ICFS_t(){} + ICFS_t(): BaseObj_t(NULL), m_icfs_analysis_status(IRDB_SDK::iasAnalysisIncomplete) {} + ICFS_t(const ICFS_Analysis_Status_t p_status) : BaseObj_t(NULL), m_icfs_analysis_status(p_status) {} + ICFS_t(db_id_t p_set_id, const ICFS_Analysis_Status_t p_status = IRDB_SDK::iasAnalysisIncomplete); + ICFS_t(db_id_t p_set_id, const std::string); + std::string WriteToDB(File_t *fid); + + + // this is bad -- you loose data with this operator=. + + void setTargets(const InstructionSet_t &other) + { + InstructionSet_t::operator=(other); + } + void addTargets(const InstructionSet_t &other) + { + insert(std::begin(other), std::end(other)); + } + + bool isIncomplete() const { + return getAnalysisStatus() == IRDB_SDK::iasAnalysisIncomplete; + } + + bool isComplete() const { + return getAnalysisStatus() == IRDB_SDK::iasAnalysisComplete; + } + + bool isModuleComplete() const { + return getAnalysisStatus() == IRDB_SDK::iasAnalysisModuleComplete; + } + + void setAnalysisStatus(const ICFS_Analysis_Status_t p_status) { + m_icfs_analysis_status = p_status; + } + + ICFS_Analysis_Status_t getAnalysisStatus() const { + return m_icfs_analysis_status; + } + + private: + ICFS_Analysis_Status_t m_icfs_analysis_status; +}; + +} diff --git a/irdb-lib/libIRDB-core/include/instruction.hpp b/irdb-lib/libIRDB-core/include/instruction.hpp new file mode 100644 index 0000000000000000000000000000000000000000..0a332983d156da80f52f9f2774dfe4a57a0a0b0b --- /dev/null +++ b/irdb-lib/libIRDB-core/include/instruction.hpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +namespace libIRDB +{ + +using RelocationSet_t = IRDB_SDK::RelocationSet_t; + +// The basic instruction of a variant. +class Instruction_t : public BaseObj_t, virtual public IRDB_SDK::Instruction_t +{ + public: + virtual ~Instruction_t(){} + Instruction_t(); + Instruction_t(db_id_t id, AddressID_t *addr, Function_t *func, db_id_t orig_id, + std::string data, std::string callback, std::string comment, AddressID_t *my_indTarg, db_id_t doip_id); + + IRDB_SDK::AddressID_t* getAddress() const { return my_address; } + IRDB_SDK::Function_t* getFunction() const ; // { return my_function; } + db_id_t getOriginalAddressID() const { return orig_address_id; } + IRDB_SDK::Instruction_t* getFallthrough() const { return fallthrough; } + IRDB_SDK::Instruction_t* getTarget() const { return target; } + IRDB_SDK::ICFS_t* getIBTargets() const { return icfs; } + + std::string getDataBits() const { return data; } + std::string getCallback() const { return callback; } + std::string getComment() const { return comment; } + IRDB_SDK::EhProgram_t* getEhProgram() const ; // { return eh_pgm; } + IRDB_SDK::EhCallSite_t* getEhCallSite() const ; // { return eh_cs; } + + + void setAddress(IRDB_SDK::AddressID_t* newaddr) ; // { my_address=newaddr; } + void setFunction(IRDB_SDK::Function_t* func ) ; // { my_function=func;} + void setOriginalAddressID(db_id_t origid) { orig_address_id=origid; /* you shouldn't do this, unless you know what you're doing! */} + void setFallthrough(IRDB_SDK::Instruction_t* i) ; // { fallthrough=i; } + void setTarget(IRDB_SDK::Instruction_t* i) ; // { target=i; } + void setIBTargets(IRDB_SDK::ICFS_t *p_icfs) ; // { icfs=p_icfs; } + void setDataBits(std::string orig) { data=orig; } + void setCallback(std::string orig) { callback=orig; } + void setComment(std::string orig) { comment=orig; } + void setEhProgram(IRDB_SDK::EhProgram_t* orig) ; // { eh_pgm=orig; } + void setEhCallSite(IRDB_SDK::EhCallSite_t* orig); // { eh_cs=orig; } + + IRDB_SDK::AddressID_t* getIndirectBranchTargetAddress() const; // { return indTarg; } + void setIndirectBranchTargetAddress(IRDB_SDK::AddressID_t* myIndTarg) ; // { indTarg=myIndTarg; } + + void WriteToDB() { assert(0); } + std::vector<std::string> WriteToDB(File_t *fid, db_id_t newid); + // int Disassemble(DISASM &d) const; + std::string getDisassembly() const; + bool assemble(std::string assembly); + + bool isFunctionExit() const; + + //static bool SetsStackPointer(DISASM *disasm); + //static bool SetsStackPointer(ARGTYPE* arg); + + bool IsSyscall() { return getDisassembly().find("int 0x80") != std::string::npos; } + + private: + AddressID_t* my_address; + Function_t* my_function; + db_id_t orig_address_id; // const, should not change. + Instruction_t* fallthrough; + Instruction_t* target; + std::string data; + std::string callback; // name of callback handler (if any) + std::string comment; + AddressID_t* indTarg; + ICFS_t* icfs; + EhProgram_t* eh_pgm; + EhCallSite_t* eh_cs; +}; +} diff --git a/irdb-lib/libIRDB-core/include/libIRDB-core.hpp b/irdb-lib/libIRDB-core/include/libIRDB-core.hpp new file mode 100644 index 0000000000000000000000000000000000000000..681d93a330914a1953761dee21fb246b913d08b4 --- /dev/null +++ b/irdb-lib/libIRDB-core/include/libIRDB-core.hpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef libIRDB_core +#define libIRDB_core + +#include <string> +#include <vector> +#include <set> +#include <assert.h> +#include <string.h> +#include <iostream> +#include <pqxx/pqxx> +#include <ctime> +#include <stdint.h> + +// include SDK +#include <irdb-core> + +#include <basetypes.hpp> +#include <dbinterface.hpp> +#include <doip.hpp> +#include <baseobj.hpp> +#include <reloc.hpp> +#include <address.hpp> +#include <icfs.hpp> +#include <instruction.hpp> +#include <file.hpp> +#include <function.hpp> +#include <variantid.hpp> +#include <archdesc.hpp> +#include <type.hpp> +#include <scoop.hpp> +#include <eh.hpp> +#include <fileir.hpp> +#include <pqxxdb.hpp> +#include <IRDB_Objects.hpp> +#include <transform_step.h> +#include <decode.hpp> + +int command_to_stream(const std::string& command, std::ostream& stream); + + +#endif diff --git a/irdb-lib/libIRDB-core/include/operand_base.hpp b/irdb-lib/libIRDB-core/include/operand_base.hpp new file mode 100644 index 0000000000000000000000000000000000000000..7c408fc3f96a55cac0e295a15a6ecbe4a564fa57 --- /dev/null +++ b/irdb-lib/libIRDB-core/include/operand_base.hpp @@ -0,0 +1,45 @@ +#if 0 +namespace libIRDB +{ + +using namespace std; +using namespace libIRDB; + + +class DecodedOperandCapstone_t : virtual public IRDB_SDK::DecodedOperand_t +{ + public: + virtual bool isConstant() const=0; + virtual uint64_t getConstant() const=0; + virtual string getString() const=0; + virtual bool isRegister() const=0; + virtual bool isGeneralPurposeRegister() const=0; + virtual bool isMmxRegister() const=0; + virtual bool isFpuRegister() const=0; + virtual bool isSseRegister() const=0; + virtual bool isAvxRegister() const=0; + virtual bool isZmmRegister() const=0; + virtual bool isSpecialRegister() const=0; + virtual bool isSegmentRegister() const=0; + virtual uint32_t getRegNumber() const=0; + virtual bool isMemory() const=0; + virtual bool hasSegmentRegister() const=0; + virtual uint32_t getSegmentRegister() const=0; + virtual bool hasBaseRegister() const=0; + virtual bool hasIndexRegister() const=0; + virtual uint32_t getBaseRegister() const=0; + virtual uint32_t getIndexRegister() const=0; + virtual bool hasMemoryDisplacement() const=0; + virtual virtual_offset_t getMemoryDisplacement() const=0; + virtual bool isPcrel() const=0; + virtual uint32_t getScaleValue() const=0; + virtual uint32_t getMemoryDisplacementEncodingSize() const=0; + virtual uint32_t getArgumentSizeInBytes() const=0; + virtual uint32_t getArgumentSizeInBits() const=0; + virtual bool isRead() const=0; + virtual bool isWritten() const=0; + +}; + +} +#endif diff --git a/irdb-lib/libIRDB-core/include/operand_csarm.hpp b/irdb-lib/libIRDB-core/include/operand_csarm.hpp new file mode 100644 index 0000000000000000000000000000000000000000..da26a2105ca45719f9262f9e0a9912939195e7fa --- /dev/null +++ b/irdb-lib/libIRDB-core/include/operand_csarm.hpp @@ -0,0 +1,57 @@ + +namespace libIRDB +{ + +using namespace std; +using namespace libIRDB; + +class DecodedOperandCapstoneARM64_t; + +class DecodedOperandCapstoneARM64_t : virtual public IRDB_SDK::DecodedOperand_t +{ + public: + DecodedOperandCapstoneARM64_t() =delete; + virtual ~DecodedOperandCapstoneARM64_t(); + + virtual bool isConstant() const override; + virtual uint64_t getConstant() const override; + virtual string getString() const override; + virtual bool isRegister() const override; + virtual bool isGeneralPurposeRegister() const override; + virtual bool isMmxRegister() const override; + virtual bool isFpuRegister() const override; + virtual bool isSseRegister() const override; + virtual bool isAvxRegister() const override; + virtual bool isZmmRegister() const override; + virtual bool isSpecialRegister() const override; + virtual bool isSegmentRegister() const override; + virtual uint32_t getRegNumber() const override; + virtual bool isMemory() const override; + virtual bool hasSegmentRegister() const override; + virtual uint32_t getSegmentRegister() const override; + virtual bool hasBaseRegister() const override; + virtual bool hasIndexRegister() const override; + virtual uint32_t getBaseRegister() const override; + virtual uint32_t getIndexRegister() const override; + virtual bool hasMemoryDisplacement() const override; + virtual virtual_offset_t getMemoryDisplacement() const override; + virtual bool isPcrel() const override; + virtual uint32_t getScaleValue() const override; + virtual uint32_t getMemoryDisplacementEncodingSize() const override; + virtual uint32_t getArgumentSizeInBytes() const override; + virtual uint32_t getArgumentSizeInBits() const override; + virtual bool isRead() const override; + virtual bool isWritten() const override; + + + private: + + DecodedOperandCapstoneARM64_t( const shared_ptr<void> &my_insn, uint8_t op_num); + + shared_ptr<void> my_insn; + uint8_t op_num; + + friend class DecodedInstructionCapstoneARM64_t; +}; + +} diff --git a/irdb-lib/libIRDB-core/include/operand_csx86.hpp b/irdb-lib/libIRDB-core/include/operand_csx86.hpp new file mode 100644 index 0000000000000000000000000000000000000000..2c2a250824843b0c151162d2bb330d070143cf74 --- /dev/null +++ b/irdb-lib/libIRDB-core/include/operand_csx86.hpp @@ -0,0 +1,58 @@ + +namespace libIRDB +{ + +using namespace std; +using namespace libIRDB; + +class DecodedInstructionCapstoneX86_t; + +class DecodedOperandCapstoneX86_t : virtual public IRDB_SDK::DecodedOperand_t +{ + public: + DecodedOperandCapstoneX86_t() =delete; + virtual ~DecodedOperandCapstoneX86_t(); + + virtual bool isConstant() const override; + virtual uint64_t getConstant() const override; + virtual string getString() const override; + virtual bool isRegister() const override; + virtual bool isGeneralPurposeRegister() const override; + virtual bool isMmxRegister() const override; + virtual bool isFpuRegister() const override; + virtual bool isSseRegister() const override; + virtual bool isAvxRegister() const override; + virtual bool isZmmRegister() const override; + virtual bool isSpecialRegister() const override; + virtual bool isSegmentRegister() const override; + virtual uint32_t getRegNumber() const override; + virtual bool isMemory() const override; + virtual bool hasSegmentRegister() const override; + virtual uint32_t getSegmentRegister() const override; + virtual bool hasBaseRegister() const override; + virtual bool hasIndexRegister() const override; + virtual uint32_t getBaseRegister() const override; + virtual uint32_t getIndexRegister() const override; + virtual bool hasMemoryDisplacement() const override; + virtual virtual_offset_t getMemoryDisplacement() const override; + virtual bool isPcrel() const override; + virtual uint32_t getScaleValue() const override; + virtual uint32_t getMemoryDisplacementEncodingSize() const override; + virtual uint32_t getArgumentSizeInBytes() const override; + virtual uint32_t getArgumentSizeInBits() const override; + virtual bool isRead() const override; + virtual bool isWritten() const override; + + + private: + + DecodedOperandCapstoneX86_t( const shared_ptr<void> &my_insn, uint8_t op_num); + + shared_ptr<void> my_insn; + uint8_t op_num; + + friend class DecodedInstructionCapstoneX86_t; + +}; + +} diff --git a/irdb-lib/libIRDB-core/include/operand_dispatch.hpp b/irdb-lib/libIRDB-core/include/operand_dispatch.hpp new file mode 100644 index 0000000000000000000000000000000000000000..7d7087668047338a912eb5ea7239fd15dfb05d0c --- /dev/null +++ b/irdb-lib/libIRDB-core/include/operand_dispatch.hpp @@ -0,0 +1,55 @@ +namespace libIRDB +{ + +using namespace std; +using namespace libIRDB; + + +class DecodedOperandDispatcher_t : virtual public IRDB_SDK::DecodedOperand_t +{ + public: + DecodedOperandDispatcher_t() =delete; + DecodedOperandDispatcher_t& operator=(const DecodedOperandDispatcher_t& copy); + DecodedOperandDispatcher_t(const DecodedOperandDispatcher_t& copy); + virtual ~DecodedOperandDispatcher_t(); + + bool isConstant() const; + uint64_t getConstant() const; + string getString() const; + bool isRegister() const; + bool isGeneralPurposeRegister() const; + bool isMmxRegister() const; + bool isFpuRegister() const; + bool isSseRegister() const; + bool isAvxRegister() const; + bool isSpecialRegister() const; + bool isSegmentRegister() const; + uint32_t getRegNumber() const; + bool isMemory() const; + bool hasSegmentRegister() const; + uint32_t getSegmentRegister() const; + bool hasBaseRegister() const; + bool hasIndexRegister() const; + uint32_t getBaseRegister() const; + uint32_t getIndexRegister() const; + bool hasMemoryDisplacement() const; + virtual_offset_t getMemoryDisplacement() const; + bool isPcrel() const; + uint32_t getScaleValue() const; + uint32_t getMemoryDisplacementEncodingSize() const; + uint32_t getArgumentSizeInBytes() const; + uint32_t getArgumentSizeInBits() const; + bool isRead() const; + bool isWritten() const; + + + private: + DecodedOperandDispatcher_t(const shared_ptr<DecodedOperandCapstone_t> in); + + std::shared_ptr<DecodedOperandCapstone_t> cs; + + friend class DecodedInstructionDispatcher_t; + +}; + +} diff --git a/irdb-lib/libIRDB-core/include/pqxxdb.hpp b/irdb-lib/libIRDB-core/include/pqxxdb.hpp new file mode 100644 index 0000000000000000000000000000000000000000..031bd635313ae1a7e1c950ea74387cd9e4d6ebbb --- /dev/null +++ b/irdb-lib/libIRDB-core/include/pqxxdb.hpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +namespace libIRDB +{ + + +class pqxxDB_t : public DBinterface_t, virtual public IRDB_SDK::pqxxDB_t +{ + public: + pqxxDB_t(); + virtual ~pqxxDB_t() override + { + // do nothing + }; + void issueQuery(std::string query); + void issueQuery(std::stringstream & query); + void moveToNextRow(); + std::string getResultColumn(std::string colname); + bool isDone(); + void commit(); + + pqxx::connection& getConnection() { return conn; } + pqxx::work& getTransaction() { return txn; } + + private: + pqxx::connection conn; + pqxx::work txn; + pqxx::result results; + pqxx::result::const_iterator results_iter; + +}; +} diff --git a/irdb-lib/libIRDB-core/include/reloc.hpp b/irdb-lib/libIRDB-core/include/reloc.hpp new file mode 100644 index 0000000000000000000000000000000000000000..bcd911010fee1e4309eb273fd797966c8fd1a537 --- /dev/null +++ b/irdb-lib/libIRDB-core/include/reloc.hpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +namespace libIRDB +{ + +// An ELF file as represented by the DB +class Relocation_t : public BaseObj_t, virtual public IRDB_SDK::Relocation_t +{ + public: + + // create new item. + virtual ~Relocation_t() {} + Relocation_t() : BaseObj_t(NULL), offset(0), wrt_obj(NULL), addend(0) {} // new reloc w/no data + + // a reloc read from the DB + Relocation_t(db_id_t reloc_id, int _offset, std::string _type, IRDB_SDK::BaseObj_t* p_wrt_obj=NULL, int32_t p_addend=0) : + BaseObj_t(NULL), offset(_offset), type(_type), wrt_obj(p_wrt_obj), addend(p_addend) { setBaseID(reloc_id); } + + + void WriteToDB() { assert(0); } // writes to DB ID is not -1. + std::vector<std::string> WriteToDB(File_t* fid, BaseObj_t* insn); // writes to DB, ID is not -1. + + void setOffset(int off) { offset=off;} + int getOffset() const { return offset; } + void setType(std::string ty) { type=ty;} + std::string getType() const { return type; } + + void setAddend(uint32_t p_addend) { addend=p_addend;} + uint32_t getAddend() const { return addend; } + + /* get and set "with respect to" field */ + void setWRT(IRDB_SDK::BaseObj_t* WRT) { wrt_obj=dynamic_cast<BaseObj_t*>(WRT); if(WRT) assert(wrt_obj); } + IRDB_SDK::BaseObj_t* getWRT() const { return wrt_obj; } + + friend class FileIR_t; + friend class Function_t; + friend class AddressID_t; + friend class Instruction_t; + friend class VariantID_t; + + private: + int offset; // how far into the instruction the relocation should be applied. + std::string type; // a string that describes the relocation type. + // possible values: 32-bit, pcrel + + IRDB_SDK::BaseObj_t* wrt_obj; + int32_t addend; +}; +} diff --git a/irdb-lib/libIRDB-core/include/scoop.hpp b/irdb-lib/libIRDB-core/include/scoop.hpp new file mode 100644 index 0000000000000000000000000000000000000000..1985de0c01a347e195b36d605fc9dde0620e7045 --- /dev/null +++ b/irdb-lib/libIRDB-core/include/scoop.hpp @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2016 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +namespace libIRDB +{ + +class DataScoopByAddressComp_t; + +class DataScoop_t : public BaseObj_t, virtual public IRDB_SDK::DataScoop_t +{ + + public: + DataScoop_t() + : + BaseObj_t(NULL), + name(), + start(NULL), + end(NULL), + type(NULL), + permissions(0), + is_relro(false), + contents() + {} + + DataScoop_t( libIRDB::db_id_t id, + std::string p_name, + libIRDB::AddressID_t* p_start, + libIRDB::AddressID_t* p_end, + libIRDB::Type_t* p_type, + int p_permissions, + bool p_is_relro, + const std::string &p_contents) + : + BaseObj_t(NULL), + name(p_name), + start(p_start), + end(p_end), + type(p_type), + permissions(p_permissions), + is_relro(p_is_relro), + contents(p_contents) + { + assert(start && end); + setBaseID(id); + } + + virtual ~DataScoop_t() { /* management of addresses and types is explicit */ } + + const std::string getName() const { return name; } + const std::string& getContents() const { return contents; } + std::string &getContents() { return contents; } + IRDB_SDK::AddressID_t* getStart() const { return start; } + IRDB_SDK::AddressID_t* getEnd() const { return end; } + IRDB_SDK::Type_t* getType() const { return type; } + IRDB_SDK::VirtualOffset_t getSize() const { assert(start && end); return end->getVirtualOffset() - start->getVirtualOffset() + 1 ; } + bool isReadable() const { return (permissions & permissions_r) == permissions_r; } + bool isWriteable() const { return (permissions & permissions_w) == permissions_w; }; + bool isExecuteable() const { return (permissions & permissions_x) == permissions_x; }; + bool isRelRo() const { return is_relro; }; + uint8_t getRawPerms() const { return permissions; } + void setRawPerms(int newperms) { permissions=newperms; } + + void setName(const std::string &n) { name=n; } + void setContents(const std::string &n) { contents=n; } + void setStart( IRDB_SDK::AddressID_t* addr) { assert(addr); start=dynamic_cast<AddressID_t*>(addr); assert(start); } + void setEnd ( IRDB_SDK::AddressID_t* addr) { assert(addr); end =dynamic_cast<AddressID_t*>(addr); assert(end ); } + void setType( IRDB_SDK::Type_t* t) { type=dynamic_cast<Type_t*>(t); } + + void setReadable() { permissions |= permissions_r; } + void setWriteable() { permissions |= permissions_w; } + void setExecuteable() { permissions |= permissions_x; } + void setRelRo() { is_relro = true; } + + void clearReadable() { permissions &= ~permissions_r; } + void clearWriteable() { permissions &= ~permissions_w; } + void clearExecuteable() { permissions &= ~permissions_x; } + void clearRelRo() { is_relro=false; } + + std::string WriteToDB(File_t *fid, db_id_t newid); + std::string WriteToDBRange(File_t *fid, db_id_t newid, int start, int end, std::string table_name); + + friend DataScoopByAddressComp_t; + + private: + const static int permissions_r=4; + const static int permissions_w=2; + const static int permissions_x=1; + + std::string name; + AddressID_t* start; + AddressID_t* end; + Type_t* type; + int permissions; + bool is_relro; + std::string contents; + + +}; + +class DataScoopByAddressComp_t { + public: + bool operator()(const DataScoop_t *lhs, const DataScoop_t *rhs) { + + if (!lhs || + !rhs || + !lhs->start || + !rhs->start + ) + throw std::logic_error("Cannot order scoops that have null elements."); + + return std::make_tuple(lhs->start->getVirtualOffset(), lhs) < + std::make_tuple(rhs->start->getVirtualOffset(), rhs); + } +}; + +using DataScoopSet_t = IRDB_SDK::DataScoopSet_t; +using DataScoopByAddressSet_t = std::set<DataScoop_t*, DataScoopByAddressComp_t>; + +} diff --git a/irdb-lib/libIRDB-core/include/transform_step.h b/irdb-lib/libIRDB-core/include/transform_step.h new file mode 100644 index 0000000000000000000000000000000000000000..7e6d40926b5d577d2fc61001834dde4a669c7424 --- /dev/null +++ b/irdb-lib/libIRDB-core/include/transform_step.h @@ -0,0 +1,32 @@ + + +namespace libIRDB +{ + class TransformStep_t : virtual public IRDB_SDK::TransformStep_t + { + public: + // Step names must be unique, allows arguments to + // be directed to their matching transform steps. + virtual std::string getStepName(void) const = 0; + + // Allows all steps to parse args before any step takes time to execute + virtual int parseArgs(const std::vector<std::string> step_args) + { + return 0; // success + } + + virtual int executeStep(IRDB_SDK::IRDBObjects_t *const irdb_objects) + { + return 0; // success + } + + virtual ~TransformStep_t(void) + { + // do nothing + } + }; +} + +extern "C" +std::shared_ptr<IRDB_SDK::TransformStep_t> GetTransformStep(void); + diff --git a/irdb-lib/libIRDB-core/include/type.hpp b/irdb-lib/libIRDB-core/include/type.hpp new file mode 100644 index 0000000000000000000000000000000000000000..da04eb8b8a8cc94e2a1f472ca484a47342c6fb2a --- /dev/null +++ b/irdb-lib/libIRDB-core/include/type.hpp @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +namespace libIRDB +{ +using IRDB_Type = IRDB_SDK::IRDBType_t; +using TypeSet_t = IRDB_SDK::TypeSet_t; +using TypeVector_t = IRDB_SDK::TypeVector_t; + +class Type_t : public BaseObj_t, virtual public IRDB_SDK::Type_t +{ + public: + Type_t() : BaseObj_t(NULL) { + typeID = IRDB_SDK::itUnknown; + } + Type_t(db_id_t dbid, IRDB_Type t, std::string n) : BaseObj_t(NULL) { + setBaseID(dbid); + typeID = t; + name = n; + } + virtual ~Type_t() {} + + virtual std::string WriteToDB(File_t *fid, db_id_t newid) = 0; + + std::string getName() const { return name; } + void setName(const std::string& newname) { name=newname; } + IRDB_Type getTypeID() const { return typeID; } + void setTypeID(IRDB_Type t) { typeID = t; } + + virtual bool isUnknownType() const { return typeID == IRDB_SDK::itUnknown; } + virtual bool isVariadicType() const { return typeID == IRDB_SDK::itVariadic; } + virtual bool isAggregateType() const { return typeID == IRDB_SDK::itAggregate; } + virtual bool isFuncType() const { return typeID == IRDB_SDK::itFunc; } + virtual bool isBasicType() const { return false; } + virtual bool isPointerType() const { return false; } + virtual bool isNumericType() const { return false; } + + private: + std::string name; + IRDB_Type typeID; +}; + +class BasicType_t : public Type_t, virtual public IRDB_SDK::BasicType_t +{ + public: + BasicType_t() : Type_t() {} + BasicType_t(db_id_t id, IRDB_Type type, std::string p_name) : Type_t(id, type, p_name) {} + virtual ~BasicType_t() {} + + virtual bool isBasicType() const { return true; } + virtual bool isNumericType() const; + + std::string WriteToDB(File_t *fid, db_id_t newid); +}; + +class PointerType_t : public Type_t, virtual public IRDB_SDK::PointerType_t +{ + public: + PointerType_t() : Type_t() { setTypeID(IRDB_SDK::itPointer); referentType = NULL; } + PointerType_t(db_id_t id, Type_t* ref, std::string p_name) : Type_t(id, IRDB_SDK::itPointer, p_name) { + setReferentType(ref); + } + virtual ~PointerType_t() {} + virtual bool isPointerType() const { return true; } + + IRDB_SDK::Type_t* getReferentType() const { return referentType; } + void setReferentType(IRDB_SDK::Type_t* r) { referentType = dynamic_cast<Type_t*>(r); if(r) assert(referentType); } + + std::string WriteToDB(File_t *fid, db_id_t newid); + + private: + Type_t* referentType; +}; + +class AggregateType_t : public Type_t, virtual public IRDB_SDK::AggregateType_t +{ + public: + AggregateType_t() : Type_t() { setTypeID(IRDB_SDK::itAggregate); } + AggregateType_t(db_id_t id, std::string p_name) : Type_t(id, IRDB_SDK::itAggregate, p_name) {} + virtual ~AggregateType_t() {} + virtual bool isAggregateType() const { return true; } + + void addAggregatedType(IRDB_SDK::Type_t *t, int pos); + virtual size_t getNumAggregatedTypes() const { return refTypes.size(); } + IRDB_SDK::Type_t* getAggregatedType(unsigned int pos) const { + return (pos < (unsigned int)refTypes.size()) ? refTypes.at(pos) : NULL; + } + + std::string toString() { + return getName(); + } + + std::string WriteToDB(File_t *fid, db_id_t newid); + + private: + TypeVector_t refTypes; +}; + +class FuncType_t : public Type_t, virtual public IRDB_SDK::FuncType_t +{ + public: + FuncType_t() : Type_t() { setTypeID(IRDB_SDK::itFunc); _init(); } + FuncType_t(db_id_t id, std::string p_name) : Type_t(id, IRDB_SDK::itFunc, p_name) { _init(); } + virtual ~FuncType_t() {} + + virtual bool isFuncType() const { return true; } + + std::string WriteToDB(File_t *fid, db_id_t newid); + + IRDB_SDK::Type_t* getReturnType() const { return returnType; } + void setReturnType(IRDB_SDK::Type_t *t) { returnType = dynamic_cast<Type_t*>(t); if(t) assert(returnType); } + IRDB_SDK::AggregateType_t* getArgumentsType() const { return argsType; } + void setArgumentsType(IRDB_SDK::AggregateType_t *t) { argsType = dynamic_cast<AggregateType_t*>(t); if(t) assert(argsType); } + + private: + void _init() { + returnType = NULL; + argsType = NULL; + } + + private: + Type_t* returnType; + AggregateType_t* argsType; +}; + +} diff --git a/irdb-lib/libIRDB-core/include/variantid.hpp b/irdb-lib/libIRDB-core/include/variantid.hpp new file mode 100644 index 0000000000000000000000000000000000000000..578ff647efbc08183a6677b00c8af65cc217a165 --- /dev/null +++ b/irdb-lib/libIRDB-core/include/variantid.hpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +namespace libIRDB +{ + +#define CURRENT_SCHEMA 2 + +using FileSet_t = IRDB_SDK::FileSet_t; + +class VariantID_t : public BaseObj_t, virtual public IRDB_SDK::VariantID_t +{ + public: + VariantID_t(); // create a Variant ID not in the database + VariantID_t(db_id_t pid); // read from the DB + ~VariantID_t(); // Deletes the File_t objects -- beware dangling File_t* in FileIR_t objects! + + bool isRegistered() const; + bool registerID(); // accesses DB + + IRDB_SDK::VariantID_t* clone(bool deep=true); // accesses DB + + void WriteToDB(); + + void DropFromDB(); + + const FileSet_t& getFiles() const { return files; } + + std::string getName() const { return name; } + void setName(std::string newname) { name=newname;} + + IRDB_SDK::File_t* getMainFile() const; + + + db_id_t getOriginalVariantID() const { return orig_pid;} + + void CloneFiles(FileSet_t& files); + File_t* CloneFile(File_t* fptr); + + private: + schema_version_t schema_ver; + db_id_t orig_pid; // matches pid if this is an "original" + // Variant and not a cloned variant. + + std::string name; + + void CreateTables(); // create the address, function and instruction tables + + FileSet_t files; + + void ReadFilesFromDB(); + +}; + + + + +} + diff --git a/irdb-lib/libIRDB-core/src/IRDB_Objects.cpp b/irdb-lib/libIRDB-core/src/IRDB_Objects.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f61feee43be90c3164841e9ac71232492526bd08 --- /dev/null +++ b/irdb-lib/libIRDB-core/src/IRDB_Objects.cpp @@ -0,0 +1,255 @@ +#include <map> +#include <libIRDB-core.hpp> +#include <irdb-util> +#include <utility> +#include <memory> +#include <algorithm> +#include <assert.h> + + +using namespace libIRDB; +using namespace std; + +#define ALLOF(a) begin(a),end(a) + + +IRDBObjects_t::~IRDBObjects_t() +{ + // All dynamically allocated DB objects + // are held as unique pointers and don't need to be + // explicitly deleted. +} + +IRDB_SDK::FileIR_t* IRDBObjects_t::addFileIR(const IRDB_SDK::DatabaseID_t variant_id, const IRDB_SDK::DatabaseID_t file_id) +{ + const auto it = file_IR_map.find(file_id); + + if(it == file_IR_map.end()) + { + return nullptr; + } + else + { + const auto the_file = (it->second).file; + auto& the_fileIR = (it->second).fileIR; + + if(the_fileIR == NULL) + { + assert(the_file != NULL); + + assert(variant_map.find(variant_id) != variant_map.end()); + const auto & the_variant = *(variant_map.at(variant_id).get()); + + the_fileIR = unique_ptr<FileIR_t>(new FileIR_t(the_variant, the_file)); + assert(the_fileIR != NULL); + } + + // make sure static variable is set in the calling module -- IMPORTANT + the_fileIR->setArchitecture(); + return the_fileIR.get(); + } +} + +int IRDBObjects_t::writeBackFileIR(const IRDB_SDK::DatabaseID_t file_id, ostream *verbose_logging) +{ + const auto it = file_IR_map.find(file_id); + + if(it == file_IR_map.end()) + return 1; + + const auto& the_file = (it->second).file; + assert(the_file != NULL); + + try + { + // cout<<"Writing changes for "<<the_file->getURL()<<endl; + // make sure static variable is set in the calling module -- IMPORTANT + const auto & the_fileIR = (it->second).fileIR; + the_fileIR->setArchitecture(); + the_fileIR->writeToDB(verbose_logging); + return 0; + } + catch (DatabaseError_t pnide) + { + cerr << "Unexpected database error: " << pnide << "file url: " << the_file->getURL() << endl; + return -1; + } + catch (...) + { + cerr << "Unexpected error file url: " << the_file->getURL() << endl; + return -1; + } + assert(0); // should not reach + +} + +void IRDBObjects_t::deleteFileIR(const IRDB_SDK::DatabaseID_t file_id) +{ + const auto it = file_IR_map.find(file_id); + + if(it == file_IR_map.end()) + return; + + auto& the_fileIR = (it->second).fileIR; + if(the_fileIR != NULL) + { + the_fileIR.reset(); + } +} + +bool IRDBObjects_t::filesAlreadyPresent(const FileSet_t& the_files) const +{ + // look for a missing file + const auto missing_file_it=find_if(ALLOF(the_files), [&](const IRDB_SDK::File_t* const f) + { + return (file_IR_map.find(f->getBaseID()) == file_IR_map.end()); + }); + + // return true if no files missing + return missing_file_it==the_files.end(); +} + +IRDB_SDK::VariantID_t* IRDBObjects_t::addVariant(const IRDB_SDK::DatabaseID_t variant_id) +{ + const auto var_it = variant_map.find(variant_id); + + if(var_it != variant_map.end()) + { + return (var_it->second).get(); + } + + variant_map[variant_id].reset(new VariantID_t(variant_id)); + auto the_variant = variant_map[variant_id].get(); + + assert(the_variant->isRegistered()==true); + // disallow variants that share shallow copies to both be read in + // to prevent desynchronization. + assert(!filesAlreadyPresent(the_variant->getFiles())); + + // add files + for(auto &curr_file : the_variant->getFiles()) + { + file_IR_map[curr_file->getBaseID()]=FileIRInfo_t(); + file_IR_map[curr_file->getBaseID()].file = dynamic_cast<File_t*>(curr_file); + } + + return the_variant; +} + + +int IRDBObjects_t::writeBackVariant(const IRDB_SDK::DatabaseID_t variant_id) +{ + const auto it = variant_map.find(variant_id); + + if(it == variant_map.end()) + return 1; + + try + { + // cout<<"Writing changes for variant "<<variant_id<<endl; + it->second->WriteToDB(); + return 0; + } + catch (DatabaseError_t pnide) + { + cerr << "Unexpected database error: " << pnide << "variant ID: " << variant_id << endl; + return -1; + } + catch (...) + { + cerr << "Unexpected error variant ID: " << variant_id << endl; + return -1; + } + assert(0); // unreachable. + +} + +void IRDBObjects_t::deleteVariant(const IRDB_SDK::DatabaseID_t variant_id) +{ + const auto var_it = variant_map.find(variant_id); + + if(var_it == variant_map.end()) + return; + + // remove files and file IRs + for(const auto file : var_it->second->getFiles()) + { + file_IR_map.erase(file->getBaseID()); + } + + // remove variant + variant_map.erase(variant_id); +} + +int IRDBObjects_t::writeBackAll(ostream *verbose_logging) +{ + int ret_status = 0; + + // Write back FileIRs + for(auto &file_pair : file_IR_map) + { + const int result = IRDBObjects_t::writeBackFileIR((file_pair.second.file)->getBaseID(), verbose_logging); + if(result != 0) + { + ret_status = -1; + } + } + + // Write back Variants + for(auto & variant_pair : variant_map) + { + const int result = IRDBObjects_t::writeBackVariant((variant_pair.second)->getBaseID()); + if(result != 0) + { + ret_status = -1; + } + } + return ret_status; +} + +void IRDBObjects_t::deleteAll(void) +{ + // Delete Variants (also deletes all files) + for( auto &variant_pair : variant_map) + { + IRDBObjects_t::deleteVariant((variant_pair.second)->getBaseID()); + } +} + +IRDB_SDK::pqxxDB_t* IRDBObjects_t::getDBInterface() const +{ + return pqxx_interface.get(); +} + +IRDB_SDK::pqxxDB_t* IRDBObjects_t::resetDBInterface() +{ + pqxx_interface.reset(new pqxxDB_t()); // Aborts if Commit() has not been called + BaseObj_t::setInterface(pqxx_interface.get()); + return pqxx_interface.get(); +} + + +void IRDBObjects_t::tidyIR(void) +{ + // Delete Variants (also deletes all files) + for( auto &variant_pair : file_IR_map) + { + const auto &file_ir_info = variant_pair.second; + auto fileIR=file_ir_info.fileIR.get(); + fileIR->assembleRegistry(); + fileIR->setBaseIDS(); + } +} + +void FileIR_t::moveRelocation(IRDB_SDK::Relocation_t* reloc, IRDB_SDK::Instruction_t* from, IRDB_SDK::Instruction_t* to) +{ + auto irdb_from=dynamic_cast<libIRDB::Instruction_t*>(from); + auto irdb_to =dynamic_cast<libIRDB::Instruction_t*>(to); + + irdb_to ->GetRelocations().insert(reloc); + irdb_from->GetRelocations().erase (reloc); + + + +} + diff --git a/irdb-lib/libIRDB-core/src/SConscript b/irdb-lib/libIRDB-core/src/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..a98b3d156e385fe8ccc4ceeb536ca852bcd7969f --- /dev/null +++ b/irdb-lib/libIRDB-core/src/SConscript @@ -0,0 +1,63 @@ +import os +import glob + +Import('env') +myenv=env.Clone() +myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) + + +libname="irdb-core" +files= ''' + address.cpp + baseobj.cpp + dbinterface.cpp + file.cpp + fileir.cpp + function.cpp + generate_spri.cpp + icfs.cpp + instruction.cpp + pqxxdb.cpp + type.cpp + scoop.cpp + variantid.cpp + eh.cpp + reloc.cpp + decode_csx86.cpp + operand_csx86.cpp + decode_csarm.cpp + operand_csarm.cpp + IRDB_Objects.cpp + decode_base.cpp +''' +unused_files=''' + decode_bea.cpp + operand_bea.cpp + ''' + +# bea engine listed for core components. + +cpppath=''' + . + $IRDB_SDK/include/ + $SECURITY_TRANSFORMS_HOME/include/ + $SECURITY_TRANSFORMS_HOME/libIRDB-core/include/ + $SECURITY_TRANSFORMS_HOME/libcapstone/include/capstone/ + ''' +libpath=''' + $SECURITY_TRANSFORMS_HOME/lib + ''' + +#globs=glob.glob(os.environ['SECURITY_TRANSFORMS_HOME']+'/libcapstone/zipr_unpack/*.o') + +myenv.Append(CCFLAGS=" -Wall -std=c++11 -fmax-errors=2 ") +myenv.Append(LIBPATH=libpath) + +myenv=myenv.Clone(CPPPATH=Split(cpppath)) +mylib=myenv.SharedLibrary(libname, Split(files), LIBS=Split("pqxx capstone")) + +install=myenv.Install("$SECURITY_TRANSFORMS_HOME/lib/", mylib) +Default(install) + +Return('install') + diff --git a/irdb-lib/libIRDB-core/src/SConstruct b/irdb-lib/libIRDB-core/src/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..b2e8e0ca9b3cfeb2a49f186cdc49b783f79c5adb --- /dev/null +++ b/irdb-lib/libIRDB-core/src/SConstruct @@ -0,0 +1,9 @@ + + + +env=Environment() +Export('env') +lib=SConscript("SConscript") + +Return('lib') + diff --git a/irdb-lib/libIRDB-core/src/address.cpp b/irdb-lib/libIRDB-core/src/address.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cb5bb7ebb755a51270bf2145f2b894aff2c1207d --- /dev/null +++ b/irdb-lib/libIRDB-core/src/address.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +#include <all.hpp> +#include <irdb-util> +#include <stdlib.h> + +using namespace libIRDB; +using namespace std; + + +vector<string> AddressID_t::WriteToDB(File_t *fid, db_id_t newid, bool p_withHeader) +{ + assert(fid); + + if(getBaseID()==NOT_IN_DATABASE) + setBaseID(newid); + +/* + string q; + if (p_withHeader) + q=string("insert into ")+fid->address_table_name + + string("(address_id , file_id , vaddress_offset , doip_id)") + + string(" values "); + else + q = ","; + + q += +*/ + return { + to_string(getBaseID()), + to_string(fileID), + to_string(virtual_offset), + to_string(getDoipID()) + }; + +} + diff --git a/irdb-lib/libIRDB-core/src/all.hpp b/irdb-lib/libIRDB-core/src/all.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ec6b27114c86012d806295c583494384ad7dd980 --- /dev/null +++ b/irdb-lib/libIRDB-core/src/all.hpp @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <libIRDB-core.hpp> +using namespace libIRDB; diff --git a/irdb-lib/libIRDB-core/src/baseobj.cpp b/irdb-lib/libIRDB-core/src/baseobj.cpp new file mode 100644 index 0000000000000000000000000000000000000000..90cef65fdb8e19e1a20240f196cea48ca6633050 --- /dev/null +++ b/irdb-lib/libIRDB-core/src/baseobj.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +#include <all.hpp> + + +/* + * initialize the DB interface + */ +DBinterface_t* BaseObj_t::dbintr=nullptr; +const db_id_t IRDB_SDK::BaseObj_t::NOT_IN_DATABASE=-1; + +/* + * BaseObj_t constructor + */ +BaseObj_t::BaseObj_t(doip_t* _doip) : doip(_doip), base_id(BaseObj_t::NOT_IN_DATABASE) +{ +} + + +/* + * Set the database interface to be used for the base object class. + */ +void IRDB_SDK::BaseObj_t::setInterface(IRDB_SDK::DBinterface_t *dbi) +{ + ::libIRDB::BaseObj_t::dbintr=dynamic_cast<libIRDB::DBinterface_t*>(dbi); + assert(::libIRDB::BaseObj_t::dbintr); +} + diff --git a/irdb-lib/libIRDB-core/src/dbinterface.cpp b/irdb-lib/libIRDB-core/src/dbinterface.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f408adb289669812df763c1ea5bdb82eebef7acf --- /dev/null +++ b/irdb-lib/libIRDB-core/src/dbinterface.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +#include <all.hpp> +#include <iostream> +#include <stdlib.h> + +using namespace std; + +ostream& libIRDB::operator<<(ostream& output, const libIRDB::DatabaseError_t& p) +{ + switch(p.GetErrorCode()) + { + case DatabaseError_t::VariantTableNotRegistered: + output<<"Error accessing variant_info table"; + break; + case DatabaseError_t::VariantNotInDatabase: + output<<"Variant not detected in database"; + break; + default: + output<<"Cannot print database error code."; + break; + } + return output; +} + +ostream& IRDB_SDK::operator<<(ostream& output, const IRDB_SDK::DatabaseError_t& p) +{ + const auto p_p = &p; + const auto real_p=dynamic_cast<const libIRDB::DatabaseError_t* const>(p_p); + assert(real_p); + output << *real_p; + return output; +} + diff --git a/irdb-lib/libIRDB-core/src/decode_base.cpp b/irdb-lib/libIRDB-core/src/decode_base.cpp new file mode 100644 index 0000000000000000000000000000000000000000..25e996b556c895ec1755e67804667818d5d279c3 --- /dev/null +++ b/irdb-lib/libIRDB-core/src/decode_base.cpp @@ -0,0 +1,43 @@ + +#include <libIRDB-core.hpp> +#include <decode_base.hpp> +#include <operand_base.hpp> +#include <decode_csx86.hpp> +#include <operand_csx86.hpp> +#include <decode_csarm.hpp> +#include <operand_csarm.hpp> +#include <exception> + +using namespace std; +using namespace libIRDB; + + +unique_ptr<IRDB_SDK::DecodedInstruction_t> IRDB_SDK::DecodedInstruction_t::factory(const IRDB_SDK::Instruction_t* p_i) +{ + const auto i=dynamic_cast<const libIRDB::Instruction_t*>(p_i); + assert(i); + auto op=IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtAarch64 ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneARM64_t(i) : + IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtX86_64 ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneX86_t (i) : + IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtI386 ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneX86_t (i) : + throw invalid_argument("Unknown machine type"); + return unique_ptr<DecodedInstruction_t>(op); +} + +unique_ptr<IRDB_SDK::DecodedInstruction_t> IRDB_SDK::DecodedInstruction_t::factory(const IRDB_SDK::VirtualOffset_t start_addr, const void *data, uint32_t max_len) +{ + auto op=IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtAarch64 ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneARM64_t(start_addr,data,max_len) : + IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtX86_64 ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneX86_t (start_addr,data,max_len) : + IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtI386 ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneX86_t (start_addr,data,max_len) : + throw invalid_argument("Unknown machine type"); + return unique_ptr<DecodedInstruction_t>(op); +} + +unique_ptr<IRDB_SDK::DecodedInstruction_t> IRDB_SDK::DecodedInstruction_t::factory(const IRDB_SDK::VirtualOffset_t start_addr, const void *data, const void* endptr) +{ + auto op=IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtAarch64 ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneARM64_t(start_addr,data,endptr) : + IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtX86_64 ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneX86_t (start_addr,data,endptr) : + IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtI386 ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneX86_t (start_addr,data,endptr) : + throw invalid_argument("Unknown machine type"); + return unique_ptr<DecodedInstruction_t>(op); +} + diff --git a/irdb-lib/libIRDB-core/src/decode_csarm.cpp b/irdb-lib/libIRDB-core/src/decode_csarm.cpp new file mode 100644 index 0000000000000000000000000000000000000000..497d92b2abdfc0f5d903baac223fc2e388b1253a --- /dev/null +++ b/irdb-lib/libIRDB-core/src/decode_csarm.cpp @@ -0,0 +1,364 @@ + +#include <libIRDB-core.hpp> +#include <decode_base.hpp> +#include <decode_csarm.hpp> +#include <operand_base.hpp> +#include <operand_csarm.hpp> + + +#include <capstone.h> +#include <arm64.h> +#include <string> +#include <functional> +#include <set> +#include <algorithm> +#include <stdexcept> + +using namespace libIRDB; +using namespace std; + +#define ALLOF(a) begin(a),end(a) +static const auto ARM64_REG_PC=(arm64_reg)(ARM64_REG_ENDING+1); + + +DecodedInstructionCapstoneARM64_t::CapstoneHandle_t* DecodedInstructionCapstoneARM64_t::cs_handle=NULL ; + +DecodedInstructionCapstoneARM64_t::CapstoneHandle_t::CapstoneHandle_t(FileIR_t* firp) +{ + const auto mode = CS_MODE_LITTLE_ENDIAN; + static_assert(sizeof(csh)==sizeof(handle), "Capstone handle size is unexpected. Has CS changed?"); + auto err = cs_open(CS_ARCH_ARM64, mode, (csh*)&handle); + + if (err) + { + const auto s=string("Failed on cs_open() with error returned: ")+to_string(err)+"\n"; + throw std::runtime_error(s); + } + cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); + cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_INTEL); + + +} + + + + +static bool isPartOfGroup(const cs_insn* the_insn, const arm64_insn_group the_grp) +{ + const auto grp_it=find(ALLOF(the_insn->detail->groups), the_grp); + return grp_it!=end(the_insn->detail->groups); + +} + +static bool isJmp(cs_insn* the_insn) +{ + return isPartOfGroup(the_insn,ARM64_GRP_JUMP); +} + + +template<class type> +static inline type insnToImmedHelper(cs_insn* the_insn, csh handle) +{ + const auto count = cs_op_count(handle, the_insn, ARM64_OP_IMM); + const auto arm = &(the_insn->detail->arm64); + + if (count==0) + return 0; /* no immediate is the same as an immediate of 0, i guess? */ + else if (count==1) + { + const auto index = cs_op_index(handle, the_insn, ARM64_OP_IMM, 1); + return arm->operands[index].imm; + } + else + throw std::logic_error(string("Called ")+__FUNCTION__+" with number of immedaites not equal 1"); +} + + + +// shared code +// constructors, destructors, operators. + +void DecodedInstructionCapstoneARM64_t::Disassemble(const virtual_offset_t start_addr, const void *data, const uint32_t max_len) +{ + using namespace std::placeholders; + auto insn=cs_malloc(cs_handle->getHandle()); + auto address=(uint64_t)start_addr; + auto size=(size_t)max_len; + const uint8_t* code=(uint8_t*)data; + const auto ok = cs_disasm_iter(cs_handle->getHandle(), &code, &size, &address, insn); + if(!ok) + insn->size=0; + + auto &op0 = (insn->detail->arm64.operands[0]); // might change these. + auto &op1 = (insn->detail->arm64.operands[1]); + + const auto mnemonic=string(insn->mnemonic); + const auto is_ldr_type = mnemonic=="ldr" || mnemonic=="ldrsw" ; + if(is_ldr_type && op1.type==ARM64_OP_IMM) + { + // no, this is a pcrel load. + const auto imm=op1.imm; + op1.type=ARM64_OP_MEM; + op1.mem.base=ARM64_REG_PC; + op1.mem.index=ARM64_REG_INVALID; + op1.mem.disp=imm; + } + if(mnemonic=="prfm" && op0.type==ARM64_OP_IMM) + { + // no, this is a pcrel load. + const auto imm=op0.imm; + op0.type=ARM64_OP_MEM; + op0.mem.base=ARM64_REG_PC; + op0.mem.index=ARM64_REG_INVALID; + op0.mem.disp=imm; + } + + + const auto cs_freer=[](cs_insn * insn) -> void + { + cs_free(insn,1); + } ; + my_insn.reset(insn,cs_freer); +} + +DecodedInstructionCapstoneARM64_t::DecodedInstructionCapstoneARM64_t(const Instruction_t* i) +{ + if(!cs_handle) cs_handle=new CapstoneHandle_t(NULL); + if(!i) throw std::invalid_argument("No instruction given to DecodedInstruction_t(Instruction_t*)"); + + const auto length=i->getDataBits().size(); + const auto &databits=i->getDataBits(); + const auto data=databits.data(); + const auto address=i->getAddress()->getVirtualOffset(); + Disassemble(address,data,length); + + if(!valid()) throw std::invalid_argument("The Instruction_t::getDataBits field is not a valid instruction."); +} + +DecodedInstructionCapstoneARM64_t::DecodedInstructionCapstoneARM64_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len) +{ + if(!cs_handle) cs_handle=new CapstoneHandle_t(NULL); + Disassemble(start_addr, data, max_len); +} + +DecodedInstructionCapstoneARM64_t::DecodedInstructionCapstoneARM64_t(const virtual_offset_t start_addr, const void *data, const void* endptr) +{ + if(!cs_handle) cs_handle=new CapstoneHandle_t(NULL); + const auto length=(char*)endptr-(char*)data; + Disassemble(start_addr,data,length); +} + +DecodedInstructionCapstoneARM64_t::DecodedInstructionCapstoneARM64_t(const DecodedInstructionCapstoneARM64_t& copy) +{ + *this=copy; +} + +DecodedInstructionCapstoneARM64_t::DecodedInstructionCapstoneARM64_t(const shared_ptr<void> &p_my_insn) + : my_insn(p_my_insn) +{ +} + +DecodedInstructionCapstoneARM64_t::~DecodedInstructionCapstoneARM64_t() +{ + // no need to cs_free(my_insn) because shared pointer will do that for us! +} + +DecodedInstructionCapstoneARM64_t& DecodedInstructionCapstoneARM64_t::operator=(const DecodedInstructionCapstoneARM64_t& copy) +{ + my_insn=copy.my_insn; + return *this; +} + +// public methods + +string DecodedInstructionCapstoneARM64_t::getDisassembly() const +{ + + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + auto full_str=getMnemonic()+" "+the_insn->op_str; + + return full_str; +} + +bool DecodedInstructionCapstoneARM64_t::valid() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + return the_insn->size!=0; +} + +uint32_t DecodedInstructionCapstoneARM64_t::length() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + return the_insn->size; +} + +bool DecodedInstructionCapstoneARM64_t::isBranch() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + return isCall() || isReturn() || isJmp(the_insn); +} + +bool DecodedInstructionCapstoneARM64_t::isCall() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + + const auto mnemonic=getMnemonic(); + return mnemonic=="bl" || mnemonic=="blr"; +} + +bool DecodedInstructionCapstoneARM64_t::isUnconditionalBranch() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + + return isJmp(the_insn) && + (getMnemonic()=="b" || getMnemonic()=="br"); +} + +bool DecodedInstructionCapstoneARM64_t::isConditionalBranch() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + return isJmp(the_insn) && !isUnconditionalBranch(); +} + +bool DecodedInstructionCapstoneARM64_t::isReturn() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + return isPartOfGroup(the_insn,ARM64_GRP_RET); +} + +bool DecodedInstructionCapstoneARM64_t::hasOperand(const int op_num) const +{ + if(op_num<0) throw std::logic_error(string("Called ")+ __FUNCTION__+" with opnum="+to_string(op_num)); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &arm = (the_insn->detail->arm64); + return 0 <= op_num && op_num < arm.op_count; +} + +// 0-based. first operand is numbered 0. +shared_ptr<DecodedOperand_t> DecodedInstructionCapstoneARM64_t::getOperand(const int op_num) const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + if(!hasOperand(op_num)) throw std::logic_error(string("Called ")+__FUNCTION__+" on without hasOperand()==true"); + + return shared_ptr<DecodedOperand_t>(new DecodedOperandCapstoneARM64_t(my_insn,(uint8_t)op_num)); + +} + +DecodedOperandVector_t DecodedInstructionCapstoneARM64_t::getOperands() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &arm = (the_insn->detail->arm64); + const auto opcount=arm.op_count; + + auto ret_val=DecodedOperandVector_t(); + + for(auto i=0;i<opcount;i++) + ret_val.push_back(getOperand(i)); + + return ret_val; +} + +string DecodedInstructionCapstoneARM64_t::getMnemonic() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + + // return the new string. + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + return the_insn->mnemonic; + + +} + + +int64_t DecodedInstructionCapstoneARM64_t::getImmediate() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + + // direct calls and jumps have a "immediate" which is really an address" those are returned by getAddress + if(isCall() || isJmp(the_insn)) + return 0; + + return insnToImmedHelper<int64_t>(the_insn, cs_handle->getHandle()); +} + + +virtual_offset_t DecodedInstructionCapstoneARM64_t::getAddress() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + if(isCall() || isJmp(the_insn)) + { + const auto mnemonic=getMnemonic(); + if( mnemonic=="tbnz" || mnemonic=="tbz") + return getOperand(2)->getConstant(); + return insnToImmedHelper<int64_t>(the_insn, cs_handle->getHandle()); + } + assert(0); + +} + + +bool DecodedInstructionCapstoneARM64_t::setsStackPointer() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + + if(!hasOperand(0)) return false; + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &arm = (the_insn->detail->arm64); + return (arm.operands[0].type==ARM64_OP_REG && arm.operands[0].reg==ARM64_REG_SP); +} + +uint32_t DecodedInstructionCapstoneARM64_t::getPrefixCount() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + return 0; +} + +IRDB_SDK::VirtualOffset_t DecodedInstructionCapstoneARM64_t::getMemoryDisplacementOffset(const IRDB_SDK::DecodedOperand_t* t, const IRDB_SDK::Instruction_t* insn) const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + assert(0); +} + + + +bool DecodedInstructionCapstoneARM64_t::hasRelevantRepPrefix() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + return false; +} + +bool DecodedInstructionCapstoneARM64_t::hasRelevantRepnePrefix() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + return false; +} + +bool DecodedInstructionCapstoneARM64_t::hasRelevantOperandSizePrefix() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + return false; +} + +bool DecodedInstructionCapstoneARM64_t::hasRexWPrefix() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + return false; +} + +bool DecodedInstructionCapstoneARM64_t::hasImplicitlyModifiedRegs() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + return false; +} + diff --git a/irdb-lib/libIRDB-core/src/decode_csx86.cpp b/irdb-lib/libIRDB-core/src/decode_csx86.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c261c069e16dfca79dc32f723d2b53337adb4f31 --- /dev/null +++ b/irdb-lib/libIRDB-core/src/decode_csx86.cpp @@ -0,0 +1,712 @@ + +#include <libIRDB-core.hpp> +#include <decode_base.hpp> +#include <decode_csx86.hpp> +#include <operand_base.hpp> +#include <operand_csx86.hpp> + +#include <capstone.h> +#include <x86.h> +#include <string> +#include <functional> +#include <set> +#include <algorithm> +#include <stdexcept> + +using namespace libIRDB; +using namespace std; + +#define ALLOF(a) begin(a),end(a) + + + +DecodedInstructionCapstoneX86_t::CapstoneHandle_t* DecodedInstructionCapstoneX86_t::cs_handle=NULL ; + +DecodedInstructionCapstoneX86_t::CapstoneHandle_t::CapstoneHandle_t(FileIR_t* firp) +{ + const auto width=FileIR_t::getArchitectureBitWidth(); + const auto mode = (width==64) ? CS_MODE_64: CS_MODE_32; + static_assert(sizeof(csh)==sizeof(handle), "Capstone handle size is unexpected. Has CS changed?"); + auto err = cs_open(CS_ARCH_X86, mode, (csh*)&handle); + + if (err) + { + const auto s=string("Failed on cs_open() with error returned: ")+to_string(err)+"\n"; + throw std::runtime_error(s); + } + cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); + cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_INTEL); + + +} + + + +typedef struct special_instruction special_instruction_t; +struct special_instruction +{ + string binary; + string mnemonic; + string operands; +}; + +vector<special_instruction_t> cs_special_instructions= + { + {"\xdf\xc0", "ffreep", "st0"} + }; + + +// static helpers +static inline bool hasPrefix(const cs_insn* the_insn, const x86_prefix desired_pref) +{ + const auto count=count_if(ALLOF(the_insn->detail->x86.prefix), [&](const uint8_t actual_pref) { return actual_pref==desired_pref; } ) ; + return count!=0; +} + +static bool isPartOfGroup(const cs_insn* the_insn, const x86_insn_group the_grp) +{ + const auto grp_it=find(ALLOF(the_insn->detail->groups), the_grp); + return grp_it!=end(the_insn->detail->groups); + +} + +static bool isJmp(cs_insn* the_insn) +{ + return isPartOfGroup(the_insn,X86_GRP_JUMP); +} + +#if 0 +class CapstoneHandle_t +{ + public: + CapstoneHandle_t(FileIR_t* firp=NULL) + { + + const auto width=FileIR_t::getArchitectureBitWidth(); + const auto mode = (width==64) ? CS_MODE_64: CS_MODE_32; + auto err = cs_open(CS_ARCH_X86, mode, &handle); + + if (err) + { + const auto s=string("Failed on cs_open() with error returned: ")+to_string(err)+"\n"; + throw std::runtime_error(s); + } + cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); + cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_INTEL); + + + } + inline csh getHandle() { return handle; } + + private: + csh handle; +}; +static CapstoneHandle_t *cs_handle=NULL; +#endif + +template<class type> +static inline type insnToImmedHelper(cs_insn* the_insn, csh handle) +{ + const auto count = cs_op_count(handle, the_insn, X86_OP_IMM); + const auto x86 = &(the_insn->detail->x86); + + if (count==0) + return 0; /* no immediate is the same as an immediate of 0, i guess? */ + else if (count==1) + { + const auto index = cs_op_index(handle, the_insn, X86_OP_IMM, 1); + return x86->operands[index].imm; + } + else + throw std::logic_error(string("Called ")+__FUNCTION__+" with number of immedaites not equal 1"); +} + + + +// shared code +// constructors, destructors, operators. + +void DecodedInstructionCapstoneX86_t::Disassemble(const virtual_offset_t start_addr, const void *data, const uint32_t max_len) +{ + using namespace std::placeholders; + auto insn=cs_malloc(cs_handle->getHandle()); + auto address=(uint64_t)start_addr; + auto size=(size_t)max_len; + const uint8_t* code=(uint8_t*)data; + const auto ok = cs_disasm_iter(cs_handle->getHandle(), &code, &size, &address, insn); + if(!ok) + insn->size=0; + + + if(insn->size==0) + { + const auto special_it=find_if(ALLOF(cs_special_instructions), [&](const special_instruction_t& si) + { + if(si.binary.length() > max_len) + return false; + const auto data_as_str=string((char*)data,si.binary.length()); + return si.binary==data_as_str; + }); + const auto is_special=special_it != end(cs_special_instructions); + if(is_special) + { + // if we run into more complicated stuff, we may need to extend this + insn->size=special_it->binary.length(); + strcpy(insn->mnemonic, special_it->mnemonic.c_str()); + strcpy(insn->op_str, special_it->operands.c_str()); + } + + } + + const auto mnemonic=string(insn->mnemonic); + + const auto x86=insn->detail->x86; + + if(mnemonic=="fcompi") + strcpy(insn->mnemonic, "fcomip"); // bad opcode out of capstone. + else if(x86.opcode[0]==0xa5 && string(insn->mnemonic)=="movsq") + strcpy(insn->op_str, ""); // force into MOVS version + // note, there's two forms of movsd -- one is move string, the other is move scalar double, + // only adjust the move string version + else if(x86.opcode[0]==0xa4 && string(insn->mnemonic)=="movsd") + strcpy(insn->op_str, ""); // force into MOVS version + else if(x86.opcode[0]==0xa5 && string(insn->mnemonic)=="movsw") + strcpy(insn->op_str, ""); // force into MOVS version + else if(x86.opcode[0]==0xa4 && string(insn->mnemonic)=="movsb") + strcpy(insn->op_str, ""); // force into MOVS version + +/* + if(mnemonic=="movabs") + { + if(insn->detail->x86.operands[0].type==X86_OP_MEM) + { + insn->detail->x86.operands[0].imm=insn->detail->x86.operands[0].mem.disp; + insn->detail->x86.operands[0].type=X86_OP_IMM; + } + if(insn->detail->x86.operands[1].type==X86_OP_MEM) + { + insn->detail->x86.operands[1].imm=insn->detail->x86.operands[1].mem.disp; + insn->detail->x86.operands[1].type=X86_OP_IMM; + } + } +*/ + + const auto cs_freer=[](cs_insn * insn) -> void + { + cs_free(insn,1); + } ; + my_insn.reset(insn,cs_freer); +} + +DecodedInstructionCapstoneX86_t::DecodedInstructionCapstoneX86_t(const Instruction_t* i) +{ + if(!cs_handle) cs_handle=new CapstoneHandle_t(NULL); + if(!i) throw std::invalid_argument("No instruction given to DecodedInstruction_t(Instruction_t*)"); + + const auto length=i->getDataBits().size(); + const auto &databits=i->getDataBits(); + const auto data=databits.data(); + const auto address=i->getAddress()->getVirtualOffset(); + Disassemble(address,data,length); + + if(!valid()) throw std::invalid_argument("The Instruction_t::getDataBits field is not a valid instruction."); +} + +DecodedInstructionCapstoneX86_t::DecodedInstructionCapstoneX86_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len) +{ + if(!cs_handle) cs_handle=new CapstoneHandle_t(NULL); + Disassemble(start_addr, data, max_len); +} + +DecodedInstructionCapstoneX86_t::DecodedInstructionCapstoneX86_t(const virtual_offset_t start_addr, const void *data, const void* endptr) +{ + if(!cs_handle) cs_handle=new CapstoneHandle_t(NULL); + const auto length=(char*)endptr-(char*)data; + Disassemble(start_addr,data,length); +} + +DecodedInstructionCapstoneX86_t::DecodedInstructionCapstoneX86_t(const DecodedInstructionCapstoneX86_t& copy) +{ + *this=copy; +} + +DecodedInstructionCapstoneX86_t::DecodedInstructionCapstoneX86_t(const shared_ptr<void> &p_my_insn) + : my_insn(p_my_insn) +{ +} + +DecodedInstructionCapstoneX86_t::~DecodedInstructionCapstoneX86_t() +{ + // no need to cs_free(my_insn) because shared pointer will do that for us! +} + +DecodedInstructionCapstoneX86_t& DecodedInstructionCapstoneX86_t::operator=(const DecodedInstructionCapstoneX86_t& copy) +{ + my_insn=copy.my_insn; + return *this; +} + +// public methods + +string DecodedInstructionCapstoneX86_t::getDisassembly() const +{ + const auto myReplace=[](std::string &str, + const std::string& oldStr, + const std::string& newStr) -> void + { + std::string::size_type pos = 0u; + while((pos = str.find(oldStr, pos)) != std::string::npos) + { + str.replace(pos, oldStr.length(), newStr); + pos += newStr.length(); + } + }; + + + // a list of special mnemonics that can't have a mem decoration because nasm sux. + const auto no_memdec_mnemonics=set<string>( + { + "lea", + "movd", + "pinsrw", + "psllw", + "pslld", + "psllq", + "psrlw", + "psrld", + "psrlq", + "psraw", + "psrad", + }); + + + // a list of prefixes and suffixes of mnemonics that can't have a mem decoration because nasm sux. + // helps deal with things like {mov,add,sub,mul,div, cmp}*{ss,sd,pd,pq}, esp when the cmp has a + // {l,le,ne,eq,g,gt} specifier. + const auto prefixes=set<string>( + { + "max", + "min", + "mov", + "movl", + "cmp", + "movh", + "add", + "sub", + "sqrt", + "mul", + "div", + "ucomi", + "cvtpi2", + "shuf", + //"cvtsi2", had to remove this one? + }); + const auto suffixes=set<string>( + { + "sd", + "ss", + "ps", + "pd" + }); + + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + auto full_str=getMnemonic()+" "+the_insn->op_str; + + myReplace(full_str," ptr ", " "); + myReplace(full_str," xword ", " tword "); + myReplace(full_str," xmmword ", " "); + + + const auto has_prefix_it=find_if(ALLOF(prefixes),[&](const string& prefix) + { const auto s=getMnemonic(); return s.substr(0,prefix.size())==prefix; } ); + const auto has_prefix = has_prefix_it != prefixes.end(); + const auto has_suffix_it=find_if(ALLOF(suffixes),[&](const string& suffix) + { const auto s=getMnemonic(); return s.rfind(suffix) == (s.size() - suffix.size()); } ); + const auto has_suffix = has_suffix_it != suffixes.end(); + + const auto needs_memdec_special=no_memdec_mnemonics.find(getMnemonic())==end(no_memdec_mnemonics); + const auto needs_memdec_shape=!(has_prefix && has_suffix); + const auto needs_memdec=needs_memdec_special && needs_memdec_shape; + + //const auto no_dec1=needs_memdec ? noxmmword : (myReplace(noxmmword," qword ", " ")) ; + //const auto no_dec2=needs_memdec ? no_dec1 : (myReplace(no_dec1," dword ", " ")) ; + //const auto no_rip=myReplace(no_dec2, "rip", to_string(the_insn->size)); + + if(!needs_memdec) + { + myReplace(full_str," qword ", " "); + myReplace(full_str," dword ", " "); + } + + myReplace(full_str, "rip", to_string(the_insn->size)); + + return full_str; +} + +bool DecodedInstructionCapstoneX86_t::valid() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + return the_insn->size!=0; +} + +uint32_t DecodedInstructionCapstoneX86_t::length() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + return the_insn->size; +} + +bool DecodedInstructionCapstoneX86_t::isBranch() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + return isCall() || isReturn() || isJmp(the_insn); +} + +bool DecodedInstructionCapstoneX86_t::isCall() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + return isPartOfGroup(the_insn,X86_GRP_CALL); +} + +bool DecodedInstructionCapstoneX86_t::isUnconditionalBranch() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + + return isJmp(the_insn) && !isConditionalBranch(); +} + +bool DecodedInstructionCapstoneX86_t::isConditionalBranch() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + return isJmp(the_insn) && getMnemonic()!="jmp"; +} + +bool DecodedInstructionCapstoneX86_t::isReturn() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + return isPartOfGroup(the_insn,X86_GRP_RET); +} + +bool DecodedInstructionCapstoneX86_t::hasOperand(const int op_num) const +{ + if(op_num<0) throw std::logic_error(string("Called ")+ __FUNCTION__+" with opnum="+to_string(op_num)); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &x86 = (the_insn->detail->x86); + return 0 <= op_num && op_num < x86.op_count; +} + +// 0-based. first operand is numbered 0. +shared_ptr<DecodedOperand_t> DecodedInstructionCapstoneX86_t::getOperand(const int op_num) const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + if(!hasOperand(op_num)) throw std::logic_error(string("Called ")+__FUNCTION__+" on without hasOperand()==true"); + + return shared_ptr<DecodedOperand_t>(new DecodedOperandCapstoneX86_t(my_insn,(uint8_t)op_num)); + +} + +IRDB_SDK::DecodedOperandVector_t DecodedInstructionCapstoneX86_t::getOperands() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &x86 = (the_insn->detail->x86); + const auto opcount=x86.op_count; + + auto ret_val=IRDB_SDK::DecodedOperandVector_t(); + + for(auto i=0;i<opcount;i++) + ret_val.push_back(getOperand(i)); + + return ret_val; +} + +string DecodedInstructionCapstoneX86_t::getMnemonic() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + + // list of opcodes to rename capstone to bea engine names + typedef pair<string,string> renamer_t; + const auto renamer=set<renamer_t>( + { + /* bea (right), capstone */ + { "mov", "movabs" } , + { "fucomip", "fucompi" }, + // { "cmovnb", "cmovae" }, + // { "cmovnbe", "cmova" }, + // { "cmovnle", "cmovg" }, +// { "jnbe", "ja"}, +// { "jnc", "jae"}, +// { "jng", "jle"}, +// { "jnl", "jge"}, +// { "jnle", "jg"}, + // { "movsd", "movsd" }, + // { "setnbe", "seta" }, + // { "setnle", "setg" }, + + }); + + // get the cs insn via casting. + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + + + // get mnemonic as a string + auto mnemonic=string(the_insn->mnemonic); + + + // remove any prefixes by finding the last space and removing anything before it. + const auto space_pos=mnemonic.rfind(" "); + if(space_pos!=string::npos) + mnemonic.erase(0,space_pos+1); + + // check if it needs a rename. + const auto finder_it=find_if(ALLOF(renamer), [&](const renamer_t& r) { return r.second==the_insn->mnemonic; } ); + if(finder_it!=end(renamer)) + mnemonic=finder_it->first; + + // return the new string. + return mnemonic; + + +} + + +int64_t DecodedInstructionCapstoneX86_t::getImmediate() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + + // direct calls and jumps have a "immediate" which is really an address" those are returned by getAddress + if(isCall() || isJmp(the_insn)) + return 0; + + return insnToImmedHelper<int64_t>(the_insn, cs_handle->getHandle()); +} + + +virtual_offset_t DecodedInstructionCapstoneX86_t::getAddress() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + + if(isCall() || isJmp(the_insn)) + return insnToImmedHelper<virtual_offset_t>(the_insn, cs_handle->getHandle()); + + + const auto count = cs_op_count(cs_handle->getHandle(), the_insn, X86_OP_MEM); + const auto x86 = &(the_insn->detail->x86); + + if (count==0) + return 0; /* no immediate is the same as an immediate of 0, i guess? */ + else if (count==1) + { + const auto index = cs_op_index(cs_handle->getHandle(), the_insn, X86_OP_MEM, 1); + if(x86->operands[index].mem.base==X86_REG_RIP) + return X86_REL_ADDR(*the_insn); + if(getMnemonic()=="lea") + return 0; + return x86->operands[index].mem.disp; + } + else + return 0; +} + + +bool DecodedInstructionCapstoneX86_t::setsStackPointer() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + +/* slow string manip */ + if(getMnemonic()=="push") + return true; + if(getMnemonic()=="pop") + return true; + if(getMnemonic()=="call") + return true; + + // any sp reg + const auto sp_regs=set<x86_reg>({X86_REG_RSP, X86_REG_ESP, X86_REG_SP, X86_REG_SPL}); + + // check the implicit regs. + const auto regs_write_end=begin(the_insn->detail->regs_write)+the_insn->detail->regs_write_count; + const auto implicit_regs_it=find_if + ( + begin(the_insn->detail->regs_write), + regs_write_end, + [sp_regs](const uint8_t actual_reg) + { + return sp_regs.find((x86_reg)actual_reg)!=sp_regs.end(); + } + ) ; + if(implicit_regs_it!=regs_write_end) + return true; + + + // now check each operand + const auto operands_begin=begin(the_insn->detail->x86.operands); + const auto operands_end=begin(the_insn->detail->x86.operands)+the_insn->detail->x86.op_count; + const auto rsp_it=find_if + ( + begin(the_insn->detail->x86.operands), + operands_end, + [sp_regs](const cs_x86_op& op) + { + return op.type==X86_OP_REG && sp_regs.find(op.reg)!=sp_regs.end(); + } + ); + // not found in the operands, we're done. + if(rsp_it==operands_end) + return false; + + // now decide if it's a register that's read or written. + + // special check for things without a destation (as op[0]) + if(getMnemonic()=="push" || + getMnemonic()=="cmp" || + getMnemonic()=="call" || + getMnemonic()=="test") + return false; + + // standard check -- is the reg op 0 + const auto is_op0=(rsp_it==operands_begin); + + return is_op0; +} + +uint32_t DecodedInstructionCapstoneX86_t::getPrefixCount() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto count=count_if(ALLOF(the_insn->detail->x86.prefix), [](const uint8_t pref) { return pref!=0x0; } ) ; + const auto count_with_rex = the_insn->detail->x86.rex == 0 ? count : count + 1; + return count_with_rex; +} + +IRDB_SDK::VirtualOffset_t DecodedInstructionCapstoneX86_t::getMemoryDisplacementOffset(const IRDB_SDK::DecodedOperand_t* p_t, const IRDB_SDK::Instruction_t* insn) const +{ + auto &t = *p_t; + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + + //const auto encoding_size=t.getMemoryDisplacementEncodingSize(); + //const auto x86 = &(the_insn->detail->x86); + const auto imm_count = cs_op_count(cs_handle->getHandle(), the_insn, X86_OP_IMM); + const auto disp_size=t.getMemoryDisplacementEncodingSize(); + const auto imm=getImmediate(); + const auto disp=t.getMemoryDisplacement(); + + if(string((char*)the_insn->detail->x86.opcode)=="\x0f\xc2") // CMPPD, CMPSS + { + return the_insn->size - disp_size - 1; // last byte encodes an immediate value to distinguish pseudo-ops + } + + if(imm_count==0) + return the_insn->size - disp_size; + + // shifts can an immediate that's note encoded in the instruction + // but never an immediate encoded in the instruction. + if( + string((char*)the_insn->detail->x86.opcode)=="\xd0" || // shift left or right with an immediate that's not actually encoded in the insn + string((char*)the_insn->detail->x86.opcode)=="\xd1" + ) + return the_insn->size - disp_size; + + const auto possible_imm_sizes= string(the_insn->mnemonic)=="movabs" ? set<int>({1,2,4,8}) : set<int>({1,2,4}); + + // Reverse iterate to find the maximum size value-match possible. + // E.g. with a mov [rbx*8 + 0x00000000],0x00000000 instruction, it would be easy to match + // a 1-byte immediate value of 0 and a 4-byte displacement value of zero, while + // the desired behavior is to match two 4-byte values of zero when searching + // for the actual start offsets of the displacement and immediate fields. + for (auto imm_size_iter = possible_imm_sizes.crbegin(); imm_size_iter != possible_imm_sizes.crend(); ++imm_size_iter) + { + const auto imm_size = (*imm_size_iter); + if(the_insn->size < disp_size + imm_size) + continue; + + const auto disp_start=the_insn->size-imm_size-disp_size; + const auto imm_start=the_insn->size-imm_size; + + const auto candidate_disp_eq = disp_size==4 ? *(int32_t*)(&insn->getDataBits().c_str()[disp_start])==(int32_t)disp : + disp_size==2 ? *(int16_t*)(&insn->getDataBits().c_str()[disp_start])==(int16_t)disp : + disp_size==1 ? *(int8_t *)(&insn->getDataBits().c_str()[disp_start])==(int8_t )disp : (assert(0),false); + + const auto candidate_imm_eq = imm_size==8 ? *(int64_t*)(&insn->getDataBits().c_str()[imm_start])==(int64_t)imm : + imm_size==4 ? *(int32_t*)(&insn->getDataBits().c_str()[imm_start])==(int32_t)imm : + imm_size==2 ? *(int16_t*)(&insn->getDataBits().c_str()[imm_start])==(int16_t)imm : + imm_size==1 ? *(int8_t *)(&insn->getDataBits().c_str()[imm_start])==(int8_t )imm : (int64_t)(assert(0),false); + + if(candidate_disp_eq && candidate_imm_eq) + return disp_start; + + } + + assert(0); + + +} + + + +bool DecodedInstructionCapstoneX86_t::hasRelevantRepPrefix() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + return hasPrefix(the_insn,X86_PREFIX_REP); +} + +bool DecodedInstructionCapstoneX86_t::hasRelevantRepnePrefix() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + return hasPrefix(the_insn,X86_PREFIX_REPNE); +} + +bool DecodedInstructionCapstoneX86_t::hasRelevantOperandSizePrefix() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + return hasPrefix(the_insn,X86_PREFIX_OPSIZE); +} + +bool DecodedInstructionCapstoneX86_t::hasRexWPrefix() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + return (the_insn->detail->x86.rex & 0x8) == 0x8; +} + +bool DecodedInstructionCapstoneX86_t::hasImplicitlyModifiedRegs() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + + + const auto count=count_if + ( + begin(the_insn->detail->regs_write), + begin(the_insn->detail->regs_write)+the_insn->detail->regs_write_count, + [](const uint8_t actual_pref) + { + return actual_pref!=X86_REG_EFLAGS; + } + ) ; + + return count>0; + +} + diff --git a/irdb-lib/libIRDB-core/src/decode_dispatch.cpp b/irdb-lib/libIRDB-core/src/decode_dispatch.cpp new file mode 100644 index 0000000000000000000000000000000000000000..97631d5cbad1dacf76a3a569b157251ee08f4c68 --- /dev/null +++ b/irdb-lib/libIRDB-core/src/decode_dispatch.cpp @@ -0,0 +1,115 @@ + +#include <libIRDB-core.hpp> +#include <decode_base.hpp> +#include <decode_csx86.hpp> +#include <decode_csarm.hpp> + +#include <operand_base.hpp> +#include <operand_csx86.hpp> +#include <operand_csarm.hpp> + +#include <decode_dispatch.hpp> +#include <operand_dispatch.hpp> + + +using namespace libIRDB; +using namespace std; + +// constructors, destructors, operators. + +DecodedInstructionDispatcher_t::DecodedInstructionDispatcher_t(const Instruction_t* i) +{ + cs=DecodedInstructionCapstone_t::factory(i); +} + +DecodedInstructionDispatcher_t::DecodedInstructionDispatcher_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len) +{ + cs=DecodedInstructionCapstone_t::factory(start_addr,data,max_len); +} + +DecodedInstructionDispatcher_t::DecodedInstructionDispatcher_t(const virtual_offset_t start_addr, const void *data, const void* endptr) +{ + cs=DecodedInstructionCapstone_t::factory(start_addr,data,endptr); +} + +DecodedInstructionDispatcher_t::DecodedInstructionDispatcher_t(const DecodedInstructionDispatcher_t& copy) +{ + cs=copy.cs; +} + +DecodedInstructionDispatcher_t::~DecodedInstructionDispatcher_t() +{ +} + +DecodedInstructionDispatcher_t& DecodedInstructionDispatcher_t::operator=(const DecodedInstructionDispatcher_t& copy) +{ + cs=copy.cs; + return *this; +} + + + +#define passthrough_to_cs(ret_type, method_name) \ + ret_type DecodedInstructionDispatcher_t::method_name() const \ + { \ + return cs->method_name(); \ + } + +// public methods + +/* demonstrating things are the same */ +passthrough_to_cs(bool, valid); +passthrough_to_cs(uint32_t, length); +passthrough_to_cs(bool, isBranch); +passthrough_to_cs(bool, isCall); +passthrough_to_cs(bool, isUnconditionalBranch); +passthrough_to_cs(bool, isConditionalBranch); +passthrough_to_cs(bool, isReturn); +passthrough_to_cs(uint32_t, getPrefixCount); +passthrough_to_cs(bool, hasRexWPrefix); +passthrough_to_cs(bool, setsStackPointer); +passthrough_to_cs(bool, hasRelevantRepPrefix); // rep ret disagreement. +passthrough_to_cs(bool, hasRelevantRepnePrefix); +passthrough_to_cs(bool, hasRelevantOperandSizePrefix); + +/* demonstrating when capstone is better */ +passthrough_to_cs(string, getMnemonic); +passthrough_to_cs(string,getDisassembly); +passthrough_to_cs(virtual_offset_t, getAddress); +passthrough_to_cs(int64_t, getImmediate); + +// demonstrating they different and trying to determine which is better. +passthrough_to_cs(bool, hasImplicitlyModifiedRegs); + +// not yet completed +// needs more complicated impl. + + +bool DecodedInstructionDispatcher_t::hasOperand(const int op_num) const +{ + const auto cs_res = cs->hasOperand(op_num); + return cs_res; +} + +// 0-based. first operand is numbered 0. +unique_ptr<DecodedOperand_t> DecodedInstructionDispatcher_t::getOperand(const int op_num) const +{ + return unique_ptr<DecodedOperand_t>(new DecodedOperandDispatcher_t(cs->getOperand(op_num))); +} + +DecodedOperandMetaVector_t DecodedInstructionDispatcher_t::getOperands() const +{ + auto ret_val=DecodedOperandMetaVector_t(); + auto cs_operands=cs->getOperands(); + for(const auto &op : cs_operands ) + ret_val.push_back(DecodedOperandDispatcher_t(op)); + return ret_val; +} + +virtual_offset_t DecodedInstructionDispatcher_t::getMemoryDisplacementOffset(const DecodedOperandDispatcher_t& t, const Instruction_t* insn) const +{ + return cs->getMemoryDisplacementOffset(*t.cs, insn); +} + + + diff --git a/irdb-lib/libIRDB-core/src/eh.cpp b/irdb-lib/libIRDB-core/src/eh.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fea5ca337dbd240bac597e77a55383a0a40cfcd3 --- /dev/null +++ b/irdb-lib/libIRDB-core/src/eh.cpp @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <all.hpp> +#include <irdb-util> +#include <tuple> +#include <functional> +#include <assert.h> +#include <sstream> +#include <iostream> +#include <iomanip> +#include <algorithm> + +using namespace libIRDB; +using namespace std; + +bool libIRDB::operator<(const EhProgram_t&a, const EhProgram_t&b) +{ + return tie(a.cie_program,a.fde_program,a.code_alignment_factor,a.data_alignment_factor,a.return_register, a.ptrsize, a.getRelocations()) + < + tie(b.cie_program,b.fde_program,b.code_alignment_factor,b.data_alignment_factor,b.return_register, b.ptrsize, b.getRelocations()); +} + +namespace std +{ +template<> +class hash<EhProgramListing_t> +{ + public: + std::size_t operator()(const EhProgramListing_t& s) const + { + auto sub_hasher=std::hash<string>(); + auto res=std::size_t(0); + for(const auto& i: s) + { + res ^= sub_hasher(i); + } + return res; + } + +}; +} + + +void libIRDB::EhProgram_t::print() const +{ + std::hash<EhProgramListing_t> ehpgmlist_hash; + auto cie_hash=ehpgmlist_hash(cie_program); + auto fde_hash=ehpgmlist_hash(fde_program); + cout<<dec<<"CAF: "<<code_alignment_factor<<" DAF: "<<data_alignment_factor<<" ptrsize="<< +ptrsize<<" cie_hash: "<<hex<<cie_hash<<" fde_hash: "<<fde_hash<<endl; +} + +vector<std::string> EhProgram_t::WriteToDB(File_t* fid) // writes to DB, ID is not -1. +{ + auto str_to_encoded_string=[](const string& data) -> string + { + ostringstream hex_data; + hex_data << setfill('0') << hex; + for (size_t i = 0; i < data.length(); ++i) + hex_data << setw(2) << (int)(data[i]&0xff); + return hex_data.str(); + }; + + auto vec_to_encoded_string=[&](const vector<string>& in) -> string + { + string q=""; + for(const auto& i : in) + { + if(q!="") + q+=","; + q+=str_to_encoded_string(i); + } + return q; + }; + + string encoded_cie_program=vec_to_encoded_string(cie_program); + string encoded_fde_program=vec_to_encoded_string(fde_program); + + + return { + to_string(getBaseID()), + to_string(+code_alignment_factor), + to_string(+data_alignment_factor), + to_string(+return_register), + to_string(+ptrsize), + encoded_cie_program, + encoded_fde_program + }; + +} + +std::string EhCallSite_t::WriteToDB(File_t* fid) // writes to DB, ID is not -1. +{ + const auto vec_to_string=[](const vector<int> &v) + { + stringstream s; + for(const auto &e : v) + { + s<<dec<<e<<" "; + } + + return s.str(); + }; + string q; + + + + auto landing_pad_id=BaseObj_t::NOT_IN_DATABASE; + if(landing_pad != NULL) + landing_pad_id=landing_pad->getBaseID(); + + const auto ttov_str=vec_to_string(ttov); + + q ="insert into " + fid->getEhCallSiteTableName(); + q+="(ehcs_id,tt_encoding,ttov,lp_insn_id) "+ + string(" VALUES (") + + string("'") + to_string(getBaseID()) + string("', ") + + string("'") + to_string(+tt_encoding) + string("', ") + + string("'") + ttov_str + string("', ") + + string("'") + to_string(landing_pad_id) + string("') ;"); + return q; +} + +bool EhCallSite_t::getHasCleanup() const +{ + const auto ttov_it=find(ttov.begin(), ttov.end(), 0); + return ttov_it!=ttov.end(); +} + +void EhCallSite_t::setHasCleanup(bool p_has_cleanup) +{ + if(p_has_cleanup) + { + if(!getHasCleanup()) + ttov.push_back(0); + } + else + { + if(getHasCleanup()) + { + const auto ttov_it=find(ttov.begin(), ttov.end(), 0); + ttov.erase(ttov_it); + } + } +} + diff --git a/irdb-lib/libIRDB-core/src/file.cpp b/irdb-lib/libIRDB-core/src/file.cpp new file mode 100644 index 0000000000000000000000000000000000000000..87a55124bb4324f7d4859786c08ce2e1256cf363 --- /dev/null +++ b/irdb-lib/libIRDB-core/src/file.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +#include <all.hpp> +#include <irdb-util> +#include <stdlib.h> +#include <unistd.h> +#include <fstream> +#include <iostream> + +#include <irdb-util> + +using namespace libIRDB; +using namespace std; + + +File_t::File_t(const db_id_t &myfile_id, const db_id_t &my_orig_fid, const std::string &myurl, + const std::string &myhash, const std::string &myarch, const int &myoid, + const std::string &atn, const std::string &ftn, const std::string &itn, const std::string &icfs, + const std::string &icfs_map, const std::string &rtn, const std::string &typ, const std::string &scoop, + const std::string &ehpgms, const std::string &ehcss, + const db_id_t &mydoipid) + : + BaseObj_t(NULL), + orig_fid(my_orig_fid), + url(myurl), + hash(myhash), + arch(myarch), + address_table_name(atn), + function_table_name(ftn), + instruction_table_name(itn), + icfs_table_name(icfs), + icfs_map_table_name(icfs_map), + relocs_table_name(rtn), + types_table_name(typ), + scoop_table_name(scoop), + ehpgm_table_name(ehpgms), + ehcss_table_name(ehcss), + elfoid(myoid) +{ + setBaseID(myfile_id); +} + + +void File_t::CreateTables() +{ + + // to avoid duplicate schemas for the DB, we're calling + // the script that has the table creation schema in it + string home(getenv("PEASOUP_HOME")); + string tmpfile= "db_script."+to_string(getpid()); + + string command=home+"/tools/db/pdb_create_program_tables.sh "+ + address_table_name+" "+ + function_table_name+" "+ + instruction_table_name+" "+ + icfs_table_name+" "+ + icfs_map_table_name+" "+ + relocs_table_name+" "+ + types_table_name+" "+ + scoop_table_name+" "+ + ehpgm_table_name+" "+ + ehcss_table_name+" "+ + tmpfile; + + // ignore_result(system(command.c_str())); + command_to_stream(command,cout); + + + std::ifstream t(tmpfile.c_str()); + std::stringstream buffer; + buffer << t.rdbuf(); + + + dbintr->issueQuery(buffer.str().c_str()); + +} diff --git a/irdb-lib/libIRDB-core/src/fileir.cpp b/irdb-lib/libIRDB-core/src/fileir.cpp new file mode 100644 index 0000000000000000000000000000000000000000..14502548e6d95423ff93e52ecd9b2a9c28e7bce9 --- /dev/null +++ b/irdb-lib/libIRDB-core/src/fileir.cpp @@ -0,0 +1,1919 @@ + +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <all.hpp> +#include <irdb-util> +#include <cstdlib> +#include <map> +#include <fstream> +#include <elf.h> +#include <stdlib.h> +#include <algorithm> +#include <sys/wait.h> +#include <iomanip> +#include <irdb-util> + +using namespace libIRDB; +using namespace std; + + +#define SCOOP_CHUNK_SIZE (10*1024*1024) /* 10 mb */ +#define ALLOF(a) begin(a),end(a) + + +#undef EIP + +int command_to_stream(const string& command, ostream& stream) +{ + auto redirect_command=command+" 2>&1 "; + auto buffer=array<char,128>(); + + std::cout << "Issuing subcommand: "<< command << std::endl; + auto pipe = popen(redirect_command.c_str(), "r"); + if (!pipe) + { + stream << "Couldn't start command:"<< strerror(errno) << endl; + return 1; + } + while (fgets(buffer.data(), 128, pipe) != NULL) + { + stream<<buffer.data(); + } + auto returnCode = pclose(pipe); + if(returnCode==-1) + stream << "Could not close pipe: "<< strerror(errno) << endl; + + std::cout << "Return code = "<<returnCode << std::endl; + return returnCode; +} + +static void UpdateEntryPoints( + const std::map<db_id_t,Instruction_t*> &insnMap, + const map<Function_t*,db_id_t>& entry_points) +{ + /* for each function, look up the instruction that's the entry point */ + for( map<Function_t*,db_id_t>::const_iterator it=entry_points.begin(); + it!=entry_points.end(); + ++it + ) + { + Function_t* func=(*it).first; + db_id_t func_entry_id=(*it).second; + + assert(func_entry_id==-1 || insnMap.at(func_entry_id)); + func->setEntryPoint(insnMap.at(func_entry_id)); +// cout<<"Function named "<<func->getName()<< " getting entry point set to "<<insnMap[func_entry_id]->getComment()<<"."<<endl; + } + +} + +static void UpdateUnresolvedEhCallSites( + const std::map<db_id_t,Instruction_t*> &insnMap, + const std::map<EhCallSite_t*,db_id_t> & unresolvedEhcss) +{ + for(const auto &i : unresolvedEhcss) + { + const auto& ehcs=i.first; + const auto& insnid=i.second; + const auto& insn=insnMap.at(insnid); + assert(insn); + ehcs->setLandingPad(insn); + } +} + +static virtual_offset_t strtovo(std::string s) +{ + return IRDB_SDK::strtoint<virtual_offset_t>(s); +} + +// Create a Variant from the database +FileIR_t::FileIR_t(const VariantID_t &newprogid, File_t* fid) + : BaseObj_t(NULL), progid((VariantID_t&) newprogid) + +{ + orig_variant_ir_p=NULL; + + if(fid==NULL) + fileptr=dynamic_cast<File_t*>(newprogid.getMainFile()); + else + fileptr=fid; + + if(progid.isRegistered()) + { + ReadFromDB(); + setArchitecture(); + } + +} + +FileIR_t::~FileIR_t() +{ + for(auto i : funcs ) delete i; + for(auto i : insns ) delete i; + for(auto i : addrs ) delete i; + for(auto i : relocs) delete i; + for(auto i : types ) delete i; + + // @todo: clear icfs_t +} + +// DB operations +void FileIR_t::ReadFromDB() +{ + ReadIRDB_start = clock(); + + + auto entry_points=map<Function_t*,db_id_t>(); + auto unresolvedICFS=std::map<Instruction_t*, db_id_t>(); + auto unresolvedEhCallSites=std::map<EhCallSite_t*,db_id_t>(); + auto objMap=std::map<db_id_t,BaseObj_t*>(); + auto addressToInstructionMap=std::map<db_id_t,Instruction_t*>(); + + auto ehpgmMap = ReadEhPgmsFromDB(); + auto ehcsMap = ReadEhCallSitesFromDB(unresolvedEhCallSites); + auto typesMap = ReadTypesFromDB(types); + auto addrMap = ReadAddrsFromDB(); + auto funcMap = ReadFuncsFromDB(addrMap, typesMap,entry_points); + auto scoopMap = ReadScoopsFromDB(addrMap, typesMap); + auto insnMap = ReadInsnsFromDB(funcMap,addrMap,ehpgmMap,ehcsMap,addressToInstructionMap, unresolvedICFS); + + + ReadAllICFSFromDB(addressToInstructionMap, unresolvedICFS); + + // put the scoops, instructions, ehpgms, eh call sites into the object map. + // if relocs end up on other objects, we'll need to add them to. for now only these things. + objMap.insert(insnMap.begin(), insnMap.end()); + objMap.insert(scoopMap.begin(), scoopMap.end()); + objMap.insert(ehcsMap.begin(), ehcsMap.end()); + objMap.insert(ehpgmMap.begin(), ehpgmMap.end()); + ReadRelocsFromDB(objMap); + + UpdateEntryPoints(insnMap,entry_points); + UpdateUnresolvedEhCallSites(insnMap,unresolvedEhCallSites); + + ReadIRDB_end = clock(); + + +} + + +void FileIR_t::changeRegistryKey(IRDB_SDK::Instruction_t *p_orig, IRDB_SDK::Instruction_t *p_updated) +{ + auto orig=dynamic_cast<libIRDB::Instruction_t*>(p_orig); + auto updated=dynamic_cast<libIRDB::Instruction_t*>(p_updated); + + if(assembly_registry.find(orig) != assembly_registry.end()) + { + assembly_registry[updated] = assembly_registry[orig]; + + assembly_registry.erase(orig); + } +} + +void FileIR_t::assembleRegistry() +{ + if(assembly_registry.size() == 0) + return; + + string assemblyFile = "tmp.asm"; + string binaryOutputFile = "tmp.bin"; + + string command = "rm -f " + assemblyFile + " " + binaryOutputFile; + auto actual_exit = command_to_stream(command, cout); // system(command.c_str()); + + assert(actual_exit == 0); + + ofstream asmFile; + asmFile.open(assemblyFile.c_str()); + if(!asmFile.is_open()) + assert(false); + + asmFile<<"BITS "<<std::dec<<getArchitectureBitWidth()<<endl; + + for(auto it : assembly_registry) + { + asmFile<<it.second<<endl; + } + asmFile.close(); + + command = string("nasm ") + assemblyFile + string(" -o ") + binaryOutputFile; + actual_exit = command_to_stream(command,cout); // system(command.c_str()); + assert(actual_exit == 0); + + ifstream binreader; + unsigned int filesize; + binreader.open(binaryOutputFile.c_str(),ifstream::in|ifstream::binary); + + assert(binreader.is_open()); + + binreader.seekg(0,ios::end); + filesize = binreader.tellg(); + binreader.seekg(0,ios::beg); + + unsigned char *binary_stream = new unsigned char[filesize]; + + binreader.read((char*)binary_stream,filesize); + binreader.close(); + + unsigned int index = 0; + registry_type::iterator reg_val = assembly_registry.begin(); + + while(index < filesize) + { + //the number of registered instructions should not be exceeded + assert(reg_val != assembly_registry.end()); + Instruction_t *instr = reg_val->first; + + + // disasm.EIP = (UIntPtr)&binary_stream[index]; + // int instr_len = Disasm(&disasm); + + const auto p_disasm=DecodedInstruction_t::factory + ( + /* fake start addr doesn't matter */0x1000, + (void*)&binary_stream[index], + (void*)&binary_stream[filesize] + ); + const auto& disasm=*p_disasm; + + assert(disasm.valid()); + const auto instr_len=disasm.length(); + + string rawBits; + rawBits.resize(instr_len); + for(auto i=0U;i<instr_len;i++,index++) + { + rawBits[i] = binary_stream[index]; + } + + instr->setDataBits(rawBits); +// *verbose_logging << "doing instruction:" << ((Instruction_t*)instr)->getDisassembly() << " comment: " << ((Instruction_t*)instr)->getComment() << endl; + reg_val++; + } + + assert(reg_val == assembly_registry.end()); + + delete [] binary_stream; + assembly_registry.clear(); + +} + +void FileIR_t::registerAssembly(IRDB_SDK::Instruction_t *p_instr, string assembly) +{ + auto instr=dynamic_cast<Instruction_t*>(p_instr); + assert(instr); + assembly_registry[instr] = assembly; +} + +void FileIR_t::unregisterAssembly(IRDB_SDK::Instruction_t *p_instr) +{ + auto instr=dynamic_cast<Instruction_t*>(p_instr); + assert(instr); + assembly_registry.erase(instr); +} + +std::string FileIR_t::lookupAssembly(IRDB_SDK::Instruction_t *p_instr) +{ + auto instr=dynamic_cast<Instruction_t*>(p_instr); + assert(instr); + if (assembly_registry.find(instr) != assembly_registry.end()) + return assembly_registry[instr]; + else + return std::string(); +} + +std::map<db_id_t,Function_t*> FileIR_t::ReadFuncsFromDB + ( + std::map<db_id_t,AddressID_t*> &addrMap, + std::map<db_id_t,Type_t*> &typesMap, + map<Function_t*,db_id_t> &entry_points + ) +{ + auto idMap=std::map<db_id_t,Function_t*> (); + + auto q=std::string("select * from ") + fileptr->function_table_name + " ; "; + + dbintr->issueQuery(q); + + while(!dbintr->isDone()) + { +// function_id | file_id | name | stack_frame_size | out_args_region_size | use_frame_pointer | is_safe | doip_id + + db_id_t fid=atoi(dbintr->getResultColumn("function_id").c_str()); + db_id_t entry_point_id=atoi(dbintr->getResultColumn("entry_point_id").c_str()); + std::string name=dbintr->getResultColumn("name"); + int sfsize=atoi(dbintr->getResultColumn("stack_frame_size").c_str()); + int oasize=atoi(dbintr->getResultColumn("out_args_region_size").c_str()); + db_id_t function_type_id=atoi(dbintr->getResultColumn("type_id").c_str()); +// postgresql encoding of boolean can be 'true', '1', 'T', 'y' + bool useFP=false; + bool isSafe=false; + string useFPString=dbintr->getResultColumn("use_frame_pointer"); + string isSafeString=dbintr->getResultColumn("is_safe"); + const char *useFPstr=useFPString.c_str(); + const char *isSafestr=isSafeString.c_str(); + if (strlen(useFPstr) > 0) + { + if (useFPstr[0] == 't' || useFPstr[0] == 'T' || useFPstr[0] == '1' || useFPstr[0] == 'y' || useFPstr[0] == 'Y') + useFP = true; + } + + if (strlen(isSafestr) > 0) + { + if (isSafestr[0] == 't' || isSafestr[0] == 'T' || isSafestr[0] == '1' || isSafestr[0] == 'y' || isSafestr[0] == 'Y') + isSafe = true; + } + + // handle later? + //db_id_t doipid=atoi(dbintr->getResultColumn("doip_id").c_str()); + + FuncType_t* fnType = NULL; + if (typesMap.count(function_type_id) > 0) + fnType = dynamic_cast<FuncType_t*>(typesMap[function_type_id]); + Function_t *newfunc=new Function_t(fid,name,sfsize,oasize,useFP,isSafe,fnType, NULL); + assert(newfunc); + entry_points[newfunc]=entry_point_id; + +//std::cout<<"Found function "<<name<<"."<<std::endl; + + idMap[fid]=newfunc; + + funcs.insert(newfunc); + + dbintr->moveToNextRow(); + } + + return idMap; +} + + +std::map<db_id_t,EhCallSite_t*> FileIR_t::ReadEhCallSitesFromDB + ( + map<EhCallSite_t*,db_id_t> &unresolvedEhCssLandingPads // output arg. + ) +{ + auto ehcsMap=std::map<db_id_t,EhCallSite_t*>(); + + std::string q= "select * from " + fileptr->getEhCallSiteTableName() + " ; "; + + for(dbintr->issueQuery(q); !dbintr->isDone(); dbintr->moveToNextRow()) + { + const auto string_to_vec=[&](const string& str ) -> vector<int> + { + auto out=vector<int>(); + istringstream s(str); + auto in=(int)0; + while ( s >> in) + out.push_back(in); + return out; + }; + /* + * ehcs_id integer, -- id of this object. + * tt_encoding integer, -- the encoding of the type table. + * lp_insn_id integer -- the landing pad instruction's id. + */ + + + const auto eh_cs_id=atoi(dbintr->getResultColumn("ehcs_id").c_str()); + const auto tt_encoding=atoi(dbintr->getResultColumn("tt_encoding").c_str()); + const auto &ttov=string(dbintr->getResultColumn("ttov").c_str()); + const auto lp_insn_id=atoi(dbintr->getResultColumn("lp_insn_id").c_str()); + + auto newEhCs=new EhCallSite_t(eh_cs_id,tt_encoding,NULL); // create the call site with an unresolved LP + newEhCs->GetTTOrderVector()=string_to_vec(ttov); + eh_css.insert(newEhCs); // record that it exists. + ehcsMap[eh_cs_id]=newEhCs; // record the map for when we read instructions. + if(lp_insn_id != BaseObj_t::NOT_IN_DATABASE) + unresolvedEhCssLandingPads[newEhCs]=lp_insn_id; // note that the LP is unresolved + } + + return ehcsMap; +} + +std::map<db_id_t,EhProgram_t*> FileIR_t::ReadEhPgmsFromDB() +{ + auto idMap = std::map<db_id_t,EhProgram_t*>(); + + auto q=std::string("select * from ") + fileptr->ehpgm_table_name + " ; "; + dbintr->issueQuery(q); + + auto decode_pgm=[](const string& encoded_pgm, EhProgramListing_t& decoded_pgm) + { + + auto split=[](const string& str, const string& delim, EhProgramListing_t& tokens) -> void + { + auto prev = size_t(0); + auto pos = size_t(0); + do + { + pos = str.find(delim, prev); + if (pos == string::npos) pos = str.length(); + string token = str.substr(prev, pos-prev); + if (!token.empty()) tokens.push_back(token); + prev = pos + delim.length(); + } + while (pos < str.length() && prev < str.length()); + }; + + auto decode_in_place=[](string& to_decode) -> void + { + auto charToHex=[](uint8_t value) -> uint8_t + { + if (value >= '0' && value <= '9') return value - '0'; + else if (value >= 'A' && value <= 'F') return value - 'A' + 10; + else if (value >= 'a' && value <= 'f') return value - 'a' + 10; + assert(false); + }; + + + auto out=string(""); + while(to_decode.size() > 0) + { + // to-decode should have pairs of characters that represent individual bytes. + assert(to_decode.size() >= 2); + auto val = uint8_t ( charToHex(to_decode[0])*16 + charToHex(to_decode[1]) ); + out += val; + to_decode.erase(0,2); + } + + to_decode=out; + }; + + split(encoded_pgm, ",", decoded_pgm); + + // decode each one + for(auto& i : decoded_pgm) + decode_in_place(i); + + + }; + + while(!dbintr->isDone()) + { + /* + * eh_pgm_id integer, + * caf integer, + * daf integer, + * ptrsize integer, + * cie_program text, + * fde_program text + */ + + + const auto eh_pgm_id=atoi(dbintr->getResultColumn("eh_pgm_id").c_str()); + const auto caf=atoi(dbintr->getResultColumn("caf").c_str()); + const auto daf=atoi(dbintr->getResultColumn("daf").c_str()); + const auto rr=atoi(dbintr->getResultColumn("return_register").c_str()); + const auto ptrsize=atoi(dbintr->getResultColumn("ptrsize").c_str()); + const auto& encoded_cie_program = dbintr->getResultColumn("cie_program"); + const auto& encoded_fde_program = dbintr->getResultColumn("fde_program"); + + auto new_ehpgm=new EhProgram_t(eh_pgm_id, caf, daf, rr, ptrsize, {}, {}); + decode_pgm(encoded_cie_program, new_ehpgm->GetCIEProgram()); + decode_pgm(encoded_fde_program, new_ehpgm->GetFDEProgram()); + + idMap[eh_pgm_id]=new_ehpgm; + eh_pgms.insert(new_ehpgm); + dbintr->moveToNextRow(); + } + + return idMap; +} + +std::map<db_id_t,AddressID_t*> FileIR_t::ReadAddrsFromDB + ( + ) +{ + std::map<db_id_t,AddressID_t*> idMap; + + std::string q= "select * from " + fileptr->address_table_name + " ; "; + + + dbintr->issueQuery(q); + + while(!dbintr->isDone()) + { +// address_id integer PRIMARY KEY, +// file_id integer REFERENCES file_info, +// vaddress_offset bigint, +// doip_id integer DEFAULT -1 + + + db_id_t aid=atoi(dbintr->getResultColumn("address_id").c_str()); + db_id_t file_id=atoi(dbintr->getResultColumn("file_id").c_str()); + virtual_offset_t vaddr=strtovo(dbintr->getResultColumn("vaddress_offset")); + + // handle later? + //db_id_t doipid=atoi(dbintr->getResultColumn("doip_id").c_str()); + + AddressID_t *newaddr=new AddressID_t(aid,file_id,vaddr); + +//std::cout<<"Found address "<<aid<<"."<<std::endl; + + idMap[aid]=newaddr; + + addrs.insert(newaddr); + + dbintr->moveToNextRow(); + } + + return idMap; +} + + +static string encoded_to_raw_string(string encoded) +{ + int len = encoded.length(); + std::string raw; + for(int i=0; i< len; i+=2) + { + string byte = encoded.substr(i,2); + char chr = (char) (int)strtol(byte.c_str(), nullptr, 16); + raw.push_back(chr); + } + return raw; +} + +std::map<db_id_t,Instruction_t*> FileIR_t::ReadInsnsFromDB + ( + const std::map<db_id_t,Function_t*> &funcMap, + const std::map<db_id_t,AddressID_t*> &addrMap, + const std::map<db_id_t,EhProgram_t*> &ehpgmMap, + const std::map<db_id_t,EhCallSite_t*> &ehcsMap, + std::map<db_id_t,Instruction_t*> &addressToInstructionMap, + std::map<Instruction_t*, db_id_t> &unresolvedICFS + ) +{ + std::map<db_id_t,Instruction_t*> idMap; + std::map<db_id_t,db_id_t> fallthroughs; + std::map<db_id_t,db_id_t> targets; + + std::string q= "select * from " + fileptr->instruction_table_name + " ; "; + + + dbintr->issueQuery(q); + + while(!dbintr->isDone()) + { + +// address_id integer REFERENCES #PROGNAME#_address, +// parent_function_id integer, +// orig_address_id integer REFERENCES #PROGNAME#_address, +// fallthrough_address_id integer, +// target_address_id integer, +// icfs_id integer, +// data bytea, +// callback text, +// comment text, +// doip_id integer DEFAULT -1 + + + db_id_t instruction_id=atoi(dbintr->getResultColumn("instruction_id").c_str()); + db_id_t aid=atoi(dbintr->getResultColumn("address_id").c_str()); + db_id_t parent_func_id=atoi(dbintr->getResultColumn("parent_function_id").c_str()); + db_id_t orig_address_id=atoi(dbintr->getResultColumn("orig_address_id").c_str()); + db_id_t fallthrough_address_id=atoi(dbintr->getResultColumn("fallthrough_address_id").c_str()); + db_id_t targ_address_id=atoi(dbintr->getResultColumn("target_address_id").c_str()); + db_id_t icfs_id=atoi(dbintr->getResultColumn("icfs_id").c_str()); + db_id_t eh_pgm_id=atoi(dbintr->getResultColumn("ehpgm_id").c_str()); + db_id_t eh_cs_id=atoi(dbintr->getResultColumn("ehcss_id").c_str()); + std::string encoded_data=(dbintr->getResultColumn("data")); + std::string data=encoded_to_raw_string(encoded_data); + std::string callback=(dbintr->getResultColumn("callback")); + std::string comment=(dbintr->getResultColumn("comment")); + db_id_t indirect_branch_target_address_id = atoi(dbintr->getResultColumn("ind_target_address_id").c_str()); + db_id_t doipid=atoi(dbintr->getResultColumn("doip_id").c_str()); + + std::string isIndStr=(dbintr->getResultColumn("ind_target_address_id")); + + auto indTarg=(AddressID_t*)NULL; + if (indirect_branch_target_address_id != NOT_IN_DATABASE) + indTarg = addrMap.at(indirect_branch_target_address_id); + + auto parent_func=(Function_t*)NULL; + if(parent_func_id!= NOT_IN_DATABASE) parent_func=funcMap.at(parent_func_id); + + Instruction_t *newinsn=new Instruction_t(instruction_id, + addrMap.at(aid), + parent_func, + orig_address_id, + data, callback, comment, indTarg, doipid); + + if(eh_pgm_id != NOT_IN_DATABASE) newinsn->setEhProgram(ehpgmMap.at(eh_pgm_id)); + if(eh_cs_id != NOT_IN_DATABASE) newinsn->setEhCallSite(ehcsMap.at(eh_cs_id)); + + if(parent_func) + { + parent_func->GetInstructions().insert(newinsn); + newinsn->setFunction(funcMap.at(parent_func_id)); + } + +//std::cout<<"Found address "<<aid<<"."<<std::endl; + + idMap[instruction_id]=newinsn; + fallthroughs[instruction_id]=fallthrough_address_id; + targets[instruction_id]=targ_address_id; + + addressToInstructionMap[aid] = newinsn; + insns.insert(newinsn); + + if (icfs_id == NOT_IN_DATABASE) + { + newinsn->setIBTargets(NULL); + } + else + { + // keep track of instructions for which we have not yet + // resolved the ICFS + unresolvedICFS[newinsn] = icfs_id; + } + + dbintr->moveToNextRow(); + } + + for(std::map<db_id_t,Instruction_t*>::const_iterator i=idMap.begin(); i!=idMap.end(); ++i) + { + Instruction_t *instr=(*i).second; + db_id_t fallthroughid=fallthroughs[instr->getBaseID()]; + if(idMap[fallthroughid]) + instr->setFallthrough(idMap[fallthroughid]); + db_id_t targetid=targets[instr->getBaseID()]; + if(idMap[targetid]) + instr->setTarget(idMap[targetid]); + } + + + return idMap; +} + +void FileIR_t::ReadRelocsFromDB + ( + std::map<db_id_t,BaseObj_t*> &objMap + ) +{ + std::string q= "select * from " + fileptr->relocs_table_name + " ; "; + dbintr->issueQuery(q); + + while(!dbintr->isDone()) + { + db_id_t reloc_id=atoi(dbintr->getResultColumn("reloc_id").c_str()); + int reloc_offset=atoi(dbintr->getResultColumn("reloc_offset").c_str()); + std::string reloc_type=(dbintr->getResultColumn("reloc_type")); + db_id_t instruction_id=atoi(dbintr->getResultColumn("instruction_id").c_str()); + + // handle later? + //db_id_t doipid=atoi(dbintr->getResultColumn("doip_id").c_str()); + db_id_t wrt_id=atoi(dbintr->getResultColumn("wrt_id").c_str()); + uint32_t addend=atoi(dbintr->getResultColumn("addend").c_str()); + + + BaseObj_t* wrt_obj=objMap[wrt_id]; // might be null. + Relocation_t *reloc=new Relocation_t(reloc_id,reloc_offset,reloc_type,wrt_obj,addend); + + assert(objMap[instruction_id]!=NULL); + + objMap[instruction_id]->GetRelocations().insert(reloc); + relocs.insert(reloc); + + dbintr->moveToNextRow(); + } + +} + + +void FileIR_t::writeToDB(ostream *verbose_logging) +{ +// const auto WriteIRDB_start = clock(); + + const auto pqIntr=dynamic_cast<pqxxDB_t*>(dbintr); + assert(pqIntr); + + //Resolve (assemble) any instructions in the registry. + assembleRegistry(); + + /* assign each item a unique ID */ + setBaseIDS(); + + CleanupICFS(verbose_logging); + + db_id_t j=-1; + + dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->instruction_table_name + string(" cascade;")); + dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->icfs_table_name + string(" cascade;")); + dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->icfs_map_table_name + string(" cascade;")); + dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->function_table_name + string(" cascade;")); + dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->address_table_name + string(" cascade;")); + dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->relocs_table_name + string(" cascade;")); + dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->types_table_name + string(" cascade;")); + dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->scoop_table_name + string(" cascade;")); + dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->scoop_table_name+"_part2"+ string(" cascade;")); + dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->ehpgm_table_name + string(" cascade;")); + dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->ehcss_table_name + string(" cascade;")); + + /* and now that everything has an ID, let's write to the DB */ + +// write out the types + string q=string(""); + for(auto t=types.begin(); t!=types.end(); ++t) + { + auto real_t=dynamic_cast<Type_t*>(*t); + assert(real_t); + q+=real_t->WriteToDB(fileptr,j); // @TODO: wtf is j? + if(q.size()>1024*1024) + { + dbintr->issueQuery(q); + q=string(""); + } + } + dbintr->issueQuery(q); + + +// write out functions + auto withHeader=true; + q=string(""); + for(auto f=funcs.begin(); f!=funcs.end(); ++f) + { + auto real_f=dynamic_cast<Function_t*>(*f); + assert(real_f); + q+=real_f->WriteToDB(fileptr,j); + if(q.size()>1024*1024) + { + dbintr->issueQuery(q); + q=string(""); + } + } + dbintr->issueQuery(q); + + +// write out addresses + pqxx::tablewriter W_addrs(pqIntr->getTransaction(),fileptr->address_table_name); + for(const auto &a : addrs) + { + auto real_a=dynamic_cast<AddressID_t*>(a); + assert(real_a); + W_addrs << real_a->WriteToDB(fileptr,j,withHeader); + } + W_addrs.complete(); + +// write out instructions + + pqxx::tablewriter W(pqIntr->getTransaction(),fileptr->instruction_table_name); + for(auto i=insns.begin(); i!=insns.end(); ++i) + { + auto insnp=dynamic_cast<Instruction_t*>(*i); + //DISASM disasm; + //Disassemble(insnp,disasm); + const auto p_disasm=DecodedInstruction_t::factory(insnp); + const auto& disasm=*p_disasm; + + if(insnp->getOriginalAddressID() == NOT_IN_DATABASE) + { + + // if(insnp->getFallthrough()==NULL && disasm.Instruction.BranchType!=RetType && disasm.Instruction.BranchType!=JmpType ) + if(insnp->getFallthrough()==NULL && !disasm.isReturn() && !disasm.isUnconditionalBranch()) + { + // instructions that fall through are required to either specify a fallthrough that's + // in the IRDB, or have an associated "old" instruction. + // without these bits of information, the new instruction can't possibly execute correctly. + // and we won't have the information necessary to emit spri. + + *verbose_logging << "NULL fallthrough: offending instruction:" << ((Instruction_t*)insnp)->getDisassembly() << " comment: " << ((Instruction_t*)insnp)->getComment() << endl; + assert(0); + abort(); + } + //if(insnp->getTarget()==NULL && disasm.Instruction.BranchType!=0 && + // disasm.Instruction.BranchType!=RetType && + // // not an indirect branch + // ((disasm.Instruction.BranchType!=JmpType && disasm.Instruction.BranchType!=CallType) || + // disasm.Argument1.ArgType&CONSTANT_TYPE)) + + if(insnp->getTarget()==NULL && disasm.isBranch() && !disasm.isReturn() && + // not an indirect branch + ( (!disasm.isUnconditionalBranch() && !disasm.isCall()) || disasm.getOperand(0)->isConstant()) + ) + { + // direct branches are required to either specify a target that's + // in the IRDB, or have an associated "old" instruction. + // without these bits of information, the new instruction can't possibly execute correctly. + // and we won't have the information necessary to emit spri. + *verbose_logging << "Call must have a target; offending instruction:" << ((Instruction_t*)insnp)->getDisassembly() << " comment: " << ((Instruction_t*)insnp)->getComment() << endl; + assert(0); + abort(); + } + } + + const auto &insn_values=insnp->WriteToDB(fileptr,j); + W << insn_values; + + } + W.complete(); + + +// icfs + for (auto it = GetAllICFS().begin(); it != GetAllICFS().end(); ++it) + { + ICFS_t* icfs = dynamic_cast<ICFS_t*>(*it); + assert(icfs); + string q = icfs->WriteToDB(fileptr); + dbintr->issueQuery(q); + } + +// scoops + for(auto it=scoops.begin(); it!=scoops.end(); ++it) + { + DataScoop_t* scoop = dynamic_cast<DataScoop_t*>(*it); + assert(scoop); + string q = scoop->WriteToDB(fileptr,j); + dbintr->issueQuery(q); + } + +// ehpgms + pqxx::tablewriter W_eh(pqIntr->getTransaction(),fileptr->ehpgm_table_name); + for(const auto& i : eh_pgms) + { + W_eh << dynamic_cast<EhProgram_t*>(i)->WriteToDB(fileptr); + } + W_eh.complete(); + +// eh css + for(const auto& i : eh_css) + { + string q = dynamic_cast<EhCallSite_t*>(i)->WriteToDB(fileptr); + dbintr->issueQuery(q); + } + + +// all relocs + pqxx::tablewriter W_reloc(pqIntr->getTransaction(),fileptr->relocs_table_name); + +// eh css relocs + for(const auto& i : eh_css) + { + const auto &relocs=i->getRelocations(); + for(auto& reloc : relocs) + W_reloc << dynamic_cast<Relocation_t*>(reloc)->WriteToDB(fileptr,dynamic_cast<BaseObj_t*>(i)); + } + +// eh pgms relocs + for(const auto& i : eh_pgms) + { + const auto &relocs=i->getRelocations(); + for(auto& reloc : relocs) + W_reloc << dynamic_cast<Relocation_t*>(reloc)->WriteToDB(fileptr,dynamic_cast<BaseObj_t*>(i)); + } +// scoops relocs + for(const auto& i : scoops) + { + const auto &relocs=i->getRelocations(); + for(auto& reloc : relocs) + W_reloc << dynamic_cast<Relocation_t*>(reloc)->WriteToDB(fileptr,dynamic_cast<BaseObj_t*>(i)); + } +// write out instruction's relocs + for(const auto& i : insns) + { + const auto &relocs=i->getRelocations(); + for(auto& reloc : relocs) + W_reloc << dynamic_cast<Relocation_t*>(reloc)->WriteToDB(fileptr,dynamic_cast<BaseObj_t*>(i)); + } + W_reloc.complete(); + +} + + +db_id_t FileIR_t::getMaxBaseID() const +{ +#define MAX(a,b) (((a)>(b)) ? (a) : (b)) + + /* find the highest database ID */ + db_id_t j=0; + for(auto i=funcs.begin(); i!=funcs.end(); ++i) + j=MAX(j,(*i)->getBaseID()); + for(auto i=addrs.begin(); i!=addrs.end(); ++i) + j=MAX(j,(*i)->getBaseID()); + for(auto i=insns.begin(); i!=insns.end(); ++i) + j=MAX(j,(*i)->getBaseID()); + for(auto i=relocs.begin(); i!=relocs.end(); ++i) + j=MAX(j,(*i)->getBaseID()); + for(auto i=types.begin(); i!=types.end(); ++i) + j=MAX(j,(*i)->getBaseID()); + for(auto i=scoops.begin(); i!=scoops.end(); ++i) + j=MAX(j,(*i)->getBaseID()); + for(auto i=icfs_set.begin(); i!=icfs_set.end(); ++i) + j=MAX(j,(*i)->getBaseID()); + for(auto i=eh_pgms.begin(); i!=eh_pgms.end(); ++i) + j=MAX(j,(*i)->getBaseID()); + for(auto i=eh_css.begin(); i!=eh_css.end(); ++i) + j=MAX(j,(*i)->getBaseID()); + + return j+1; // easy to off-by-one this so we do it for a user just in case. +} + +void FileIR_t::setBaseIDS() +{ + auto j=getMaxBaseID(); + /* increment past the max ID so we don't duplicate */ + j++; + /* for anything that's not yet in the DB, assign an ID to it */ + for(auto i=funcs.begin(); i!=funcs.end(); ++i) + if((*i)->getBaseID()==NOT_IN_DATABASE) + (*i)->setBaseID(j++); + for(auto i=addrs.begin(); i!=addrs.end(); ++i) + if((*i)->getBaseID()==NOT_IN_DATABASE) + (*i)->setBaseID(j++); + for(auto i=insns.begin(); i!=insns.end(); ++i) + if((*i)->getBaseID()==NOT_IN_DATABASE) + (*i)->setBaseID(j++); + for(auto i=relocs.begin(); i!=relocs.end(); ++i) + if((*i)->getBaseID()==NOT_IN_DATABASE) + (*i)->setBaseID(j++); + for(auto i=types.begin(); i!=types.end(); ++i) + if((*i)->getBaseID()==NOT_IN_DATABASE) + (*i)->setBaseID(j++); + for(auto i=scoops.begin(); i!=scoops.end(); ++i) + if((*i)->getBaseID()==NOT_IN_DATABASE) + (*i)->setBaseID(j++); + for(auto i=icfs_set.begin(); i!=icfs_set.end(); ++i) + if((*i)->getBaseID()==NOT_IN_DATABASE) + (*i)->setBaseID(j++); + for(auto i=eh_pgms.begin(); i!=eh_pgms.end(); ++i) + if((*i)->getBaseID()==NOT_IN_DATABASE) + (*i)->setBaseID(j++); + for(auto i=eh_css.begin(); i!=eh_css.end(); ++i) + if((*i)->getBaseID()==NOT_IN_DATABASE) + (*i)->setBaseID(j++); +} + +const IRDB_SDK::ArchitectureDescription_t* IRDB_SDK::FileIR_t::getArchitecture() +{ + return libIRDB::FileIR_t::archdesc; +} + +uint32_t IRDB_SDK::FileIR_t::getArchitectureBitWidth() +{ + return libIRDB::FileIR_t::archdesc->getBitWidth(); +} + +void FileIR_t::setArchitecture(const int width, const ADMachineType_t mt) +{ + if(archdesc==NULL) + archdesc=new ArchitectureDescription_t; + archdesc->setBitWidth(width); + archdesc->setMachineType(mt); +} + +void FileIR_t::setArchitecture() +{ + + /* the first 16 bytes of an ELF file define the magic number and ELF Class. */ + // unsigned char e_ident[16]; + union + { + Elf32_Ehdr ehdr32; + Elf64_Ehdr ehdr64; + } hdr_union; + + auto myinter=BaseObj_t::GetInterface(); + auto *mypqxxintr=dynamic_cast<pqxxDB_t*>(myinter); + + const auto elfoid=getFile()->getELFOID(); + pqxx::largeobjectaccess loa(mypqxxintr->getTransaction(), elfoid, PGSTD::ios::in); + + + loa.cread((char*)&hdr_union, sizeof(hdr_union)); + + const auto e_ident=hdr_union.ehdr32.e_ident; + + libIRDB::FileIR_t::archdesc=new ArchitectureDescription_t; + + auto is_elf=false; + auto is_pe=false; + + if((e_ident[EI_MAG0]==ELFMAG0) && + (e_ident[EI_MAG1]==ELFMAG1) && + (e_ident[EI_MAG2]==ELFMAG2) && + (e_ident[EI_MAG3]==ELFMAG3)) + { + is_elf=true; + } + else if((e_ident[EI_MAG0]=='M') && + (e_ident[EI_MAG1]=='Z')) + { + is_pe=true; + } + else + { + cerr << "File format magic number wrong: is this an ELF, PE or CGC file? [" << e_ident[EI_MAG0] << " " << e_ident[EI_MAG1] << "]" << endl; + exit(-1); + } + + + if (is_pe) // libIRDB::FileIR_t::archdesc->getFileType() == IRDB_SDK::adftPE) + { + libIRDB::FileIR_t::archdesc->setFileType(IRDB_SDK::adftPE); + // just assume x86-64 bit for Windows, o/w could also extract from file + libIRDB::FileIR_t::archdesc->setBitWidth(64); + libIRDB::FileIR_t::archdesc->setMachineType(IRDB_SDK::admtX86_64); + } + else if(is_elf) + { + switch(e_ident[4]) + { + case ELFCLASS32: + { + + if(hdr_union.ehdr32.e_type == ET_DYN) + libIRDB::FileIR_t::archdesc->setFileType(IRDB_SDK::adftELFSO); + else + libIRDB::FileIR_t::archdesc->setFileType(IRDB_SDK::adftELFEXE); + libIRDB::FileIR_t::archdesc->setBitWidth(32); + if(hdr_union.ehdr32.e_machine!=EM_386) + throw std::invalid_argument("Arch not supported. 32-bit archs supported: I386"); + libIRDB::FileIR_t::archdesc->setMachineType(IRDB_SDK::admtI386); + break; + } + case ELFCLASS64: + { + if(hdr_union.ehdr64.e_type == ET_DYN) + libIRDB::FileIR_t::archdesc->setFileType(IRDB_SDK::adftELFSO); + else + libIRDB::FileIR_t::archdesc->setFileType(IRDB_SDK::adftELFEXE); + libIRDB::FileIR_t::archdesc->setBitWidth(64); + const auto mt= + hdr_union.ehdr64.e_machine==EM_AARCH64 ? IRDB_SDK::admtAarch64 : + hdr_union.ehdr64.e_machine==EM_X86_64 ? IRDB_SDK::admtX86_64 : + throw std::invalid_argument("Arch not supported. 64-bit archs supported: Aarch64, X86-64"); + libIRDB::FileIR_t::archdesc->setMachineType(mt); + break; + } + default: + cerr << "Unknown ELF class " <<endl; + exit(-1); + } + } +} + +ArchitectureDescription_t* FileIR_t::archdesc=NULL; + +std::map<db_id_t, Type_t*> FileIR_t::ReadTypesFromDB (TypeSet_t& types) +{ + std::map<db_id_t, Type_t*> tMap; + + // 3 pass algorithm. Must be done in this exact order as: + // aggregrate type depend on basic types + // function type depends on both aggregate and basic types + // + // pass 1: retrieve all basic types + // pass 2: retrieve all aggregate types + // pass 3: retrieve all function types + // + + // pass 1, get all the basic types first +// std::string q= "select * from " + fileptr->types_table_name + " WHERE ref_type_id = -1 AND ref_type_id2 = -1 AND pos = -1 order by type; "; + + std::string q= "select * from " + fileptr->types_table_name + " WHERE ref_type_id = -1 order by type; "; + +// cout << "pass1: query: " << q; + + dbintr->issueQuery(q); + + while(!dbintr->isDone()) + { +// type_id integer, +// type integer DEFAULT 0, -- possible types (0: UNKNOWN) +// name text DEFAULT '', -- string representation of the type +// ref_type_id integer DEFAULT -1, -- for aggregate types and func +// pos integer DEFAULT -1, -- for aggregate types, position in aggregate +// ref_type_id2 integer DEFAULT -1, -- for func types +// doip_id integer DEFAULT -1 -- the DOIP + + db_id_t tid=atoi(dbintr->getResultColumn("type_id").c_str()); + IRDB_Type type=(IRDB_Type)atoi(dbintr->getResultColumn("type").c_str()); + std::string name=dbintr->getResultColumn("name"); + BasicType_t *t = NULL; + +// cout << "fileir::ReadFromDB(): pass1: " << name << endl; + switch(type) + { + case IRDB_SDK::itUnknown: + case IRDB_SDK::itVoid: + case IRDB_SDK::itNumeric: + case IRDB_SDK::itVariadic: + case IRDB_SDK::itInt: + case IRDB_SDK::itChar: + case IRDB_SDK::itFloat: + case IRDB_SDK::itDouble: + t = new BasicType_t(tid, type, name); + types.insert(t); + tMap[tid] = t; + break; + + case IRDB_SDK::itPointer: + // do nothing for pointers + break; + + default: + cerr << "ReadTypesFromDB(): ERROR: pass 1 should only see basic types or pointer" << endl; + assert(0); + break; + } + + dbintr->moveToNextRow(); + } // end pass1 + + char query[2048]; + + // pass2 get pointers + sprintf(query,"select * from %s WHERE type = %d;", fileptr->types_table_name.c_str(), IRDB_SDK::itPointer); + dbintr->issueQuery(query); + + while(!dbintr->isDone()) + { + db_id_t tid=atoi(dbintr->getResultColumn("type_id").c_str()); + IRDB_Type type=(IRDB_Type)atoi(dbintr->getResultColumn("type").c_str()); + std::string name=dbintr->getResultColumn("name"); + db_id_t ref1=atoi(dbintr->getResultColumn("ref_type_id").c_str()); +// cout << "fileir::ReadFromDB(): pass2 (pointers): " << name << endl; + switch(type) + { + case IRDB_SDK::itPointer: + { +// cout << " pointer type: ref1: " << ref1 << endl; + Type_t *referentType = NULL; + if (ref1 >= 0) + { + assert(tMap.count(ref1) > 0); + referentType = tMap[ref1]; + } + PointerType_t *ptr = new PointerType_t(tid, referentType, name); + types.insert(ptr); + tMap[tid] = ptr; + } + break; + + default: + cerr << "ReadTypesFromDB(): ERROR: pass3: unhandled type id = " << type << endl; + assert(0); // not yet handled + break; + + } + + dbintr->moveToNextRow(); + } // end pass3 + + // pass3 get all aggregates + sprintf(query,"select * from %s WHERE type = %d order by type_id, pos;", fileptr->types_table_name.c_str(), IRDB_SDK::itAggregate); + dbintr->issueQuery(query); + + while(!dbintr->isDone()) + { + db_id_t tid=atoi(dbintr->getResultColumn("type_id").c_str()); + IRDB_Type type=(IRDB_Type)atoi(dbintr->getResultColumn("type").c_str()); + std::string name=dbintr->getResultColumn("name"); + db_id_t ref1=atoi(dbintr->getResultColumn("ref_type_id").c_str()); + int pos=atoi(dbintr->getResultColumn("pos").c_str()); + AggregateType_t *agg = NULL; +// cout << "fileir::ReadFromDB(): pass3 (aggregates): " << name << endl; + switch(type) + { + case IRDB_SDK::itAggregate: + { + if (tMap.count(tid) == 0) // new aggregate + { +// cout << "fileir::ReadFromDB(): pass3: new aggregate type: typeid: " << tid << " name: " << name << endl; + agg = new AggregateType_t(tid, name); + types.insert(agg); + tMap[tid] = agg; + } + else + agg = dynamic_cast<AggregateType_t*>(tMap[tid]); + + assert(agg); + // ref1 has the id of a basic type, look it up + Type_t *ref = tMap[ref1]; + assert(ref); + agg->addAggregatedType(ref, pos); + } + break; + + default: + cerr << "ReadTypesFromDB(): ERROR: pass2: unhandled type id = " << type << endl; + assert(0); // not yet handled + break; + + } + + dbintr->moveToNextRow(); + } // end pass3 + + // pass4 get all functions + sprintf(query,"select * from %s WHERE type = %d;", fileptr->types_table_name.c_str(), IRDB_SDK::itFunc); + dbintr->issueQuery(query); + + while(!dbintr->isDone()) + { + db_id_t tid=atoi(dbintr->getResultColumn("type_id").c_str()); + IRDB_Type type=(IRDB_Type)atoi(dbintr->getResultColumn("type").c_str()); + std::string name=dbintr->getResultColumn("name"); + db_id_t ref1=atoi(dbintr->getResultColumn("ref_type_id").c_str()); + db_id_t ref2=atoi(dbintr->getResultColumn("ref_type_id2").c_str()); + FuncType_t *fn = NULL; + + switch(type) + { + case IRDB_SDK::itFunc: + { + assert(tMap.count(tid) == 0); + + fn = new FuncType_t(tid, name); + types.insert(fn); + tMap[tid] = fn; + assert(tMap[ref1]); // return type + assert(tMap[ref2]); // argument type (which is an aggregate) + fn->setReturnType(tMap[ref1]); + AggregateType_t *args = dynamic_cast<AggregateType_t*>(tMap[ref2]); + assert(args); + fn->setArgumentsType(args); + break; + } + default: + cerr << "ReadTypesFromDB(): ERROR: pass4: unhandled type id = " << type << endl; + assert(0); // not yet handled + break; + + } + + dbintr->moveToNextRow(); + } // end pass4 + + return tMap; +} + +void FileIR_t::ReadAllICFSFromDB(std::map<db_id_t,Instruction_t*> &addr2instMap, + std::map<Instruction_t*, db_id_t> &unresolvedICFS) +{ + std::map<db_id_t, ICFS_t*> icfsMap; + + // retrieve all sets + std::string q= "select * from " + fileptr->icfs_table_name + " ; "; + dbintr->issueQuery(q); + + while(!dbintr->isDone()) + { + db_id_t icfs_id = atoi(dbintr->getResultColumn("icfs_id").c_str()); + string statusString=dbintr->getResultColumn("icfs_status"); + + ICFS_t* icfs = new ICFS_t(icfs_id, statusString); + GetAllICFS().insert(icfs); + + icfsMap[icfs_id] = icfs; + dbintr->moveToNextRow(); + } + + ICFSSet_t all_icfs = GetAllICFS(); + + // for each set, populate its members + for (auto it = all_icfs.begin(); it != all_icfs.end(); ++it) + { + char query2[2048]; + auto icfs = dynamic_cast<ICFS_t*>(*it); + assert(icfs); + int icfsid = icfs->getBaseID(); + sprintf(query2,"select * from %s WHERE icfs_id = %d;", fileptr->icfs_map_table_name.c_str(), icfsid); + dbintr->issueQuery(query2); + while(!dbintr->isDone()) + { + db_id_t address_id = atoi(dbintr->getResultColumn("address_id").c_str()); + Instruction_t* instruction = addr2instMap[address_id]; + if (instruction) + { + icfs->insert(instruction); + } + + // @todo: handle cross-file addresses + // these are allowed by the DB schema but we don't yet handle them + // if we encounter an unresolved address, we should mark the ICFS + // as unresolved + + dbintr->moveToNextRow(); + } + } + + // backpatch all unresolved instruction -> ICFS + std::map<Instruction_t*, db_id_t>::iterator uit; + for (auto uit = unresolvedICFS.begin(); uit != unresolvedICFS.end(); ++uit) + { + auto unresolved = dynamic_cast<Instruction_t*>(uit->first); + db_id_t icfs_id = uit->second; + + assert(unresolved); + + ICFS_t *icfs = icfsMap[icfs_id]; + assert(icfs); + + unresolved->setIBTargets(icfs); + } +} + +void FileIR_t::GarbageCollectICFS(ostream* verbose_logging) +{ + auto used_icfs= ICFSSet_t(); + // get the IBTarget of each instruction into used_icfs + transform( ALLOF(insns), inserter(used_icfs, begin(used_icfs)), + [](const IRDB_SDK::Instruction_t* insn) -> IRDB_SDK::ICFS_t* { return insn->getIBTargets(); } + ); + // we likely inserted null into the set, which we just will remove as a special ase. + used_icfs.erase(nullptr); + + // update the list to include only the used ones. + icfs_set=used_icfs; +} + +void FileIR_t::DedupICFS(ostream *verbose_logging) +{ + std::set<InstructionSet_t> unique_icfs; + + auto& all_icfs=this->GetAllICFS(); + + // detect duplicate icfs + ICFSSet_t duplicates; + for(auto it=all_icfs.begin(); it!=all_icfs.end(); ++it) + { + auto p=dynamic_cast<ICFS_t*>(*it); + assert(p); + auto ret = unique_icfs.insert( *p ); + if (!ret.second) { + duplicates.insert(p); + } + } + + if (duplicates.size() > 0) + { + *verbose_logging << "FileIR_t::DedupICFS(): WARNING: " << dec << duplicates.size() << " duplicate ICFS out of " << all_icfs.size() << " total ICFS"; + *verbose_logging << ". De-duplicating before committing to IRDB" << endl; + } + + // remove duplicate icfs + for(auto it=duplicates.begin(); it!=duplicates.end(); ++it) + { + auto icfs=*it; + all_icfs.erase(icfs); + } + + // build duplicate icfs map + std::map<IRDB_SDK::ICFS_t*, IRDB_SDK::ICFS_t*> duplicate_map; + for(auto it=duplicates.begin(); it!=duplicates.end(); ++it) + { + auto icfs = *it; + for(auto it=all_icfs.begin(); it!=all_icfs.end(); ++it) + { + auto t = *it; + + assert(t); + if (*icfs == *t) + { + duplicate_map[icfs] = t; + *verbose_logging << "FileIR_t::DedupICFS(): remap: icfs id " << icfs->getBaseID() << " --> icsf id " << t->getBaseID() << endl; + break; + } + } + } + + // reassign ibtargets + for(auto it=this->GetInstructions().begin(); + it!=this->GetInstructions().end(); + ++it) + { + auto instr=*it; + if(instr->getIBTargets() && duplicate_map[instr->getIBTargets()]) + { + instr->setIBTargets(duplicate_map[instr->getIBTargets()]); + } + } +} + +void FileIR_t::CleanupICFS(ostream *verbose_logging) +{ + GarbageCollectICFS(verbose_logging); + DedupICFS(verbose_logging); +} + +std::map<db_id_t,DataScoop_t*> FileIR_t::ReadScoopsFromDB + ( + std::map<db_id_t,AddressID_t*> &addrMap, + std::map<db_id_t,Type_t*> &typeMap + ) +{ +/* + scoop_id SERIAL PRIMARY KEY, -- key + name text DEFAULT '', -- string representation of the type + type_id integer, -- the type of the data, as an index into the table table. + start_address_id integer, -- address id for start. + end_address_id integer, -- address id for end + permissions integer -- in umask format (bitmask for rwx) + + */ + + std::map<db_id_t,DataScoop_t*> scoopMap; + + //std::map<db_id_t,string> bonus_contents; + // + // read part 2 of the scoops. + //std::string q= "select * from " + fileptr->scoop_table_name + "_part2 ; "; + //dbintr->issueQuery(q); + //while(!dbintr->isDone()) + //{ + // db_id_t sid=atoi(dbintr->getResultColumn("scoop_id").c_str()); + // bonus_contents[sid]=dbintr->getResultColumn("data"); + // dbintr->moveToNextRow(); + //} + + + + // read part 1 of the scoops, and merge in the part 2s + // scoop_id SERIAL PRIMARY KEY, -- key + // name text DEFAULT '', -- string representation of the type + // type_id integer, -- the type of the data, as an index into the table table. + // start_address_id integer, -- address id for start. + // end_address_id integer, -- address id for end + // permissions integer, -- in umask format (bitmask for rwx) + // relro bit, -- is this scoop a relro scoop (i.e., is r/w until relocs are done). + // data bytea -- the actual bytes of the scoop + + string q= "select scoop_id,name,type_id,start_address_id,end_address_id,permissions,relro from " + fileptr->scoop_table_name + " ; "; + dbintr->issueQuery(q); + while(!dbintr->isDone()) + { + + db_id_t sid=atoi(dbintr->getResultColumn("scoop_id").c_str()); + std::string name=dbintr->getResultColumn("name"); + db_id_t type_id=atoi(dbintr->getResultColumn("type_id").c_str()); + Type_t *type=typeMap[type_id]; + db_id_t start_id=atoi(dbintr->getResultColumn("start_address_id").c_str()); + AddressID_t* start_addr=addrMap[start_id]; + db_id_t end_id=atoi(dbintr->getResultColumn("end_address_id").c_str()); + AddressID_t* end_addr=addrMap[end_id]; + int permissions=atoi(dbintr->getResultColumn("permissions").c_str()); + bool is_relro=atoi(dbintr->getResultColumn("relro").c_str()) != 0 ; + + DataScoop_t* newscoop=new DataScoop_t(sid,name,start_addr,end_addr,type,permissions,is_relro,""); + assert(newscoop); + GetDataScoops().insert(newscoop); + dbintr->moveToNextRow(); + + scoopMap[sid]=newscoop; + } + + for(auto it=getDataScoops().begin(); it!=getDataScoops().end(); ++it) + { + DataScoop_t* scoop=dynamic_cast<DataScoop_t*>(*it); + + q= "select length(data) from " + fileptr->scoop_table_name + " where scoop_id='"+to_string(scoop->getBaseID())+"'; "; + dbintr->issueQuery(q); + if(!dbintr->isDone()) + { + int data_len=atoi(dbintr->getResultColumn("length").c_str()); + for(int i=0;i<data_len;i+=SCOOP_CHUNK_SIZE) + { + string start_pos=to_string(i); + string len_to_get=to_string(SCOOP_CHUNK_SIZE); + string field="substr(data,"+start_pos+","+len_to_get+")"; + q= "select "+field+" from " + fileptr->scoop_table_name + " where scoop_id='"+to_string(scoop->getBaseID())+"'; "; + dbintr->issueQuery(q); + + scoop->getContents()+=dbintr->getResultColumn("substr"); + + } + } + + + // read part 2 from db + q= "select length(data) from " + fileptr->scoop_table_name + "_part2 where scoop_id='"+to_string(scoop->getBaseID())+"'; "; + dbintr->issueQuery(q); + if(!dbintr->isDone()) + { + int part2_len=atoi(dbintr->getResultColumn("length").c_str()); + for(int i=0;i<part2_len; i+=SCOOP_CHUNK_SIZE) + { + string start_pos=to_string(i); + string len_to_get=to_string(SCOOP_CHUNK_SIZE); + string field="substr(data,"+start_pos+","+len_to_get+")"; + q= "select "+field+" from " + fileptr->scoop_table_name + "_part2 where scoop_id='"+to_string(scoop->getBaseID())+"'; "; + dbintr->issueQuery(q); + + scoop->getContents()+=dbintr->getResultColumn("substr"); + + } + } + } + for(auto s : getDataScoops()) + { + auto scoop=dynamic_cast<DataScoop_t*>(s); + assert(scoop->getContents().size() == scoop->getSize()); + } + + + return scoopMap; +} + + +// Lookup a scoop by address +IRDB_SDK::DataScoop_t* FileIR_t::findScoop(const IRDB_SDK::VirtualOffset_t &addr) const +{ + for(auto it=scoops.begin(); it!=scoops.end(); ++it) + { + auto s=dynamic_cast<DataScoop_t*>(*it); + // we're doing <= in both comparisons here intentionally. + // scoop addresses are the start/end address are inclusive + // so that start+size-1 == end. + if( s->getStart()->getVirtualOffset() <= addr && addr <= s->getEnd()->getVirtualOffset() ) + return *it; + } + return NULL; +} + + +void FileIR_t::splitScoop( + IRDB_SDK::DataScoop_t *p_tosplit, + const IRDB_SDK::VirtualOffset_t &addr, + size_t size, + IRDB_SDK::DataScoop_t* &p_before, + IRDB_SDK::DataScoop_t* &p_containing, + IRDB_SDK::DataScoop_t* &p_after, + IRDB_SDK::DatabaseID_t *max_id_ptr /* in and out param */ + ) +{ + auto tosplit = dynamic_cast<DataScoop_t*>(p_tosplit); + auto before = dynamic_cast<DataScoop_t*>(p_before); + auto containing = dynamic_cast<DataScoop_t*>(p_containing); + auto after = dynamic_cast<DataScoop_t*>(p_after); + + // init output params. + before=containing=after=NULL; + + + if(tosplit->getStart()->getVirtualOffset() == addr && + tosplit->getEnd()->getVirtualOffset() == addr+size-1) + { + // no split necessary + p_containing=tosplit; + return; + } + + auto calcd_max_id=db_id_t(0); + if(max_id_ptr==NULL) + calcd_max_id = getMaxBaseID(); + + auto &max_id = max_id_ptr == NULL ? calcd_max_id : *max_id_ptr ; + + if(max_id==0) + max_id=calcd_max_id; + + const auto multiple=(unsigned)1000; + + // round to nearest multiple + const auto rounded_max = ((max_id + (multiple/2)) / multiple) * multiple; + + max_id=rounded_max + multiple; // and skip forward so we're passed the highest. + + const bool needs_before = addr!=tosplit->getStart()->getVirtualOffset(); + const bool needs_after = addr+size-1 != tosplit->getEnd()->getVirtualOffset(); + + + if(needs_before) + { + // setup before + // const AddressID_t* before_start=NULL; + + const auto before_start=new AddressID_t; + before_start->setBaseID(max_id++); + before_start->setFileID(tosplit->getStart()->getFileID()); + before_start->setVirtualOffset(tosplit->getStart()->getVirtualOffset()); + + // const AddressID_t* before_end=new AddressID_t; + const auto before_end=new AddressID_t; + before_end->setBaseID(max_id++); + before_end->setFileID(tosplit->getStart()->getFileID()); + before_end->setVirtualOffset(addr-1); + + before=new DataScoop_t; + before->setBaseID(max_id++); + before->setName(tosplit->getName()+"3"); + before->setStart(before_start); + before->setEnd(before_end); + before->setRawPerms(tosplit->getRawPerms()); + before->getContents().resize(before_end->getVirtualOffset() - before_start->getVirtualOffset()+1); + + // copy bytes + for(virtual_offset_t i=before_start->getVirtualOffset() ; i <= before_end->getVirtualOffset(); i++) + before->getContents()[i-before_start->getVirtualOffset()] = tosplit->getContents()[i-tosplit->getStart()->getVirtualOffset()]; + + + GetAddresses().insert(before_start); + GetAddresses().insert(before_end); + GetDataScoops().insert(before); + } + + // setup containing + // AddressID_t* containing_start=new AddressID_t; + const auto containing_start=new AddressID_t; + containing_start->setBaseID(max_id++); + containing_start->setFileID(tosplit->getStart()->getFileID()); + containing_start->setVirtualOffset(addr); + + //AddressID_t* containing_end=new AddressID_t; + const auto containing_end=new AddressID_t; + containing_end->setBaseID(max_id++); + containing_end->setFileID(tosplit->getStart()->getFileID()); + containing_end->setVirtualOffset(addr+size-1); + + containing=new DataScoop_t; + containing->setBaseID(max_id++); + containing->setName(tosplit->getName()+"3"); + containing->setStart(containing_start); + containing->setEnd(containing_end); + containing->setRawPerms(tosplit->getRawPerms()); + containing->getContents().resize(containing_end->getVirtualOffset() - containing_start->getVirtualOffset()+1); + // copy bytes + for(virtual_offset_t i=containing_start->getVirtualOffset() ; i <= containing_end->getVirtualOffset(); i++) + containing->getContents()[i-containing_start->getVirtualOffset()] = tosplit->getContents()[i-tosplit->getStart()->getVirtualOffset()]; + + GetAddresses().insert(containing_start); + GetAddresses().insert(containing_end); + GetDataScoops().insert(containing); + + + if(needs_after) + { + // setup after + // AddressID_t* after_start=new AddressID_t; + const auto after_start=new AddressID_t; + after_start->setBaseID(max_id++); + after_start->setFileID(tosplit->getStart()->getFileID()); + after_start->setVirtualOffset(addr+size); + + // AddressID_t* after_end=new AddressID_t; + const auto after_end=new AddressID_t; + after_end->setBaseID(max_id++); + after_end->setFileID(tosplit->getStart()->getFileID()); + after_end->setVirtualOffset(tosplit->getEnd()->getVirtualOffset()); + + after=new DataScoop_t; + after->setBaseID(max_id++); + after->setName(tosplit->getName()+"3"); + after->setStart(after_start); + after->setEnd(after_end); + after->setRawPerms(tosplit->getRawPerms()); + after->getContents().resize(after_end->getVirtualOffset() - after_start->getVirtualOffset()+1); + // copy bytes + for(virtual_offset_t i=after_start->getVirtualOffset() ; i <= after_end->getVirtualOffset(); i++) + after->getContents()[i-after_start->getVirtualOffset()] = tosplit->getContents()[i-tosplit->getStart()->getVirtualOffset()]; + + GetAddresses().insert(after_start); + GetAddresses().insert(after_end); + GetDataScoops().insert(after); + } + + + // since tosplit is going away, we need to move every relocation from the + // tosplit scoop into one of the others. Iterate through each and + // adjust the reloc's offset accordingly before inserting into the correct scoop's reloc set. + while(!tosplit->GetRelocations().empty()) + { + auto reloc=dynamic_cast<Relocation_t*>(*(tosplit->getRelocations().begin())); + tosplit->GetRelocations().erase(tosplit->getRelocations().begin()); + + virtual_offset_t reloc_start=reloc->getOffset()+tosplit->getStart()->getVirtualOffset(); + + if(reloc_start < containing->getStart()->getVirtualOffset() ) + { + before->GetRelocations().insert(reloc); + } + else if(reloc_start > containing->getEnd()->getVirtualOffset() ) + { + reloc->setOffset(reloc_start-after->getStart()->getVirtualOffset()); + after->GetRelocations().insert(reloc); + } + else + { + reloc->setOffset(reloc_start-containing->getStart()->getVirtualOffset()); + containing->GetRelocations().insert(reloc); + } + + } + + /* look at each relocation in the IR */ + for(auto & r : GetRelocations()) + { + if(r->getWRT()==tosplit) + { + const auto &addend=r->getAddend(); + const auto containing_start_offset=(containing -> getStart()->getVirtualOffset() - + tosplit->getStart()->getVirtualOffset()); + const auto containing_end_offset=containing_start_offset+containing->getSize(); + if(needs_before && addend<before->getSize()) + { + r->setWRT(before); + } + else if( addend < containing_end_offset) + { + r->setWRT(containing); + r->setAddend(addend-containing_start_offset); + } + else + { + assert(needs_after); + const auto after_start_offset=(after -> getStart()->getVirtualOffset() - + tosplit->getStart()->getVirtualOffset()); + r->setWRT(after); + r->setAddend(addend-after_start_offset); + } + } + } + + + GetAddresses().erase(tosplit->getStart()); + GetAddresses().erase(tosplit->getEnd()); + GetDataScoops().erase(tosplit); + + delete tosplit->getStart(); + delete tosplit->getEnd(); + delete tosplit; + + // set output parameters before returning. + p_before = before; + p_containing= containing; + p_after = after; + + return; +} + + +IRDB_SDK::EhCallSite_t* FileIR_t::addEhCallSite_t(IRDB_SDK::Instruction_t* for_insn, const uint64_t enc, IRDB_SDK::Instruction_t* lp) +{ + auto new_ehcs = new libIRDB::EhCallSite_t(BaseObj_t::NOT_IN_DATABASE, enc, lp); + GetAllEhCallSites().insert(new_ehcs); + for_insn->setEhCallSite(new_ehcs); + return new_ehcs; + +} + +IRDB_SDK::Relocation_t* FileIR_t::addNewRelocation( + IRDB_SDK::BaseObj_t* p_from_obj, + int32_t p_offset, + string p_type, + IRDB_SDK::BaseObj_t* p_wrt_obj, + int32_t p_addend) +{ + const auto from_obj=dynamic_cast<libIRDB::BaseObj_t*>(p_from_obj); + auto newreloc=new libIRDB::Relocation_t(BaseObj_t::NOT_IN_DATABASE, p_offset, p_type, p_wrt_obj, p_addend); + GetRelocations().insert(newreloc); + if(from_obj) + from_obj->GetRelocations().insert(newreloc); + + return newreloc; +} + +EhProgram_t* FileIR_t::addEhProgram( + IRDB_SDK::Instruction_t* insn, + const uint64_t caf, + const int64_t daf, + const uint8_t rr, + const uint8_t p_ptrsize, + const EhProgramListing_t& p_cie_program, + const EhProgramListing_t& p_fde_program) +{ + auto newehpgm=new EhProgram_t(BaseObj_t::NOT_IN_DATABASE, caf,daf,rr,p_ptrsize, p_cie_program, p_fde_program); + assert(newehpgm); + GetAllEhPrograms().insert(newehpgm); + if(insn) + insn->setEhProgram(newehpgm); + return newehpgm; +} + + + +void FileIR_t::removeScoop(IRDB_SDK::DataScoop_t* s) +{ + auto remove_reloc=[&](IRDB_SDK::Relocation_t* r) -> void + { + GetRelocations().erase(r); + delete r; + }; + + auto remove_address=[&](IRDB_SDK::AddressID_t* a) -> void + { + GetAddresses().erase(a); + for(auto &r : a->getRelocations()) remove_reloc(r); + for(auto &r : getRelocations()) assert(r->getWRT() != a); + delete a; + }; + + auto remove_scoop=[&] (IRDB_SDK::DataScoop_t* s) -> void + { + if(s==NULL) + return; + GetDataScoops().erase(s); + remove_address(s->getStart()); + remove_address(s->getEnd()); + for(auto &r : s->getRelocations()) remove_reloc(r); + for(auto &r : GetRelocations()) assert(r->getWRT() != s); + delete s; + }; + + remove_scoop(s); +} + +IRDB_SDK::AddressID_t* FileIR_t::addNewAddress(const IRDB_SDK::DatabaseID_t& myfileID, const IRDB_SDK::VirtualOffset_t& voff) +{ + auto newaddr = new libIRDB::AddressID_t(BaseObj_t::NOT_IN_DATABASE, myfileID, voff); + GetAddresses().insert(newaddr); + return newaddr; +} + + +IRDB_SDK::ICFS_t* FileIR_t::addNewICFS( + IRDB_SDK::Instruction_t* insn, + const IRDB_SDK::InstructionSet_t& targets, + const IRDB_SDK::ICFSAnalysisStatus_t& status) +{ + auto newicfs=new libIRDB::ICFS_t(BaseObj_t::NOT_IN_DATABASE, status); + newicfs->setTargets(targets); + if(insn) + insn->setIBTargets(newicfs); + GetAllICFS().insert(newicfs); + return newicfs; +} + +IRDB_SDK::Instruction_t* FileIR_t::addNewInstruction( + IRDB_SDK::AddressID_t* addr, + IRDB_SDK::Function_t* func, + const string& bits, + const string& comment, + IRDB_SDK::AddressID_t* indTarg) +{ + auto irdb_func = dynamic_cast<libIRDB::Function_t* >(func); + auto irdb_addr = dynamic_cast<libIRDB::AddressID_t*>(addr); + auto irdb_indTarg = dynamic_cast<libIRDB::AddressID_t*>(indTarg); + + if(irdb_addr==nullptr) + { + irdb_addr=dynamic_cast<libIRDB::AddressID_t*>(addNewAddress(getFile()->getBaseID(), 0)); + } + + auto newinsn=new libIRDB::Instruction_t(BaseObj_t::NOT_IN_DATABASE, irdb_addr, irdb_func, BaseObj_t::NOT_IN_DATABASE, bits, "", comment, irdb_indTarg, BaseObj_t::NOT_IN_DATABASE); + + GetInstructions().insert(newinsn); + + if(irdb_func) + irdb_func->GetInstructions().insert(newinsn); + return newinsn; +} + +IRDB_SDK::DataScoop_t* FileIR_t::addNewDataScoop( + const string& p_name, + IRDB_SDK::AddressID_t* p_start, + IRDB_SDK::AddressID_t* p_end, + IRDB_SDK::Type_t* p_type, + uint8_t p_permissions, + bool p_is_relro, + const string& p_contents, + IRDB_SDK::DatabaseID_t id) +{ + auto irdb_start = dynamic_cast<libIRDB::AddressID_t*>(p_start); + auto irdb_end = dynamic_cast<libIRDB::AddressID_t*>(p_end); + auto irdb_type = dynamic_cast<libIRDB::Type_t*> (p_type); + + auto newscoop=new libIRDB::DataScoop_t(id, p_name,irdb_start,irdb_end,irdb_type,p_permissions, p_is_relro, p_contents); + GetDataScoops().insert(newscoop); + return newscoop; +} + +IRDB_SDK::EhProgram_t* FileIR_t::copyEhProgram(const IRDB_SDK::EhProgram_t& orig) +{ + const auto ehpgm=dynamic_cast<const libIRDB::EhProgram_t*>(&orig); + assert(ehpgm); + auto new_eh_pgm=new libIRDB::EhProgram_t(*ehpgm); + GetAllEhPrograms().insert(new_eh_pgm); + return new_eh_pgm; +} + + + diff --git a/irdb-lib/libIRDB-core/src/function.cpp b/irdb-lib/libIRDB-core/src/function.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0be6aa95b661e68a9c3a8e004b0e7c287e79662a --- /dev/null +++ b/irdb-lib/libIRDB-core/src/function.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <all.hpp> +#include <irdb-util> +#include <stdlib.h> + +using namespace libIRDB; +using namespace std; + +Function_t::Function_t(db_id_t id, std::string myname, int size, int oa_size, bool useFP, bool isSafe, IRDB_SDK::FuncType_t *fn_type, IRDB_SDK::Instruction_t* entry) + : BaseObj_t(NULL), entry_point(dynamic_cast<Instruction_t*>(entry)) +{ + setBaseID(id); + name=myname; + stack_frame_size=size; + out_args_region_size=oa_size; + use_fp = useFP; + setSafe(isSafe); + function_type = dynamic_cast<FuncType_t*>(fn_type); + if(entry) assert(entry_point); + if(fn_type) assert(function_type); +} + +string Function_t::WriteToDB(File_t *fid, db_id_t newid) +{ + assert(fid); + + int entryid=NOT_IN_DATABASE; + if(entry_point) + entryid=entry_point->getBaseID(); + + if(getBaseID()==NOT_IN_DATABASE) + setBaseID(newid); + + int function_type_id = NOT_IN_DATABASE; + if (getType()) + function_type_id = getType()->getBaseID(); + + string q=string("insert into ")+fid->function_table_name + + string(" (function_id, entry_point_id, name, stack_frame_size, out_args_region_size, use_frame_pointer, is_safe, type_id, doip_id) ")+ + string(" VALUES (") + + string("'") + to_string(getBaseID()) + string("', ") + + string("'") + to_string(entryid) + string("', ") + + string("'") + name + string("', ") + + string("'") + to_string(stack_frame_size) + string("', ") + + string("'") + to_string(out_args_region_size) + string("', ") + + string("'") + to_string(use_fp) + string("', ") + + string("'") + to_string(is_safe) + string("', ") + + string("'") + to_string(function_type_id) + string("', ") + + string("'") + to_string(getDoipID()) + string("') ; ") ; + + return q; +} + +int Function_t::getNumArguments() const +{ + if (!function_type) return -1; + auto argtype = function_type->getArgumentsType(); + if (argtype) + return argtype->getNumAggregatedTypes(); + else + return -1; +} + +void Function_t::setType(IRDB_SDK::FuncType_t *t) +{ + function_type = dynamic_cast<FuncType_t*>(t); + if(t) + assert(function_type); +} + +IRDB_SDK::FuncType_t* Function_t::getType() const +{ + return function_type; +} + diff --git a/irdb-lib/libIRDB-core/src/generate_spri.cpp b/irdb-lib/libIRDB-core/src/generate_spri.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d9754e9d27f9763aadefb38ec83e733db91b8ab6 --- /dev/null +++ b/irdb-lib/libIRDB-core/src/generate_spri.cpp @@ -0,0 +1,946 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + + +#include <all.hpp> +#include <irdb-util> // to_string function from libIRDB +#include <iostream> +#include <fstream> +#include <stdlib.h> +#include <map> +#include <string.h> +#include <assert.h> + +#undef EIP + +using namespace libIRDB; +using namespace std; + +#if 0 + +// forward decls for this file +static string qualified_addressify(FileIR_t* fileIRp, Instruction_t *insn); +static string labelfy(IRDB_SDK::Instruction_t* insn); + + +// +// the set of insturctions that have control +// transfers to them (including fallthrough type control transfers) from instructions that do not need a spri rule. +// +static set<Instruction_t*> unmoved_insn_targets; + +// +// The set of all addresses that are ibts +// +static set <AddressID_t> ibts; + +// +// map an instruction from the new variant back to the old variant; +// +static map<Instruction_t*,Instruction_t*> insnMap; + +// +// does this instruction need a spri rule +// +static bool needs_spri_rule(Instruction_t* newinsn,Instruction_t* oldinsn); + + +// +// return the address as a string for this instruction +// +static string addressify(Instruction_t* insn); + + +// +// determine if this branch has a short offset that can't be represented as a long branch +// +static bool needs_short_branch_rewrite(Instruction_t* newinsn, const DecodedInstruction_t &disasm) +{ + if ( (disasm.getMnemonic()== "jecxz" ) + || (disasm.getMnemonic()== "jrcxz" ) + || (disasm.getMnemonic()== "loop" ) + || (disasm.getMnemonic()== "loopne") + || (disasm.getMnemonic()== "loope" ) ) + return true; + + /* 64-bit has more needs than this */ + // if(disasm.Archi==32) + if(FileIR_t::getArchitectureBitWidth()==32) + return false; + + // if(disasm.Instruction.BranchType==0) /* non-branches, jumps, calls and returns don't need this rewrite */ + if(!disasm.isBranch()) + return false; + // if(disasm.Instruction.BranchType==JmpType) + if(disasm.isUnconditionalBranch()) + return false; + // if(disasm.Instruction.BranchType==CallType) + if(disasm.isCall()) + return false; + // if(disasm.Instruction.BranchType==RetType) + if(disasm.isReturn()) + return false; + + /* all other branches (on x86-64) need further checking */ + if(!newinsn->getTarget()) /* no specified target, no need to modify it */ + return false; + string new_target=labelfy(newinsn->getTarget()); + if (new_target.c_str()[0]=='0') /* if we're jumping back to the base instruction */ + return true; + return false; +} + + +// +// create a label for the given instruction +// +static string qualified_labelfy(FileIR_t* fileIRp, IRDB_SDK::Instruction_t* p_insn) +{ + auto insn=dynamic_cast<Instruction_t*>(p_insn); + if(!needs_spri_rule(insn, insnMap[insn])) + return qualified_addressify(fileIRp, insn); + + return labelfy(insn); +} + +static long long int label_offset=0; + +static void update_label_offset(FileIR_t *firp) +{ + int max=0; + for(auto insn : firp->GetInstructions()) + { + if(insn->getBaseID()>max) + max=insn->getBaseID(); + } + label_offset+=max+1; +} + +static long long int IDToSPRIID(int id) +{ + return id+label_offset; +} + +static string labelfy(IRDB_SDK::Instruction_t* p_insn) +{ + auto insn=dynamic_cast<Instruction_t*>(p_insn); + + if(!needs_spri_rule(insn, insnMap[insn])) + return addressify(insn); + + return string("LI_") + to_string(IDToSPRIID(insn->getBaseID())); +} + + +// +// return the address for an instruction. If the instruction has no absolute address, return the label for this instruction. +// +static string addressify(Instruction_t* insn) +{ + stringstream s; + + Instruction_t* old_insn=insnMap[insn]; + if(!old_insn) + return labelfy(insn); + + s<<"0x"<<std::hex<<old_insn->getAddress()->getVirtualOffset(); + + return s.str(); + + +} + +static string URLToFile(string url) +{ + auto loc=(size_t)0; + + loc=url.find('/'); + while(loc!=string::npos) + { + url=url.substr(loc+1,url.length()-loc-1); + + loc=url.find('/'); + } + // maybe need to check filename for odd characters + + return url; +} + +static string qualify(FileIR_t* fileIRp) +{ + return URLToFile(fileIRp->getFile()->GetURL()) + "+" ; +} + + +static string qualify_address(FileIR_t* fileIRp, int addr) +{ + stringstream ss; + ss<< qualify(fileIRp) << "0x" << std::hex << (addr); + return ss.str(); +} + +static string better_qualify_address(FileIR_t* fileIRp, IRDB_SDK::AddressID_t* addr) +{ + db_id_t fileID=addr->getFileID(); + virtual_offset_t off=addr->getVirtualOffset(); + + /* in theory, we could have an address from any file.. + * but this appears to be broken. NOT_IN_DATABASE means we're in the spri address space, + * so that's all i'm checking for for now. + * do it the old way if it's in the DB, else the new way. + */ + if(fileID!=BaseObj_t::NOT_IN_DATABASE) + return qualify_address(fileIRp,off); + + /* having a file not in the DB means we're int he spridd address space */ + stringstream s; + s<<"spridd+0x"<<std::hex<<off; + return s.str(); + +} + +static string qualified_addressify(FileIR_t* fileIRp, Instruction_t *insn) +{ + string address=addressify(insn); + if(address.c_str()[0]=='0') + return qualify(fileIRp) + address; + return address; + +} + +static string get_short_branch_label(Instruction_t *newinsn) +{ + if (!newinsn) + return string(""); + else + return "sj_" + labelfy(newinsn); +} + +static string get_data_label(Instruction_t *newinsn) +{ + if (!newinsn) + return string(""); + else + return "da_" + labelfy(newinsn); +} + +static string getPostCallbackLabel(Instruction_t *newinsn) +{ + if (!newinsn) + return string(""); + else + return "pcb_" + labelfy(newinsn); +} + + +static string get_relocation_string(FileIR_t* fileIRp, ostream& fout, int offset, string type, Instruction_t* insn) +{ + stringstream ss; + ss<<labelfy(insn)<<" rl " << offset << " " << type << " " << URLToFile(fileIRp->getFile()->GetURL()) << endl; + return ss.str(); +} + +static void emit_relocation(FileIR_t* fileIRp, ostream& fout, int offset, string type, Instruction_t* insn) +{ + fout<<"\t"<<get_relocation_string(fileIRp,fout,offset,type,insn); +} + + +/* return true if converted */ +bool convert_jump_for_64bit(Instruction_t* newinsn, string &final, string &emit_later, string new_target) +{ + /* skip for labeled addresses */ + if (new_target.c_str()[0]!='0') + return false; + + string datalabel=get_data_label(newinsn); + + /* convert a "call <addr>" into "call qword [rel data_label] \n data_label ** dq <addr>" */ + int start=final.find(new_target,0); + + string new_string=final.substr(0,start)+" qword [ rel " +datalabel + "]\n"; + emit_later="\t"+ datalabel + " ** dq "+final.substr(start) + "\n"; + + final=new_string; + + return true; +} + +void emit_jump(FileIR_t* fileIRp, ostream& fout, const DecodedInstruction_t& disasm, Instruction_t* newinsn, Instruction_t *old_insn, string & original_target, string &emit_later) +{ + + string label=labelfy(newinsn); + string complete_instr=disasm.getDisassembly(); + string address_string=disasm.getOperand(0)->getString(); + + + /* if we have a target instruction in the database */ + if(newinsn->getTarget() || needs_short_branch_rewrite(newinsn,disasm)) + { + /* change the target to be symbolic */ + + /* first get the new target */ + string new_target; + if(newinsn->getTarget()) + new_target=labelfy(newinsn->getTarget()); + /* if this is a short branch, write this branch to jump to the next insn */ + if(needs_short_branch_rewrite(newinsn,disasm)) + { + new_target=get_short_branch_label(newinsn); + + /* also get the real target if it's a short branch */ + if(newinsn->getTarget()) + original_target=labelfy(newinsn->getTarget()); + else + original_target=address_string; + } + + /* find the location in the disassembled string of the old target */ + int start=complete_instr.find(address_string,0); + + /* and build up a new string that has the label of the target instead of the address */ + string final=complete_instr.substr(0,start) + new_target + complete_instr.substr(start+address_string.length()); + + + /* sanity, no segment registers for absolute mode */ + //assert(disasm.Argument1.SegmentReg==0); + + // if(disasm.Archi==64) + if(FileIR_t::getArchitectureBitWidth()==64) + { + auto converted=convert_jump_for_64bit(newinsn,final, emit_later,new_target); + (void)converted; // unused? + } + + fout<<final<<endl; + + if (new_target.c_str()[0]=='0') + { +assert(0); +#if 0 +this will never work again? + // if we converted to an indirect jump, do a 64-bit reloc + if(converted) + { + /* jumps have a 1-byte opcode */ + string reloc=get_relocation_string(fileIRp, fout,0,"64-bit",newinsn); + emit_later=emit_later+"da_"+reloc; + } + // if we're jumping to an absolute address vrs a label, we will need a relocation for this jump instruction + else if( + disasm.Instruction.Opcode==0xeb || // jmp with 8-bit addr -- should be recompiled to 32-bit + disasm.Instruction.Opcode==0xe8 || // jmp with 32-bit addr + disasm.Instruction.Opcode==0xe9 // call with 32-bit addr + + ) + { + /* jumps have a 1-byte opcode */ + emit_relocation(fileIRp, fout,1,"32-bit",newinsn); + } + else + { + /* other jcc'often use a 2-byte opcode for far jmps (which is what spri will emit) */ + emit_relocation(fileIRp, fout,2,"32-bit",newinsn); + } +#endif + } + } + else /* this instruction has a target, but it's not in the DB */ + { + /* so we'll just emit the instruction and let it go back to the application text. */ + fout<<complete_instr<<endl; +// needs relocation info. +#if 0 +// never to work again? + if(complete_instr.compare("call 0x00000000")==0 || + complete_instr.compare("jmp 0x00000000")==0 + ) + { + // just ignore these bogus instructions. + } + else + { + if( + disasm.Instruction.Opcode==0xeb || // jmp with 8-bit addr + disasm.Instruction.Opcode==0xe8 || // jmp with 32-bit addr + disasm.Instruction.Opcode==0xe9 // call with 32-bit addr + ) + { + emit_relocation(fileIRp, fout,1,"32-bit",newinsn); + } + else + { + // assert this is the "main" file and no relocation is necessary. + assert(strstr(fileIRp->getFile()->GetURL().c_str(),"a.ncexe")!=0); + } + } +#endif + } +} + + + +// +// emit this instruction as spri code. +// +static string emit_spri_instruction(FileIR_t* fileIRp, Instruction_t *newinsn, ostream& fout, string &emit_later) +{ + string original_target; + Instruction_t* old_insn=insnMap[newinsn]; + + // disassemble using BeaEngine + // DISASM disasm; + + /* Disassemble the instruction */ + //int instr_len = Disassemble(newinsn,disasm); + const auto p_disasm=DecodedInstruction_t::factory(newinsn); + const auto &disasm=*p_disasm; + + string label=labelfy(newinsn); + string complete_instr=disasm.getDisassembly(); + string address_string=disasm.getOperand(0)->getString(); + + /* Emit any callback functions */ + if (!newinsn->getCallback().empty()) + { + fout << "\t"+label+"\t () " << newinsn->getCallback() << " # acts as a call <callback> insn" << endl; + fout << "\t"+ getPostCallbackLabel(newinsn)+" ** "; + } + else + { + fout << "\t"+label+"\t ** "; + } + + /* emit the actual instruction from the database */ + if( + strstr(disasm.getDisassembly().c_str(),"jmp far")!=0 || + strstr(disasm.getDisassembly().c_str(),"call far")!=0 + ) + { + fout<<"\t hlt " << endl; + } + + /* if it's a branch instruction, we have extra work to do */ + else if( + //(disasm.Instruction.BranchType!=0) && // it is a branch + //(disasm.Instruction.BranchType!=RetType) && // and not a return + //(disasm.Argument1.ArgType & CONSTANT_TYPE)!=0 // and has a constant argument type 1 + disasm.isBranch() && + !disasm.isReturn() && + disasm.getOperand(0)->isConstant() + ) + { + emit_jump(fileIRp, fout, disasm,newinsn,old_insn, original_target, emit_later); + } + else + { + /* no target, just emit the instruction */ + + /* beaEngine kinda sucks and does some non-nasmness. */ + + /* in this case, we look for an "lea <reg>, dword [ addr ]" and remove the "dword" part */ + // if(strstr(disasm.CompleteInstr,"lea ") != NULL ) + +// not needed after bea and/or libdecode fixes. +#if 0 + if(disasm.getMnemonic()=="lea") + { + char* a=strstr(disasm.CompleteInstr, "dword "); + if(a!=NULL) + { + a[0]=' '; // d + a[1]=' '; // w + a[2]=' '; // o + a[3]=' '; // r + a[4]=' '; // d + } + } + + + /* In this case, we look for "mov*x dstreg, srcreg" and convert srcreg to an appropriate size */ + //if( strstr(disasm.CompleteInstr, "movzx ") || + // strstr(disasm.CompleteInstr, "movsx ") ) + if( disasm.getMnemonic()== "movzx" || disasm.getMnemonic()== "movsx" ) + { + if( disasm.Instruction.Opcode==0xfbe || disasm.Instruction.Opcode==0xfb6 ) + { + char* comma=strstr(disasm.CompleteInstr, ","); + assert(comma); + if(comma[2]=='e' && comma[3]=='a' && comma[4]=='x') // eax -> al + comma[2]=' ', comma[3],'a', comma[4]='l'; + if(comma[2]=='e' && comma[3]=='b' && comma[4]=='x') // ebx -> bl + comma[2]=' ', comma[3],'b', comma[4]='l'; + if(comma[2]=='e' && comma[3]=='c' && comma[4]=='x') // ecx -> cl + comma[2]=' ', comma[3],'c', comma[4]='l'; + if(comma[2]=='e' && comma[3]=='d' && comma[4]=='x') // edx -> dl + comma[2]=' ', comma[3],'d', comma[4]='l'; + if(comma[2]=='e' && comma[3]=='s' && comma[4]=='p') // esp -> ah + comma[2]=' ', comma[3],'a', comma[4]='h'; + if(comma[2]=='e' && comma[3]=='b' && comma[4]=='p') // ebp -> bh + comma[2]=' ', comma[3],'b', comma[4]='h'; + if(comma[2]=='e' && comma[3]=='s' && comma[4]=='i') // esi -> ch + comma[2]=' ', comma[3],'c', comma[4]='l'; + if(comma[2]=='e' && comma[3]=='d' && comma[4]=='i') // edi -> dh + comma[2]=' ', comma[3],'d', comma[4]='l'; + } + else if( disasm.Instruction.Opcode==0xfbf || disasm.Instruction.Opcode==0xfb7 ) + { +#if 0 +/* this seems to be fixed in beaEngine -r175 */ + char* comma=strstr(disasm.CompleteInstr, ","); + assert(comma); + if(strstr(&comma[2], "word [") == NULL) // if it's not a memory operation + { + assert(comma[2]=='e'); + comma[2]=' '; + } +#endif + } + else + assert(0); // wtf? + } + // look for an fld st0, st0, and convert it to fld st0 + else if(strcmp("fld st0 , st0", disasm.CompleteInstr)==0) + { + disasm.CompleteInstr[8]='\0'; + } +#endif + + fout<<disasm.getDisassembly(); + fout<<endl; + } + + //for(set<Relocation_t*>::iterator it=newinsn->GetRelocations().begin(); it!=newinsn->GetRelocations().end(); ++it) + for(auto this_reloc : newinsn->getRelocations()) + { + //Relocation_t* this_reloc=*it; + emit_relocation(fileIRp, fout, this_reloc->getOffset(),this_reloc->getType(), newinsn); + } + + auto IB_targets = newinsn->getIBTargets(); + if (NULL != IB_targets) + { + if (IB_targets->isComplete()) + { + // Iterate through all IB targets and produce SPRI rules for IBTL (IB Target Limitation). + for (auto TargIter = IB_targets->begin(); TargIter != IB_targets->end(); ++TargIter) + { + fout << "\t" << labelfy(newinsn) << " IL " << qualified_labelfy(fileIRp, *TargIter) << endl; + } + } + } + + return original_target; + +} + +// +// check to see if this instruction needs a spri rewrite rule. +// +static bool needs_spri_rule(Instruction_t* newinsn,Instruction_t* oldinsn) +{ + // check if this is an inserted instruction + if(newinsn->getOriginalAddressID()==BaseObj_t::NOT_IN_DATABASE) + return true; + + assert(oldinsn); + assert(newinsn->getOriginalAddressID()==oldinsn->getAddress()->getBaseID()); + + + /* We moved the instruction to a new address*/ + if(newinsn->getAddress()->getVirtualOffset()!=oldinsn->getAddress()->getVirtualOffset()) + return true; + + /* We moved the instruction to a new file? */ + if(newinsn->getAddress()->getFileID()!=oldinsn->getAddress()->getFileID()) + { + // + // coders: verify this is OK before allowing an insn to change files. + // + assert(0); + return true; + } + + + auto newFT=newinsn->getFallthrough(); + auto newTG=newinsn->getTarget(); + auto oldFT=oldinsn->getFallthrough(); + auto oldTG=oldinsn->getTarget(); + + // + // check that both have a fallthrough or both don't have a fallthrough + // + if(!!newFT != !!oldFT) + return true; + // + // check that both have a target or both don't have a target + // + if(!!newTG != !!oldTG) + return true; + + // if there's a fallthrough, but it is different, return true + if(newFT && newFT->getOriginalAddressID()!=oldFT->getAddress()->getBaseID()) + return true; + + // if there's a target, but it is different, return true + if(newTG && newTG->getOriginalAddressID()!=oldTG->getAddress()->getBaseID()) + return true; + + // data bits themselves changed + if(newinsn->getDataBits() != oldinsn->getDataBits()) + return true; + + return false; +} + +// +// emit the spri rule to redirect this instruction. +// +static void emit_spri_rule(FileIR_t* fileIRp, Instruction_t* newinsn, ostream& fout, bool with_ilr) +{ + string emit_later; + + Instruction_t* old_insn=insnMap[newinsn]; + + fout << endl << "# Orig addr: "<<addressify(newinsn)<<" insn_id: "<< std::dec + << newinsn->getBaseID()<<" with comment "<<newinsn->getComment()<<endl; + if (newinsn->getIndirectBranchTargetAddress()) + fout << "# Orig addr: "<<addressify(newinsn)<<" indirect branch target: " + <<newinsn->getIndirectBranchTargetAddress()->getVirtualOffset() << endl; + + bool redirected_addr=false; + bool redirected_ibt=false; + + // if it's the target of an unmodified instruction + if( unmoved_insn_targets.find(newinsn) != unmoved_insn_targets.end() ) + { + redirected_addr=true; + if(old_insn) + { + // then we will need a rule so that the unmodified instruction gets here correctly + fout << "# because its target of unmoved"<<endl; + fout << qualified_addressify(fileIRp, newinsn) <<" -> ."<<endl; + } + } + + /* if this insn is an IB target, emit the redirect appropriately */ + if (newinsn->getIndirectBranchTargetAddress()) + { + redirected_ibt=true; + /* If the IBT address isn't this insns address, redirect appropriately. + * If this insn isn't an unmoved insn target, always redirect appropriately. + */ + // if((old_insn && (*newinsn->getIndirectBranchTargetAddress()) != (*old_insn->getAddress())) + // || !redirected_addr) + assert(0); // couldn't make this work + { + // use the better qualify address to check for file matches. + fout << "# because has indir "<<endl; + fout << better_qualify_address(fileIRp,newinsn->getIndirectBranchTargetAddress()) + <<" -> ."<<endl; + } + + /* i don't understand this part. hopefully this is right */ + if(!newinsn->getCallback().empty()) + fout << ". -> "<< getPostCallbackLabel(newinsn) <<endl; + } + // if there's a corresponding "old" instruction (i.e., in Variant 0, aka from the binary) + if(old_insn) + { + /* the address of new insns with a corresponding old insn should start with 0x */ + assert(addressify(newinsn).c_str()[0]=='0'); + + /* check to see if this address an IBT somewhere else */ + /* and we havne't already redirected it */ + if (ibts.find(*old_insn->getAddress()) == ibts.end() && !redirected_ibt && !redirected_addr) + { + + // with ILR turned off, we don't try to redirect to 0 + if(with_ilr) + { + fout << "# eliding, no indirect targets"<<endl; + fout << qualified_addressify(fileIRp, newinsn) <<" -> 0x0 " <<endl; + } + else + { + fout << "# skipping elide because ilr is off (in this module) and " + "no indirect targets, but emitting a rule anyhow"<<endl; + fout << qualified_addressify(fileIRp, newinsn) <<" -> ." << endl; + } + + } + + // not yet handling callbacks on original instructions. + // this may be tricky because it seems we are overloading the indirect branch + // target address to mean two things for instructions with callbacks. Good luck if + // you're reading this. + assert(newinsn->getCallback().empty()); + + } + + string original_target=emit_spri_instruction(fileIRp, newinsn, fout, emit_later); + + + /* if there's a fallthrough instruction, jump to it. */ + if(newinsn->getFallthrough()) + { + fout << ". -> " << qualified_labelfy(fileIRp,newinsn->getFallthrough())<<endl; + } + else + { + //DISASM disasm; + //disasm.Options = NasmSyntax + PrefixedNumeral + ShowSegmentRegs; + //disasm.Archi = fileIRp->getArchitectureBitWidth(); + //disasm.EIP = (UIntPtr)newinsn->getDataBits().c_str(); + //disasm.VirtualAddr = old_insn ? old_insn->getAddress()->getVirtualOffset() : 0; + const auto disasm=DecodedInstruction_t(newinsn); + + /* Disassemble the instruction */ + //int instr_len = Disasm(&disasm); + assert(disasm.valid()); + int instr_len = disasm.length(); + + + //if( disasm.Instruction.BranchType!=RetType && disasm.Instruction.BranchType!=JmpType ) + if( !disasm.isReturn() && !disasm.isUnconditionalBranch()) + { + assert(old_insn); /* it's an error to insert a new, non-unconditional branch instruction + * and not specify it's fallthrough */ + fout << ". -> " << qualify(fileIRp)<< "0x" << std::hex << old_insn->getAddress()->getVirtualOffset()+instr_len <<endl; + } + } + + fout<<endl; + + /* if the original target string is set, we need to emit + * a rule for this instruction so that short branches can always be resolved + */ + if(!original_target.empty()) + { + /* qualify this target if necessary */ + if(original_target.c_str()[0]=='0') + original_target=qualify(fileIRp)+original_target; + fout << "\t" << get_short_branch_label(newinsn) << "\t -> \t " << original_target << endl; + } + fout<<emit_later<<endl; + +} + + + +// +// generate a map from new instructions to old instructions +// +static void generate_insn_to_insn_maps(FileIR_t *fileIRp, FileIR_t *orig_fileIRp) +{ + static map<Instruction_t*,Instruction_t*> new_insnMap; + insnMap=new_insnMap; // re-init the global instruction map. + + /* since a variant does not hold a pointer to the original code, we need to create that mapping + * we do it in two steps. the first step is to make a map from ids in the original code + * to instructions in the original code + * the second step is to is to create the final mapping using the first map + */ + + map<db_id_t,Instruction_t*> idMap; + + /* loop through each insn in the original program */ + for( + auto it=orig_fileIRp->getInstructions().begin(); + it!=orig_fileIRp->getInstructions().end(); + ++it + ) + { + /* get the insn */ + Instruction_t *insn=*it; + assert(insn); + + /* get it's ID */ + db_id_t address_id=insn->getAddress()->getBaseID(); + assert(address_id!=-1); + + /* sanity check */ + assert(insn->getAddress()->getFileID()!=-1); + assert(insn->getAddress()->getVirtualOffset()!=0); + + /* insert into map */ + idMap[address_id]=insn; + } + + /* loop through the new variant and create the final mapping of new insn to old insn */ + for( + std::set<Instruction_t*>::const_iterator it=fileIRp->GetInstructions().begin(); + it!=fileIRp->GetInstructions().end(); + ++it + ) + { + /* get the insn */ + Instruction_t *insn=*it; + assert(insn); + + db_id_t orig_addr=insn->getOriginalAddressID(); + + /* no mapping if this is true */ + if(orig_addr==-1) + continue; + + assert(idMap[orig_addr]!=NULL); + + insnMap[insn]=idMap[orig_addr]; + + } +} + +// +// GenerateSPRI - spri for the entire database +// +void FileIR_t::GenerateSPRI(ostream &fout, bool with_ilr) +{ + VariantID_t orig_varidp(progid.GetOriginalVariantID()); + assert(orig_varidp.IsRegistered()==true); + + for( + set<File_t*>::iterator it=orig_varidp.getFiles().begin(); + it!=orig_varidp.getFiles().end(); + ++it + ) + { + File_t* the_file=*it; + + if(the_file->getBaseID()==fileptr->orig_fid) + { + fout <<"# Generating spri for "<< the_file->GetURL()<<endl; + + orig_variant_ir_p=new FileIR_t(orig_varidp,the_file); + this->GenerateSPRI(orig_variant_ir_p,fout,with_ilr); + delete orig_variant_ir_p; + orig_variant_ir_p=NULL; + } + + } + + + +} + +// +// generate_IBT_set -- record all addresses in the program +// +static void generate_IBT_set(FileIR_t* fileIRp) +{ + ibts.clear(); + for( + set<Instruction_t*>::const_iterator it=fileIRp->GetInstructions().begin(); + it!=fileIRp->GetInstructions().end(); + ++it + ) + { + Instruction_t *insn=*it; + AddressID_t *ibt=insn->getIndirectBranchTargetAddress(); + + if(ibt) + { + ibts.insert(*ibt); + } + + } + +} + +// +// generate_unmoved_insn_targets_set -- create the set of insturctions that have control +// transfers to them (including fallthrough type control transfers) from instructions that do not need a spri rule. +// +static void generate_unmoved_insn_targets_set(FileIR_t* fileIRp) +{ + unmoved_insn_targets.clear(); + for( + set<Instruction_t*>::const_iterator it=fileIRp->GetInstructions().begin(); + it!=fileIRp->GetInstructions().end(); + ++it + ) + { + Instruction_t *insn=*it; + + if( + // this instruction corresponds to an old instruction + insnMap[insn] && + // and we need a spri rule for it + !needs_spri_rule(insn, insnMap[insn]) + ) + { + unmoved_insn_targets.insert(insn->getTarget()); + unmoved_insn_targets.insert(insn->getFallthrough()); + } + + } + +} +#endif + +void FileIR_t::GenerateSPRI(FileIR_t *orig_fileIRp, ostream &fout, bool with_ilr) +{ + assert(0); + /* + //Resolve (assemble) any instructions in the registry. + AssembleRegistry(); + + // give 'this' a name + FileIR_t *fileIRp=this; + + setBaseIDS(); // need unique ID to generate unique label name + + // generate the map from new instruction to old instruction needed for this transform. + generate_insn_to_insn_maps(fileIRp, orig_fileIRp); + + // generate the set of all indirect branch target addressses for this fileIR + generate_IBT_set(fileIRp); + + // generate unmoved_insn_targets_set -- the set of instructions that have control + // transfers to them (including fallthrough type control transfers) from instructions that do not need a spri rule. + generate_unmoved_insn_targets_set(fileIRp); + + // + // for each instruction, compare the new instruction with the original instruction and see if + // they are the same. If so, do nothing, otherwise emit a rewrite rule for this instruction. + // + for( + std::set<Instruction_t*>::const_iterator it=fileIRp->GetInstructions().begin(); + it!=fileIRp->GetInstructions().end(); + ++it + ) + { + Instruction_t* newinsn=*it; + Instruction_t* oldinsn=insnMap[newinsn]; + + assert(newinsn); + + if(needs_spri_rule(newinsn,oldinsn)) + { + emit_spri_rule(fileIRp,newinsn,fout,with_ilr); + } + } + update_label_offset(fileIRp); + + fout<<"#DEBUG: maximum ID is "<<label_offset<<endl; + */ +} + diff --git a/irdb-lib/libIRDB-core/src/icfs.cpp b/irdb-lib/libIRDB-core/src/icfs.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f5e26b287aa6fa3a95f23e6264bda3c7702a0a1e --- /dev/null +++ b/irdb-lib/libIRDB-core/src/icfs.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <all.hpp> +#include <irdb-util> + +using namespace libIRDB; +using namespace std; + +static string getICFSAnalysisStatus(const ICFS_Analysis_Status_t p_status) { + // strings must match DB definition + switch (p_status) { + case IRDB_SDK::iasAnalysisIncomplete: + return string("icfs_analysis_incomplete"); + break; + case IRDB_SDK::iasAnalysisModuleComplete: + return string("icfs_analysis_module_complete"); + break; + case IRDB_SDK::iasAnalysisComplete: + return string("icfs_analysis_complete"); + break; + default: + return string("icfs_analysis_incomplete"); + break; + } + + std::cerr << "error: unknown ICFS analysis status: " << p_status << std::endl; + assert(0); +} + +ICFS_t::ICFS_t(db_id_t p_set_id, const ICFS_Analysis_Status_t p_status) : BaseObj_t(NULL) +{ + setBaseID(p_set_id); + setAnalysisStatus(p_status); +} + +ICFS_t::ICFS_t(db_id_t p_set_id, const string p_statusString) : BaseObj_t(NULL) +{ + setBaseID(p_set_id); + if (p_statusString == "icfs_analysis_incomplete") { + setAnalysisStatus(IRDB_SDK::iasAnalysisIncomplete); + } else if (p_statusString == "icfs_analysis_module_complete") { + setAnalysisStatus(IRDB_SDK::iasAnalysisModuleComplete); + } else if (p_statusString == "icfs_analysis_complete") { + setAnalysisStatus(IRDB_SDK::iasAnalysisComplete); + } else { + std::cerr << "error: unknown ICFS analysis status string: " << p_statusString << std::endl; + assert(0); + } +} + +string ICFS_t::WriteToDB(File_t *fid) +{ + assert(fid); + + db_id_t icfs_id = getBaseID(); + + string analysis_status = getICFSAnalysisStatus(getAnalysisStatus()); + + string q=string("insert into ") + fid->icfs_table_name + + string(" (icfs_id, icfs_status) VALUES (") + + string("'") + to_string(icfs_id) + string("', ") + + string("'") + analysis_status + string("'); ") ; + + for (InstructionSet_t::const_iterator it = this->begin(); + it != this->end(); ++it) + { + auto insn = *it; + assert(insn); + + auto address_id = insn->getAddress()->getBaseID(); + + q += string("insert into ") + fid->icfs_map_table_name + + string(" (icfs_id, address_id) VALUES(") + + string("'") + to_string(icfs_id) + string("', ") + + string("'") + to_string(address_id) + string("'); "); + } + + return q; +} + diff --git a/irdb-lib/libIRDB-core/src/instruction.cpp b/irdb-lib/libIRDB-core/src/instruction.cpp new file mode 100644 index 0000000000000000000000000000000000000000..447f432de30535e300160d5231786c6e85ed0202 --- /dev/null +++ b/irdb-lib/libIRDB-core/src/instruction.cpp @@ -0,0 +1,264 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <all.hpp> +#include <irdb-util> +#include <stdlib.h> +#include <fstream> +#include <sstream> +#include <iomanip> +#include <irdb-util> + +#undef EIP + +using namespace libIRDB; +using namespace std; + +Instruction_t::Instruction_t() : + BaseObj_t(NULL), + my_address(NULL), + my_function(NULL), + orig_address_id(NOT_IN_DATABASE), + fallthrough(NULL), + target(NULL), + data(""), + callback(""), + comment(""), + indTarg(NULL), + icfs(NULL), + eh_pgm(NULL), + eh_cs(NULL) +{ + setBaseID(NOT_IN_DATABASE); +} + +Instruction_t::Instruction_t(db_id_t id, + AddressID_t *addr, + Function_t *func, + db_id_t orig_id, + std::string thedata, + std::string my_callback, + std::string my_comment, + AddressID_t *my_indTarg, + db_id_t doip_id) : + + BaseObj_t(NULL), + my_address(addr), + my_function(func), + orig_address_id(orig_id), + fallthrough(NULL), + target(NULL), + data(thedata), + callback(my_callback), + comment(my_comment), + indTarg(my_indTarg), + icfs(NULL), + eh_pgm(NULL), + eh_cs(NULL) +{ + setBaseID(id); +} + +/* +int Instruction_t::Disassemble(DISASM &disasm) const +{ + + memset(&disasm, 0, sizeof(DISASM)); + + disasm.Options = NasmSyntax + PrefixedNumeral; + disasm.Archi = FileIR_t::getArchitectureBitWidth(); + disasm.EIP = (UIntPtr) getDataBits().c_str(); + disasm.VirtualAddr = getAddress()->getVirtualOffset(); + int instr_len = Disasm(&disasm); + + return instr_len; +} +*/ + +std::string Instruction_t::getDisassembly() const +{ +// DISASM disasm; +// Disassemble(this,disasm); +// return std::string(disasm.CompleteInstr); + + const auto d=DecodedInstruction_t::factory(this); + return d->getDisassembly(); +} + +// +// Given an instruction in assembly, returns the raw bits in a string +// On error, return the empty string +// +bool Instruction_t::assemble(string assembly) +{ + const string assemblyFile = "tmp.asm"; + const string binaryOutputFile = "tmp.bin"; + + //remove any preexisting assembly or nasm generated files + string command = "rm -f " + assemblyFile; + command_to_stream(command,cout); + command = "rm -f "+assemblyFile+".bin"; + command_to_stream(command,cout); + + ofstream asmFile; + asmFile.open(assemblyFile.c_str()); + if(!asmFile.is_open()) + { + return false; + } + + asmFile<<"BITS "<<std::dec<<FileIR_t::getArchitectureBitWidth()<<endl; + + asmFile<<assembly<<endl; + asmFile.close(); + + command = "nasm " + assemblyFile + " -o "+ binaryOutputFile; + command_to_stream(command,cout); + + ifstream binreader; + unsigned int filesize; + binreader.open(binaryOutputFile.c_str(),ifstream::in|ifstream::binary); + + if(!binreader.is_open()) + { + return false; + } + + binreader.seekg(0,ios::end); + + filesize = binreader.tellg(); + + binreader.seekg(0,ios::beg); + + if (filesize == 0) return false; + + unsigned char *memblock = new unsigned char[filesize]; + + binreader.read((char*)memblock,filesize); + binreader.close(); + + string rawBits; + rawBits.resize(filesize); + for (auto i = 0U; i < filesize; ++i) + rawBits[i] = memblock[i]; + + // should erase those 2 files here + + this->setDataBits(rawBits); + return true; +} + + +vector<string> Instruction_t::WriteToDB(File_t *fid, db_id_t newid) +{ + assert(fid); + assert(my_address); + + if(getBaseID()==NOT_IN_DATABASE) + setBaseID(newid); + + auto func_id=NOT_IN_DATABASE; + if(my_function) func_id=my_function->getBaseID(); + + auto ft_id=NOT_IN_DATABASE; + if(fallthrough) ft_id=fallthrough->getBaseID(); + + auto targ_id=NOT_IN_DATABASE; + if(target) targ_id=target->getBaseID(); + + auto icfs_id=NOT_IN_DATABASE; + if (icfs) icfs_id=icfs->getBaseID(); + + auto indirect_bt_id=NOT_IN_DATABASE; + if(indTarg) indirect_bt_id=indTarg->getBaseID(); + + auto eh_pgm_id=NOT_IN_DATABASE; + if(eh_pgm) eh_pgm_id=eh_pgm->getBaseID(); + + auto eh_css_id=NOT_IN_DATABASE; + if(eh_cs) eh_css_id=eh_cs->getBaseID(); + + ostringstream hex_data; + hex_data << setfill('0') << hex;; + for (size_t i = 0; i < data.length(); ++i) + hex_data << setw(2) << (int)(data[i]&0xff); + + + return { + to_string(getBaseID()), + to_string(my_address->getBaseID()), + to_string(func_id), + to_string(orig_address_id), + to_string(ft_id), + to_string(targ_id), + to_string(icfs_id), + to_string(eh_pgm_id), + to_string(eh_css_id), + hex_data.str(), + callback, + comment, + to_string(indirect_bt_id), + to_string(getDoipID()) }; +} + + +/* return true if this instructino exits the function -- true if there's no function, because each instruction is it's own function? */ +bool Instruction_t::isFunctionExit() const +{ + if(!my_function) + return true; + + /* if there's a target that's outside this function */ + auto target=getTarget(); + if(target && target->getFunction()!=getFunction()) // !is_in_set(my_function->GetInstructions(),target)) + return true; + + /* if there's a fallthrough that's outside this function */ + auto ft=getFallthrough(); + if(fallthrough && ft->getFunction()!=getFunction()) // !is_in_set(my_function->GetInstructions(),ft)) + return true; + + /* some instructions have no next-isntructions defined in the db, and we call them function exits */ + if(!target && !fallthrough) + return true; + + return false; +} + +IRDB_SDK::Function_t* Instruction_t::getFunction() const +{ + return my_function; +} + + +IRDB_SDK::EhProgram_t* Instruction_t::getEhProgram() const { return eh_pgm; } +IRDB_SDK::EhCallSite_t* Instruction_t::getEhCallSite() const { return eh_cs; } +IRDB_SDK::AddressID_t* Instruction_t::getIndirectBranchTargetAddress() const { return indTarg; } + +void Instruction_t::setAddress (IRDB_SDK::AddressID_t* newaddr) { my_address=dynamic_cast<AddressID_t*>(newaddr); } +void Instruction_t::setFunction (IRDB_SDK::Function_t* func ) { my_function=dynamic_cast<Function_t*>(func);} +void Instruction_t::setFallthrough (IRDB_SDK::Instruction_t* i) { fallthrough=dynamic_cast<Instruction_t*>(i); } +void Instruction_t::setTarget (IRDB_SDK::Instruction_t* i) { target=dynamic_cast<Instruction_t*>(i); } +void Instruction_t::setIBTargets (IRDB_SDK::ICFS_t *p_icfs) { icfs=dynamic_cast<ICFS_t*>(p_icfs); } +void Instruction_t::setEhProgram(IRDB_SDK::EhProgram_t* orig) { eh_pgm=dynamic_cast<EhProgram_t*>(orig); } +void Instruction_t::setEhCallSite(IRDB_SDK::EhCallSite_t* orig) { eh_cs=dynamic_cast<EhCallSite_t*>(orig); } +void Instruction_t::setIndirectBranchTargetAddress(IRDB_SDK::AddressID_t* myIndTarg) { indTarg=dynamic_cast<AddressID_t*>(myIndTarg); } + + diff --git a/irdb-lib/libIRDB-core/src/operand_csarm.cpp b/irdb-lib/libIRDB-core/src/operand_csarm.cpp new file mode 100644 index 0000000000000000000000000000000000000000..01a20a17d5061ca3ed15f602c074ed6b06caeea2 --- /dev/null +++ b/irdb-lib/libIRDB-core/src/operand_csarm.cpp @@ -0,0 +1,310 @@ + +#include <libIRDB-core.hpp> +#include <memory> +#include <decode_base.hpp> +#include <decode_csarm.hpp> +#include <operand_base.hpp> +#include <operand_csarm.hpp> + + +using namespace std; +using namespace libIRDB; + +#include <capstone.h> +static const auto ARM64_REG_PC=(arm64_reg)(ARM64_REG_ENDING+1); + + +DecodedOperandCapstoneARM64_t::DecodedOperandCapstoneARM64_t( const shared_ptr<void> & p_my_insn, uint8_t p_op_num) + : + my_insn(p_my_insn), + op_num(p_op_num) +{ + +} + +DecodedOperandCapstoneARM64_t::~DecodedOperandCapstoneARM64_t() +{ +} + + +bool DecodedOperandCapstoneARM64_t::isConstant() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return op.type==ARM64_OP_IMM; +} + +uint64_t DecodedOperandCapstoneARM64_t::getConstant() const +{ + if(!isConstant()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-constant operand"); + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return op.imm; +} + +string DecodedOperandCapstoneARM64_t::getString() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + const auto handle=DecodedInstructionCapstoneARM64_t::cs_handle->getHandle(); + + switch(op.type) + { + case ARM64_OP_REG: + return string(cs_reg_name(handle, op.reg)); + case ARM64_OP_REG_MRS: + case ARM64_OP_REG_MSR: + case ARM64_OP_FP: + return string("fpcr"); + case ARM64_OP_IMM: + return to_string(op.imm); + case ARM64_OP_MEM: + { + string ret_val; + if (op.mem.base != ARM64_REG_INVALID) + ret_val+=cs_reg_name(handle, op.mem.base); + + if (op.mem.index != ARM64_REG_INVALID) + ret_val+=string(" + ") +cs_reg_name(handle, op.mem.index); + + if (op.mem.disp != 0) + ret_val+=" + "+ to_string(op.mem.disp); + + if(ret_val=="") + return "0"; + + return ret_val; + } + default: + assert(0); + } +} + +bool DecodedOperandCapstoneARM64_t::isRegister() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return op.type==ARM64_OP_REG; +} + +bool DecodedOperandCapstoneARM64_t::isGeneralPurposeRegister() const +{ + const auto gp_regs=set<arm64_reg>({ + ARM64_REG_X29, ARM64_REG_X30, ARM64_REG_SP, ARM64_REG_WSP, ARM64_REG_WZR, ARM64_REG_XZR, + ARM64_REG_W0, ARM64_REG_W1, ARM64_REG_W2, ARM64_REG_W3, ARM64_REG_W4, ARM64_REG_W5, ARM64_REG_W6, ARM64_REG_W7, + ARM64_REG_W8, ARM64_REG_W9, ARM64_REG_W10, ARM64_REG_W11, ARM64_REG_W12, ARM64_REG_W13, ARM64_REG_W14, ARM64_REG_W15, + ARM64_REG_W16, ARM64_REG_W17, ARM64_REG_W18, ARM64_REG_W19, ARM64_REG_W20, ARM64_REG_W21, ARM64_REG_W22, ARM64_REG_W23, + ARM64_REG_W24, ARM64_REG_W25, ARM64_REG_W26, ARM64_REG_W27, ARM64_REG_W28, ARM64_REG_W29, ARM64_REG_W30, + ARM64_REG_X0, ARM64_REG_X1, ARM64_REG_X2, ARM64_REG_X3, ARM64_REG_X4, ARM64_REG_X5, ARM64_REG_X6, ARM64_REG_X7, + ARM64_REG_X8, ARM64_REG_X9, ARM64_REG_X10, ARM64_REG_X11, ARM64_REG_X12, ARM64_REG_X13, ARM64_REG_X14, ARM64_REG_X15, + ARM64_REG_X16, ARM64_REG_X17, ARM64_REG_X18, ARM64_REG_X19, ARM64_REG_X20, ARM64_REG_X21, ARM64_REG_X22, ARM64_REG_X23, + ARM64_REG_X24, ARM64_REG_X25, ARM64_REG_X26, ARM64_REG_X27, ARM64_REG_X28, + }); + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return isRegister() && gp_regs.find(op.reg)!=end(gp_regs); + +} + +bool DecodedOperandCapstoneARM64_t::isMmxRegister() const +{ + return false; +} + +bool DecodedOperandCapstoneARM64_t::isFpuRegister() const +{ + const auto fpu_regs=set<arm64_reg>({ + ARM64_REG_B0, ARM64_REG_B1, ARM64_REG_B2, ARM64_REG_B3, ARM64_REG_B4, ARM64_REG_B5, ARM64_REG_B6, ARM64_REG_B7, + ARM64_REG_B8, ARM64_REG_B9, ARM64_REG_B10, ARM64_REG_B11, ARM64_REG_B12, ARM64_REG_B13, ARM64_REG_B14, ARM64_REG_B15, + ARM64_REG_B16, ARM64_REG_B17, ARM64_REG_B18, ARM64_REG_B19, ARM64_REG_B20, ARM64_REG_B21, ARM64_REG_B22, ARM64_REG_B23, + ARM64_REG_B24, ARM64_REG_B25, ARM64_REG_B26, ARM64_REG_B27, ARM64_REG_B28, ARM64_REG_B29, ARM64_REG_B30, ARM64_REG_B31, + ARM64_REG_H0, ARM64_REG_H1, ARM64_REG_H2, ARM64_REG_H3, ARM64_REG_H4, ARM64_REG_H5, ARM64_REG_H6, ARM64_REG_H7, + ARM64_REG_H8, ARM64_REG_H9, ARM64_REG_H10, ARM64_REG_H11, ARM64_REG_H12, ARM64_REG_H13, ARM64_REG_H14, ARM64_REG_H15, + ARM64_REG_H16, ARM64_REG_H17, ARM64_REG_H18, ARM64_REG_H19, ARM64_REG_H20, ARM64_REG_H21, ARM64_REG_H22, ARM64_REG_H23, + ARM64_REG_H24, ARM64_REG_H25, ARM64_REG_H26, ARM64_REG_H27, ARM64_REG_H28, ARM64_REG_H29, ARM64_REG_H30, ARM64_REG_H31, + ARM64_REG_D0, ARM64_REG_D1, ARM64_REG_D2, ARM64_REG_D3, ARM64_REG_D4, ARM64_REG_D5, ARM64_REG_D6, ARM64_REG_D7, + ARM64_REG_D8, ARM64_REG_D9, ARM64_REG_D10, ARM64_REG_D11, ARM64_REG_D12, ARM64_REG_D13, ARM64_REG_D14, ARM64_REG_D15, + ARM64_REG_D16, ARM64_REG_D17, ARM64_REG_D18, ARM64_REG_D19, ARM64_REG_D20, ARM64_REG_D21, ARM64_REG_D22, ARM64_REG_D23, + ARM64_REG_D24, ARM64_REG_D25, ARM64_REG_D26, ARM64_REG_D27, ARM64_REG_D28, ARM64_REG_D29, ARM64_REG_D30, ARM64_REG_D31, + ARM64_REG_H0, ARM64_REG_H1, ARM64_REG_H2, ARM64_REG_H3, ARM64_REG_H4, ARM64_REG_H5, ARM64_REG_H6, ARM64_REG_H7, + ARM64_REG_H8, ARM64_REG_H9, ARM64_REG_H10, ARM64_REG_H11, ARM64_REG_H12, ARM64_REG_H13, ARM64_REG_H14, ARM64_REG_H15, + ARM64_REG_H16, ARM64_REG_H17, ARM64_REG_H18, ARM64_REG_H19, ARM64_REG_H20, ARM64_REG_H21, ARM64_REG_H22, ARM64_REG_H23, + ARM64_REG_H24, ARM64_REG_H25, ARM64_REG_H26, ARM64_REG_H27, ARM64_REG_H28, ARM64_REG_H29, ARM64_REG_H30, ARM64_REG_H31, + ARM64_REG_Q0, ARM64_REG_Q1, ARM64_REG_Q2, ARM64_REG_Q3, ARM64_REG_Q4, ARM64_REG_Q5, ARM64_REG_Q6, ARM64_REG_Q7, + ARM64_REG_Q8, ARM64_REG_Q9, ARM64_REG_Q10, ARM64_REG_Q11, ARM64_REG_Q12, ARM64_REG_Q13, ARM64_REG_Q14, ARM64_REG_Q15, + ARM64_REG_Q16, ARM64_REG_Q17, ARM64_REG_Q18, ARM64_REG_Q19, ARM64_REG_Q20, ARM64_REG_Q21, ARM64_REG_Q22, ARM64_REG_Q23, + ARM64_REG_Q24, ARM64_REG_Q25, ARM64_REG_Q26, ARM64_REG_Q27, ARM64_REG_Q28, ARM64_REG_Q29, ARM64_REG_Q30, ARM64_REG_Q31, + ARM64_REG_S0, ARM64_REG_S1, ARM64_REG_S2, ARM64_REG_S3, ARM64_REG_S4, ARM64_REG_S5, ARM64_REG_S6, ARM64_REG_S7, + ARM64_REG_S8, ARM64_REG_S9, ARM64_REG_S10, ARM64_REG_S11, ARM64_REG_S12, ARM64_REG_S13, ARM64_REG_S14, ARM64_REG_S15, + ARM64_REG_S16, ARM64_REG_S17, ARM64_REG_S18, ARM64_REG_S19, ARM64_REG_S20, ARM64_REG_S21, ARM64_REG_S22, ARM64_REG_S23, + ARM64_REG_S24, ARM64_REG_S25, ARM64_REG_S26, ARM64_REG_S27, ARM64_REG_S28, ARM64_REG_S29, ARM64_REG_S30, ARM64_REG_S31, + }); + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return isRegister() && fpu_regs.find(op.reg)!=end(fpu_regs); +} + +bool DecodedOperandCapstoneARM64_t::isSseRegister() const +{ + return false; +} + +bool DecodedOperandCapstoneARM64_t::isAvxRegister() const +{ + return false; +} + +bool DecodedOperandCapstoneARM64_t::isZmmRegister() const +{ + return false; +} + +bool DecodedOperandCapstoneARM64_t::isSpecialRegister() const +{ + const auto special_regs=set<arm64_reg>({ + ARM64_REG_NZCV, + }); + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return isRegister() && special_regs.find(op.reg)!=end(special_regs); + return false; +} + +bool DecodedOperandCapstoneARM64_t::isSegmentRegister() const +{ + return false; +} + + + +uint32_t DecodedOperandCapstoneARM64_t::getRegNumber() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return op.reg; +} + +bool DecodedOperandCapstoneARM64_t::isMemory() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return op.type==ARM64_OP_MEM; + +} + +bool DecodedOperandCapstoneARM64_t::hasBaseRegister() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return isMemory() && op.mem.base!=ARM64_REG_INVALID; + +} + +bool DecodedOperandCapstoneARM64_t::hasIndexRegister() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return isMemory() && op.mem.index!=ARM64_REG_INVALID; +} + +uint32_t DecodedOperandCapstoneARM64_t::getBaseRegister() const +{ + if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return op.mem.base; +} + +uint32_t DecodedOperandCapstoneARM64_t::getIndexRegister() const +{ + if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return op.mem.index; +} + +uint32_t DecodedOperandCapstoneARM64_t::getScaleValue() const +{ + assert(0); +} + +bool DecodedOperandCapstoneARM64_t::hasMemoryDisplacement() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return op.mem.disp!=0; + +} // end of DecodedOperandCapstoneARM64_t::hasMemoryDisplacement() + +virtual_offset_t DecodedOperandCapstoneARM64_t::getMemoryDisplacement() const +{ + if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return op.mem.disp; +} + +bool DecodedOperandCapstoneARM64_t::isPcrel() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + + // covers ldr, ldrsw, prfm + // note: capstone's reports ldr, ldrsw, and prfm as using an imm, when they actually access memory. + // jdh fixed this in the IRDB's Disassemble routine + if(isMemory() && op.mem.base==ARM64_REG_PC) + return true; + + const auto mnemonic=string(the_insn->mnemonic); + const auto is_adr_type= mnemonic=="adr" || mnemonic=="adrp"; + if(is_adr_type && op.type==ARM64_OP_IMM) + return true; + + return false; // no PC as general purpose reg. +} + +/* in bytes */ +uint32_t DecodedOperandCapstoneARM64_t::getMemoryDisplacementEncodingSize() const +{ + if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); + assert(0); +} + +uint32_t DecodedOperandCapstoneARM64_t::getArgumentSizeInBytes() const +{ + return false; +} + +uint32_t DecodedOperandCapstoneARM64_t::getArgumentSizeInBits() const +{ + return getArgumentSizeInBytes()*8; +} + +bool DecodedOperandCapstoneARM64_t::hasSegmentRegister() const +{ + return false; +} + +uint32_t DecodedOperandCapstoneARM64_t::getSegmentRegister() const +{ + throw std::logic_error(string("Cannot ")+__FUNCTION__+" on ARM architecture"); +} + +bool DecodedOperandCapstoneARM64_t::isRead() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return (op.access & CS_AC_READ)!=0; +} + +bool DecodedOperandCapstoneARM64_t::isWritten() const +{ + // default: use capstone's advice. + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->arm64.operands[op_num]); + return (op.access & CS_AC_WRITE)!=0; +} diff --git a/irdb-lib/libIRDB-core/src/operand_csx86.cpp b/irdb-lib/libIRDB-core/src/operand_csx86.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ce863a9ef45d60a35f2354a6fc2a5f81e0b65e91 --- /dev/null +++ b/irdb-lib/libIRDB-core/src/operand_csx86.cpp @@ -0,0 +1,820 @@ + +#include <libIRDB-core.hpp> +#include <memory> +#include <decode_base.hpp> +#include <decode_csx86.hpp> +#include <operand_base.hpp> +#include <operand_csx86.hpp> + + + +using namespace std; +using namespace libIRDB; + +#include <capstone.h> + + +// static helpers. + + +static uint32_t to_seg_reg_number(const x86_reg ®) +{ + switch(reg) + { + case X86_REG_ES: return 0; + case X86_REG_CS: return 1; + case X86_REG_SS: return 2; + case X86_REG_DS: return 3; + case X86_REG_FS: return 4; + case X86_REG_GS: return 5; + default: break; + } + assert(0); +} + +static uint32_t to_reg_number(const x86_reg ®) +{ + switch(reg) + { + case X86_REG_AH: + case X86_REG_AL: + case X86_REG_AX: + case X86_REG_EAX: + case X86_REG_RAX: + return 0; + + case X86_REG_CH: + case X86_REG_CL: + case X86_REG_CX: + case X86_REG_ECX: + case X86_REG_RCX: + return 1; + + case X86_REG_DH: + case X86_REG_DX: + case X86_REG_DL: + case X86_REG_EDX: + case X86_REG_RDX: + return 2; + + case X86_REG_BH: + case X86_REG_BL: + case X86_REG_BX: + case X86_REG_EBX: + case X86_REG_RBX: + return 3; + + case X86_REG_ESP: + case X86_REG_RSP: + case X86_REG_SP: + case X86_REG_SPL: + return 4; + + case X86_REG_BP: + case X86_REG_BPL: + case X86_REG_EBP: + case X86_REG_RBP: + return 5; + + case X86_REG_ESI: + case X86_REG_RSI: + case X86_REG_SI: + case X86_REG_SIL: + return 6; + + case X86_REG_DI: + case X86_REG_DIL: + case X86_REG_EDI: + case X86_REG_RDI: + return 7; + + case X86_REG_R8: + case X86_REG_R8B: + case X86_REG_R8D: + case X86_REG_R8W: + return 8; + + case X86_REG_R9: + case X86_REG_R9B: + case X86_REG_R9D: + case X86_REG_R9W: + return 9; + + case X86_REG_R10: + case X86_REG_R10B: + case X86_REG_R10D: + case X86_REG_R10W: + return 10; + + case X86_REG_R11: + case X86_REG_R11B: + case X86_REG_R11D: + case X86_REG_R11W: + return 11; + + case X86_REG_R12: + case X86_REG_R12B: + case X86_REG_R12D: + case X86_REG_R12W: + return 12; + + case X86_REG_R13: + case X86_REG_R13B: + case X86_REG_R13D: + case X86_REG_R13W: + return 13; + + case X86_REG_R14: + case X86_REG_R14B: + case X86_REG_R14D: + case X86_REG_R14W: + return 14; + + case X86_REG_R15: + case X86_REG_R15B: + case X86_REG_R15D: + case X86_REG_R15W: + return 15; + default: break; + } + assert(0); +} + +// methods + +//DecodedOperandCapstoneX86_t& DecodedOperandCapstoneX86_t::operator=(const DecodedOperandCapstoneX86_t& copy) +//{ +// return *this; +//} +// +//DecodedOperandCapstoneX86_t::DecodedOperandCapstoneX86_t(const DecodedOperandCapstoneX86_t& copy) +//{ +// *this=copy; +//} + +DecodedOperandCapstoneX86_t::DecodedOperandCapstoneX86_t( const shared_ptr<void> & p_my_insn, uint8_t p_op_num) + : + my_insn(p_my_insn), + op_num(p_op_num) +{ + +} + +DecodedOperandCapstoneX86_t::~DecodedOperandCapstoneX86_t() +{ +} + + +bool DecodedOperandCapstoneX86_t::isConstant() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + + return op.type==X86_OP_IMM; +} + +uint64_t DecodedOperandCapstoneX86_t::getConstant() const +{ + if(!isConstant()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-constant operand"); + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return op.imm; +} + +string DecodedOperandCapstoneX86_t::getString() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + const auto handle=DecodedInstructionCapstoneX86_t::cs_handle->getHandle(); + + switch(op.type) + { + case X86_OP_REG: + return string(cs_reg_name(handle, op.reg)); + case X86_OP_IMM: + return to_string(op.imm); + case X86_OP_MEM: + { +// if (op.mem.segment != X86_REG_INVALID) +// ret_val+=cs_reg_name(handle, op.mem.segment) +" : " ; + if (op.mem.base == X86_REG_RIP) + { + /* convert pc+disp into disp+insn_size. */ + return to_string(op.mem.disp+the_insn->size); + } + else + { + string ret_val; + if (op.mem.base != X86_REG_INVALID) + ret_val+=cs_reg_name(handle, op.mem.base); + + if (op.mem.index != X86_REG_INVALID) + ret_val+=string(" + ") +cs_reg_name(handle, op.mem.index); + + if (op.mem.scale != 1) + ret_val+=string(" * ") + to_string(op.mem.scale); + + if (op.mem.disp != 0) + ret_val+=" + "+ to_string(op.mem.disp); + + if(ret_val=="") + return "0"; + + return ret_val; + } + assert(0); + } + case X86_OP_INVALID: + default: + assert(0); + } +} + +bool DecodedOperandCapstoneX86_t::isRegister() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return op.type==X86_OP_REG; +} + +bool DecodedOperandCapstoneX86_t::isGeneralPurposeRegister() const +{ + + const auto gp_regs=set<x86_reg>({ + X86_REG_AH, X86_REG_AL, X86_REG_AX, X86_REG_BH, X86_REG_BL, + X86_REG_BP, X86_REG_BPL, X86_REG_BX, X86_REG_CH, X86_REG_CL, + X86_REG_CX, X86_REG_DH, X86_REG_DI, X86_REG_DIL, + X86_REG_DL, X86_REG_DX, X86_REG_EAX, X86_REG_EBP, + X86_REG_EBX, X86_REG_ECX, X86_REG_EDI, X86_REG_EDX, + X86_REG_ESI, X86_REG_ESP, X86_REG_RAX, + X86_REG_RBP, X86_REG_RBX, X86_REG_RCX, X86_REG_RDI, X86_REG_RDX, + X86_REG_RSI, X86_REG_RSP, X86_REG_SI, + X86_REG_SIL, X86_REG_SP, X86_REG_SPL, + X86_REG_R8, X86_REG_R9, X86_REG_R10, X86_REG_R11, + X86_REG_R12, X86_REG_R13, X86_REG_R14, X86_REG_R15, + X86_REG_R8B, X86_REG_R9B, X86_REG_R10B, X86_REG_R11B, + X86_REG_R12B, X86_REG_R13B, X86_REG_R14B, X86_REG_R15B, X86_REG_R8D, + X86_REG_R9D, X86_REG_R10D, X86_REG_R11D, X86_REG_R12D, X86_REG_R13D, + X86_REG_R14D, X86_REG_R15D, X86_REG_R8W, X86_REG_R9W, X86_REG_R10W, + X86_REG_R11W, X86_REG_R12W, X86_REG_R13W, X86_REG_R14W, X86_REG_R15W + }); + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return isRegister() && gp_regs.find(op.reg)!=end(gp_regs); +} + +bool DecodedOperandCapstoneX86_t::isMmxRegister() const +{ + const auto regs=set<x86_reg>({ + X86_REG_MM0, X86_REG_MM1, + X86_REG_MM2, X86_REG_MM3, X86_REG_MM4, X86_REG_MM5, X86_REG_MM6, + X86_REG_MM7, X86_REG_R8}); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return isRegister() && regs.find(op.reg)!=end(regs); +} + +bool DecodedOperandCapstoneX86_t::isFpuRegister() const +{ + const auto regs=set<x86_reg>({ + X86_REG_ST0, X86_REG_ST1, X86_REG_ST2, X86_REG_ST3, + X86_REG_ST4, X86_REG_ST5, X86_REG_ST6, X86_REG_ST7, + }); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return isRegister() && regs.find(op.reg)!=end(regs); +} + +bool DecodedOperandCapstoneX86_t::isSseRegister() const +{ + const auto regs=set<x86_reg>({ + X86_REG_XMM0, X86_REG_XMM1, X86_REG_XMM2, X86_REG_XMM3, X86_REG_XMM4, + X86_REG_XMM5, X86_REG_XMM6, X86_REG_XMM7, X86_REG_XMM8, X86_REG_XMM9, + X86_REG_XMM10, X86_REG_XMM11, X86_REG_XMM12, X86_REG_XMM13, X86_REG_XMM14, + X86_REG_XMM15, X86_REG_XMM16, X86_REG_XMM17, X86_REG_XMM18, X86_REG_XMM19, + X86_REG_XMM20, X86_REG_XMM21, X86_REG_XMM22, X86_REG_XMM23, X86_REG_XMM24, + X86_REG_XMM25, X86_REG_XMM26, X86_REG_XMM27, X86_REG_XMM28, X86_REG_XMM29, + X86_REG_XMM30, X86_REG_XMM31 + }); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return isRegister() && regs.find(op.reg)!=end(regs); +} + +bool DecodedOperandCapstoneX86_t::isAvxRegister() const +{ + const auto regs=set<x86_reg>({ + X86_REG_YMM0, X86_REG_YMM1, X86_REG_YMM2, + X86_REG_YMM3, X86_REG_YMM4, X86_REG_YMM5, X86_REG_YMM6, X86_REG_YMM7, + X86_REG_YMM8, X86_REG_YMM9, X86_REG_YMM10, X86_REG_YMM11, X86_REG_YMM12, + X86_REG_YMM13, X86_REG_YMM14, X86_REG_YMM15, X86_REG_YMM16, X86_REG_YMM17, + X86_REG_YMM18, X86_REG_YMM19, X86_REG_YMM20, X86_REG_YMM21, X86_REG_YMM22, + X86_REG_YMM23, X86_REG_YMM24, X86_REG_YMM25, X86_REG_YMM26, X86_REG_YMM27, + X86_REG_YMM28, X86_REG_YMM29, X86_REG_YMM30, X86_REG_YMM31, + }); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return isRegister() && regs.find(op.reg)!=end(regs); +} + +bool DecodedOperandCapstoneX86_t::isZmmRegister() const +{ + const auto regs=set<x86_reg>({ + X86_REG_ZMM0, X86_REG_ZMM1, X86_REG_ZMM2, + X86_REG_ZMM3, X86_REG_ZMM4, X86_REG_ZMM5, X86_REG_ZMM6, X86_REG_ZMM7, + X86_REG_ZMM8, X86_REG_ZMM9, X86_REG_ZMM10, X86_REG_ZMM11, X86_REG_ZMM12, + X86_REG_ZMM13, X86_REG_ZMM14, X86_REG_ZMM15, X86_REG_ZMM16, X86_REG_ZMM17, + X86_REG_ZMM18, X86_REG_ZMM19, X86_REG_ZMM20, X86_REG_ZMM21, X86_REG_ZMM22, + X86_REG_ZMM23, X86_REG_ZMM24, X86_REG_ZMM25, X86_REG_ZMM26, X86_REG_ZMM27, + X86_REG_ZMM28, X86_REG_ZMM29, X86_REG_ZMM30, X86_REG_ZMM31, + }); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return isRegister() && regs.find(op.reg)!=end(regs); +} + +bool DecodedOperandCapstoneX86_t::isSpecialRegister() const +{ + const auto regs=set<x86_reg>({ + X86_REG_CR1, X86_REG_CR2, X86_REG_CR3, X86_REG_CR4, X86_REG_CR5, + X86_REG_CR6, X86_REG_CR7, X86_REG_CR8, X86_REG_CR9, X86_REG_CR10, + X86_REG_CR11, X86_REG_CR12, X86_REG_CR13, X86_REG_CR14, X86_REG_CR15, + X86_REG_DR0, X86_REG_DR1, X86_REG_DR2, X86_REG_DR3, X86_REG_DR4, + X86_REG_DR5, X86_REG_DR6, X86_REG_DR7, + }); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return isRegister() && regs.find(op.reg)!=end(regs); +} + +bool DecodedOperandCapstoneX86_t::isSegmentRegister() const +{ + const auto regs=set<x86_reg>({ + X86_REG_CS, + X86_REG_DS, + X86_REG_ES, + X86_REG_FS, + X86_REG_GS, + + }); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return isRegister() && regs.find(op.reg)!=end(regs); +} + + + +uint32_t DecodedOperandCapstoneX86_t::getRegNumber() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + if(isGeneralPurposeRegister()) + return to_reg_number(op.reg); + else if(isMmxRegister()) + return op.reg-X86_REG_MM0; + else if(isFpuRegister()) + return op.reg-X86_REG_ST0; + else if(isSseRegister()) + return op.reg-X86_REG_XMM0; + else if(isAvxRegister()) + return op.reg-X86_REG_YMM0; + else if(isZmmRegister()) + return op.reg-X86_REG_ZMM0; + else if(isSegmentRegister()) + return to_seg_reg_number(op.reg); + else + assert(0); +} + +bool DecodedOperandCapstoneX86_t::isMemory() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return op.type==X86_OP_MEM; +} + +bool DecodedOperandCapstoneX86_t::hasBaseRegister() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return isMemory() && op.mem.base!=X86_REG_INVALID && op.mem.base!=X86_REG_RIP; +} + +bool DecodedOperandCapstoneX86_t::hasIndexRegister() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return isMemory() && op.mem.index!=X86_REG_INVALID; +} + +uint32_t DecodedOperandCapstoneX86_t::getBaseRegister() const +{ + if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return to_reg_number((x86_reg)op.mem.base); +} + +uint32_t DecodedOperandCapstoneX86_t::getIndexRegister() const +{ + if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return to_reg_number((x86_reg)op.mem.index); +} + +uint32_t DecodedOperandCapstoneX86_t::getScaleValue() const +{ + if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return op.mem.scale; +} + +bool DecodedOperandCapstoneX86_t::hasMemoryDisplacement() const +{ + + if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); + + const auto the_insn = static_cast<cs_insn*>(my_insn.get()); + //const auto &op = (the_insn->detail->x86.operands[op_num]); + + const auto modrm = the_insn->detail->x86.modrm; + const auto mod = (modrm >> 6) & 0x3; + const auto rm = (modrm & 0x7); + const auto sib = the_insn->detail->x86.sib; + const auto sib_base = (sib >> 0) & 0x7; + //const auto sib_index = (sib >> 3) & 0x7; + + switch (mod) + { + case 0 /* 00 */: + if (rm == 4 && // indicates SIB is present. + sib_base == 0x5 // indicates disp32 when sib present and mod=00. + ) + return true; // abs 32-bit + + if (rm == 5) + return true; // pcrel or abs 32-bit depending on if 32-bit or 64-bit arch. + + return false; + + case 1 /* 01 */: + return true; + + case 2 /* 10 */: + return true; + + case 3 /* 11 */: + return false; + + default: + assert(0); //unreachable + } + assert(0); // unreachable +} // end of DecodedOperandCapstoneX86_t::hasMemoryDisplacement() + +virtual_offset_t DecodedOperandCapstoneX86_t::getMemoryDisplacement() const +{ + if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return op.mem.disp; +} + +bool DecodedOperandCapstoneX86_t::isPcrel() const +{ + if(!isMemory()) return false; + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + + return (op.mem.base==X86_REG_RIP || op.mem.base==X86_REG_EIP || op.mem.base==X86_REG_IP); +} + +/* in bytes */ +uint32_t DecodedOperandCapstoneX86_t::getMemoryDisplacementEncodingSize() const +{ + if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + //const auto &op = (the_insn->detail->x86.operands[op_num]); + + const auto modrm=the_insn->detail->x86.modrm; + const auto mod=(modrm>>6)&0x3; + const auto rm=(modrm)&0x7; + const auto sib=the_insn->detail->x86.sib; + const auto sib_base=(sib>>0)&0x7; + //const auto sib_index=(sib>>3)&0x7; + + switch(mod) + { + case 0 /* 00 */: + if(rm==4 && // indicates SIB is present. + sib_base==0x5 // indicates disp32 when sib present and mod=00. + ) + return 4; // abs 32-bit + + if(rm==5) + return 4; // pcrel or abs 32-bit depending on if 32-bit or 64-bit arch. + + throw std::logic_error(string("Cannot ")+__FUNCTION__+" of operand without displacement"); + + case 1 /* 01 */: return 1; + case 2 /* 10 */: return 4; + + case 3 /* 11 */: + throw std::logic_error(string("Cannot ")+__FUNCTION__+" of operand without displacement"); + default: assert(0); + } + assert(0); +} + +uint32_t DecodedOperandCapstoneX86_t::getArgumentSizeInBytes() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return op.size; +} + +uint32_t DecodedOperandCapstoneX86_t::getArgumentSizeInBits() const +{ + return getArgumentSizeInBytes()*8; +} + +bool DecodedOperandCapstoneX86_t::hasSegmentRegister() const +{ + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return isMemory() && (op.mem.segment != X86_REG_INVALID); + +} + +uint32_t DecodedOperandCapstoneX86_t::getSegmentRegister() const +{ + if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of operand without memory operand"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return to_seg_reg_number((x86_reg)op.mem.segment); +} + + +set<string> write_only_operand_mnemonics= + { + "seta", + "setae", + "setb", + "setbe", + "setc", + "sete", + "setg", + "setge", + "setl", + "setle", + "setna", + "setnae", + "setnb", + "setnbe", + "setnc", + "setne", + "setng", + "setnge", + "setnl", + "setnle", + "setno", + "setnp", + "setns", + "setnz", + "seto", + "setp", + "setpe", + "setpo", + "sets", + "setz", + "fst", + "fstp", + "fist", + "fistp" + }; + +set<string> write_first_operand_mnemonics= + { + "movups", + "movd", + "rol", + "movdqa", + "ror", + "movdqu", + "movq" + }; + +set<string> read_only_operand_mnemonics= + { + // specal read-only op cases, rest are some form of compare. + "push", + + // test + "test", + + // bit test (but not bt+comp or bt+reset as those have a reg dest. + "bt", + + // compare + "cmp", + + // multiplies and divides implicitly read/write eax/ax instead of op0 + "mul", + // "imul", imul has 2 forms, have to handle separately. + "div", + "idiv", + + // compare string + "cmps", + "cmpsb", + "cmpsw", + "cmpsd", + "cmpsq", + + // float compare [and pop] + "fcom", + "fcomp", + "fcompp", + + // compare floating point values + "fcomi", + "fcomip", + "fucomi", + "fucomip", + + + // logical compare + "ptest", + "vptest", + + // scas variants + "scas", + "scass", + "scasb", + "scasw", + "scasd", + + // ucomiss -- unordered cmpare scalar single-precision floating-point values and set flags + "ucomiss", + "vucomiss", + + // comiss -- unordered cmpare scalar single-precision floating-point values and set flags + "comiss", + "vcomiss", + + // comisd "comapre scalar ordered double-preicions floating-point values and set flags + "comisd", + "vcomisd", + + // ucomisd "comapre scalar ordered double-preicions floating-point values and set flags + "ucomisd", + "vucomisd", + + // packed bit test + "vtestps", + "vtestpd" + + // compare packed {double,single}-prec float values + "cmppd", + "vcmppd", + "cmpps", + "vcmpps", + + // compare sclar {double,single}-prec float values + "cmpsd", + "vcmpsd", + "cmpss", + "vcmpss", + + // compare packed data for equal + "pcmpeqb", + "vpcmpeqb", + "pcmpeqw", + "vpcmpeqw", + "pcmpeqd", + "vpcmpeqd", + "pcmpeqq", + "vpcmpeqq", + + // packed compare explicit length string, return {index, mask} + "pcmpestri", + "vpcmpestri", + "pcmpestrm", + "vpcmpestrm", + + // compare packed data for greather than + "pcompgtb", + "vpcompgtb", + "pcompgtw", + "vpcompgtw", + "pcompgtd", + "vpcompgtd", + "pcompgtq", + "vpcompgtq", + + // packed compare implicit length string, return index or mask + "pcmpistri", + "vpcmpistri", + "pcmpistrm", + "vpcmpistrm", + + // test if in transactional region + "xtest", + + }; + + + +bool DecodedOperandCapstoneX86_t::isRead() const +{ + if(!isWritten()) + return true; + + const auto d=DecodedInstructionCapstoneX86_t(my_insn); + const auto d_mnemonic=d.getMnemonic(); + const auto woom_it=write_only_operand_mnemonics.find(d_mnemonic); + const auto in_woom=(woom_it!=end(write_only_operand_mnemonics)); + if(in_woom) + return false; + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return (op.access & CS_AC_READ)!=0; +/* + if(op_num!=0) + return true; + + const auto d=DecodedInstructionCapstoneX86_t(my_insn); + if(d.isBranch()) + return true; + + const auto room_it=read_only_operand_mnemonics.find(d.getMnemonic()); + const auto in_room=(room_it!=end(read_only_operand_mnemonics)); + if(in_room) + return true; + + if(d.getMnemonic().substr(0,3)=="mov") + return false; + + // op0 is typically read/write + return true; + + assert(0); +*/ +} + +bool DecodedOperandCapstoneX86_t::isWritten() const +{ + const auto d=DecodedInstructionCapstoneX86_t(my_insn); + const auto d_mnemonic=d.getMnemonic(); + + // special case check: all operands are reads + const auto room_it=read_only_operand_mnemonics.find(d_mnemonic); + const auto in_room=(room_it!=end(read_only_operand_mnemonics)); + if(in_room) + return false; + + // special case check: all operands are writes + const auto woom_it=write_only_operand_mnemonics.find(d_mnemonic); + const auto in_woom=(woom_it!=end(write_only_operand_mnemonics)); + if(in_woom) + return true; + + // special case check: first operand is writes + if(op_num==0) + { + const auto wfom_it=write_first_operand_mnemonics.find(d_mnemonic); + const auto in_wfom=(wfom_it!=end(write_first_operand_mnemonics)); + if(in_wfom) + return true; + } + + // special case of imul + // imul has a 1-argument form which uses all it's operands + if(d_mnemonic=="imul" && !d.hasOperand(1)) + return false; + + + // default: use capstone's advice. + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return (op.access & CS_AC_WRITE)!=0; +/* + if(op_num!=0) + return false; + const auto d=DecodedInstructionCapstoneX86_t(my_insn); + if(d.isBranch()) + return false; + + const auto room_it=read_only_operand_mnemonics.find(d.getMnemonic()); + const auto in_room=(room_it!=end(read_only_operand_mnemonics)); + if(in_room) + return false; + + return true; +*/ +} diff --git a/irdb-lib/libIRDB-core/src/operand_dispatch.cpp b/irdb-lib/libIRDB-core/src/operand_dispatch.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0790f4677cdeb2637ee5ce37efe3a3df004b59c5 --- /dev/null +++ b/irdb-lib/libIRDB-core/src/operand_dispatch.cpp @@ -0,0 +1,64 @@ + +#include <libIRDB-core.hpp> +#include <operand_csx86.hpp> +#include <decode_csx86.hpp> +#include <operand_dispatch.hpp> +#include <decode_dispatch.hpp> + +using namespace std; +using namespace libIRDB; + +DecodedOperandDispatcher_t::DecodedOperandDispatcher_t(const shared_ptr<DecodedOperandCapstone_t> copy_cs) +{ + cs=copy_cs; +} + +DecodedOperandDispatcher_t::DecodedOperandDispatcher_t(const DecodedOperandDispatcher_t& copy) +{ + cs=copy.cs; +} + +DecodedOperandDispatcher_t::~DecodedOperandDispatcher_t() +{ +} + +DecodedOperandDispatcher_t& DecodedOperandDispatcher_t::operator=(const DecodedOperandDispatcher_t& copy) +{ + cs=copy.cs; + return *this; +} + +#define passthrough_to_cs(ret_type, method_name) \ + ret_type DecodedOperandDispatcher_t::method_name() const \ + { \ + return cs->method_name(); \ + } + +passthrough_to_cs(bool, isConstant); +passthrough_to_cs(uint64_t, getConstant); +passthrough_to_cs(string, getString); +passthrough_to_cs(bool, isRegister); +passthrough_to_cs(bool, isGeneralPurposeRegister); +passthrough_to_cs(bool, isMmxRegister); +passthrough_to_cs(bool, isFpuRegister); +passthrough_to_cs(bool, isSseRegister); +passthrough_to_cs(bool, isAvxRegister); +passthrough_to_cs(bool, isSpecialRegister); +passthrough_to_cs(bool, isSegmentRegister); +passthrough_to_cs(uint32_t, getRegNumber); +passthrough_to_cs(bool, isMemory); +passthrough_to_cs(bool, hasBaseRegister); +passthrough_to_cs(bool, hasIndexRegister); +passthrough_to_cs(uint32_t, getBaseRegister); +passthrough_to_cs(uint32_t, getIndexRegister); +passthrough_to_cs(uint32_t, getScaleValue); +passthrough_to_cs(bool, hasMemoryDisplacement); +passthrough_to_cs(virtual_offset_t, getMemoryDisplacement); +passthrough_to_cs(bool, isPcrel); +passthrough_to_cs(uint32_t, getMemoryDisplacementEncodingSize); +passthrough_to_cs(uint32_t, getArgumentSizeInBytes); +passthrough_to_cs(uint32_t, getArgumentSizeInBits); +passthrough_to_cs(bool, hasSegmentRegister); +passthrough_to_cs(uint32_t, getSegmentRegister); +passthrough_to_cs(bool, isRead); +passthrough_to_cs(bool, isWritten); diff --git a/irdb-lib/libIRDB-core/src/pqxxdb.cpp b/irdb-lib/libIRDB-core/src/pqxxdb.cpp new file mode 100644 index 0000000000000000000000000000000000000000..37fa2e986e477755c5b39590eb26cfad403f6fbf --- /dev/null +++ b/irdb-lib/libIRDB-core/src/pqxxdb.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +#include <all.hpp> +#include <pqxx/pqxx> +#include <string> + +using namespace libIRDB; +using namespace std; + +pqxxDB_t::pqxxDB_t() : DBinterface_t(), txn(conn) +{ + /* no other init needed */ +} + +void pqxxDB_t::issueQuery(std::string query) +{ + results=txn.exec(query); + results_iter=results.begin(); +} + +void pqxxDB_t::issueQuery(std::stringstream & query) +{ + results=txn.exec(query); + results_iter=results.begin(); +} + +void pqxxDB_t::moveToNextRow() +{ + assert(!isDone()); + ++results_iter; +} + +std::string pqxxDB_t::getResultColumn(std::string colname) +{ + if(results_iter[colname].is_null()) + return std::string(""); + + pqxx::binarystring bin_str(results_iter.at(colname)); + + return bin_str.str(); + +// return results_iter[colname].as<std::string>(); +} + +bool pqxxDB_t::isDone() +{ + return results_iter==results.end(); +} + +void pqxxDB_t::commit() +{ + txn.commit(); +} + +unique_ptr<IRDB_SDK::pqxxDB_t> IRDB_SDK::pqxxDB_t::factory() +{ + return unique_ptr<IRDB_SDK::pqxxDB_t>(new libIRDB::pqxxDB_t); +} diff --git a/irdb-lib/libIRDB-core/src/reloc.cpp b/irdb-lib/libIRDB-core/src/reloc.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dac3a40c8a3f6cb214501f89280d4e88510c4705 --- /dev/null +++ b/irdb-lib/libIRDB-core/src/reloc.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <all.hpp> +#include <irdb-util> + +using namespace std; + +vector<std::string> Relocation_t::WriteToDB(File_t* fid, BaseObj_t* myinsn) +{ + db_id_t wrt_id=wrt_obj ? wrt_obj->getBaseID() : BaseObj_t::NOT_IN_DATABASE; +/* + string q; + q ="insert into " + fid->relocs_table_name; + q+="(reloc_id,reloc_offset,reloc_type,instruction_id,addend,wrt_id,doip_id) "+ + string(" VALUES (") + +*/ + return { + to_string(getBaseID()), + to_string(offset), + (type), + to_string(myinsn->getBaseID()), + to_string(addend), + to_string(wrt_id), + to_string(getDoipID()) + }; +} + diff --git a/irdb-lib/libIRDB-core/src/scoop.cpp b/irdb-lib/libIRDB-core/src/scoop.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ff6512a9eab76f8e43ad4511197f1e5b623c2606 --- /dev/null +++ b/irdb-lib/libIRDB-core/src/scoop.cpp @@ -0,0 +1,103 @@ +#include "all.hpp" +#include <irdb-util> +#include <sstream> +#include <iomanip> + + +using namespace std; +using namespace libIRDB; + + +#define SCOOP_THRESHOLD 990000000 /* almost 1gb -- leaving a bit of head room for overhead sql syntax overheads */ +#define SCOOP_CHUNK_SIZE (10*1024*1024) /* 10 mb */ + +//#define SCOOP_THRESHOLD 10 /* almost 1gb -- leaving a bit of head room for overhead sql syntax overheads */ +//#define SCOOP_CHUNK_SIZE (128) + +string DataScoop_t::WriteToDB(File_t *fid, db_id_t newid) +{ + string q= ""; + + if(contents.length() < SCOOP_THRESHOLD) + q+=WriteToDBRange(fid,newid, 0, contents.length(), fid->scoop_table_name); + else + { + q+=WriteToDBRange(fid,newid, 0, SCOOP_THRESHOLD, fid->scoop_table_name); + q+=WriteToDBRange(fid,newid , SCOOP_THRESHOLD, contents.length(), fid->scoop_table_name+"_part2"); + } + + return q; +} + +string DataScoop_t::WriteToDBRange(File_t *fid, db_id_t newid, int start, int end, string table_name) +{ + +/* + scoop_id SERIAL PRIMARY KEY, -- key + name text DEFAULT '', -- string representation of the type + type_id integer, -- the type of the data, as an index into the table table. + start_address_id integer, -- address id for start. + end_address_id integer, -- address id for end + permissions integer -- in umask format (bitmask for rwx) + + */ + + db_id_t type_id=(getType() ? getType()->getBaseID() : BaseObj_t::NOT_IN_DATABASE); + + ostringstream hex_data; + + + string q=string("insert into ")+table_name+ + string(" (scoop_id, name, type_id, start_address_id, end_address_id, data, permissions, relro) ")+ + string(" VALUES (") + + string("'") + to_string(getBaseID()) + string("', ") + + string("'") + getName() + string("', ") + + string("'") + to_string(type_id) + string("', ") + + string("'") + to_string(getStart()->getBaseID()) + string("', ") + + string("'") + to_string(getEnd()->getBaseID()) + string("', ") + + string("'") + /* empty data field -- for now + */ string("', ") + + string("'") + to_string(permissions) + string("', ") + + string("'") + to_string(is_relro) + string("'); ") ; + // add the table row with empty data field. + dbintr->issueQuery(q); + + + // now try to append the data to the field in chunks. + + string query_start="update "+table_name+" set data = data || decode('"; + string query_end="', 'hex') where scoop_id="+ string("'") + to_string(getBaseID()) + string("'; ") ; + + + hex_data << query_start << setfill('0') << hex; + for (auto i = start; i < end; ++i) + { + hex_data << setw(2) << (int)(contents[i]&0xff); + + stringstream::pos_type offset = hex_data.tellp(); + + if(offset > SCOOP_CHUNK_SIZE) + { + // q+=hex_data.str(); + // hex_data.str(""); // reset to empty + // hex_data.clear(); + + // tag the end, + hex_data << query_end; + + // append this chunk to the db. + dbintr->issueQuery(hex_data.str()); + + // restart + hex_data.str(""); // reset to empty + hex_data.clear(); + hex_data << query_start << setfill('0') << hex; + } + } + hex_data << query_end; + + // append this chunk to the db. + dbintr->issueQuery(hex_data.str()); + + return ""; +} + diff --git a/irdb-lib/libIRDB-core/src/type.cpp b/irdb-lib/libIRDB-core/src/type.cpp new file mode 100644 index 0000000000000000000000000000000000000000..67ceb48b61da9637c3012b9ec8424e667af0007a --- /dev/null +++ b/irdb-lib/libIRDB-core/src/type.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include "all.hpp" +#include <irdb-util> + +using namespace std; +using namespace libIRDB; + +bool BasicType_t::isNumericType() const +{ + auto type = getTypeID(); + return type == IRDB_SDK::itNumeric || + type == IRDB_SDK::itInt || + type == IRDB_SDK::itFloat || + type == IRDB_SDK::itDouble || + type == IRDB_SDK::itChar; +} + +/* +CREATE TABLE #TYP# +( + type_id integer, + type integer DEFAULT 0, -- possible types (0: UNKNOWN) + name text DEFAULT '', -- string representation of the type + ref_type_id integer DEFAULT -1, -- for aggregate types + pos integer DEFAULT -1, -- for aggregate types, position in aggregate + ref_type_id2 integer DEFAULT -1, -- for func types + doip_id integer DEFAULT -1 -- the DOIP +); +*/ + +string BasicType_t::WriteToDB(File_t *fid, db_id_t newid) +{ + assert(fid); + + string q=string("insert into ")+fid->types_table_name + + string(" (type_id, type, name, ref_type_id, pos, ref_type_id2) ")+ + string(" VALUES (") + + string("'") + to_string(getBaseID()) + string("', ") + + string("'") + to_string(getTypeID()) + string("', ") + + string("'") + getName() + string("','-1','-1','-1') ; ") ; + +// cout << "BasicType_t::WriteToDB(): " << q << endl; + return q; +} + +string PointerType_t::WriteToDB(File_t *fid, db_id_t newid) +{ + assert(fid && getReferentType()); + string q=string("insert into ")+fid->types_table_name + + string(" (type_id, type, name, ref_type_id,pos,ref_type_id2) ")+ + string(" VALUES (") + + string("'") + to_string(getBaseID()) + string("', ") + + string("'") + to_string(getTypeID()) + string("', ") + + string("'") + getName() + string("', ") + + string("'") + to_string(getReferentType()->getBaseID()) + + string("','-1','-1') ; ") ; + +// cout << "PointerType_t::WriteToDB(): " << q << endl; + return q; +} + +string AggregateType_t::WriteToDB(File_t *fid, db_id_t newid) +{ + assert(fid); + assert(getNumAggregatedTypes() > 0); + + string q; + + for (auto i = 0U; i < getNumAggregatedTypes(); ++i) + { + auto t = getAggregatedType(i); + q+=string("insert into ")+fid->types_table_name + + string(" (type_id, type, name, ref_type_id, pos,ref_type_id2) ")+ + string(" VALUES (") + + string("'") + to_string(getBaseID()) + string("', ") + + string("'") + to_string(getTypeID()) + string("', ") + + string("'") + getName() + string("', ") + + string("'") + to_string(t->getBaseID()) + string("', ") + + string("'") + to_string(i) + + string("','-1') ; ") ; + } + + // cout << "AggregatedType_t::WriteToDB(): " << q << endl; + return q; +} + +void AggregateType_t::addAggregatedType(IRDB_SDK::Type_t *t, int pos) +{ + refTypes.push_back(t); + +// cout << "AggregatedType_t::AddAggregatedType(): new size: " << refTypes.size() << endl; +} + +/* +CREATE TABLE #TYP# +( + type_id integer, + type integer DEFAULT 0, -- possible types (0: UNKNOWN) + name text DEFAULT '', -- string representation of the type + ref_type_id integer DEFAULT -1, -- for aggregate types + pos integer DEFAULT -1, -- for aggregate types, position in aggregate + ref_type_id2 integer DEFAULT -1, -- for func types + doip_id integer DEFAULT -1 -- the DOIP +); +*/ +string FuncType_t::WriteToDB(File_t *fid, db_id_t newid) +{ + assert(fid); + assert(getReturnType()); + assert(getArgumentsType()); + string q=string("insert into ")+fid->types_table_name + + string(" (type_id, type, name, ref_type_id, ref_type_id2,pos) ")+ + string(" VALUES (") + + string("'") + to_string(getBaseID()) + string("', ") + + string("'") + to_string(getTypeID()) + string("', ") + + string("'") + getName() + string("', ") + + string("'") + to_string(getReturnType()->getBaseID()) + string("', ") + + string("'") + to_string(getArgumentsType()->getBaseID()) + + string("','-1') ; ") ; + +// cout << "FuncType_t::WriteToDB(): " << q << endl; + return q; +} + diff --git a/irdb-lib/libIRDB-core/src/variantid.cpp b/irdb-lib/libIRDB-core/src/variantid.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fc33c6ed9434e96cab9d5383315dacfb67a8e681 --- /dev/null +++ b/irdb-lib/libIRDB-core/src/variantid.cpp @@ -0,0 +1,514 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + + +#include <all.hpp> +#include <irdb-util> +#include <stdlib.h> +using namespace std; + +template <class T> +inline string to_string (const T& t) +{ + stringstream ss; + ss << t; + return ss.str(); +} + + + +/* + * Create a new variant ID that is not yet in the database + */ +VariantID_t::VariantID_t() : + BaseObj_t(NULL) +{ + schema_ver=CURRENT_SCHEMA; + orig_pid=-1; + name=""; +} + + +VariantID_t::~VariantID_t() +{ + for(auto it : files) + { + delete it; + } +} + + +void VariantID_t::CreateTables() +{ + // note: this tables are now part of File_t. + assert(0); +} + +VariantID_t::VariantID_t(db_id_t pid) : BaseObj_t(NULL) +{ + std::string q="select * from Variant_info where variant_id = " ; + q+=to_string(pid); + q+=";"; + + try + { + BaseObj_t::dbintr->issueQuery(q); + } + catch (const std::exception &e) + { + schema_ver=-1; + orig_pid=-1; + name=""; + + throw DatabaseError_t(DatabaseError_t::VariantTableNotRegistered); + }; + + if(BaseObj_t::dbintr->isDone()) + throw DatabaseError_t(DatabaseError_t::VariantNotInDatabase); + + setBaseID(atoi(BaseObj_t::dbintr->getResultColumn("variant_id").c_str())); + schema_ver=atoi(BaseObj_t::dbintr->getResultColumn("schema_version_id").c_str()); + orig_pid=atoi(BaseObj_t::dbintr->getResultColumn("orig_variant_id").c_str()); + name=(BaseObj_t::dbintr->getResultColumn("name")); + + + BaseObj_t::dbintr->moveToNextRow(); + assert(BaseObj_t::dbintr->isDone()); + + ReadFilesFromDB(); +} + +bool VariantID_t::isRegistered() const +{ + return getBaseID()!=BaseObj_t::NOT_IN_DATABASE; +} + +bool VariantID_t::registerID() +{ + assert(!isRegistered()); + + std::string q; + q="insert into variant_info (schema_version_id,name) " + "values('"; + q+=to_string(schema_ver); + q+="','"; + q+=to_string(name); + q+="')"; + q+="returning variant_id;"; + + dbintr->issueQuery(q); + assert(!BaseObj_t::dbintr->isDone()); + + db_id_t newid=atoi(dbintr->getResultColumn("variant_id").c_str()); + + /* set IDs */ + setBaseID(newid); + if(NOT_IN_DATABASE==orig_pid) + orig_pid=newid; + + BaseObj_t::dbintr->moveToNextRow(); + assert(BaseObj_t::dbintr->isDone()); + + return true; +} + +IRDB_SDK::VariantID_t* VariantID_t::clone(bool deep) +{ + assert(isRegistered()); // cannot clone something that's not registered + + // create the new program id + VariantID_t *ret=new VariantID_t; + + // set the inhereted fields + ret->setName(name+"_cloneof"+to_string(getBaseID())); + ret->orig_pid=orig_pid; + + // register the new VID to the database. + ret->registerID(); + // and write it to the database + ret->WriteToDB(); + + // (shallow) clone the file_info table entries + std::string q; + + // lastly update the variant_dependency table to make a copy of the rows in which + // the old variant depended upon. The new rows will indicate that the + // new variant also depends on those files + q="insert into variant_dependency (variant_id, file_id, doip_id) select '"; + q+=to_string(ret->getBaseID()); + q+="', file_id, doip_id from variant_dependency where variant_id='"; + q+=to_string(getBaseID()); + q+="';"; + dbintr->issueQuery(q); + + if(deep) + ret->CloneFiles(files); + + return ret; +} + +void VariantID_t::CloneFiles(FileSet_t &files) +{ + for(auto fiter=files.begin(); fiter!=files.end(); ++fiter) + { + auto the_file=dynamic_cast<File_t*>(*fiter); + files.insert(CloneFile(the_file)); + } +} + +File_t* VariantID_t::CloneFile(File_t* fptr) +{ + std::string q; + + q ="insert into file_info " + "(" + "orig_file_id," + "url," + "hash," + "arch," + "elfoid," + "doip_id" + ") " + "values ( '" + + to_string(fptr->orig_fid) + "', '" + + to_string(fptr->url) + "', '" + + to_string(fptr->hash) + "', '" + + to_string(fptr->arch) + "', '" + + to_string(fptr->elfoid) + "', '" + + to_string(fptr->getDoipID()) + + "' ) "; + q+=" returning file_id; "; + + + dbintr->issueQuery(q); + assert(!BaseObj_t::dbintr->isDone()); + + db_id_t newfid=atoi(dbintr->getResultColumn("file_id").c_str()); + + std::string atn="atnfid"+to_string(newfid); + std::string ftn="ftnfid"+to_string(newfid); + std::string itn="itnfid"+to_string(newfid); + std::string icfs="icfsfid"+to_string(newfid); + std::string icfsmap="icfsmapfid"+to_string(newfid); + std::string rtn="rtnfid"+to_string(newfid); + std::string dtn="dtnfid"+to_string(newfid); + std::string dtn_part2="dtnfid"+to_string(newfid)+"_part2"; + std::string typ="typfid"+to_string(newfid); + std::string ehp="ehpfid"+to_string(newfid); + std::string css="cssfid"+to_string(newfid); + + q ="update file_info set address_table_name='"+atn; + q+="', function_table_name='"+ftn; + q+="', instruction_table_name='"+itn; + q+="', icfs_table_name='"+icfs; + q+="', icfs_map_table_name='"+icfsmap; + q+="', relocs_table_name='"+rtn; + q+="', types_table_name='"+typ; + q+="', scoop_table_name='"+dtn; + q+="', ehpgm_table_name='"+ehp; + q+="', ehcss_table_name='"+css; + q+="' where file_id='"; + q+=to_string(newfid); + q+="' ; "; + + dbintr->issueQuery(q); + + File_t* newfile=new File_t(newfid, fptr->orig_fid, fptr->url, fptr->hash, fptr->arch, + fptr->elfoid, atn, ftn, itn, icfs, icfsmap, rtn, typ, dtn, ehp, css, fptr->getDoipID()); + + newfile->CreateTables(); + + // first drop the old values + q="drop table "; + q+=itn; + q+=" ; "; + dbintr->issueQuery(q); + + q="drop table "; + q+=icfsmap; + q+=" ; "; + dbintr->issueQuery(q); + + q="drop table "; + q+=icfs; + q+=" ; "; + dbintr->issueQuery(q); + + q="drop table "; + q+=atn; + q+=" ; "; + dbintr->issueQuery(q); + + q="drop table "; + q+=ftn; + q+=" ; "; + dbintr->issueQuery(q); + + q="drop table "; + q+=rtn; + q+=" ; "; + dbintr->issueQuery(q); + + q="drop table "; + q+=typ; + q+=" ; "; + dbintr->issueQuery(q); + + q="drop table "; + q+=dtn; + q+=" ; "; + dbintr->issueQuery(q); + + q="drop table "; + q+=dtn_part2; + q+=" ; "; + dbintr->issueQuery(q); + + q="drop table "; + q+=ehp; + q+=" ; "; + dbintr->issueQuery(q); + + q="drop table "; + q+=css; + q+=" ; "; + dbintr->issueQuery(q); + + + // next issue SQL to clone each table + q="select * into "; + q+=atn; + q+=" from "; + q+=fptr->address_table_name; + q+=" ;"; + dbintr->issueQuery(q); + + q="select * into "; + q+=itn; + q+=" from "; + q+=fptr->instruction_table_name; + q+=" ;"; + dbintr->issueQuery(q); + + q="select * into "; + q+=icfs; + q+=" from "; + q+=fptr->icfs_table_name; + q+=" ;"; + dbintr->issueQuery(q); + + q="select * into "; + q+=icfsmap; + q+=" from "; + q+=fptr->icfs_map_table_name; + q+=" ;"; + dbintr->issueQuery(q); + + q="select * into "; + q+=ftn; + q+=" from "; + q+=fptr->function_table_name; + q+=" ;"; + dbintr->issueQuery(q); + + q="select * into "; + q+=rtn; + q+=" from "; + q+=fptr->relocs_table_name; + q+=" ;"; + dbintr->issueQuery(q); + + q="select * into "; + q+=typ; + q+=" from "; + q+=fptr->types_table_name; + q+=" ;"; + dbintr->issueQuery(q); + + q="select * into "; + q+=dtn; + q+=" from "; + q+=fptr->scoop_table_name; + q+=" ;"; + dbintr->issueQuery(q); + + q="select * into "; + q+=dtn_part2; + q+=" from "; + q+=fptr->scoop_table_name+"_part2"; + q+=" ;"; + dbintr->issueQuery(q); + + q="select * into "; + q+=ehp; + q+=" from "; + q+=fptr->ehpgm_table_name; + q+=" ;"; + dbintr->issueQuery(q); + + q="select * into "; + q+=css; + q+=" from "; + q+=fptr->ehcss_table_name; + q+=" ;"; + dbintr->issueQuery(q); + + // update the variant dependency table to represent the deep clone + q = "update variant_dependency set file_id='" + + to_string(newfid) + + "' where variant_id='" + + to_string(getBaseID()) + + "' AND file_id='" + + to_string(fptr->getBaseID()) + + "' ;"; + dbintr->issueQuery(q); + + + return newfile; + +} + +void VariantID_t::WriteToDB() +{ + assert(isRegistered()); + + std::string q="update variant_info SET "; + q+=" schema_version_id = '" + to_string(schema_ver) + "', "; + q+=" name = '" + name + "', "; + q+=" orig_variant_id = '" + to_string(orig_pid) + "', "; + q+=" doip_id = '" + to_string(getDoipID()) + "' "; + q+=" where variant_id = '" + to_string(getBaseID()) + "';"; + + dbintr->issueQuery(q); +} + +std::ostream& IRDB_SDK::operator<<(std::ostream& out, const IRDB_SDK::VariantID_t& pid) +{ + + out << "(" << + "variant_id=" << pid.getBaseID() << ":" << + "orig_pid=" << pid.getOriginalVariantID() << ":" << + "name=" << pid.getName() << + ")" ; + return out; +} + + +void VariantID_t::DropFromDB() +{ + assert(isRegistered()); + + string q; + q+=string("delete from variant_dependency where variant_id = '") + to_string(getBaseID()) + string("';"); + q+=string("delete from variant_info where variant_id = '") + to_string(getBaseID()) + string("';"); + + dbintr->issueQuery(q); + + setBaseID(NOT_IN_DATABASE); + orig_pid=NOT_IN_DATABASE; + schema_ver=CURRENT_SCHEMA; +} + + +IRDB_SDK::File_t* VariantID_t::getMainFile() const +{ + for( + auto it=files.begin(); + it!=files.end(); + ++it + ) + { + if ((*it)->getURL().find("a.ncexe") != string::npos) + return *it; + } + /* we should have found the main file somewhere. */ + assert(0); +} + + + +void VariantID_t::ReadFilesFromDB() +{ + + std::string q= "select file_info.orig_file_id, file_info.address_table_name, " + " file_info.instruction_table_name, file_info.icfs_table_name,file_info.icfs_map_table_name, " + " file_info.function_table_name, file_info.relocs_table_name, file_info.types_table_name, " + " file_info.scoop_table_name, file_info.ehpgm_table_name, file_info.ehcss_table_name, file_info.file_id, file_info.url, file_info.hash," + " file_info.arch, file_info.type, file_info.elfoid, file_info.doip_id " + " from file_info,variant_dependency " + " where variant_dependency.variant_id = '" + to_string(getBaseID()) + "' AND " + " file_info.file_id = variant_dependency.file_id ; "; + + dbintr->issueQuery(q); + + while(!dbintr->isDone()) + { +// file_info.file_id, file_info.url, file_info.hash, file_info.arch, file_info.type, file_info.doip_id + + db_id_t file_id=atoi(dbintr->getResultColumn("file_id").c_str()); + db_id_t orig_fid=atoi(dbintr->getResultColumn("orig_file_id").c_str()); + std::string url=dbintr->getResultColumn("url"); + std::string hash=dbintr->getResultColumn("hash"); + std::string type=dbintr->getResultColumn("type"); + int oid=atoi(dbintr->getResultColumn("elfoid").c_str()); + db_id_t doipid=atoi(dbintr->getResultColumn("doip_id").c_str()); + std::string atn=(BaseObj_t::dbintr->getResultColumn("address_table_name")); + std::string ftn=(BaseObj_t::dbintr->getResultColumn("function_table_name")); + std::string itn=(BaseObj_t::dbintr->getResultColumn("instruction_table_name")); + std::string dtn=(BaseObj_t::dbintr->getResultColumn("scoop_table_name")); + std::string ehp=(BaseObj_t::dbintr->getResultColumn("ehpgm_table_name")); + std::string css=(BaseObj_t::dbintr->getResultColumn("ehcss_table_name")); + std::string icfs=(BaseObj_t::dbintr->getResultColumn("icfs_table_name")); + std::string icfs_map=(BaseObj_t::dbintr->getResultColumn("icfs_map_table_name")); + std::string rtn=(BaseObj_t::dbintr->getResultColumn("relocs_table_name")); + std::string typ=(BaseObj_t::dbintr->getResultColumn("types_table_name")); + + + File_t *newfile=new File_t(file_id,orig_fid,url,hash,type,oid,atn,ftn,itn,icfs,icfs_map,rtn,typ,dtn,ehp,css,doipid); + +// std::cout<<"Found file "<<file_id<<"."<<std::endl; +// std::cout<<" atn: " << atn << " ftn: " << ftn << " rtn: " << rtn << " typ: " << typ << std::endl; + + files.insert(newfile); + + dbintr->moveToNextRow(); + } +} + + +namespace IRDB_SDK +{ + +unique_ptr<VariantID_t> VariantID_t::factory(const DatabaseID_t& id) +{ + return unique_ptr<VariantID_t>(new libIRDB::VariantID_t(id)); +} + +unique_ptr<FileIR_t> FileIR_t::factory(VariantID_t *p_progid, File_t* p_fid) +{ + const auto progid=dynamic_cast<libIRDB::VariantID_t*>(p_progid); + const auto fid=dynamic_cast<libIRDB::File_t*>(p_fid); + return unique_ptr<FileIR_t>(new libIRDB::FileIR_t(*progid,fid)); +} + + +} + diff --git a/irdb-lib/libIRDB-deep/src/SConscript b/irdb-lib/libIRDB-deep/src/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..15daf24c7d1de0049565d3abc0aab12761ac50da --- /dev/null +++ b/irdb-lib/libIRDB-deep/src/SConscript @@ -0,0 +1,28 @@ +import os + +Import('env') +myenv=env + + +libname="irdb-deep" +files= ''' + deep.cpp + ''' +cpppath=''' + $IRDB_SDK/include/ + $SECURITY_TRANSFORMS_HOME/include/ + $SECURITY_TRANSFORMS_HOME/libIRDB-deep/src + $SECURITY_TRANSFORMS_HOME/libMEDSannotation/include + $SMPSA_HOME/include/ + ''' + +#myenv.Append(CCFLAGS=" -Wall -W -Wextra -Wconversion ") + +myenv=myenv.Clone(CPPPATH=Split(cpppath)) +myenv.Append(CXXFLAGS = " -std=c++11 ") +lib=myenv.SharedLibrary(libname, Split(files), LIBS=Split("irdb-core irdb-util irdb-transform stars MEDSannotation"), LIBPATH=Split("$SECURITY_TRANSFORMS_HOME/lib")) + +install=env.Install("$SECURITY_TRANSFORMS_HOME/lib/", lib) +Default(install) + +Return('install') diff --git a/irdb-lib/libIRDB-deep/src/deep.cpp b/irdb-lib/libIRDB-deep/src/deep.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1ab77bc43feb4763f7a5b09f906af7f3d2b1ebbd --- /dev/null +++ b/irdb-lib/libIRDB-deep/src/deep.cpp @@ -0,0 +1,167 @@ + +#include <map> +#include <set> +#include <memory> +#include <deep.hpp> +#include <MEDS_DeadRegAnnotation.hpp> +#include <MEDS_MemoryRangeAnnotation.hpp> +#include <MEDS_SafeFuncAnnotation.hpp> + + +using namespace libIRDB; +using namespace std; +using namespace MEDS_Annotation; + + +StarsDeepAnalysis_t::StarsDeepAnalysis_t(IRDB_SDK::FileIR_t* firp, const vector<string>& options) + : Transform(firp) +{ + for(const auto s : options) + { + if(s=="SetDeepLoopAnalyses=true") + stars_analysis_engine.GetSTARSOptions().SetDeepLoopAnalyses(true); + else if(s=="SetConstantPropagation=true") + stars_analysis_engine.GetSTARSOptions().SetConstantPropagation(true); + else + throw invalid_argument("Unknown option: "+s); + } + stars_analysis_engine.do_STARS(getFileIR()); +} + +unique_ptr<IRDB_SDK::FunctionSet_t> StarsDeepAnalysis_t::getLeafFunctions() const +{ + auto ret=unique_ptr<IRDB_SDK::FunctionSet_t>(new IRDB_SDK::FunctionSet_t); + auto &ret_map=*ret; + auto meds_ap=stars_analysis_engine.getAnnotations(); + + for(auto func : getFileIR()->getFunctions()) + { + auto the_range = meds_ap.getFuncAnnotations().equal_range(func->getName()); + /* for each annotation for this instruction */ + for (auto it = the_range.first; it != the_range.second; ++it) + { + auto p_annotation=dynamic_cast<MEDS_SafeFuncAnnotation*>(it->second); + if(p_annotation==nullptr) + continue; + + /* bad annotation? */ + if(!p_annotation->isLeaf()) + continue; + + /* record dead reg set */ + ret_map.insert(func); + } + } + + return ret; +} + + +unique_ptr<IRDB_SDK::DeadRegisterMap_t> StarsDeepAnalysis_t::getDeadRegisters() const +{ + auto ret=unique_ptr<IRDB_SDK::DeadRegisterMap_t>(new IRDB_SDK::DeadRegisterMap_t); + auto &ret_map=*ret; + auto meds_ap=stars_analysis_engine.getAnnotations(); + for(auto insn : getFileIR()->getInstructions()) + { + auto the_range = meds_ap.getAnnotations().equal_range(insn->getBaseID()); + /* for each annotation for this instruction */ + for (auto it = the_range.first; it != the_range.second; ++it) + { + auto p_annotation=dynamic_cast<MEDS_DeadRegAnnotation*>(it->second); + if(p_annotation==nullptr) + continue; + + /* bad annotation? */ + if(!p_annotation->isValid()) + continue; + + /* record dead reg set */ + ret_map[insn] = p_annotation->getRegisterSet(); + } + } + + return ret; +} + +unique_ptr<IRDB_SDK::StaticGlobalStartMap_t> StarsDeepAnalysis_t::getStaticGlobalRanges() const +{ + auto ret=unique_ptr<IRDB_SDK::StaticGlobalStartMap_t>(new IRDB_SDK::StaticGlobalStartMap_t()); + auto &ret_map=*ret; + auto meds_ap=stars_analysis_engine.getAnnotations(); + for(auto insn : getFileIR()->getInstructions()) + { + auto the_range = meds_ap.getAnnotations().equal_range(insn->getBaseID()); + /* for each annotation for this instruction */ + for (auto it = the_range.first; it != the_range.second; ++it) + { + auto p_annotation=dynamic_cast<MEDS_MemoryRangeAnnotation*>(it->second); + if(p_annotation==nullptr) + continue; + + /* bad annotation? */ + if(!p_annotation->isValid()) + continue; + + if(!p_annotation->isStaticGlobalRange()) + continue; + + // record the range minimum. + ret_map[insn] = p_annotation->getRangeMin(); + } + } + + return ret; +} + +unique_ptr<IRDB_SDK::RangeSentinelSet_t> StarsDeepAnalysis_t::getRangeSentinels() const +{ + auto ret=unique_ptr<IRDB_SDK::RangeSentinelSet_t>(new IRDB_SDK::RangeSentinelSet_t); + auto meds_ap=stars_analysis_engine.getAnnotations(); + for(auto insn : getFileIR()->getInstructions()) + { + auto the_range = meds_ap.getAnnotations().equal_range(insn->getBaseID()); + /* for each annotation for this instruction */ + for (auto it = the_range.first; it != the_range.second; ++it) + { + auto p_annotation=dynamic_cast<MEDS_MemoryRangeAnnotation*>(it->second); + if(p_annotation==nullptr) + continue; + + /* bad annotation? */ + if(!p_annotation->isValid()) + continue; + + if(!p_annotation->isSentinel()) + continue; + + /* record sentinal marker. */ + ret->insert(insn); + } + } + return ret; +} + + +unique_ptr<IRDB_SDK::DeepAnalysis_t> IRDB_SDK::DeepAnalysis_t::factory(FileIR_t* firp, const AnalysisEngine_t& ae, const vector<string>& options) +{ + + auto ret=unique_ptr<IRDB_SDK::DeepAnalysis_t>(); + + switch(ae) + { + case IRDB_SDK::aeSTARS: + { + ret.reset(new libIRDB::StarsDeepAnalysis_t(firp,options)); + break; + } + default: + { + throw std::invalid_argument("AnalysisEngine_t value not supported"); + } + + } + return ret; +} + + diff --git a/irdb-lib/libIRDB-deep/src/deep.hpp b/irdb-lib/libIRDB-deep/src/deep.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6943da676fbd16caf9b0a49d2d806617906eb284 --- /dev/null +++ b/irdb-lib/libIRDB-deep/src/deep.hpp @@ -0,0 +1,34 @@ + +#include <irdb-core> +#include <irdb-transform> +#include <irdb-deep> +#include <memory> +#include <vector> + +#include <stars.h> + + +namespace libIRDB +{ + using namespace std; + + class StarsDeepAnalysis_t : public IRDB_SDK::DeepAnalysis_t, protected IRDB_SDK::Transform + { + private: + StarsDeepAnalysis_t() = delete; + StarsDeepAnalysis_t(const StarsDeepAnalysis_t& copy) = delete; + + public: + + StarsDeepAnalysis_t(IRDB_SDK::FileIR_t* firp, const vector<string>& options={}); + + unique_ptr<IRDB_SDK::FunctionSet_t > getLeafFunctions() const ; + unique_ptr<IRDB_SDK::DeadRegisterMap_t > getDeadRegisters() const ; + unique_ptr<IRDB_SDK::StaticGlobalStartMap_t> getStaticGlobalRanges() const ; + unique_ptr<IRDB_SDK::RangeSentinelSet_t > getRangeSentinels() const ; + + private: + STARS::IRDB_Interface_t stars_analysis_engine; + + }; +} diff --git a/irdb-lib/libIRDB-elfdep/SConscript b/irdb-lib/libIRDB-elfdep/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..f0e0b9fd099936cb34955e3edbf6031acbe0dace --- /dev/null +++ b/irdb-lib/libIRDB-elfdep/SConscript @@ -0,0 +1,7 @@ +import os + +Import('env') + +lib=SConscript("src/SConscript") + +Return('lib') diff --git a/irdb-lib/libIRDB-elfdep/SConstruct b/irdb-lib/libIRDB-elfdep/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..4d6381b5999d3e6d4e4687fc95f444ea2c4c5747 --- /dev/null +++ b/irdb-lib/libIRDB-elfdep/SConstruct @@ -0,0 +1,8 @@ + + + +env=Environment() +Export('env') +lib=SConscript("SConscript") + +Return(lib) diff --git a/irdb-lib/libIRDB-elfdep/src/SConscript b/irdb-lib/libIRDB-elfdep/src/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..dc8652648f1822c490a9b6f46d906450c9f41dd6 --- /dev/null +++ b/irdb-lib/libIRDB-elfdep/src/SConscript @@ -0,0 +1,29 @@ +import os + + + +Import('env') +myenv=env.Clone() +myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) + +files="elfdep.cpp" + +cpppath=''' + . + $IRDB_SDK/include + $SECURITY_TRANSFORMS_HOME/libIRDB/include + $SECURITY_TRANSFORMS_HOME/libtransform/include + ''' + + +LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" +LIBS=Split("irdb-core irdb-transform") + +myenv=myenv.Clone(CPPPATH=Split(cpppath)) +myenv.Append(CXXFLAGS = " -std=c++11 ") + +lib=myenv.SharedLibrary("irdb-elfdep", Split(files), LIBPATH=LIBPATH, LIBS=LIBS) +install=myenv.Install("$SECURITY_TRANSFORMS_HOME/lib/", lib) +Default(install) + +Return('install') diff --git a/irdb-lib/libIRDB-elfdep/src/SConstruct b/irdb-lib/libIRDB-elfdep/src/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..6c6fd8ea22a97d734ad3e4f3e5a937340c63375d --- /dev/null +++ b/irdb-lib/libIRDB-elfdep/src/SConstruct @@ -0,0 +1,30 @@ +import os +import utils + + +env=Environment() +Export('env') + +env.Replace(debug=ARGUMENTS.get("debug",0)) + + +if int(env['debug']) == 1: + print "Setting debug mode" + env.Append(CFLAGS=" -g ") + env.Append(CXXFLAGS=" -g ") + env.Append(LINKFLAGS=" -g ") +else: + print "Setting release mode" + env.Append(CFLAGS=" -O3 ") + env.Append(CXXFLAGS=" -O3 ") + env.Append(LINKFLAGS=" -O3 ") + +lib=SConscript("SConscript") + +pedi = Command( target = "./testoutput", + source = "./SConscript", + action = "cd "+os.environ['SECURITY_TRANSFORMS_HOME']+" ; " + os.environ['PEDI_HOME']+"/pedi -m manifest.txt " ) + +Depends(pedi,lib); +Default(pedi) + diff --git a/irdb-lib/libIRDB-elfdep/src/elfdep.cpp b/irdb-lib/libIRDB-elfdep/src/elfdep.cpp new file mode 100644 index 0000000000000000000000000000000000000000..78fa36b08f26ccb4cf8ed9d5c73ffe66bfa53fd5 --- /dev/null +++ b/irdb-lib/libIRDB-elfdep/src/elfdep.cpp @@ -0,0 +1,541 @@ +/* + * Copyright (c) 2014-2015 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +#include <irdb-core> +#include <irdb-transform> +#include <irdb-elfdep> +#include <stdlib.h> +#include <memory> +#include <math.h> +#include <elf.h> +#include <libElfDep.hpp> +#include <iterator> +#include <algorithm> + +using namespace libIRDB; +using namespace std; + +// use some of IRDB_SDK, without committing to all of it. +// it's too confusing to use libIRDB namespace as well as the IRDB_SDK namespace; +using IRDB_SDK::VirtualOffset_t; +using IRDB_SDK::Relocation_t; +using IRDB_SDK::Instruction_t; +using IRDB_SDK::DataScoop_t; + +// defines +#define REV_ALLOF(a) rbegin(a), rend(a) +#define ALLOF(a) begin(a), end(a) + +// static helpers + +// use this to determine whether a scoop has a given name. +static struct ScoopFinder : binary_function<const IRDB_SDK::DataScoop_t*,const string,bool> +{ + // declare a simple scoop finder function that finds scoops by name + bool operator()(const IRDB_SDK::DataScoop_t* scoop, const string& name) const + { + return (scoop->getName() == name); + }; +} finder; + +static IRDB_SDK::DataScoop_t* find_scoop(IRDB_SDK::FileIR_t *firp,const string &name) +{ + auto it=find_if(firp->getDataScoops().begin(), firp->getDataScoops().end(), bind2nd(finder, name)) ; + if( it != firp->getDataScoops().end() ) + return *it; + return NULL; +}; + +static unsigned int add_to_scoop(const string &str, IRDB_SDK::DataScoop_t* scoop) +{ + // assert that this scoop is unpinned. may need to enable --step move_globals --step-option move_globals:--cfi + assert(scoop->getStart()->getVirtualOffset()==0); + int len=str.length(); + scoop->setContents(scoop->getContents()+str); + VirtualOffset_t oldend=scoop->getEnd()->getVirtualOffset(); + VirtualOffset_t newend=oldend+len; + scoop->getEnd()->setVirtualOffset(newend); + return oldend+1; +}; + +template<int ptrsize> +static void insert_into_scoop_at(const string &str, IRDB_SDK::DataScoop_t* scoop, IRDB_SDK::FileIR_t* firp, const unsigned int at) +{ + // assert that this scoop is unpinned. may need to enable --step move_globals --step-option move_globals:--cfi + assert(scoop->getStart()->getVirtualOffset()==0); + int len=str.length(); + string new_scoop_contents=scoop->getContents(); + new_scoop_contents.insert(at,str); + scoop->setContents(new_scoop_contents); + + VirtualOffset_t oldend=scoop->getEnd()->getVirtualOffset(); + VirtualOffset_t newend=oldend+len; + scoop->getEnd()->setVirtualOffset(newend); + + // update each reloc to point to the new location. + for_each(scoop->getRelocations().begin(), scoop->getRelocations().end(), [str,at](IRDB_SDK::Relocation_t* reloc) + { + if((unsigned int)reloc->getOffset()>=at) + reloc->setOffset(reloc->getOffset()+str.size()); + + }); + + // check relocations for pointers to this object. + // we'll update dataptr_to_scoop relocs, but nothing else + // so assert if we find something else + for_each(firp->getRelocations().begin(), firp->getRelocations().end(), [scoop](IRDB_SDK::Relocation_t* reloc) + { + auto wrt=dynamic_cast<IRDB_SDK::DataScoop_t*>(reloc->getWRT()); + assert(wrt != scoop || reloc->getType()=="dataptr_to_scoop"); + }); + + // for each scoop + for_each(firp->getDataScoops().begin(), firp->getDataScoops().end(), [&str,scoop,firp,at](IRDB_SDK::DataScoop_t* scoop_to_update) + { + // for each relocation for that scoop + for_each(scoop_to_update->getRelocations().begin(), scoop_to_update->getRelocations().end(), [&str,scoop,firp,scoop_to_update,at](IRDB_SDK::Relocation_t* reloc) + { + // if it's a reloc that's wrt scoop + auto wrt=dynamic_cast<IRDB_SDK::DataScoop_t*>(reloc->getWRT()); + if(wrt==scoop) + { + // then we need to update the scoop + if(reloc->getType()=="dataptr_to_scoop") + { + string contents=scoop_to_update->getContents(); + // subtract the stringsize from the (implicitly stored) addend + // taking pointer size into account. + switch(ptrsize) + { + case 4: + { + unsigned int val=*((unsigned int*)&contents.c_str()[reloc->getOffset()]); + if(val>=at) + val +=str.size(); + contents.replace(reloc->getOffset(), ptrsize, (const char*)&val, ptrsize); + break; + + } + case 8: + { + unsigned long long val=*((long long*)&contents.c_str()[reloc->getOffset()]); + if(val>=at) + val +=str.size(); + contents.replace(reloc->getOffset(), ptrsize, (const char*)&val, ptrsize); + break; + + } + default: + assert(0); + } + scoop_to_update->setContents(contents); + } + } + + }); + + }); +}; + +template<int ptrsize> +static void prefix_scoop(const string &str, IRDB_SDK::DataScoop_t* scoop, IRDB_SDK::FileIR_t* firp) +{ + insert_into_scoop_at<ptrsize>(str,scoop,firp,0); +}; + + +// Public interfaces for ElfDependencies_t + + + +// constructors +ElfDependencies_t::ElfDependencies_t(IRDB_SDK::FileIR_t* firp) + : Transform(firp) +{ + typedef ElfDependencies_t::ElfDependenciesImpl_t<Elf64_Sym, Elf64_Rela, Elf64_Dyn, R_X86_64_GLOB_DAT, 32, 8> ElfDependencies64_t; + typedef ElfDependencies_t::ElfDependenciesImpl_t<Elf32_Sym, Elf32_Rel, Elf32_Dyn, R_386_GLOB_DAT, 8, 4> ElfDependencies32_t; + + if(firp->getArchitectureBitWidth()==32) + transformer.reset(new ElfDependencies32_t(firp)); + else if(firp->getArchitectureBitWidth()==64) + transformer.reset(new ElfDependencies64_t(firp)); + else + assert(0); +} + + +template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> +ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,reloc_type,rela_shift,ptrsize>::ElfDependenciesImpl_t(IRDB_SDK::FileIR_t* firp) + : ElfDependencies_t::ElfDependenciesBase_t(firp) +{ +} + + +template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> +pair<IRDB_SDK::DataScoop_t*,int> ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,reloc_type,rela_shift,ptrsize>::appendGotEntry(const string &name) +{ + auto got_scoop=add_got_entry(name); + return {got_scoop,0}; +} + +template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> +IRDB_SDK::Instruction_t* ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,reloc_type,rela_shift,ptrsize>::appendPltEntry(const string &name) +{ + + static int labelcounter=0; + + stringstream labelstream; + labelstream << "L_pltentry_" << labelcounter++; + + auto got_scoop=add_got_entry(name); + + auto newinsn=addNewAssembly(labelstream.str()+": jmp [rel "+labelstream.str()+"]"); + + /* + auto newreloc=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, 0, "pcrel", got_scoop); + + dynamic_cast<libIRDB::Instruction_t*>(newinsn)->GetRelocations().insert(newreloc); + dynamic_cast<libIRDB::FileIR_t*>(getFileIR())->GetRelocations().insert(newreloc); + */ + auto newreloc=getFileIR()->addNewRelocation(newinsn, 0,"pcrel", got_scoop); + (void)newreloc; // just give to IR. + newinsn->getAddress()->setFileID(getFileIR()->getFile()->getBaseID()); + + return newinsn; +} + + + + + +// please keep this if 0, as we likely want to add plt/got entries in a library later, but +// we need a use case to test this code -- it was copied from CFI. + +template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> +IRDB_SDK::Instruction_t* ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,reloc_type,rela_shift,ptrsize>::find_runtime_resolve(IRDB_SDK::DataScoop_t* gotplt_scoop) +{ + const auto firp=getFileIR(); + // find any data_to_insn_ptr reloc for the gotplt scoop + auto it=find_if(gotplt_scoop->getRelocations().begin(), gotplt_scoop->getRelocations().end(), [](IRDB_SDK::Relocation_t* reloc) + { + return reloc->getType()=="data_to_insn_ptr"; + }); + // there _should_ be one. + assert(it!=gotplt_scoop->getRelocations().end()); + + Relocation_t* reloc=*it; + auto wrt=dynamic_cast<Instruction_t*>(reloc->getWRT()); + assert(wrt); // should be a WRT + assert(wrt->getDisassembly().find("push ") != string::npos); // should be push K insn + return wrt->getFallthrough(); // jump to the jump, or not.. doesn't matter. zopt will fix +} + +template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> +IRDB_SDK::DataScoop_t* ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,reloc_type,rela_shift,ptrsize>::add_got_entry(const std::string& name) +{ + const auto firp=getFileIR(); // dynamic_cast<libIRDB::FileIR_t*>(getFileIR()); + // find relevant scoops + auto dynamic_scoop=find_scoop(firp,".dynamic"); + // auto gotplt_scoop=find_scoop(firp,".got.plt"); + //auto got_scoop=find_scoop(firp,".got"); + auto dynstr_scoop=find_scoop(firp,".dynstr"); + auto dynsym_scoop=find_scoop(firp,".dynsym"); + auto relaplt_scoop=find_scoop(firp,".rela.dyn coalesced w/.rela.plt"); + auto relplt_scoop=find_scoop(firp,".rel.dyn coalesced w/.rel.plt"); + auto relscoop=relaplt_scoop!=NULL ? relaplt_scoop : relplt_scoop; + auto gnu_version_scoop=find_scoop(firp,".gnu.version"); + + + // if there is versioning info in this binary, assert we unpinned it. + if(gnu_version_scoop) + assert(gnu_version_scoop->getStart()->getVirtualOffset()==0); + + if (!relscoop) + throw std::logic_error("Cannot find rela.plt or rel.plt. Did you remember to use move_globals with --elf_tables?"); + + // add 0-init'd pointer to table + auto new_got_entry_str=string(ptrsize,0); // zero-init a pointer-sized string + + + // create a new, unpinned, rw+relro scoop that's an empty pointer. + const auto start_addr=firp->addNewAddress(firp->getFile()->getBaseID(), 0); + const auto end_addr =firp->addNewAddress(firp->getFile()->getBaseID(), ptrsize-1); + auto external_func_addr_scoop=firp->addNewDataScoop(name,start_addr,end_addr,NULL,6,true,new_got_entry_str); + + // add string to string table + auto dl_str_pos=add_to_scoop(name+'\0', dynstr_scoop); + + // add symbol to dlsym + T_Elf_Sym dl_sym; + memset(&dl_sym,0,sizeof(T_Elf_Sym)); + dl_sym.st_name=dl_str_pos; + dl_sym.st_info=((STB_GLOBAL<<4)| (STT_OBJECT)); + string dl_sym_str((const char*)&dl_sym, sizeof(T_Elf_Sym)); + unsigned int dl_pos=add_to_scoop(dl_sym_str,dynsym_scoop); + + // if there is versioning info in this binary, update it. + if(gnu_version_scoop) + { + // update the gnu.version section so that the new symbol has a version. + const auto new_version_str=string("\0\0", 2); // \0\0 means *local*, as in, don't index the gnu.verneeded array. + add_to_scoop(new_version_str,gnu_version_scoop); + } + + + + // find the rela count. can't insert before that. + int rela_count=0; + for(int i=0;i+sizeof(T_Elf_Dyn)<dynamic_scoop->getSize(); i+=sizeof(T_Elf_Dyn)) + { + T_Elf_Dyn &dyn_entry=*(T_Elf_Dyn*)&dynamic_scoop->getContents().c_str()[i]; + if(dyn_entry.d_tag==DT_RELACOUNT) // diff than rela size. + { + // add to the size + rela_count=dyn_entry.d_un.d_val; + break; + } + } + + // create the new reloc + T_Elf_Rela dl_rel; + memset(&dl_rel,0,sizeof(dl_rel)); + auto r_info_tmp=(decltype(dl_rel.r_info))dl_pos; + dl_rel.r_info= ((r_info_tmp/sizeof(T_Elf_Sym)) <<rela_shift ) | reloc_type; + + string dl_rel_str((const char*)&dl_rel, sizeof(dl_rel)); + +// need to fixup relocs + unsigned int at=rela_count*sizeof(T_Elf_Rela); + insert_into_scoop_at<ptrsize>(dl_rel_str, relscoop, firp, at); + + /* + auto dl_reloc=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, at+((uintptr_t)&dl_rel.r_offset -(uintptr_t)&dl_rel), "dataptr_to_scoop", external_func_addr_scoop); + dynamic_cast<libIRDB::DataScoop_t*>(relscoop)->GetRelocations().insert(dl_reloc); + firp->GetRelocations().insert(dl_reloc); + */ + auto dl_reloc=firp->addNewRelocation(relscoop,at+((uintptr_t)&dl_rel.r_offset -(uintptr_t)&dl_rel), "dataptr_to_scoop", external_func_addr_scoop); + (void)dl_reloc; // just give to IR; + + for(int i=0;i+sizeof(T_Elf_Dyn)<dynamic_scoop->getSize(); i+=sizeof(T_Elf_Dyn)) + { + // cast the index'd c_str to an Elf_Dyn pointer and deref it to assign to a + // reference structure. That way editing the structure directly edits the string. + T_Elf_Dyn &dyn_entry=*(T_Elf_Dyn*)&dynamic_scoop->getContents().c_str()[i]; + if(dyn_entry.d_tag==DT_RELASZ) + // add to the size + dyn_entry.d_un.d_val+=sizeof(T_Elf_Rela); + + // we insert the zest_cfi_dispatch symbol after the relative relocs. + // but we need to adjust the start if there are no relative relocs. + if(at == 0 && dyn_entry.d_tag==DT_RELA) + // subtract from the start. + dyn_entry.d_un.d_val-=sizeof(T_Elf_Rela); + + } + return external_func_addr_scoop; +} + +#if 0 + +template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> +bool ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,reloc_type,rela_shift,ptrsize>::add_got_entries() +{ + const auto firp=getFileIR(); + + // find all the necessary scoops; + auto dynamic_scoop=find_scoop(firp,".dynamic"); + auto gotplt_scoop=find_scoop(firp,".got.plt"); + auto got_scoop=find_scoop(firp,".got"); + auto dynstr_scoop=find_scoop(firp,".dynstr"); + auto dynsym_scoop=find_scoop(firp,".dynsym"); + auto relaplt_scoop=find_scoop(firp,".rela.dyn coalesced w/.rela.plt"); + auto relplt_scoop=find_scoop(firp,".rel.dyn coalesced w/.rel.plt"); + auto relscoop=relaplt_scoop!=NULL ? relaplt_scoop : relplt_scoop; + + // Instruction_t* to_dl_runtime_resolve=find_runtime_resolve<T_Elf_Sym,T_Elf_Rela, T_Elf_Dyn, rela_shift, reloc_type, ptrsize>(gotplt_scoop); + Instruction_t* to_dl_runtime_resolve=find_runtime_resolve(gotplt_scoop); + + + // add necessary GOT entries. + // add_got_entry<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,reloc_type,rela_shift,ptrsize>("zest_cfi_dispatch"); + add_got_entry("zest_cfi_dispatch"); + + + // also add a zest cfi "function" that's exported so dlsym can find it. + auto zestcfi_str_pos=add_to_scoop(string("zestcfi")+'\0', dynstr_scoop); + + // add zestcfi symbol to binary + T_Elf_Sym zestcfi_sym; + memset(&zestcfi_sym,0,sizeof(T_Elf_Sym)); + zestcfi_sym.st_name=zestcfi_str_pos; + zestcfi_sym.st_size=1234; + zestcfi_sym.st_info=((STB_GLOBAL<<4)| (STT_FUNC)); + string zestcfi_sym_str((const char*)&zestcfi_sym, sizeof(T_Elf_Sym)); + unsigned int zestcfi_pos=add_to_scoop(zestcfi_sym_str,dynsym_scoop); + + // add "function" for zestcfi" + // for now, return that the target is allowed. the nonce plugin will have to have a slow path for this later. + assert(firp->GetArchitectureBitWidth()==64); // fixme for 32-bit, should jmp to ecx. + auto zestcfi_function_entry=addNewAssembly(firp,NULL,"jmp r11"); + + // this jump can target any IBT in the module. + ICFS_t *newicfs=new ICFS_t; + for_each(firp->GetInstructions().begin(), firp->GetInstructions().end(), [&](Instruction_t* insn) + { + if(insn->GetIndirectBranchTargetAddress() != NULL ) + newicfs->insert(insn); + }); + zestcfi_function_entry->SetIBTargets(newicfs); + firp->GetAllICFS().insert(newicfs); + firp->AssembleRegistry(); + + + // add a relocation so that the zest_cfi "function" gets pointed to by the symbol + Relocation_t* zestcfi_reloc=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, zestcfi_pos+((uintptr_t)&zestcfi_sym.st_value - (uintptr_t)&zestcfi_sym), "data_to_insn_ptr", zestcfi_function_entry); + dynsym_scoop->GetRelocations().insert(zestcfi_reloc); + firp->GetRelocations().insert(zestcfi_reloc); + + + // update strtabsz after got/etc entries are added. + for(int i=0;i+sizeof(T_Elf_Dyn)<dynamic_scoop->GetSize(); i+=sizeof(T_Elf_Dyn)) + { + T_Elf_Dyn &dyn_entry=*(T_Elf_Dyn*)&dynamic_scoop->GetContents().c_str()[i]; + if(dyn_entry.d_tag==DT_STRSZ) + { + dyn_entry.d_un.d_val=dynstr_scoop->GetContents().size(); + } + } + + + return true; +} +#endif + +template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> +void ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,reloc_type,rela_shift,ptrsize>::appendLibraryDepedencies(const string &libraryName) +{ + const auto firp=getFileIR(); // dynamic_cast<FileIR_t*>(getFileIR()); + + auto dynamic_scoop=find_scoop(firp,".dynamic"); + auto dynstr_scoop=find_scoop(firp,".dynstr"); + + // not dynamic executable w/o a .dynamic section. + if(!dynamic_scoop) + throw std::logic_error("Cannot change libraries in statically linked program"); + + // may need to enable --step move_globals --step-option move_globals:--cfi + if(dynamic_scoop->getStart()->getVirtualOffset()!=0) + { + cerr<<"Cannot find relocation-scoop pair: Did you enable '--step move_globals --step-option move_globals:--cfi' ? "<<endl; + exit(1); + } + + const auto libld_str_pos=add_to_scoop(libraryName+'\0', dynstr_scoop); + + // a new dt_needed entry for libdl.so + auto new_dynamic_entry=T_Elf_Dyn ({}); + new_dynamic_entry.d_tag=DT_NEEDED; + new_dynamic_entry.d_un.d_val=libld_str_pos; + const auto new_dynamic_entry_str=string((const char*)&new_dynamic_entry, sizeof(T_Elf_Dyn)); + + // a null terminator + const auto null_dynamic_entry=T_Elf_Dyn ({}); + const auto null_dynamic_entry_str=string((const char*)&null_dynamic_entry, sizeof(T_Elf_Dyn)); + + // declare an entry for the .dynamic section and add it. + auto index=0; + while(1) + { + // assert we don't run off the end. + assert((index+1)*sizeof(T_Elf_Dyn) <= dynamic_scoop->getContents().size()); + + const auto dyn_ptr=(T_Elf_Dyn*) & dynamic_scoop->getContents().c_str()[index*sizeof(T_Elf_Dyn)]; + + if(memcmp(dyn_ptr,&null_dynamic_entry,sizeof(T_Elf_Dyn)) == 0 ) + { + cout<<"Inserting new DT_NEEDED at index "<<dec<<index<<endl; + // found a null terminator entry. + for(auto i=0U; i<sizeof(T_Elf_Dyn); i++) + { + // copy new_dynamic_entry ontop of null entry. + auto str=dynamic_scoop->getContents(); + str[index*sizeof(T_Elf_Dyn) + i ] = ((char*)&new_dynamic_entry)[i]; + dynamic_scoop->setContents(str); + } + + // check if there's room for the new null entry + if((index+2)*sizeof(T_Elf_Dyn) <= dynamic_scoop->getContents().size()) + { + /* yes */ + const auto next_entry=(T_Elf_Dyn*)&dynamic_scoop->getContents().c_str()[(index+1)*sizeof(T_Elf_Dyn)]; + // assert it's actually null + assert(memcmp(next_entry,&null_dynamic_entry,sizeof(T_Elf_Dyn)) == 0 ); + } + else + { + // add to the scoop + add_to_scoop(null_dynamic_entry_str,dynamic_scoop); + } + break; + } + + index++; + } + + return; + +} + +template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> +void ElfDependencies_t::ElfDependenciesImpl_t<T_Elf_Sym,T_Elf_Rela,T_Elf_Dyn,reloc_type,rela_shift,ptrsize>::prependLibraryDepedencies(const string &libraryName) +{ + const auto firp=getFileIR(); + + auto dynamic_scoop=find_scoop(firp,".dynamic"); + auto dynstr_scoop=find_scoop(firp,".dynstr"); + + // not dynamic executable w/o a .dynamic section. + if(!dynamic_scoop || !dynstr_scoop) + throw std::logic_error("Cannot change libraries in statically linked program"); + + // may need to enable --step move_globals --step-option move_globals:--cfi + if(dynamic_scoop->getStart()->getVirtualOffset()!=0) + { + cerr<<"Cannot find relocation-scoop pair: Did you enable '--step move_globals --step-option move_globals:--cfi' ? "<<endl; + exit(1); + } + + const auto libld_str_pos=add_to_scoop(libraryName+'\0', dynstr_scoop); + + // a new dt_needed entry for libdl.so + auto new_dynamic_entry=T_Elf_Dyn ({}); + new_dynamic_entry.d_tag=DT_NEEDED; + new_dynamic_entry.d_un.d_val=libld_str_pos; + const auto new_dynamic_entry_str=string((const char*)&new_dynamic_entry, sizeof(T_Elf_Dyn)); + + prefix_scoop<ptrsize>(new_dynamic_entry_str, dynamic_scoop, firp) ; +} + +unique_ptr<IRDB_SDK::ElfDependencies_t> IRDB_SDK::ElfDependencies_t::factory(IRDB_SDK::FileIR_t* firp) +{ + return unique_ptr<IRDB_SDK::ElfDependencies_t>(new libIRDB::ElfDependencies_t(firp)); +} + diff --git a/irdb-lib/libIRDB-elfdep/src/libElfDep.hpp b/irdb-lib/libIRDB-elfdep/src/libElfDep.hpp new file mode 100644 index 0000000000000000000000000000000000000000..4b7eb1e5f7818fdb05b0315e05afc202530ab140 --- /dev/null +++ b/irdb-lib/libIRDB-elfdep/src/libElfDep.hpp @@ -0,0 +1,67 @@ + +#include <irdb-core> +#include <irdb-transform> +#include <irdb-elfdep> +#include <string> +#include <memory> + + +namespace libIRDB +{ + +using namespace std; + +class ElfDependencies_t : public IRDB_SDK::Transform, public IRDB_SDK::ElfDependencies_t +{ + public: + + ElfDependencies_t(IRDB_SDK::FileIR_t* firp); + void prependLibraryDepedencies(const string& libName) { transformer->prependLibraryDepedencies(libName); } + void appendLibraryDepedencies(const string& libName) { transformer->appendLibraryDepedencies(libName); } + + // return scoop and offset + pair<IRDB_SDK::DataScoop_t*,int> appendGotEntry(const string &symbolName) { return transformer->appendGotEntry(symbolName); } + + // return instruction that's the plt entry. + IRDB_SDK::Instruction_t* appendPltEntry(const string &symbolName) { return transformer->appendPltEntry(symbolName); } + + private: + + class ElfDependenciesBase_t : public Transform + { + public: + ElfDependenciesBase_t(IRDB_SDK::FileIR_t* firp) : Transform(firp) {} + virtual void prependLibraryDepedencies(const string &libraryName)=0; + virtual void appendLibraryDepedencies(const string &libraryName)=0; + virtual pair<IRDB_SDK::DataScoop_t*,int> appendGotEntry(const string &name)=0; + virtual IRDB_SDK::Instruction_t* appendPltEntry(const string &name)=0; + + }; + + template<typename T_Elf_Sym, typename T_Elf_Rela, typename T_Elf_Dyn, int reloc_type, int rela_shift, int ptrsize> + class ElfDependenciesImpl_t : public ElfDependenciesBase_t + { + + public: + ElfDependenciesImpl_t(IRDB_SDK::FileIR_t* fipr); + + virtual void prependLibraryDepedencies(const string& libraryName); + virtual void appendLibraryDepedencies(const string& libraryName); + virtual pair<IRDB_SDK::DataScoop_t*,int> appendGotEntry(const string& name); + virtual IRDB_SDK::Instruction_t* appendPltEntry(const string& name); + + + private: + bool add_dl_support(); + IRDB_SDK::Instruction_t* find_runtime_resolve(IRDB_SDK::DataScoop_t* gotplt_scoop); + IRDB_SDK::DataScoop_t* add_got_entry(const std::string& name); + bool add_libdl_as_needed_support(string libName); + bool execute(); + + }; + + unique_ptr<ElfDependenciesBase_t> transformer; +}; + + +} diff --git a/irdb-lib/libIRDB-elfdep/test/.gitignore b/irdb-lib/libIRDB-elfdep/test/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..6855a42d7a3b1ed434cd9b9a8b83ee5b74e3a04f --- /dev/null +++ b/irdb-lib/libIRDB-elfdep/test/.gitignore @@ -0,0 +1,9 @@ +edt.exe +edt.o +edt.out +edt_driver.o +elf_dep_test.os +libelf_dep_test.so +peasoup_executable_directory.* +tmp.out + diff --git a/irdb-lib/libIRDB-elfdep/test/SConscript b/irdb-lib/libIRDB-elfdep/test/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..3f62a1b032e5b3d6ac70e2ea1f60adb7cbba3d7d --- /dev/null +++ b/irdb-lib/libIRDB-elfdep/test/SConscript @@ -0,0 +1,36 @@ +import os + + + +Import('env') + +# import and create a copy of the environment so we don't screw up anyone elses env. +myenv=env.Clone() +myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) +myenv.Replace(ZIPR_HOME=os.environ['ZIPR_HOME']) +myenv.Replace(ZIPR_SDK=os.environ['ZIPR_SDK']) +myenv.Replace(IRDB_SDK=os.environ['IRDB_SDK']) +myenv.Replace(ZIPR_INSTALL=os.environ['ZIPR_INSTALL']) + +myenv.Replace(CXXFLAGS = " -g -std=c++11 -Wall ") +myenv.Append(LINKFLAGS = " -Wl,-unresolved-symbols=ignore-in-shared-libs ") + +cpppath=''' + $IRDB_SDK/include + ''' + + +files=Glob( Dir('.').srcnode().abspath+"/edt*.cpp") + +pgm="edt.exe" + +LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" +LIBS=Split("irdb-core irdb-transform irdb-elfdep") +myenv=myenv.Clone(CPPPATH=Split(cpppath)) +pgm=myenv.Program(pgm, files, LIBPATH=LIBPATH, LIBS=LIBS) +install=myenv.Install("$SECURITY_TRANSFORMS_HOME/plugins_install/", pgm) +Default(install) + +files=Glob( Dir('.').srcnode().abspath+"/elf_dep_test*.cpp") +sharedLib=myenv.SharedLibrary("elf_dep_test", files, LIBPATH=LIBPATH, LIBS=LIBS) +Default(sharedLib) diff --git a/irdb-lib/libIRDB-elfdep/test/SConstruct b/irdb-lib/libIRDB-elfdep/test/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..7fe41a3bcc605387c2eaafceaa7e944ab0d252fb --- /dev/null +++ b/irdb-lib/libIRDB-elfdep/test/SConstruct @@ -0,0 +1,15 @@ +import os + + +env=Environment() +Export('env') +lib=SConscript("SConscript") + + +pedi = Command( target = "./testoutput", + source = "./SConscript", + action = "cd "+os.environ['SECURITY_TRANSFORMS_HOME']+" ; " + os.environ['PEDI_HOME']+"/pedi -m manifest.txt ; cd - " ) + +Depends(pedi,lib); +Default(pedi) + diff --git a/irdb-lib/libIRDB-elfdep/test/edt.cpp b/irdb-lib/libIRDB-elfdep/test/edt.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ff1d95391fe8128bf79fa90e1c5d9eba4875a977 --- /dev/null +++ b/irdb-lib/libIRDB-elfdep/test/edt.cpp @@ -0,0 +1,68 @@ + +#include "edt.hpp" +#include <irdb-elfdep> +#include <algorithm> + +using namespace IRDB_SDK; +using namespace std; +using namespace ElfDep_Tester; + + +ElfDep_Tester_t::ElfDep_Tester_t(FileIR_t* firp) + : Transform (firp) +{ +} + + +#define ALLOF(a) begin(a),end(a) + + +int ElfDep_Tester_t::execute() +{ + // insert the PLT and GOT entries needed + auto ed=ElfDependencies_t::factory(getFileIR()); + (void)ed->appendLibraryDepedencies("libelf_dep_test.so"); + auto edpcb=ed->appendPltEntry("elf_dep_test_callback"); + auto edvar=ed->appendGotEntry("elf_dep_test_var"); + auto edvar_scoop=edvar.first; + auto edvar_offset=edvar.second; + + + // find the insertion point. + const auto &all_funcs=getFileIR()->getFunctions(); + const auto main_func_it=find_if(ALLOF(all_funcs), [&](const Function_t* f) { return f->getName()=="main";}); + assert(main_func_it!=all_funcs.end()); + const auto main_func=*main_func_it; + auto insert_loc=main_func->getEntryPoint(); + + + // insert the instrumentation + auto tmp=insert_loc; + (void)insertAssemblyBefore(tmp," push rdi") ; + tmp= insertAssemblyAfter(tmp," push rsi ") ; + tmp= insertAssemblyAfter(tmp," push rdx") ; + tmp= insertAssemblyAfter(tmp," push rcx ") ; + tmp= insertAssemblyAfter(tmp," push r8 ") ; + tmp= insertAssemblyAfter(tmp," push r9 ") ; + tmp= insertAssemblyAfter(tmp," call 0 ", edpcb) ; + tmp= insertAssemblyAfter(tmp," L1: mov rcx, [rel L1]"); + auto got_insn=tmp; + tmp= insertAssemblyAfter(tmp," inc dword [rcx]"); + tmp= insertAssemblyAfter(tmp," call 0", edpcb); + tmp= insertAssemblyAfter(tmp," pop r9"); + tmp= insertAssemblyAfter(tmp," pop r8"); + tmp= insertAssemblyAfter(tmp," pop rcx"); + tmp= insertAssemblyAfter(tmp," pop rdx"); + tmp= insertAssemblyAfter(tmp," pop rsi"); + tmp= insertAssemblyAfter(tmp," pop rdi"); + + + // map the load to point at the GOT entry. + auto got_reloc=getFileIR()->addNewRelocation(got_insn, edvar_offset, "pcrel", edvar_scoop); + (void)got_reloc; // just give to IR + + return 0; +} + + + diff --git a/irdb-lib/libIRDB-elfdep/test/edt.hpp b/irdb-lib/libIRDB-elfdep/test/edt.hpp new file mode 100644 index 0000000000000000000000000000000000000000..24c082c478f7391dd985b011fcbcfd978cde67c2 --- /dev/null +++ b/irdb-lib/libIRDB-elfdep/test/edt.hpp @@ -0,0 +1,26 @@ + +#include <string> +#include <set> +#include <irdb-core> +#include <irdb-transform> + +namespace ElfDep_Tester +{ + +using namespace IRDB_SDK; +using namespace std; + + +typedef set<string> StringSet_t; +class ElfDep_Tester_t : Transform +{ + public: + ElfDep_Tester_t(FileIR_t* firp); + + int execute(); + + private: + +}; + +} diff --git a/irdb-lib/libIRDB-elfdep/test/edt_driver.cpp b/irdb-lib/libIRDB-elfdep/test/edt_driver.cpp new file mode 100644 index 0000000000000000000000000000000000000000..52d836f477b87b1e49f367205ec58a6450c7c251 --- /dev/null +++ b/irdb-lib/libIRDB-elfdep/test/edt_driver.cpp @@ -0,0 +1,133 @@ +#include <stdlib.h> +#include <fstream> +#include <string> +#include "edt.hpp" +#include <irdb-core> +#include <getopt.h> + +using namespace std; +using namespace IRDB_SDK; +using namespace ElfDep_Tester; + +void usage(string programName) +{ + cerr << "Usage: " << programName << " <variant id> " <<endl; + cout<<"--help,--usage,-?,-h Display this message"<<endl; +} + +int main(int argc, char **argv) +{ + string programName(argv[0]); + char *strtolError = NULL; + int transformExitCode = 0; + int variantID = -1; + auto pqxx_interface=pqxxDB_t::factory(); + int exit_code=0; + + /* + * Check that we've been called correctly: + * <program> <variant id> <annotation file> + */ + if(argc < 2) + { + usage(programName); + exit(1); + } + variantID = strtol(argv[1], &strtolError, 10); + if (*strtolError != '\0') + { + cerr << "Invalid variantID: " << argv[1] << endl; + exit(1); + } + + // Parse some options for the transform + const static struct option long_options[] = { + {"help", no_argument, 0, 'h'}, + {"usage", no_argument, 0, '?'}, + {0,0,0,0} + }; + auto short_opts="h?"; + + while(1) { + int index = 0; + int c = getopt_long(argc, argv,short_opts, long_options, &index); + if(c == -1) + break; + switch(c) { + case 0: + break; + case '?': + case 'h': + usage(argv[0]); + exit(1); + break; + default: + break; + } + } + + + /* setup the interface to the sql server */ + BaseObj_t::setInterface(pqxx_interface.get()); + + auto pidp=VariantID_t::factory(variantID); + assert(pidp && pidp->isRegistered()==true); + + for(set<File_t*>::iterator it=pidp->getFiles().begin(); + it!=pidp->getFiles().end(); + ++it) + { + try + { + /* read the IR from the DB */ + File_t* this_file = *it; + auto firp = FileIR_t::factory(pidp.get(), this_file); + cout<<"Transforming "<<this_file->getURL()<<endl; + assert(firp && pidp); + + + /* + * Create a transformation and then + * invoke its execution. + */ + auto ed=ElfDep_Tester_t(firp.get()); + transformExitCode = ed.execute(); + /* + * If everything about the transformation + * went okay, then we will write the updated + * set of instructions to the database. + */ + if (transformExitCode == 0) + { + if(getenv("MG_NOUPDATE")==NULL) + { + firp->writeToDB(); + } + } + else + { + cerr << programName << ": transform failed. Check logs." << endl; + exit_code=2; + } + } + catch (DatabaseError_t pnide) + { + cerr << programName << ": Unexpected database error: " << pnide << endl; + exit(1); + } + catch (const std::exception &exc) + { + // catch anything thrown within try block that derives from std::exception + std::cerr << "Unexpected exception: " << exc.what(); + exit(1); + } + catch (...) + { + cerr << programName << ": Unexpected error" << endl; + exit(1); + } + } + pqxx_interface->commit(); + + return exit_code; +} diff --git a/irdb-lib/libIRDB-elfdep/test/elf_dep_test.cpp b/irdb-lib/libIRDB-elfdep/test/elf_dep_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5f77c041e5159998302399f3bd257bc6163e4675 --- /dev/null +++ b/irdb-lib/libIRDB-elfdep/test/elf_dep_test.cpp @@ -0,0 +1,13 @@ + +#include <stdio.h> +extern "C" +{ + +int elf_dep_test_var=0; + +void elf_dep_test_callback() +{ + printf("Elf_dep_test var = %d\n", elf_dep_test_var); +} + +} diff --git a/irdb-lib/libIRDB-elfdep/test/test-elfdep.sh b/irdb-lib/libIRDB-elfdep/test/test-elfdep.sh new file mode 100755 index 0000000000000000000000000000000000000000..39ac850f75d329f0223c1f2e177835917710a161 --- /dev/null +++ b/irdb-lib/libIRDB-elfdep/test/test-elfdep.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +TMP_ORIG=/tmp/testelfdep.ls.orig.$$ +TMP_ORIG2=/tmp/testelfdep.ls.orig.2.$$ +TMP_ELFDEP=/tmp/testelfdep.ls.elfdep.$$ + +cleanup_files() +{ + rm /tmp/testelfdep.ls* >/dev/null 2>&1 +} + +cleanup() +{ + echo "************" + echo "test failed." + echo "************" + + cleanup_files + exit 1 +} + + +# make sure xforms are built +scons || cleanup + +$PSZ /bin/ls ./xxx -c move_globals=on -o move_globals:--elftables -c edt=on || cleanup + +/bin/ls /tmp > $TMP_ORIG || cleanup + +./xxx /tmp > $TMP_ELFDEP || cleanup + +echo "Verify external vars was overwritten" +grep "var = 0" $TMP_ELFDEP || cleanup +grep "var = 1" $TMP_ELFDEP || cleanup + +echo "Verify same output" +grep -v "var =" $TMP_ELFDEP > $TMP_ORIG2 +diff $TMP_ORIG2 $TMP_ELFDEP + +cleanup_files + +echo +echo "test passed." +echo diff --git a/irdb-lib/libIRDB-syscall/include/libIRDB-syscall.hpp b/irdb-lib/libIRDB-syscall/include/libIRDB-syscall.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3ac7c4ccc9e94ae0436d7d16567bd9650a6dd135 --- /dev/null +++ b/irdb-lib/libIRDB-syscall/include/libIRDB-syscall.hpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef libIRDB_syscall +#define libIRDB_syscall + + +/* Building a CFG depends on core functionality */ + +#include <vector> +#include <set> +#include <map> +#include <ostream> + + +#include <syscall.hpp> + + +#endif diff --git a/irdb-lib/libIRDB-syscall/include/syscall.hpp b/irdb-lib/libIRDB-syscall/include/syscall.hpp new file mode 100644 index 0000000000000000000000000000000000000000..0e54e9931b42fa48e15d4ac3e7f369a844861bde --- /dev/null +++ b/irdb-lib/libIRDB-syscall/include/syscall.hpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2014 - Zephyr Software + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef irdb_syscall_hpp +#define irdb_syscall_hpp + +namespace libIRDB +{ + + class SyscallSite_t : public IRDB_SDK::SyscallSite_t + { + public: + SyscallSite_t(IRDB_SDK::Instruction_t* p_site, IRDB_SDK::SyscallNumber_t p_num) : site(p_site), num(p_num) {} + + IRDB_SDK::Instruction_t* getSyscallSite() const { return site; } + IRDB_SDK::Instruction_t* getSite() const { return site; } + IRDB_SDK::SyscallNumber_t getSyscallNumber() const { return num; } + + private: + IRDB_SDK::Instruction_t* site; + IRDB_SDK::SyscallNumber_t num; + }; + + class Syscalls_t : public IRDB_SDK::Syscalls_t + { + public: + Syscalls_t(IRDB_SDK::FileIR_t *the_firp=NULL) { if(the_firp) FindSystemCalls(the_firp); } + virtual ~Syscalls_t(); + + + + const IRDB_SDK::SyscallSiteSet_t& getSyscalls() {return syscalls;} + protected: + IRDB_SDK::SyscallNumber_t FindSystemCallNumber(IRDB_SDK::Instruction_t* insn, + const IRDB_SDK::InstructionPredecessors_t& preds); + + bool FindSystemCalls(const IRDB_SDK::FileIR_t* firp); + private: + IRDB_SDK::SyscallSiteSet_t syscalls; + }; + +} +#endif + diff --git a/irdb-lib/libIRDB-syscall/src/SConscript b/irdb-lib/libIRDB-syscall/src/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..b1d91ed7655ef3401ee373c067c1d06a7fefa917 --- /dev/null +++ b/irdb-lib/libIRDB-syscall/src/SConscript @@ -0,0 +1,30 @@ +import os + +Import('env') +myenv=env +myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) + + +libname="irdb-syscall" +files= ''' + syscall.cpp + ''' +cpppath=''' + $IRDB_SDK/include/ + $SECURITY_TRANSFORMS_HOME/include/ + $SECURITY_TRANSFORMS_HOME/libIRDB-core/include/ + $SECURITY_TRANSFORMS_HOME/libIRDB-syscall/include/ + ''' + +#myenv.Append(CCFLAGS=" -Wall -W -Wextra -Wconversion ") + +myenv.Append(CXXFLAGS = " -std=c++11 ") + + +myenv=myenv.Clone(CPPPATH=Split(cpppath)) +lib=myenv.SharedLibrary(libname, Split(files), LIBS=Split("irdb-core irdb-util"), LIBPATH=Split("$SECURITY_TRANSFORMS_HOME/lib")) + +install=myenv.Install("$SECURITY_TRANSFORMS_HOME/lib/", lib) +Default(install) + +Return('install') diff --git a/irdb-lib/libIRDB-syscall/src/SConstruct b/irdb-lib/libIRDB-syscall/src/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..17f632b8c29cd420163897b1eb044ca3486df362 --- /dev/null +++ b/irdb-lib/libIRDB-syscall/src/SConstruct @@ -0,0 +1,7 @@ + + + +env=Environment() +Export('env') +install=SConscript("SConscript") +Return('install') diff --git a/irdb-lib/libIRDB-syscall/src/syscall.cpp b/irdb-lib/libIRDB-syscall/src/syscall.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c4fc4e7108c22397f686c72e3819bdaec5b8488e --- /dev/null +++ b/irdb-lib/libIRDB-syscall/src/syscall.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2014 - Zephyr Software + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <irdb-core> +#include <irdb-util> +#include <irdb-syscall> +#include <libIRDB-syscall.hpp> +#include <stdlib.h> + +using namespace std; +using namespace libIRDB; + +Syscalls_t::~Syscalls_t() +{ + for(auto site : syscalls) + delete site; + syscalls.clear(); +} + +IRDB_SDK::SyscallNumber_t Syscalls_t::FindSystemCallNumber(IRDB_SDK::Instruction_t* insn, const IRDB_SDK::InstructionPredecessors_t& preds) +{ + IRDB_SDK::Instruction_t *pred_insn=nullptr; + + for( auto cs_preds=&preds[insn]; + cs_preds->size()==1; + cs_preds=&preds[pred_insn] + ) + { + pred_insn=*(cs_preds->begin()); + + string disass=pred_insn->getDisassembly(); + + /* look for eax being used or set */ + if(disass.find("eax")!=string::npos) + { + string to_find="mov eax,"; + size_t loc=disass.find(to_find); + // check to see if it's a mov of eax + if(loc ==string::npos) + { + // no, quit looking backwards + return IRDB_SDK::sntUnknown; + } + size_t val=strtol(disass.substr(loc+to_find.length()).c_str(),nullptr,16); + // check to see if it's a mov of eax + + return (IRDB_SDK::SyscallNumber_t)val; + } + } + + return IRDB_SDK::sntUnknown; + +} + +bool Syscalls_t::FindSystemCalls(const IRDB_SDK::FileIR_t *firp2) +{ + auto firp=const_cast<IRDB_SDK::FileIR_t*>(firp2); // discard const qualifer, but we aren't changing anything. + assert(firp); + auto predsp=IRDB_SDK::InstructionPredecessors_t::factory(firp); + auto &preds = * predsp; + + bool found_one=false; + for(auto insn : firp->getInstructions()) + { + if(insn->getDisassembly()=="int 0x80") + { + auto num=FindSystemCallNumber(insn, preds); + syscalls.insert(new libIRDB::SyscallSite_t(insn,num)); + found_one=true; + + if(getenv("PRINTSYSCALLSFOUND")) + cout<<"Found system call "<< insn->getBaseID()<< ":'"<< insn->getDisassembly() << "' with eax value "<< (size_t)num<<endl; + } + } + return found_one; + +} + + + diff --git a/irdb-lib/libIRDB-transform/Makefile b/irdb-lib/libIRDB-transform/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..8eeb9bea022e83cddb938e52c3155e2962f19924 --- /dev/null +++ b/irdb-lib/libIRDB-transform/Makefile @@ -0,0 +1,5 @@ +all: + cd src; make + +clean: + cd src; make clean diff --git a/irdb-lib/libIRDB-transform/SConscript b/irdb-lib/libIRDB-transform/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..f0e0b9fd099936cb34955e3edbf6031acbe0dace --- /dev/null +++ b/irdb-lib/libIRDB-transform/SConscript @@ -0,0 +1,7 @@ +import os + +Import('env') + +lib=SConscript("src/SConscript") + +Return('lib') diff --git a/irdb-lib/libIRDB-transform/SConstruct b/irdb-lib/libIRDB-transform/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..4d6381b5999d3e6d4e4687fc95f444ea2c4c5747 --- /dev/null +++ b/irdb-lib/libIRDB-transform/SConstruct @@ -0,0 +1,8 @@ + + + +env=Environment() +Export('env') +lib=SConscript("SConscript") + +Return(lib) diff --git a/irdb-lib/libIRDB-transform/include-unused-delete-later/Makefile.in b/irdb-lib/libIRDB-transform/include-unused-delete-later/Makefile.in new file mode 100644 index 0000000000000000000000000000000000000000..56fe02141bd2113326a9d6b1af59e3e87a7ace1b --- /dev/null +++ b/irdb-lib/libIRDB-transform/include-unused-delete-later/Makefile.in @@ -0,0 +1,18 @@ + +CXX=@CXX@ + +LIB=../lib/libtransform.a + +OBJS=Rewrite_Utility.o transform.o integertransform.o leapattern.o integertransform64.o integertransform32.o pointercheck64.o + +all: $(OBJS) + +$(OBJS): ../include/*.hpp + +clean: + rm -f $(OBJS) + +.cpp.o: + $(CXX) -g -c -I. -I../include -I../../libIRDB/include -I../../libMEDSannotation/include -I../../beaengine/include $< + ar rc $(LIB) $@ + cp $(LIB) ../../lib/ diff --git a/irdb-lib/libIRDB-transform/include-unused-delete-later/Rewrite_Utility.hpp b/irdb-lib/libIRDB-transform/include-unused-delete-later/Rewrite_Utility.hpp new file mode 100644 index 0000000000000000000000000000000000000000..7a9f1f90a0f1f02a3d981954ec78fdda87a4e81e --- /dev/null +++ b/irdb-lib/libIRDB-transform/include-unused-delete-later/Rewrite_Utility.hpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013, 2014 - University of Virginia + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#include <irdb-core> + + +namespace IRDBUtility { +using namespace IRDB_SDK; +using namespace std; + +//The "first" instruction will have its contents replaced and a duplicate of "first" will be in the follow of first. +//This duplicate is returned since the user already has a pointer to first. +Instruction_t* insertAssemblyBefore(FileIR_t* virp, Instruction_t* first, string assembly, Instruction_t *target); +Instruction_t* insertAssemblyBefore(FileIR_t* virp, Instruction_t* first, string assembly); +Instruction_t* insertDataBitsBefore(FileIR_t* virp, Instruction_t* first, string dataBits, Instruction_t *target); +Instruction_t* insertDataBitsBefore(FileIR_t* virp, Instruction_t* first, string dataBits); + +// insert new instructions after, diff types. +Instruction_t* insertAssemblyAfter(FileIR_t* virp, Instruction_t* first, string assembly, Instruction_t *target); +Instruction_t* insertAssemblyAfter(FileIR_t* virp, Instruction_t* first, string assembly); +Instruction_t* insertDataBitsAfter(FileIR_t* virp, Instruction_t* first, string dataBits, Instruction_t *target); +Instruction_t* insertDataBitsAfter(FileIR_t* virp, Instruction_t* first, string dataBits); + +// add new instructions of diff types. +Instruction_t* addNewDatabits(FileIR_t* firp, Instruction_t *p_instr, string p_bits); +Instruction_t* addNewAssembly(FileIR_t* firp, Instruction_t *p_instr, string p_asm); + + +//Does not insert into any variant, just copies data about the instruction itself, see the copyInstruction(src,dest) to see what is copied. +Instruction_t* copyInstruction(Instruction_t* instr); + +Instruction_t* copyInstruction(FileIR_t* virp, Instruction_t* instr); +//copy src to destination +void copyInstruction(Instruction_t* src, Instruction_t* dest); + +Instruction_t* allocateNewInstruction(FileIR_t* virp, DatabaseID_t p_fileID,Function_t* func); +Instruction_t* allocateNewInstruction(FileIR_t* virp, Instruction_t *template_instr); +void setInstructionAssembly(FileIR_t* virp,Instruction_t *p_instr, string p_assembly, Instruction_t *p_fallThrough, Instruction_t *p_target); + + +} diff --git a/irdb-lib/libIRDB-transform/include-unused-delete-later/integertransform.cpp b/irdb-lib/libIRDB-transform/include-unused-delete-later/integertransform.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b72c5f7941fc2a8a4f5ff688466dabf2bc06c415 --- /dev/null +++ b/irdb-lib/libIRDB-transform/include-unused-delete-later/integertransform.cpp @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2013, 2014 - University of Virginia + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#include <assert.h> +#include "integertransform.hpp" +#include "leapattern.hpp" + + +/* + * Find the first occurrence of find in s, ignore case. + */ +static char * +my_strcasestr(const char* s, const char *find) +{ + char c, sc; + size_t len; + + if ((c = *find++) != 0) { + c = tolower((unsigned char)c); + len = strlen(find); + do { + do { + if ((sc = *s++) == 0) + return (NULL); + } while ((char)tolower((unsigned char)sc) != c); + } while (strncasecmp(s, find, len) != 0); + s--; + } + return ((char *)s); +} + + +// +// For list of blacklisted functions, see: isBlacklisted() +// + +using namespace libTransform; + +IntegerTransform::IntegerTransform(VariantID_t *p_variantID, FileIR_t *p_fileIR, +// std::multimap<VirtualOffset, MEDS_AnnotationBase> +MEDS_Annotations_t *p_annotations, +set<std::string> *p_filteredFunctions, set<VirtualOffset> *p_benignFalsePositives) : Transform(p_variantID, p_fileIR, p_filteredFunctions) +{ + m_benignFalsePositives = p_benignFalsePositives; + m_policySaturatingArithmetic = false; + m_policyWarningsOnly = false; + m_pathManipulationDetected = false; + m_instrumentIdioms = false; + + m_annotations = p_annotations; + + m_numAnnotations = 0; + m_numIdioms = 0; + m_numBlacklisted = 0; + m_numBenign = 0; + m_numFP = 0; + + m_numTotalOverflows = 0; + m_numTotalUnderflows = 0; + m_numTotalTruncations = 0; + m_numTotalSignedness = 0; + + m_numOverflows = 0; + m_numUnderflows = 0; + m_numTruncations = 0; + m_numSignedness = 0; + + m_numOverflowsSkipped = 0; + m_numUnderflowsSkipped = 0; + m_numTruncationsSkipped = 0; + m_numSignednessSkipped = 0; + + m_instrumentSP = false; + m_instrumentFP = false; +} + +bool IntegerTransform::isBlacklisted(Function_t *func) +{ + if (!func) return false; + + const char *funcName = func->GetName().c_str(); + return (my_strcasestr(funcName, "hash") || + my_strcasestr(funcName, "compress") || + my_strcasestr(funcName, "encode") || + my_strcasestr(funcName, "decode") || + my_strcasestr(funcName, "crypt") || + my_strcasestr(funcName, "yyparse") || + my_strcasestr(funcName, "yyerror") || + my_strcasestr(funcName, "yydestruct") || + my_strcasestr(funcName, "yyrestart") || + my_strcasestr(funcName, "yylex") || + my_strcasestr(funcName, "yyparse") || + my_strcasestr(funcName, "yyerror") || + my_strcasestr(funcName, "yydestruct") || + my_strcasestr(funcName, "yyrestart") || + my_strcasestr(funcName, "yylex") || + my_strcasestr(funcName, "yy_")); +} + +void IntegerTransform::logStats() +{ + std::string fileURL = getFileIR()->GetFile()->GetURL(); + + std::cerr << "# ATTRIBUTE intx::file_name=" << fileURL << std::endl; + std::cerr << "# ATTRIBUTE intx::num_annotations_processed=" << dec << m_numAnnotations << std::endl; + std::cerr << "# ATTRIBUTE intx::num_idioms=" << m_numIdioms << std::endl; + std::cerr << "# ATTRIBUTE intx::num_blacklisted=" << m_numBlacklisted << std::endl; + std::cerr << "# ATTRIBUTE intx::num_benign=" << m_numBenign << std::endl; + + std::cerr << "# ATTRIBUTE intx::num_total_overflows=" << m_numTotalOverflows << std::endl; + std::cerr << "# ATTRIBUTE intx::num_overflows_instrumented=" << m_numOverflows << std::endl; + std::cerr << "# ATTRIBUTE intx::num_overflows_skipped=" << m_numOverflowsSkipped << std::endl; + std::cerr << "# ATTRIBUTE intx::overflows_coverage=" << (double)m_numOverflows/(double)m_numTotalOverflows << std::endl; + + std::cerr << "# ATTRIBUTE intx::num_total_underflows=" << m_numTotalUnderflows << std::endl; + std::cerr << "# ATTRIBUTE intx::num_underflows_instrumented=" << m_numUnderflows << std::endl; + std::cerr << "# ATTRIBUTE intx::num_underflows_skipped=" << m_numUnderflowsSkipped << std::endl; + std::cerr << "# ATTRIBUTE intx::underflows_coverage=" << (double)m_numUnderflows/(double)m_numTotalUnderflows << std::endl; + + std::cerr << "# ATTRIBUTE intx::num_total_truncations=" << m_numTotalTruncations << std::endl; + std::cerr << "# ATTRIBUTE intx::num_truncations_instrumented=" << m_numTruncations << std::endl; + std::cerr << "# ATTRIBUTE intx::num_truncations_skipped=" << m_numTruncationsSkipped << std::endl; + std::cerr << "# ATTRIBUTE intx::truncation_coverage=" << (double)m_numTruncations/(double)m_numTotalTruncations << std::endl; + + std::cerr << "# ATTRIBUTE intx::num_total_signedness=" << m_numTotalSignedness << std::endl; + std::cerr << "# ATTRIBUTE intx::num_signedness_instrumented=" << m_numSignedness << std::endl; + std::cerr << "# ATTRIBUTE intx::num_signedness_skipped=" << m_numSignednessSkipped << std::endl; + std::cerr << "# ATTRIBUTE intx::signedness_coverage=" << (double)m_numSignedness/(double)m_numTotalSignedness << std::endl; + + std::cerr << "# ATTRIBUTE intx::num_floating_point=" << m_numFP << std::endl; +} diff --git a/irdb-lib/libIRDB-transform/include-unused-delete-later/integertransform.hpp b/irdb-lib/libIRDB-transform/include-unused-delete-later/integertransform.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ce9e5f361147bfff01d5ee0bb31a25dcc7138724 --- /dev/null +++ b/irdb-lib/libIRDB-transform/include-unused-delete-later/integertransform.hpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013, 2014 - University of Virginia + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#ifndef _LIBTRANSFORM_INTEGERTRANSFORM_H_ +#define _LIBTRANSFORM_INTEGERTRANSFORM_H_ + +#include "transform.hpp" +#include "MEDS_Register.hpp" +#include "MEDS_AnnotationParser.hpp" +#include "VirtualOffset.hpp" + +namespace libTransform +{ + +using namespace std; +using namespace libIRDB; + +const int IDIOM_POINTER_NUMERIC_WEAKNESS = 18; + +class IntegerTransform : public Transform +{ + public: + IntegerTransform(VariantID_t *, FileIR_t*, MEDS_Annotations_t *p_annotations, set<std::string> *p_filteredFunctions, set<VirtualOffset> *p_warnings); + virtual int execute() = 0; + + void setSaturatingArithmetic(bool p_satArithmetic) { m_policySaturatingArithmetic = p_satArithmetic; } + bool isSaturatingArithmetic() { return m_policySaturatingArithmetic; } + void setPathManipulationDetected(bool p_pathManip) { m_pathManipulationDetected = p_pathManip; } + bool isPathManipulationDetected() { return m_pathManipulationDetected; } + void setWarningsOnly(bool p_warn) { m_policyWarningsOnly = p_warn; } + bool isWarningsOnly() { return m_policyWarningsOnly; } + void setInstrumentIdioms(bool p_idioms) { m_instrumentIdioms = p_idioms; } + bool isInstrumentIdioms() { return m_instrumentIdioms; } + void logStats(); + bool isBlacklisted(Function_t *func); + + protected: + void setInstrumentSP(bool sp) { m_instrumentSP = sp; } + bool instrumentSP() const { return m_instrumentSP; } + void setInstrumentFP(bool fp) { m_instrumentFP = fp; } + bool instrumentFP() const { return m_instrumentFP; } + + protected: + MEDS_Annotations_t* getAnnotations() { return m_annotations; } + + std::set<VirtualOffset>* m_benignFalsePositives; + bool m_policySaturatingArithmetic; + bool m_policyWarningsOnly; + bool m_pathManipulationDetected; + bool m_instrumentIdioms; + MEDS_Annotations_t *m_annotations; + + unsigned m_numAnnotations; + unsigned m_numIdioms; + unsigned m_numBlacklisted; + unsigned m_numBenign; + + unsigned m_numTotalOverflows; + unsigned m_numOverflows; + unsigned m_numOverflowsSkipped; + + unsigned m_numTotalUnderflows; + unsigned m_numUnderflows; + unsigned m_numUnderflowsSkipped; + + unsigned m_numTotalTruncations; + unsigned m_numTruncations; + unsigned m_numTruncationsSkipped; + + unsigned m_numTotalSignedness; + unsigned m_numSignedness; + unsigned m_numSignednessSkipped; + + unsigned m_numFP; + + bool m_instrumentSP; + bool m_instrumentFP; +}; + +} + +#endif diff --git a/irdb-lib/libIRDB-transform/include-unused-delete-later/integertransform32.cpp b/irdb-lib/libIRDB-transform/include-unused-delete-later/integertransform32.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3f63ef75561fff2b9d8086393e3ec25ac69819b5 --- /dev/null +++ b/irdb-lib/libIRDB-transform/include-unused-delete-later/integertransform32.cpp @@ -0,0 +1,2175 @@ +/* + * Copyright (c) 2013, 2014 - University of Virginia + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#include <assert.h> +#include "integertransform32.hpp" +#include "leapattern.hpp" + +// +// For list of blacklisted functions, see: isBlacklisted() +// + +// +// MEDS has the following annotation types: +// - OVERFLOW (SIGNED|UNSIGNED|UNKNOWN) (32,16,8) +// - UNDERFLOW (SIGNED|UNSIGNED|UNKNOWN) (32,16,8) +// - SIGNEDNESS SIGNED (32,16,8) +// - TRUNCATION (SIGNED|UNSIGNED|UNKNOWN) (32,16,8) +// - XXX_NOFLAG (Many forms, handles LEA) +// +// Saturating arithmetic implemented for: +// - OVERFLOW (when destination is a register) +// - UNDERFLOW (when destination is a register) +// - SIGNEDNESS +// - TRUNCATION +// +// ============= TO DO ============= +// Saturating arithmetic to do: +// - OVERFLOW (dest. is not a register) +// - UNDERFLOW (dest. is not a register) +// +// Instrumentation: +// - TRUNCATION (16->8) no test cases available +// - LEA only reg32+reg32 case implemented +// 20130409 Anh fixed lea reg+reg bug (we were assuming that annotation matched instruction exactly) +// 20130410 Anh implemented shared library support -- added outer loop to iterate over all files in the driver program +// 20130411 Anh skip instrumentation where there's no fallthrough for an instruction +// +using namespace libTransform; + +IntegerTransform32::IntegerTransform32(VariantID_t *p_variantID, FileIR_t *p_fileIR, +MEDS_Annotations_t *p_annotations, set<std::string> *p_filteredFunctions, set<VirtualOffset> *p_benignFalsePositives) : IntegerTransform(p_variantID, p_fileIR, p_annotations, p_filteredFunctions, p_benignFalsePositives) +{ +} + +// iterate through all functions +// filter those functions that should be ignored +// iterate through all instructions in function +// if MEDS annotation says to instrument +// add instrumentation +int IntegerTransform32::execute() +{ + if (isSaturatingArithmetic()) + cerr << "IntegerTransform32: Saturating Arithmetic is enabled" << endl; + else + cerr << "IntegerTransform32: Saturating Arithmetic is disabled" << endl; + + if (isPathManipulationDetected()) + cerr << "IntegerTransform32: Exit on truncation" << endl; + + if (isWarningsOnly()) + cerr << "IntegerTransform32: Warnings only mode" << endl; + + for( + set<Function_t*>::const_iterator itf=getFileIR()->GetFunctions().begin(); + itf!=getFileIR()->GetFunctions().end(); + ++itf + ) + { + Function_t* func=*itf; + + if (getFilteredFunctions()->find(func->GetName()) != getFilteredFunctions()->end()) + { + continue; + } + + if (isBlacklisted(func)) + { + cerr << "Heuristic filter: " << func->GetName() << endl; + m_numBlacklisted++; + continue; + } + + logMessage(__func__, "processing fn: " + func->GetName()); + + for( + set<Instruction_t*>::const_iterator it=func->GetInstructions().begin(); + it!=func->GetInstructions().end(); + ++it) + { + Instruction_t* insn=*it; + + if (insn && insn->getAddress()) + { + int policy = POLICY_DEFAULT; // use Strata default settings + virtual_offset_t irdb_vo = insn->getAddress()->GetVirtualOffset(); + if (irdb_vo == 0) continue; + + VirtualOffset vo(irdb_vo); + + if(insn->GetDataBits().c_str()[0]==(char)0xDF || insn->GetDataBits().c_str()[0]==(char)0xDB){ + handleFISTTruncation(insn); + } + + if (isSaturatingArithmetic()) + { + // saturating arithmetic is enabled + // only use if instruction is not a potential false positive + policy = POLICY_CONTINUE_SATURATING_ARITHMETIC; + } + + // takes precedence over saturation if conflict + if (isWarningsOnly()) + { + policy = POLICY_CONTINUE; + } + + // overwrite the above if needed + if (isPathManipulationDetected()) + { + policy = POLICY_EXIT; + } + + if (m_benignFalsePositives && m_benignFalsePositives->count(vo)) + { + // potential benign false positives + m_numBenign++; + policy = POLICY_CONTINUE; + } + + +/* + MEDS_InstructionCheckAnnotation annotation = (*getAnnotations())[vo]; + if (!annotation.isValid()) + continue; +*/ + if (getAnnotations()->count(vo) == 0) + continue; + + std::pair< MEDS_Annotations_t::iterator, MEDS_Annotations_t::iterator > ret; + ret = getAnnotations()->equal_range(vo); + MEDS_InstructionCheckAnnotation annotation; + MEDS_InstructionCheckAnnotation* p_annotation; + for ( MEDS_Annotations_t::iterator it = ret.first; it != ret.second; ++it) + { + MEDS_AnnotationBase *b = (it->second); + p_annotation=dynamic_cast<MEDS_InstructionCheckAnnotation*>(b); + if(!p_annotation) + continue; + annotation=*p_annotation; + if (!annotation.isValid()) + continue; + else + break; // let's just handle one annotation for now and see how it goes + } + + if (!annotation.isValid()) + continue; + + logMessage(__func__, annotation, "-- instruction: " + insn->getDisassembly()); + m_numAnnotations++; + + if (annotation.isIdiom()) + { + logMessage(__func__, "skip IDIOM"); + m_numIdioms++; + continue; + } + + if (!insn->getFallthrough()) + { + logMessage(__func__, "Warning: no fall through for instruction -- skipping"); + continue; + } + + if (annotation.isOverflow()) + { + // nb: safe with respect to esp (except for lea) + m_numTotalOverflows++; + handleOverflowCheck(insn, annotation, policy); + } + else if (annotation.isUnderflow() && !annotation.isNoFlag()) + { + m_numTotalUnderflows++; + // nb: safe with respect to esp + handleUnderflowCheck(insn, annotation, policy); + } + else if (annotation.isTruncation()) + { + m_numTotalTruncations++; + handleTruncation(insn, annotation, policy); + } + else if (annotation.isSignedness()) + { + m_numTotalSignedness++; + if (annotation.isUnknownSign()) + { + logMessage(__func__, "annotation has unknown sign: skipping"); + continue; + } + handleSignedness(insn, annotation, policy); + } + else if (annotation.isInfiniteLoop()) + { + handleInfiniteLoop(insn, annotation, POLICY_EXIT); + } + else + { + logMessage(__func__, "unknown annotation"); + } + } + } // end iterate over all instructions in a function + } // end iterate over all functions + + return 0; +} + +void IntegerTransform32::handleSignedness(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) +{ + if (p_annotation.isSigned() || p_annotation.isUnsigned()) + addSignednessCheck(p_instruction, p_annotation, p_policy); + else + logMessage(__func__, "case not yet handled"); +} + +// 8048576 5 INSTR CHECK SIGNEDNESS SIGNED 16 AX ZZ mov [esp+28h], ax +// <save flags> +// TEST ax, ax +// jns L1 +// invoke conversion handler +// (optional) mov ax, MAX_16 ; saturating arithmetic (Max for bit width/sign/unsigned) +// +// L1: <restore flags> +// mov [esp+28h], ax +// +// 20120414 We may want to saturate the destination instead. This would mean putting the saturation code +// after the instruction being instrumented +void IntegerTransform32::addSignednessCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) +{ + // sanity checks + assert(getFileIR() && p_instruction); + assert (p_annotation.isValid()); + if ( + !(p_annotation.getBitWidth() == 32 && Register::is32bit(p_annotation.getRegister())) && + !(p_annotation.getBitWidth() == 16 && (Register::is16bit(p_annotation.getRegister()) || + p_annotation.getRegister() == rn_ESI || p_annotation.getRegister() == rn_EDI || p_annotation.getRegister() == rn_EBP)) && + !(p_annotation.getBitWidth() == 8 && Register::is8bit(p_annotation.getRegister())) + ) + { + logMessage(__func__, "unexpected bit width and register combination: skipping"); + m_numSignednessSkipped++; + return; + } + + DatabaseID_t fileID = p_instruction->getAddress()->getFileID(); + Function_t* func = p_instruction->GetFunction(); + + Instruction_t* pushf_i = allocateNewInstruction(fileID, func); + Instruction_t* test_i = allocateNewInstruction(fileID, func); + Instruction_t* jns_i = allocateNewInstruction(fileID, func); + Instruction_t* nop_i = allocateNewInstruction(fileID, func); + Instruction_t* popf_i = allocateNewInstruction(fileID, func); + + addPushf(pushf_i, test_i); + Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, pushf_i); + pushf_i->setFallthrough(test_i); + pushf_i->setComment("-- in signedness check"); + addTestRegister(test_i, p_annotation.getRegister(), jns_i); + addJns(jns_i, nop_i, popf_i); + addNop(nop_i, popf_i); + + string detector; + if (p_annotation.getBitWidth() == 32) + detector = string(SIGNEDNESS_DETECTOR_32); + else if (p_annotation.getBitWidth() == 16) + detector = string(SIGNEDNESS_DETECTOR_16); + else if (p_annotation.getBitWidth() == 8) + detector = string(SIGNEDNESS_DETECTOR_8); + + // sanity filter + if (p_annotation.getRegister() == rn_UNKNOWN) + p_policy = POLICY_DEFAULT; + + if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) + { + // implement saturating arithmetic on register, i.e.: mov <reg>, value + Instruction_t* saturate_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); + + addCallbackHandler(detector, originalInstrumentInstr, nop_i, saturate_i, p_policy, p_instruction->getAddress()); + if (p_annotation.isSigned()) + addMaxSaturation(saturate_i, p_annotation.getRegister(), p_annotation, popf_i); + else + addZeroSaturation(saturate_i, p_annotation.getRegister(), popf_i); + } + else + { + addCallbackHandler(detector, originalInstrumentInstr, nop_i, popf_i, p_policy, p_instruction->getAddress()); + } + addPopf(popf_i, originalInstrumentInstr); + + m_numSignedness++; +} + +void IntegerTransform32::handleOverflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) +{ + if (p_annotation.isUnknownSign() && !p_annotation.isNoFlag()) + { + addOverflowCheckUnknownSign(p_instruction, p_annotation, p_policy); + } + else if (p_annotation.isNoFlag()) + { + // handle lea + addOverflowCheckNoFlag(p_instruction, p_annotation, p_policy); + } + else if (isMultiplyInstruction(p_instruction) || p_annotation.isUnderflow() || p_annotation.isOverflow()) + { + // handle signed/unsigned add/sub overflows (non lea) + addOverflowCheck(p_instruction, p_annotation, p_policy); + } + else + { + m_numOverflowsSkipped++; + logMessage(__func__, "OVERFLOW type not yet handled"); + } +} + +void IntegerTransform32::handleUnderflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) +{ + if (p_annotation.isUnderflow()) + { + addUnderflowCheck(p_instruction, p_annotation, p_policy); + } + else + { + m_numUnderflowsSkipped++; + logMessage(__func__, "UNDERFLOW type not yet handled"); + } +} + +/* + NOFLAGUNKNOWNSIGN 32 ESI+EDX ZZ lea eax, [esi+edx] + NOFLAGUNSIGNED 32 EDX+ESI+1900 ZZ lea esi, [edx+esi+76Ch] + NOFLAGUNSIGNED 32 EAX+382 ZZ lea esi, [eax+17Eh] + NOFLAGUNKNOWNSIGN 32 EDX*8 ZZ lea eax, ds:0[edx*8] + NOFLAGUNSIGNED 32 ECX+ECX*4 ZZ lea ebx, [ecx+ecx*4] + NOFLAGUNSIGNED 32 EDI+-66 ZZ lea eax, [edi-42h] + NOFLAGSIGNED 32 ESI+100 ZZ lea ecx, [esi+64h] + + possible patterns after the bit width field: + rpr: <reg>+<reg> + rpc: <reg>+-<constant> + rpc: <reg>+<constant> + rtc: <reg>*constant + + + not yet handling these: + rprpc: <reg>+<reg>+<constant> + rprpc: <reg>+<reg>+-<constant> + rprtc: <reg>+<reg>*<constant> +*/ +void IntegerTransform32::addOverflowCheckNoFlag(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) +{ + LEAPattern leaPattern(p_annotation); + + if (!leaPattern.isValid()) + { + logMessage(__func__, "invalid or unhandled lea pattern - skipping: "); + m_numOverflowsSkipped++; + return; + } + + if (leaPattern.getRegister1() == rn_UNKNOWN || + leaPattern.getRegister1() == rn_ESP || + leaPattern.getRegister1() == rn_EBP) + { + logMessage(__func__, "destination register is unknown, esp or ebp -- skipping: "); + m_numOverflowsSkipped++; + return; + } + + if (leaPattern.isRegisterPlusRegister()) + { + RegisterName reg1 = leaPattern.getRegister1(); + RegisterName reg2 = leaPattern.getRegister2(); + RegisterName target = getTargetRegister(p_instruction); + + if (reg1 == rn_UNKNOWN || reg2 == rn_UNKNOWN || target == rn_UNKNOWN) + { + logMessage(__func__, "lea reg+reg pattern: error retrieving register: reg1: " + Register::toString(reg1) + " reg2: " + Register::toString(reg2) + " target: " + Register::toString(target)); + m_numOverflowsSkipped++; + return; + } + else if (reg2 == rn_ESP) + { + logMessage(__func__, "source register is esp -- skipping: "); + m_numOverflowsSkipped++; + return; + } + else + { + addOverflowCheckNoFlag_RegPlusReg(p_instruction, p_annotation, reg1, reg2, target, p_policy); + } + } + else if (leaPattern.isRegisterPlusConstant()) + { + RegisterName reg1 = leaPattern.getRegister1(); + int value = leaPattern.getConstant(); + RegisterName target = getTargetRegister(p_instruction); + + if (p_annotation.isUnsigned() && value < 0) + { + logMessage(__func__, "lea reg+neg constant pattern: skip this annotation type (prone to false positives)"); + m_numOverflowsSkipped++; + return; + } + else if (reg1 == rn_UNKNOWN || target == rn_UNKNOWN) + { + logMessage(__func__, "lea reg+constant pattern: error retrieving register: reg1: " + Register::toString(reg1) + " target: " + Register::toString(target)); + m_numOverflowsSkipped++; + return; + } + else + { + addOverflowCheckNoFlag_RegPlusConstant(p_instruction, p_annotation, reg1, value, target, p_policy); + } + } + else if (leaPattern.isRegisterTimesConstant()) + { + RegisterName reg1 = leaPattern.getRegister1(); + int value = leaPattern.getConstant(); + RegisterName target = getTargetRegister(p_instruction); + + if (reg1 == rn_UNKNOWN || target == rn_UNKNOWN) + { + logMessage(__func__, "lea reg*constant pattern: error retrieving register: reg1: " + Register::toString(reg1) + " target: " + Register::toString(target)); + m_numOverflowsSkipped++; + return; + } + else + { + m_numOverflowsSkipped++; + addOverflowCheckNoFlag_RegTimesConstant(p_instruction, p_annotation, reg1, value, target, p_policy); + } + } + else + { + logMessage(__func__, "pattern not yet handled"); + m_numOverflowsSkipped++; + return; + } +} + +// Example annotation to handle +// 804852e 3 INSTR CHECK OVERFLOW NOFLAGSIGNED 32 EDX+EAX ZZ lea eax, [edx+eax] Reg1: EDX Reg2: EAX +void IntegerTransform32::addOverflowCheckNoFlag_RegPlusReg(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const RegisterName& p_reg1, const RegisterName& p_reg2, const RegisterName& p_reg3, int p_policy) +{ + cerr << __func__ << ": reg+constant: r1: " << Register::toString(p_reg1) << " r2: " << Register::toString(p_reg2) << " target register: " << Register::toString(p_reg3) << " annotation: " << p_annotation.toString() << endl; + + // orig: lea r3, [r1+r2] + // <originalNext> + // + // Instrumentation: + // push r1 ; save r1 + // pushf ; save flags + // add r1, r2 ; r1 = r1 + r2 + // <overflowcheck> ; check for overflow as dictated by annotation + // (jno|jnc <restore>) ; SIGNED|UNSIGNED + // fallthrough--><saturate> + // (jno&jnc <restore>) ; UNKNOWNSIGN both flags + // fallthrough--><saturate> + // + // <restore> + // popf ; restore flags + // pop r1 ; restore register + // + // <orig>: lea r3, [r1+r2] ; original instruction + // <originalNext> ; original next instruction + // + // <saturate> ; optional saturation code + // popf ; restore flags + // pop r1 ; restore register + // saturateMax(r3) ; + // fallthrough-->originalNext + // + + DatabaseID_t fileID = p_instruction->getAddress()->getFileID(); + Function_t* func = p_instruction->GetFunction(); + + Instruction_t* pushr1_i = allocateNewInstruction(fileID, func); + Instruction_t* pushf_i = allocateNewInstruction(fileID, func); + Instruction_t* addRR_i = allocateNewInstruction(fileID, func); + Instruction_t* popf_i = allocateNewInstruction(fileID, func); + Instruction_t* popr1_i = allocateNewInstruction(fileID, func); + + // reuse annotation info when checking for overflow + MEDS_InstructionCheckAnnotation addRR_annot; + addRR_annot.setValid(); + addRR_annot.setBitWidth(32); + addRR_annot.setOverflow(); + if (p_annotation.isSigned()) + addRR_annot.setSigned(); + else if (p_annotation.isUnsigned()) + addRR_annot.setUnsigned(); + else + addRR_annot.setUnknownSign(); + + string msg = "Originally: " + p_instruction->getDisassembly(); + Instruction_t* originalNextInstr = p_instruction->getFallthrough(); + AddressID_t *originalAddress = p_instruction->getAddress(); + + addPushRegister(pushr1_i, p_reg1, pushf_i); + Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, pushr1_i); + pushr1_i->setFallthrough(pushf_i); + pushr1_i->setComment("-- carefullyInsertBefore NoFlagRegPlusReg"); + + addPushf(pushf_i, addRR_i); + + addAddRegisters(addRR_i, p_reg1, p_reg2, popf_i); + addRR_i->setComment(msg); + + addPopf(popf_i, popr1_i); + addPopRegister(popr1_i, p_reg1, originalInstrumentInstr); + + if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) + { + // add r1, r2 ; r1 = r1 + r2 + // (jno|jnc <restore>) ; SIGNED|UNSIGNED + // fallthrough--><saturate> + // (jno&jnc <restore>) ; UNKNOWNSIGN both flags + // fallthrough--><saturate> + // + // <restore> + // popf ; restore flags + // pop r1 ; restore register + // + // <orig>: lea r3, [r1+r2] ; original instruction + // <originalNext> ; original next instruction + // + // <saturate> ; optional saturation code + // popf ; restore flags + // pop r1 ; restore register + // saturateMax(r3) ; + // fallthrough-->originalNext + + Instruction_t* j_i = allocateNewInstruction(fileID, func); + Instruction_t* jnc_i = NULL; + Instruction_t* popfsat_i = allocateNewInstruction(fileID, func); + Instruction_t* popR1sat_i = allocateNewInstruction(fileID, func); + Instruction_t* saturate_i = allocateNewInstruction(fileID, func); + + addRR_i->setFallthrough(j_i); + + if (p_annotation.isSigned()) + { + addJno(j_i, popfsat_i, popf_i); + } + else if (p_annotation.isUnsigned()) + { + addJnc(j_i, popfsat_i, popf_i); + } + else + { + jnc_i = allocateNewInstruction(fileID, func); + addJno(j_i, jnc_i, popf_i); + addJnc(jnc_i, popfsat_i, popf_i); + } + + addOverflowCheckForLea(addRR_i, addRR_annot, p_policy, originalAddress); + + addPopf(popfsat_i, popR1sat_i); + addPopRegister(popR1sat_i, p_reg1, saturate_i); + addMaxSaturation(saturate_i, p_reg3, p_annotation, originalNextInstr); + } + else + { + addOverflowCheckForLea(addRR_i, addRR_annot, p_policy, originalAddress); + } + + m_numOverflows++; +} + +void IntegerTransform32::addOverflowCheckNoFlag_RegPlusConstant(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const RegisterName& p_reg1, const int p_constantValue, const RegisterName& p_reg3, int p_policy) +{ + if (!p_instruction) + return; + + if (p_instruction->GetIndirectBranchTargetAddress()) + cerr << "IBTA set: "; + else + cerr << "no IBTA: "; + + cerr << __func__ << ": reg+constant: register: " << Register::toString(p_reg1) << " constant: " << dec << p_constantValue << " target register: " << Register::toString(p_reg3) << " annotation: " << p_annotation.toString() << endl; + + // + // Original instruction is of the form: + // lea r3, [r1+constant] + // lea r3, [r1-constant] + // <originalNext> + // + // Example annotation: + // 8049410 3 INSTR CHECK OVERFLOW NOFLAGUNSIGNED 32 EAX+-15 ZZ lea ebx, [eax-0Fh] + // + // In this example: + // r3 = ebx + // r1 = eax + // constant = -15 + // + // Instrumentation: + // push r3 ; save register + // pushf ; save flags + // mov r3, r1 ; r3 = r1 + // add r3, constant ; r3 = r1 + constant; + // <overflowCheck> ; reuse overflow code + // (jno|jnc <restore>) ; SIGNED|UNSIGNED + // fallthrough--><saturate> + // (jno&jnc <restore>) ; UNKNOWNSIGN both flags + // fallthrough--><saturate> + // <restore> + // popf ; restore flags + // pop r3 ; restore register + // + // + // <orig>: lea r3, [r1+constant] ; original instruction + // <originalNext> ; original next instruction + // + // <saturate> ; optional saturation code + // popf ; restore flags + // pop r3 ; restore register + // saturateMax(r3) ; + // fallthrough-->originalNext + // + // + // Note: if r3 == r1, code still works (though inefficiently) + // + + DatabaseID_t fileID = p_instruction->getAddress()->getFileID(); + Function_t* func = p_instruction->GetFunction(); + + Instruction_t* pushR3_i = allocateNewInstruction(fileID, func); + Instruction_t* pushf_i = allocateNewInstruction(fileID, func); + Instruction_t* movR3R1_i = allocateNewInstruction(fileID, func); + Instruction_t* addR3Constant_i = allocateNewInstruction(fileID, func); + Instruction_t* popf_i = allocateNewInstruction(fileID, func); + Instruction_t* popR3_i = allocateNewInstruction(fileID, func); + + MEDS_InstructionCheckAnnotation addR3Constant_annot; + addR3Constant_annot.setValid(); + addR3Constant_annot.setBitWidth(32); + addR3Constant_annot.setOverflow(); + if (p_annotation.isSigned()) + addR3Constant_annot.setSigned(); + else if (p_annotation.isUnsigned()) + addR3Constant_annot.setUnsigned(); + else + addR3Constant_annot.setUnknownSign(); + + string msg = "Originally: " + p_instruction->getDisassembly(); + Instruction_t* originalNextInstr = p_instruction->getFallthrough(); + + AddressID_t *originalAddress = p_instruction->getAddress(); + + addPushRegister(pushR3_i, p_reg3, pushf_i); + Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, pushR3_i); + pushR3_i->setComment("in lea -- RegPlusConstant"); + pushR3_i->setFallthrough(pushf_i); + addPushf(pushf_i, movR3R1_i); + + addMovRegisters(movR3R1_i, p_reg3, p_reg1, addR3Constant_i); + addAddRegisterConstant(addR3Constant_i, p_reg3, p_constantValue, popf_i); + addPopf(popf_i, popR3_i); + addPopRegister(popR3_i, p_reg3, originalInstrumentInstr); + + addR3Constant_i->setComment(msg); + if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) + { + // (jno|jnc <restore>) ; SIGNED|UNSIGNED + // fallthrough--><saturate> + // (jno&jnc <restore>) ; UNKNOWNSIGN both flags + // fallthrough--><saturate> + // + // <restore> + // popf ; restore flags + // pop r3 ; restore register + // + // <saturate> + // popf ; restore flags + // pop r3 ; restore register + // saturateMax(r3) ; + // fallthrough-->originalNext + Instruction_t* j_i = allocateNewInstruction(fileID, func); + Instruction_t* jnc_i = NULL; + Instruction_t* popfsat_i = allocateNewInstruction(fileID, func); + Instruction_t* popR3sat_i = allocateNewInstruction(fileID, func); + Instruction_t* saturate_i = allocateNewInstruction(fileID, func); + + addR3Constant_i->setFallthrough(j_i); + + if (p_annotation.isSigned()) + { + addJno(j_i, popfsat_i, popf_i); + } + else if (p_annotation.isUnsigned()) + { + addJnc(j_i, popfsat_i, popf_i); + } + else + { + jnc_i = allocateNewInstruction(fileID, func); + addJno(j_i, jnc_i, popf_i); + addJnc(jnc_i, popfsat_i, popf_i); + } + + addOverflowCheckForLea(addR3Constant_i, addR3Constant_annot, p_policy, originalAddress); + + addPopf(popfsat_i, popR3sat_i); + addPopRegister(popR3sat_i, p_reg3, saturate_i); + addMaxSaturation(saturate_i, p_reg3, p_annotation, originalNextInstr); + } + else + { + addOverflowCheckForLea(addR3Constant_i, addR3Constant_annot, p_policy, originalAddress); + } + m_numOverflows++; +} + +void IntegerTransform32::addOverflowCheckNoFlag_RegTimesConstant(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const RegisterName& p_reg1, const int p_constantValue, const RegisterName& p_reg3, int p_policy) +{ + cerr << __func__ << ": reg*constant: register: " << Register::toString(p_reg1) << " constant: " << p_constantValue << " target register: " << Register::toString(p_reg3) << " annotation: " << p_annotation.toString() << endl; + + // + // Original instruction is of the form: + // lea r3, [r1*constant] + // <originalNext> + // + // Instrumentation: + // push r3 ; save register + // pushf ; save flags + // mov r3, r1 ; r3 = r1 + // imul r3, constant ; r3 = r1 * constant; + // <overflowCheck> ; emit diagnostics + // (jo <saturate>) ; optional saturation code + // popf ; restore flags + // pop r3 ; restore register + // + // <orig>: lea r3, [r1*constant] ; original instruction + // <originalNext> ; original next instruction + // + // ; optional saturation code + // <saturate> + // popf ; restore flags + // pop r3 ; restore register + // saturateMax(r3) ; + // fallthrough-->originalNext + // + // Note: if r3 == r1, code still works (though inefficiently) + // + DatabaseID_t fileID = p_instruction->getAddress()->getFileID(); + Function_t* func = p_instruction->GetFunction(); + + Instruction_t* pushR3_i = allocateNewInstruction(fileID, func); + Instruction_t* pushf_i = allocateNewInstruction(fileID, func); + Instruction_t* movR3R1_i = allocateNewInstruction(fileID, func); + Instruction_t* mulR3Constant_i = allocateNewInstruction(fileID, func); + Instruction_t* popf_i = allocateNewInstruction(fileID, func); + Instruction_t* popR3_i = allocateNewInstruction(fileID, func); + + MEDS_InstructionCheckAnnotation mulR3Constant_annot; + mulR3Constant_annot.setValid(); + mulR3Constant_annot.setBitWidth(32); + mulR3Constant_annot.setOverflow(); + if (p_annotation.isSigned()) + mulR3Constant_annot.setSigned(); + else if (p_annotation.isUnsigned()) + mulR3Constant_annot.setUnsigned(); + else + mulR3Constant_annot.setUnknownSign(); + + string msg = "Originally: " + p_instruction->getDisassembly(); + Instruction_t* originalNextInstr = p_instruction->getFallthrough(); + + AddressID_t *originalAddress = p_instruction->getAddress(); + + addPushRegister(pushR3_i, p_reg3, pushf_i); + Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, pushR3_i); + pushR3_i->setFallthrough(pushf_i); + pushR3_i->setComment("in lea -- Reg * Constant"); + addPushf(pushf_i, movR3R1_i); + + addMovRegisters(movR3R1_i, p_reg3, p_reg1, mulR3Constant_i); + addMulRegisterConstant(mulR3Constant_i, p_reg3, p_constantValue, popf_i); + addPopf(popf_i, popR3_i); + addPopRegister(popR3_i, p_reg3, originalInstrumentInstr); + + mulR3Constant_i->setComment(msg); + + if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) + { + // (jo <saturate>) ; optional saturation code + // popf ; restore flags + // + // <saturate> + // popf ; restore flags + // pop r3 ; restore register + // saturateMax(r3) ; + // fallthrough-->originalNext + Instruction_t* jo_i = allocateNewInstruction(fileID, func); + Instruction_t* popfsat_i = allocateNewInstruction(fileID, func); + Instruction_t* popR3sat_i = allocateNewInstruction(fileID, func); + Instruction_t* saturate_i = allocateNewInstruction(fileID, func); + + mulR3Constant_i->setFallthrough(jo_i); + addOverflowCheckForLea(mulR3Constant_i, mulR3Constant_annot, p_policy, originalAddress); + + addJo(jo_i, popf_i, popfsat_i); + addPopf(popfsat_i, popR3sat_i); + addPopRegister(popR3sat_i, p_reg3, saturate_i); + addMaxSaturation(saturate_i, p_reg3, p_annotation, originalNextInstr); + } + else + { + // fallthrough was set previously to popf_i + addOverflowCheckForLea(mulR3Constant_i, mulR3Constant_annot, p_policy, originalAddress); + } + m_numOverflows++; +} + + +void IntegerTransform32::handleFISTTruncation(Instruction_t *p_instruction){ + cerr << "IntegerTransform32::handleFISTTruncation(): instr: " << p_instruction->getDisassembly() << " address: " + << p_instruction->getAddress() << endl; + int len=0; + + //We skip the qword case. + if(p_instruction->getDisassembly().find("qword")!=std::string::npos){ + len = 64; + } + else if(p_instruction->getDisassembly().find("dword")!=std::string::npos){ + len = 32; + } + else if(p_instruction->getDisassembly().find(" word")!=std::string::npos){ + len = 16; + } + if(p_instruction->getDisassembly().substr(0,5)=="fistp"){ + cerr << "IntegerTransform32::addFistpTruncationCheck(): instr: " << p_instruction->getDisassembly() << " len= " + << len << endl; + addFistpTruncationCheck(p_instruction, len); + } + else if (p_instruction->getDisassembly().substr(0,4)=="fist"){ + cerr << "IntegerTransform32::addFistTruncationCheck(): instr: " << p_instruction->getDisassembly() << " len= " + << len << endl; + addFistTruncationCheck(p_instruction, len); + } +} + +void IntegerTransform32::addFistpTruncationCheck(Instruction_t *p_instruction, int len){ + if(len!=32 && len!=16) return; + DatabaseID_t fileID = p_instruction->getAddress()->getFileID(); + Function_t* func = p_instruction->GetFunction(); + string dataBits; + + //Fistp dword [esp+0x28]; + + /* + pusha + pushf + sub esp, 0x70 + fstp dword [esp] + fsave [esp+4] + push_ret //call some_func + frstor [esp+4] + test eax, 0 + jz_eax_0 label0 + + test eax, 1 + jz_eax_1 label1 + + label2: + add esp, 0x70 + ;; negtive min + mov [esp+0x28], 0x80000000 + + + label0: + + add esp, 0x70 + popf + popa + Fistp dword [esp+0x28] + + label1: ;;positive max + add esp, 0x70 + popf + popa + mov [esp+0x28], 0x7FFFFFFF + //fistp [] + */ + + Instruction_t* pusha_i = allocateNewInstruction(fileID, func); + Instruction_t* pushf_i = allocateNewInstruction(fileID, func); + Instruction_t* sub_esp_0x70 = allocateNewInstruction(fileID, func); //81 ec 70 00 00 00 + Instruction_t* fst_esp = allocateNewInstruction(fileID, func);//d9 14 24 + // fsave [esp+4] + Instruction_t* fsave_wait = allocateNewInstruction(fileID, func);//9b + Instruction_t* fsave_esp_4 = allocateNewInstruction(fileID, func);//dd 74 24 04 + Instruction_t* pushretaddress = allocateNewInstruction(fileID, func); + Instruction_t* frstor_esp_4 = allocateNewInstruction(fileID, func);//dd 64 24 04 + + Instruction_t* test_eax_0 = allocateNewInstruction(fileID, func); + Instruction_t* test_eax_1 = allocateNewInstruction(fileID, func); + + Instruction_t* jz_eax_0 = allocateNewInstruction(fileID, func); + Instruction_t* jz_eax_1 = allocateNewInstruction(fileID, func); + + + Instruction_t* add_esp_0x70_label0 = allocateNewInstruction(fileID, func); //81 c4 70 00 00 00 + Instruction_t* add_esp_0x70_label1 = allocateNewInstruction(fileID, func); + Instruction_t* add_esp_0x70_label2 = allocateNewInstruction(fileID, func); + + Instruction_t* popf_label0 = allocateNewInstruction(fileID, func); + Instruction_t* popa_label0 = allocateNewInstruction(fileID, func); + + Instruction_t* popf_label1 = allocateNewInstruction(fileID, func); + Instruction_t* popa_label1 = allocateNewInstruction(fileID, func); + + Instruction_t* popf_label2 = allocateNewInstruction(fileID, func); + Instruction_t* popa_label2 = allocateNewInstruction(fileID, func); + Instruction_t* nop = allocateNewInstruction(fileID, func); + + + addPusha(pusha_i, pushf_i);//pusha + Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, pusha_i); + pusha_i->setFallthrough(pushf_i); + + addPushf(pushf_i, sub_esp_0x70);//pushf + + dataBits.resize(6);//sub esp,0x70 + dataBits[0] = 0x81; + dataBits[1] = 0xec; + dataBits[2] = 0x70; + dataBits[3] = 0x00; + dataBits[4] = 0x00; + dataBits[5] = 0x00; + sub_esp_0x70->setFallthrough(fst_esp); + sub_esp_0x70->setDataBits(dataBits); + sub_esp_0x70->setComment(sub_esp_0x70->getDisassembly()); + addInstruction(sub_esp_0x70, dataBits, fst_esp, NULL); + + dataBits.resize(3);//fst [esp] + dataBits[0] = 0xd9; + dataBits[1] = 0x14; + dataBits[2] = 0x24; + fst_esp->setFallthrough(fsave_esp_4); + fst_esp->setDataBits(dataBits); + fst_esp->setComment(fst_esp->getDisassembly()); + addInstruction(fst_esp, dataBits, fsave_esp_4, NULL); + dataBits.resize(1);//fsave [esp+4] + dataBits[0] = 0x9b; + fsave_esp_4->setFallthrough(pushretaddress); + fsave_esp_4->setDataBits(dataBits); + fsave_esp_4->setComment(fsave_wait->getDisassembly()); + addInstruction(fsave_wait, dataBits, fsave_esp_4, NULL); + dataBits.resize(4); + dataBits[0] = 0xdd; + dataBits[1] = 0x74; + dataBits[2] = 0x24; + dataBits[3] = 0x04; + fsave_esp_4->setFallthrough(pushretaddress); + fsave_esp_4->setDataBits(dataBits); + fsave_esp_4->setComment(fsave_esp_4->getDisassembly()); + addInstruction(fsave_esp_4, dataBits, pushretaddress, NULL); + + virtual_offset_t AfterTheCheckerReturn = getAvailableAddress(); + nop->getAddress()->SetVirtualOffset(AfterTheCheckerReturn); + nop->getAddress()->SetFileID(BaseObj_t::NOT_IN_DATABASE); + + dataBits.resize(5);//push return_address + dataBits[0] = 0x68; + virtual_offset_t *tmp; + tmp = (virtual_offset_t *) &dataBits[1]; + *tmp = AfterTheCheckerReturn; + pushretaddress->setDataBits(dataBits); + pushretaddress->setComment(pushretaddress->getDisassembly()); + pushretaddress->setFallthrough(nop); + + + dataBits.resize(1);//nop + dataBits[0] = 0x90; + nop->setDataBits(dataBits); + nop->setComment(nop->getDisassembly() + " -- with callback to floating number check") ; + nop->setFallthrough(frstor_esp_4); + nop->SetIndirectBranchTargetAddress(nop->getAddress()); + if(len==32) + nop->SetCallback(string("FloatingRangeCheck32")); + else + nop->SetCallback(string("FloatingRangeCheck16")); + + dataBits.resize(4);//frstor [esp+4] + dataBits[0] = 0xdd; + dataBits[1] = 0x64; + dataBits[2] = 0x24; + dataBits[3] = 0x04; + frstor_esp_4->setDataBits(dataBits); + frstor_esp_4->setFallthrough(test_eax_0); + frstor_esp_4->setComment(frstor_esp_4->getDisassembly()); + dataBits.resize(2);//test eax, eax + dataBits[0] = 0x85; + dataBits[1] = 0xC0; + test_eax_0->setDataBits(dataBits); + test_eax_0->setFallthrough(jz_eax_0); + addInstruction(test_eax_0, dataBits, jz_eax_0, NULL); + addJz(jz_eax_0, test_eax_1, add_esp_0x70_label0); + + + //label 0: + Instruction_t* jmpOriginalInst = allocateNewInstruction(fileID, func); + + dataBits.resize(6);//add esp,0x70 + dataBits[0] = 0x81; + dataBits[1] = 0xc4; + dataBits[2] = 0x70; + dataBits[3] = 0x00; + dataBits[4] = 0x00; + dataBits[5] = 0x00; + add_esp_0x70_label0->setFallthrough(popf_label0); + add_esp_0x70_label0->setDataBits(dataBits); + add_esp_0x70_label0->setComment(add_esp_0x70_label0->getDisassembly()); + addInstruction(add_esp_0x70_label0, dataBits, popf_label0, NULL); + + addPopf(popf_label0, popa_label0); + addPopa(popa_label0, jmpOriginalInst); + + + dataBits.resize(2); + dataBits[0] = 0xeb; + jmpOriginalInst->setComment("Jump to original Inst"); + addInstruction(jmpOriginalInst,dataBits,NULL, originalInstrumentInstr); + + //label 1: + + dataBits.resize(5);//test eax, 1 + dataBits[0] = 0xA9; + dataBits[1] = 0x01; + dataBits[2] = 0x00; + dataBits[3] = 0x00; + dataBits[4] = 0x00; + test_eax_1->setDataBits(dataBits); + test_eax_1->setComment(test_eax_1->getDisassembly()) ; + test_eax_1->setFallthrough(jz_eax_1); + addInstruction(test_eax_1, dataBits, jz_eax_1, NULL); + addJz(jz_eax_1, add_esp_0x70_label1, add_esp_0x70_label2); + + + dataBits.resize(6);//add esp,0x70 + dataBits[0] = 0x81; + dataBits[1] = 0xc4; + dataBits[2] = 0x70; + dataBits[3] = 0x00; + dataBits[4] = 0x00; + dataBits[5] = 0x00; + add_esp_0x70_label1->setFallthrough(popf_label1); + add_esp_0x70_label1->setDataBits(dataBits); + add_esp_0x70_label1->setComment(add_esp_0x70_label1->getDisassembly()); + addInstruction(add_esp_0x70_label1, dataBits, popf_label1, NULL); + addPopf(popf_label1, popa_label1); + + if(len==32){ + Instruction_t* mov0x7FFFFFFF = allocateNewInstruction(fileID, func); + Instruction_t* fstpST0 =allocateNewInstruction(fileID, func); + Instruction_t* jmpOriginalInstNext = allocateNewInstruction(fileID, func); + + addPopa(popa_label1, mov0x7FFFFFFF); + string instrStr= originalInstrumentInstr->getDisassembly(); + string addExpr = instrStr.substr(instrStr.find(" ")+1); + mov0x7FFFFFFF->Assemble("mov "+ addExpr + ", 0x7FFFFFFF"); + mov0x7FFFFFFF->setComment(mov0x7FFFFFFF->getDisassembly()); + addInstruction(mov0x7FFFFFFF, mov0x7FFFFFFF->GetDataBits(), fstpST0, NULL); + popa_label1->setComment("just before " + mov0x7FFFFFFF->getDisassembly()); + + dataBits.resize(2);//fstp st(0) + dataBits[0] = 0xDD; + dataBits[1] = 0xD8; + fstpST0->setDataBits(dataBits); + fstpST0->setFallthrough(jmpOriginalInstNext); + addInstruction(fstpST0, dataBits, jmpOriginalInstNext, NULL); + + dataBits.resize(2); + dataBits[0] = 0xeb; + addInstruction(jmpOriginalInstNext,dataBits,NULL, originalInstrumentInstr->getFallthrough()); + } + else{ + Instruction_t* mov0x7FFF = allocateNewInstruction(fileID, func); + Instruction_t* fstpST0 =allocateNewInstruction(fileID, func); + Instruction_t* jmpOriginalInstNext = allocateNewInstruction(fileID, func); + + addPopa(popa_label1, mov0x7FFF); + string instrStr= originalInstrumentInstr->getDisassembly(); + string addExpr = instrStr.substr(instrStr.find(" ")+1); + mov0x7FFF->Assemble("mov "+ addExpr + ", 0x7FFF"); + mov0x7FFF->setComment(mov0x7FFF->getDisassembly()); + + //mov0x7FFF->setFallthrough(fstpST0); + addInstruction(mov0x7FFF, mov0x7FFF->GetDataBits(), fstpST0, NULL); + + dataBits.resize(2);//fstp st(0) + dataBits[0] = 0xDD; + dataBits[1] = 0xD8; + + fstpST0->setDataBits(dataBits); + fstpST0->setFallthrough(jmpOriginalInstNext); + addInstruction(fstpST0, dataBits, jmpOriginalInstNext, NULL); + + dataBits.resize(2); + dataBits[0] = 0xeb; + addInstruction(jmpOriginalInstNext,dataBits,NULL, originalInstrumentInstr->getFallthrough()); + } + + dataBits.resize(6);//add esp,0x70 + dataBits[0] = 0x81; + dataBits[1] = 0xc4; + dataBits[2] = 0x70; + dataBits[3] = 0x00; + dataBits[4] = 0x00; + dataBits[5] = 0x00; + add_esp_0x70_label2->setFallthrough(popf_label2); + add_esp_0x70_label2->setDataBits(dataBits); + add_esp_0x70_label2->setComment(add_esp_0x70_label2->getDisassembly()); + addInstruction(add_esp_0x70_label2, dataBits, popf_label2, NULL); + + addPopf(popf_label2, popa_label2); + if(len==32){ + Instruction_t* mov0x80000000 = allocateNewInstruction(fileID, func); + Instruction_t* fstpST0 =allocateNewInstruction(fileID, func); + Instruction_t* jmpOriginalInstNext = allocateNewInstruction(fileID, func); + + addPopa(popa_label2, mov0x80000000); + string instrStr= originalInstrumentInstr->getDisassembly(); + string addExpr = instrStr.substr(instrStr.find(" ")+1); + mov0x80000000->Assemble("mov "+ addExpr + ", 0x80000001"); + mov0x80000000->setComment(mov0x80000000->getDisassembly()); + mov0x80000000->setFallthrough(fstpST0); + addInstruction(mov0x80000000, mov0x80000000->GetDataBits(), fstpST0, NULL); + + dataBits.resize(2);//fstp st(0) + dataBits[0] = 0xDD; + dataBits[1] = 0xD8; + + addInstruction(fstpST0, dataBits, jmpOriginalInstNext, NULL); + + dataBits.resize(2); + dataBits[0] = 0xeb; + addInstruction(jmpOriginalInstNext,dataBits,NULL, originalInstrumentInstr->getFallthrough()); + } + else{ + Instruction_t* mov0x8000 = allocateNewInstruction(fileID, func); + Instruction_t* fstpST0 =allocateNewInstruction(fileID, func); + Instruction_t* jmpOriginalInstNext = allocateNewInstruction(fileID, func); + + addPopa(popa_label2, mov0x8000); + string instrStr= originalInstrumentInstr->getDisassembly(); + string addExpr = instrStr.substr(instrStr.find(" ")+1); + mov0x8000->Assemble("mov "+ addExpr + ", 0x8001"); + mov0x8000->setComment(mov0x8000->getDisassembly()); + + addInstruction(mov0x8000, mov0x8000->GetDataBits(), fstpST0, NULL); + + dataBits.resize(2);//fstp st(0) + dataBits[0] = 0xDD; + dataBits[1] = 0xD8; + + addInstruction(fstpST0, dataBits, jmpOriginalInstNext, NULL); + dataBits.resize(2); + dataBits[0] = 0xeb; + addInstruction(jmpOriginalInstNext,dataBits,NULL, originalInstrumentInstr->getFallthrough()); + } + + m_numFP++; + return; +} + +void IntegerTransform32::addFistTruncationCheck(Instruction_t *p_instruction, int len){ + if(len!=32 && len!=16) return; + DatabaseID_t fileID = p_instruction->getAddress()->getFileID(); + Function_t* func = p_instruction->GetFunction(); + string dataBits; + + //Fist dword [esp+0x28]; + + /* + pusha + pushf + sub esp, 4 + fstp dword [esp] + push_ret //call some_func + test eax, 0 + jz_eax_0 label0 + + test eax, 1 + jz_eax_1 label1 + + label2: + add esp, 4 + ;; negtive min + mov [esp+0x28], 0x80000001 + + + label0: + + add esp, 4 + popf + popa + Fist dword [esp+0x28] + + label1: ;;positive max + add esp, 4 + popf + popa + mov [esp+0x28], 0x7FFFFFFF + + */ + + Instruction_t* pusha_i = allocateNewInstruction(fileID, func); + Instruction_t* pushf_i = allocateNewInstruction(fileID, func); + Instruction_t* sub_esp_0x70 = allocateNewInstruction(fileID, func); //81 ec 70 00 00 00 + Instruction_t* fst_esp = allocateNewInstruction(fileID, func);//d9 14 24 + // fsave [esp+4] + Instruction_t* fsave_wait = allocateNewInstruction(fileID, func);//9b + Instruction_t* fsave_esp_4 = allocateNewInstruction(fileID, func);//dd 74 24 04 + Instruction_t* pushretaddress = allocateNewInstruction(fileID, func); + Instruction_t* frstor_esp_4 = allocateNewInstruction(fileID, func);//67 dd 64 24 04 + + Instruction_t* test_eax_0 = allocateNewInstruction(fileID, func); + Instruction_t* test_eax_1 = allocateNewInstruction(fileID, func); + + Instruction_t* jz_eax_0 = allocateNewInstruction(fileID, func); + Instruction_t* jz_eax_1 = allocateNewInstruction(fileID, func); + + + Instruction_t* add_esp_0x70_label0 = allocateNewInstruction(fileID, func); + Instruction_t* add_esp_0x70_label1 = allocateNewInstruction(fileID, func); + Instruction_t* add_esp_0x70_label2 = allocateNewInstruction(fileID, func); + + Instruction_t* popf_label0 = allocateNewInstruction(fileID, func); + Instruction_t* popa_label0 = allocateNewInstruction(fileID, func); + + Instruction_t* popf_label1 = allocateNewInstruction(fileID, func); + Instruction_t* popa_label1 = allocateNewInstruction(fileID, func); + + Instruction_t* popf_label2 = allocateNewInstruction(fileID, func); + Instruction_t* popa_label2 = allocateNewInstruction(fileID, func); + Instruction_t* nop = allocateNewInstruction(fileID, func); + + + addPusha(pusha_i, pushf_i);//pusha + Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, pusha_i); + pusha_i->setFallthrough(pushf_i); + + addPushf(pushf_i, sub_esp_0x70);//pushf + + dataBits.resize(6);//sub esp,0x70 + dataBits[0] = 0x81; + dataBits[1] = 0xec; + dataBits[2] = 0x70; + dataBits[3] = 0x00; + dataBits[4] = 0x00; + dataBits[5] = 0x00; + sub_esp_0x70->setFallthrough(fst_esp); + sub_esp_0x70->setDataBits(dataBits); + sub_esp_0x70->setComment(sub_esp_0x70->getDisassembly()); + addInstruction(sub_esp_0x70, dataBits, fst_esp, NULL); + + dataBits.resize(3);//fst [esp] + dataBits[0] = 0xd9; + dataBits[1] = 0x14; + dataBits[2] = 0x24; + fst_esp->setFallthrough(fsave_esp_4); + fst_esp->setDataBits(dataBits); + fst_esp->setComment(fst_esp->getDisassembly()); + addInstruction(fst_esp, dataBits, fsave_esp_4, NULL); + dataBits.resize(1);//fsave [esp+4] + dataBits[0] = 0x9b; + fsave_esp_4->setFallthrough(pushretaddress); + fsave_esp_4->setDataBits(dataBits); + fsave_esp_4->setComment(fsave_wait->getDisassembly()); + addInstruction(fsave_wait, dataBits, fsave_esp_4, NULL); + dataBits.resize(4); + dataBits[0] = 0xdd; + dataBits[1] = 0x74; + dataBits[2] = 0x24; + dataBits[3] = 0x04; + fsave_esp_4->setFallthrough(pushretaddress); + fsave_esp_4->setDataBits(dataBits); + fsave_esp_4->setComment(fsave_esp_4->getDisassembly()); + addInstruction(fsave_esp_4, dataBits, pushretaddress, NULL); + + virtual_offset_t AfterTheCheckerReturn = getAvailableAddress(); + nop->getAddress()->SetVirtualOffset(AfterTheCheckerReturn); + nop->getAddress()->SetFileID(BaseObj_t::NOT_IN_DATABASE); + + dataBits.resize(5);//push return_address + dataBits[0] = 0x68; + virtual_offset_t *tmp; + tmp = (virtual_offset_t *) &dataBits[1]; + *tmp = AfterTheCheckerReturn; + pushretaddress->setDataBits(dataBits); + pushretaddress->setComment(pushretaddress->getDisassembly()); + pushretaddress->setFallthrough(nop); + + + dataBits.resize(1);//nop + dataBits[0] = 0x90; + nop->setDataBits(dataBits); + nop->setComment(nop->getDisassembly() + " -- with callback to floating number check") ; + nop->setFallthrough(frstor_esp_4); + nop->SetIndirectBranchTargetAddress(nop->getAddress()); + if(len==32) + nop->SetCallback(string("FloatingRangeCheck32")); + else + nop->SetCallback(string("FloatingRangeCheck16")); + + dataBits.resize(4);//frstor [esp+4] + dataBits[0] = 0xdd; + dataBits[1] = 0x64; + dataBits[2] = 0x24; + dataBits[3] = 0x04; + frstor_esp_4->setDataBits(dataBits); + frstor_esp_4->setFallthrough(test_eax_0); + frstor_esp_4->setComment(frstor_esp_4->getDisassembly()); + dataBits.resize(2);//test eax, eax + dataBits[0] = 0x85; + dataBits[1] = 0xC0; + test_eax_0->setDataBits(dataBits); + test_eax_0->setFallthrough(jz_eax_0); + addInstruction(test_eax_0, dataBits, jz_eax_0, NULL); + addJz(jz_eax_0, test_eax_1, add_esp_0x70_label0); + + + //label 0: + Instruction_t* jmpOriginalInst = allocateNewInstruction(fileID, func); + + dataBits.resize(6);//add esp,0x70 + dataBits[0] = 0x81; + dataBits[1] = 0xc4; + dataBits[2] = 0x70; + dataBits[3] = 0x00; + dataBits[4] = 0x00; + dataBits[5] = 0x00; + add_esp_0x70_label0->setFallthrough(popf_label0); + add_esp_0x70_label0->setDataBits(dataBits); + add_esp_0x70_label0->setComment(add_esp_0x70_label0->getDisassembly()); + addInstruction(add_esp_0x70_label0, dataBits, popf_label0, NULL); + + addPopf(popf_label0, popa_label0); + addPopa(popa_label0, jmpOriginalInst); + + + dataBits.resize(2); + dataBits[0] = 0xeb; + jmpOriginalInst->setComment("Jump to original Inst"); + addInstruction(jmpOriginalInst,dataBits,NULL, originalInstrumentInstr); + + //label 1: + + dataBits.resize(5);//test eax, 1 + dataBits[0] = 0xA9; + dataBits[1] = 0x01; + dataBits[2] = 0x00; + dataBits[3] = 0x00; + dataBits[4] = 0x00; + test_eax_1->setDataBits(dataBits); + test_eax_1->setComment(test_eax_1->getDisassembly()) ; + test_eax_1->setFallthrough(jz_eax_1); + addInstruction(test_eax_1, dataBits, jz_eax_1, NULL); + addJz(jz_eax_1, add_esp_0x70_label1, add_esp_0x70_label2); + + + dataBits.resize(6);//add esp,0x70 + dataBits[0] = 0x81; + dataBits[1] = 0xc4; + dataBits[2] = 0x70; + dataBits[3] = 0x00; + dataBits[4] = 0x00; + dataBits[5] = 0x00; + add_esp_0x70_label1->setFallthrough(popf_label1); + add_esp_0x70_label1->setDataBits(dataBits); + add_esp_0x70_label1->setComment(add_esp_0x70_label1->getDisassembly()); + addInstruction(add_esp_0x70_label1, dataBits, popf_label1, NULL); + addPopf(popf_label1, popa_label1); + + if(len==32){ + Instruction_t* mov0x7FFFFFFF = allocateNewInstruction(fileID, func); + //Instruction_t* fstpST0 =allocateNewInstruction(fileID, func); + Instruction_t* jmpOriginalInstNext = allocateNewInstruction(fileID, func); + + addPopa(popa_label1, mov0x7FFFFFFF); + string instrStr= originalInstrumentInstr->getDisassembly(); + string addExpr = instrStr.substr(instrStr.find(" ")+1); + mov0x7FFFFFFF->Assemble("mov "+ addExpr + ", 0x7FFFFFFF"); + mov0x7FFFFFFF->setComment(mov0x7FFFFFFF->getDisassembly()); + addInstruction(mov0x7FFFFFFF, mov0x7FFFFFFF->GetDataBits(), jmpOriginalInstNext, NULL); + popa_label1->setComment("just before " + mov0x7FFFFFFF->getDisassembly()); + + //dataBits.resize(2);//fstp st(0) + //dataBits[0] = 0xDD; + //dataBits[1] = 0xD8; + //fstpST0->setDataBits(dataBits); + //fstpST0->setFallthrough(jmpOriginalInstNext); + //addInstruction(fstpST0, dataBits, jmpOriginalInstNext, NULL); + + dataBits.resize(2); + dataBits[0] = 0xeb; + addInstruction(jmpOriginalInstNext,dataBits,NULL, originalInstrumentInstr->getFallthrough()); + } + else{ + Instruction_t* mov0x7FFF = allocateNewInstruction(fileID, func); + //Instruction_t* fstpST0 =allocateNewInstruction(fileID, func); + Instruction_t* jmpOriginalInstNext = allocateNewInstruction(fileID, func); + + addPopa(popa_label1, mov0x7FFF); + string instrStr= originalInstrumentInstr->getDisassembly(); + string addExpr = instrStr.substr(instrStr.find(" ")+1); + mov0x7FFF->Assemble("mov "+ addExpr + ", 0x7FFF"); + mov0x7FFF->setComment(mov0x7FFF->getDisassembly()); + + //mov0x7FFF->setFallthrough(fstpST0); + addInstruction(mov0x7FFF, mov0x7FFF->GetDataBits(), jmpOriginalInstNext, NULL); + + //dataBits.resize(2);//fstp st(0) + //dataBits[0] = 0xDD; + //dataBits[1] = 0xD8; + + //fstpST0->setDataBits(dataBits); + //fstpST0->setFallthrough(jmpOriginalInstNext); + //addInstruction(fstpST0, dataBits, jmpOriginalInstNext, NULL); + + dataBits.resize(2); + dataBits[0] = 0xeb; + addInstruction(jmpOriginalInstNext,dataBits,NULL, originalInstrumentInstr->getFallthrough()); + } + + dataBits.resize(6);//add esp,0x70 + dataBits[0] = 0x81; + dataBits[1] = 0xc4; + dataBits[2] = 0x70; + dataBits[3] = 0x00; + dataBits[4] = 0x00; + dataBits[5] = 0x00; + add_esp_0x70_label2->setFallthrough(popf_label2); + add_esp_0x70_label2->setDataBits(dataBits); + add_esp_0x70_label2->setComment(add_esp_0x70_label2->getDisassembly()); + addInstruction(add_esp_0x70_label2, dataBits, popf_label2, NULL); + + addPopf(popf_label2, popa_label2); + if(len==32){ + Instruction_t* mov0x80000000 = allocateNewInstruction(fileID, func); + //Instruction_t* fstpST0 =allocateNewInstruction(fileID, func); + Instruction_t* jmpOriginalInstNext = allocateNewInstruction(fileID, func); + + addPopa(popa_label2, mov0x80000000); + string instrStr= originalInstrumentInstr->getDisassembly(); + string addExpr = instrStr.substr(instrStr.find(" ")+1); + mov0x80000000->Assemble("mov "+ addExpr + ", 0x80000001"); + mov0x80000000->setComment(mov0x80000000->getDisassembly()); + //mov0x80000000->setFallthrough(fstpST0); + addInstruction(mov0x80000000, mov0x80000000->GetDataBits(), jmpOriginalInstNext, NULL); + + //dataBits.resize(2);//fstp st(0) + //dataBits[0] = 0xDD; + //dataBits[1] = 0xD8; + + //addInstruction(fstpST0, dataBits, jmpOriginalInstNext, NULL); + + dataBits.resize(2); + dataBits[0] = 0xeb; + addInstruction(jmpOriginalInstNext,dataBits,NULL, originalInstrumentInstr->getFallthrough()); + } + else{ + Instruction_t* mov0x8000 = allocateNewInstruction(fileID, func); + Instruction_t* fstpST0 =allocateNewInstruction(fileID, func); + Instruction_t* jmpOriginalInstNext = allocateNewInstruction(fileID, func); + + addPopa(popa_label2, mov0x8000); + string instrStr= originalInstrumentInstr->getDisassembly(); + string addExpr = instrStr.substr(instrStr.find(" ")+1); + mov0x8000->Assemble("mov "+ addExpr + ", 0x8001"); + mov0x8000->setComment(mov0x8000->getDisassembly()); + + addInstruction(mov0x8000, mov0x8000->GetDataBits(), jmpOriginalInstNext, NULL); + + //dataBits.resize(2);//fstp st(0) + //dataBits[0] = 0xDD; + //dataBits[1] = 0xD8; + + //addInstruction(fstpST0, dataBits, jmpOriginalInstNext, NULL); + dataBits.resize(2); + dataBits[0] = 0xeb; + addInstruction(jmpOriginalInstNext,dataBits,NULL, originalInstrumentInstr->getFallthrough()); + } + + m_numFP++; + return; +} + +void IntegerTransform32::handleTruncation(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) +{ + if (p_annotation.getTruncationFromWidth() == 32) + { + if (p_annotation.getTruncationToWidth() == 8 || p_annotation.getTruncationToWidth() == 16) + { + addTruncationCheck(p_instruction, p_annotation, p_policy); + } + else + { + cerr << __func__ << ": TRUNCATION annotation not yet handled: " << p_annotation.toString() << "fromWidth: " << p_annotation.getTruncationFromWidth() << " toWidth: " << p_annotation.getTruncationToWidth() << endl; + } + } +} + +// +// before: after: +// <inst> nop (with callback handler) +// <inst> +// +void IntegerTransform32::handleInfiniteLoop(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) +{ + assert(getFileIR() && p_instruction); + + logMessage(__func__, "handling infinite loop"); + + DatabaseID_t fileID = p_instruction->getAddress()->getFileID(); + Function_t* func = p_instruction->GetFunction(); + + AddressID_t *originalAddress = p_instruction->getAddress(); + Instruction_t* nop_i = allocateNewInstruction(fileID, func); + + addNop(nop_i, p_instruction); + Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, nop_i); + + addCallbackHandler(string(INFINITE_LOOP_DETECTOR), originalInstrumentInstr, nop_i, nop_i->getFallthrough(), p_policy, originalAddress); +} + +// +// <instruction to instrument> +// jno <originalFallthroughInstruction> +// pusha +// pushf +// push_arg <address original instruction> +// push L1 +// ... setup detector ... +// L1: pop_arg +// popf +// popa +// +// 20111024 Current policy: +// imul, mul -- always check using jno +// add, sub -- use signedness information annotation to emit either jno, jnc +// +// p_addressOriginalInstruction is set when we call method from lea instrumentation +void IntegerTransform32::addOverflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) +{ + assert(getFileIR() && p_instruction && p_instruction->getFallthrough()); + + RegisterName targetReg = getTargetRegister(p_instruction); + if (targetReg == rn_UNKNOWN) + { + logMessage(__func__, "OVERFLOW UNKNOWN SIGN: unknown register -- skip instrumentation"); + if (p_annotation.isUnderflow()) + m_numUnderflowsSkipped++; + else + m_numOverflowsSkipped++; + return; + } + +cerr << __func__ << ": instr: " << p_instruction->getDisassembly() << " address: " << std::hex << p_instruction->getAddress() << " annotation: " << p_annotation.toString() << " policy: " << p_policy << endl; + + string detector(INTEGER_OVERFLOW_DETECTOR); + string dataBits; + + // old style of setting up these params + // update to cleaner style + Function_t* origFunction = p_instruction->GetFunction(); + AddressID_t *jncond_a =new AddressID_t; + jncond_a->SetFileID(p_instruction->getAddress()->getFileID()); + Instruction_t* jncond_i = new Instruction_t; + jncond_i->SetFunction(origFunction); + jncond_i->SetAddress(jncond_a); + + // set fallthrough for the original instruction + Instruction_t* nextOrig_i = p_instruction->getFallthrough(); + p_instruction->setFallthrough(jncond_i); + + // jncond + dataBits.resize(2); + if (isMultiplyInstruction(p_instruction)) + { + dataBits[0] = 0x71; // jno + dataBits[1] = 0x00; // value doesn't matter, we will fill it in later + if (p_annotation.getBitWidth() == 32) + detector = string(MUL_OVERFLOW_DETECTOR_32); + else if (p_annotation.getBitWidth() == 16) + detector = string(MUL_OVERFLOW_DETECTOR_16); + else if (p_annotation.getBitWidth() == 8) + detector = string(MUL_OVERFLOW_DETECTOR_8); + cerr << "integertransform: MUL OVERFLOW: " << detector << endl; + } + else if (p_annotation.isUnsigned()) + { + dataBits[0] = 0x73; // jnc + dataBits[1] = 0x00; // value doesn't matter, we will fill it in later + + if (p_annotation.getBitWidth() == 32) + detector = string(ADDSUB_OVERFLOW_DETECTOR_UNSIGNED_32); + else if (p_annotation.getBitWidth() == 16) + detector = string(ADDSUB_OVERFLOW_DETECTOR_UNSIGNED_16); + else if (p_annotation.getBitWidth() == 8) + detector = string(ADDSUB_OVERFLOW_DETECTOR_UNSIGNED_8); + cerr << "integertransform: UNSIGNED OVERFLOW: " << detector << endl; + } + else + { + dataBits[0] = 0x71; // jno + dataBits[1] = 0x00; // value doesn't matter, we will fill it in later + + if (p_annotation.getBitWidth() == 32) + detector = string(ADDSUB_OVERFLOW_DETECTOR_SIGNED_32); + else if (p_annotation.getBitWidth() == 16) + detector = string(ADDSUB_OVERFLOW_DETECTOR_SIGNED_16); + else if (p_annotation.getBitWidth() == 8) + detector = string(ADDSUB_OVERFLOW_DETECTOR_SIGNED_8); + cerr << "integertransform: SIGNED OVERFLOW: " << detector << endl; + } + + jncond_i->setDataBits(dataBits); + jncond_i->setComment(jncond_i->getDisassembly()); + jncond_i->setTarget(nextOrig_i); + + p_instruction->setFallthrough(jncond_i); + + if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) + { + // implement saturating arithmetic, e.g.: + // mov <reg>, value + Instruction_t* saturate_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); + + if (p_annotation.flowsIntoCriticalSink() && p_annotation.getBitWidth() == 32) + { + logMessage(__func__, "OVERFLOW UNSIGNED 32: CRITICAL SINK: saturate by masking"); + + DatabaseID_t fileID = p_instruction->getAddress()->getFileID(); + Function_t* func = p_instruction->GetFunction(); + Instruction_t* pushf_i = allocateNewInstruction(fileID, func); + Instruction_t* popf_i = allocateNewInstruction(fileID, func); + addCallbackHandler(detector, p_instruction, jncond_i, pushf_i, p_policy); + addPushf(pushf_i, saturate_i); + addAndRegister32Mask(saturate_i, targetReg, 0x00FFFFFF, popf_i); + addPopf(popf_i, nextOrig_i); + } + else + { + addCallbackHandler(detector, p_instruction, jncond_i, saturate_i, p_policy); + addMaxSaturation(saturate_i, targetReg, p_annotation, nextOrig_i); + } + } + else + { + addCallbackHandler(detector, p_instruction, jncond_i, nextOrig_i, p_policy); + } + + getFileIR()->getAddresses().insert(jncond_a); + getFileIR()->GetInstructions().insert(jncond_i); + + if (p_annotation.isUnderflow()) + m_numUnderflows++; + else + m_numOverflows++; +} + +// +// <instruction to instrument> +// jno <originalFallthroughInstruction> +// pusha +// pushf +// push_arg <address original instruction> +// push L1 +// ... setup detector ... +// L1: pop_arg +// popf +// popa +// +// 20111024 Current policy: +// add, sub -- use signedness information annotation to emit either jno, jnc +// +void IntegerTransform32::addUnderflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) +{ + assert(getFileIR() && p_instruction); + + RegisterName targetReg = getTargetRegister(p_instruction); + if (targetReg == rn_UNKNOWN) + { + cerr << "IntegerTransform32::addUnderflowCheck(): instr: " << p_instruction->getDisassembly() << " address: " << p_instruction->getAddress() << " annotation: " << p_annotation.toString() << "-- SKIP b/c no target registers" << endl; + m_numUnderflowsSkipped++; + return; + } + + cerr << "IntegerTransform32::addUnderflowCheck(): instr: " << p_instruction->getDisassembly() << " address: " << p_instruction->getAddress() << " annotation: " << p_annotation.toString() << endl; + + string detector(INTEGER_OVERFLOW_DETECTOR); + string dataBits; + + // old style of setting up these params + // update to cleaner style + Function_t* origFunction = p_instruction->GetFunction(); + AddressID_t *jncond_a =new AddressID_t; + jncond_a->SetFileID(p_instruction->getAddress()->getFileID()); + Instruction_t* jncond_i = new Instruction_t; + jncond_i->SetFunction(origFunction); + jncond_i->SetAddress(jncond_a); + + // set fallthrough for the original instruction + Instruction_t* nextOrig_i = p_instruction->getFallthrough(); + p_instruction->setFallthrough(jncond_i); + + // jncond + dataBits.resize(2); + if (p_annotation.isUnsigned()) + { + dataBits[0] = 0x73; // jnc + dataBits[1] = 0x00; // value doesn't matter, we will fill it in later + + if (p_annotation.getBitWidth() == 32) + detector = string(UNDERFLOW_DETECTOR_UNSIGNED_32); + else if (p_annotation.getBitWidth() == 16) + detector = string(UNDERFLOW_DETECTOR_UNSIGNED_16); + else if (p_annotation.getBitWidth() == 8) + detector = string(UNDERFLOW_DETECTOR_UNSIGNED_8); + cerr << "integertransform: UNSIGNED OVERFLOW: " << detector << endl; + } + else if (p_annotation.isSigned()) + { + dataBits[0] = 0x71; // jno + dataBits[1] = 0x00; // value doesn't matter, we will fill it in later + + if (p_annotation.getBitWidth() == 32) + detector = string(UNDERFLOW_DETECTOR_SIGNED_32); + else if (p_annotation.getBitWidth() == 16) + detector = string(UNDERFLOW_DETECTOR_SIGNED_16); + else if (p_annotation.getBitWidth() == 8) + detector = string(UNDERFLOW_DETECTOR_SIGNED_8); + + cerr << "integertransform: SIGNED UNDERFLOW: " << detector << endl; + } + else + { + dataBits[0] = 0x71; // jno + dataBits[1] = 0x00; // value doesn't matter, we will fill it in later + + if (p_annotation.getBitWidth() == 32) + detector = string(UNDERFLOW_DETECTOR_32); + else if (p_annotation.getBitWidth() == 16) + detector = string(UNDERFLOW_DETECTOR_16); + else if (p_annotation.getBitWidth() == 8) + detector = string(UNDERFLOW_DETECTOR_8); + cerr << "integertransform: UNDERFLOW UNKONWN: assume signed for now: " << detector << endl; + } + + jncond_i->setDataBits(dataBits); + jncond_i->setComment(jncond_i->getDisassembly()); + jncond_i->setTarget(nextOrig_i); + + p_instruction->setFallthrough(jncond_i); + + if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) + { + // implement saturating arithmetic, e.g.: + // mov <reg>, value + Instruction_t* saturate_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); + + addCallbackHandler(detector, p_instruction, jncond_i, saturate_i, p_policy); + addMinSaturation(saturate_i, targetReg, p_annotation, nextOrig_i); + } + else + { + addCallbackHandler(detector, p_instruction, jncond_i, nextOrig_i, p_policy); + } + + getFileIR()->getAddresses().insert(jncond_a); + getFileIR()->GetInstructions().insert(jncond_i); + + m_numUnderflows++; +} + + +// +// STARS has extensive discussion of the logic behind truncation and +// signedness annotations in module SMPInstr.cpp, method EmitIntegerErrorAnnotation(). +// The possible combinations are categorized in terms of the instrumentation +// needed at run time: +// CHECK TRUNCATION UNSIGNED : discarded bits must be all zeroes. +// CHECK TRUNCATION SIGNED: discarded bits must be sign-extension of stored bits. +// CHECK TRUNCATION UNKNOWNSIGN: discarded bits must be all zeroes, OR must +// be the sign-extension of the stored bits. +// All truncation annotations are emitted on stores (mov opcodes in x86). +// Other possibilities might be handled in the future. +// +void IntegerTransform32::addTruncationCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) +{ + assert(getFileIR() && p_instruction); + assert(p_annotation.getTruncationFromWidth() == 32 && p_annotation.getTruncationToWidth() == 8 || p_annotation.getTruncationToWidth() == 16); + + cerr << __func__ << ": instr: " << p_instruction->getDisassembly() << " address: " << p_instruction->getAddress() << " annotation: " << p_annotation.toString() << " policy: " << p_policy << endl; + + string detector; + + // Complicated case: + // 80484ed 3 INSTR CHECK TRUNCATION UNKNOWNSIGN 32 EAX 8 AL ZZ mov [ebp+var_4], al + // example: for unknownsign truncation - 8 bit on AL + // it's ok if 24 upper bits are sign-extension or all 0's + // Re-phrased: upper 24 are 0s, upper 25 are 0s, upper 25 are 1s + // are all OK in the UNKNOWNSIGN case + // Note that upper 24 are 0's means no need to check for the + // case where the upper 25 are 0's; already OK. + // + // <save flags> + // test eax, 0xFFFFFF00 ; (for 8 bit) + // jz <continue> ; upper 24 bits are 0's + // + // cmp eax, 0xFFFFFF80 ;(for 8 bit) + // jae continue ; upper 25 bits are 1's + // (invoke truncation handler) + // nop ; truncation handler returns here + // SAT: saturating-arithmetic ; optional + // + // continue: <restore flags> + // mov [ebp+var_4], al ; <originalInstruction> + // + + // Unsigned case: + // 80484ed 3 INSTR CHECK TRUNCATION UNSIGNED 32 EAX 8 AL ZZ mov [ebp+var_4], al + // example: for unsigned truncation - 8 bit on AL + // it's ok if 24 upper bits are all 0's + // + // <save flags> + // test eax, 0xFFFFFF00 ; (for 8 bit) + // jz <continue> ; upper 24 bits are 0's + // + // (invoke truncation handler) + // nop ; truncation handler returns here + // SAT: saturating-arithmetic ; optional + // + // continue: <restore flags> + // mov [ebp+var_4], al ; <originalInstruction> + // + + DatabaseID_t fileID = p_instruction->getAddress()->getFileID(); + Function_t* func = p_instruction->GetFunction(); + AddressID_t *saveAddress = p_instruction->getAddress(); + + Instruction_t* pushf_i = allocateNewInstruction(fileID, func); + Instruction_t* test_i = allocateNewInstruction(fileID, func); + Instruction_t* jz_i = allocateNewInstruction(fileID, func); + Instruction_t* saturate_i = NULL; + Instruction_t* popf_i = allocateNewInstruction(fileID, func); + + if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) { + saturate_i = allocateNewInstruction(fileID, func); + addMaxSaturation(saturate_i, p_annotation.getRegister(), p_annotation, popf_i); + } + + addPushf(pushf_i, test_i); + Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, pushf_i); + pushf_i->setFallthrough(test_i); + pushf_i->setComment("-- in truncation"); + originalInstrumentInstr->setComment("-- in truncation (was original)"); + + unsigned mask = 0; + unsigned mask2 = 0; + if (p_annotation.getTruncationToWidth() == 16) { + mask = 0xFFFF0000; + mask2 = 0xFFFF8000; + if(p_annotation.flowsIntoCriticalSink()){ + cerr <<"find flowsIntoCriticalSink in addTruncationCheck" <<endl; + detector = "forceSoupToExit"; + } + else if (p_annotation.isUnsigned()) + detector = string(TRUNCATION_DETECTOR_UNSIGNED_32_16); + else if (p_annotation.isSigned()) + detector = string(TRUNCATION_DETECTOR_SIGNED_32_16); + else + detector = string(TRUNCATION_DETECTOR_32_16); + } + else if (p_annotation.getTruncationToWidth() == 8) { + mask = 0xFFFFFF00; + mask2 = 0xFFFFFF80; + if(p_annotation.flowsIntoCriticalSink()){ + cerr <<"find flowsIntoCriticalSink in addTruncationCheck" <<endl; + detector = "forceSoupToExit"; + } + else if (p_annotation.isUnsigned()) + detector = string(TRUNCATION_DETECTOR_UNSIGNED_32_8); + else if (p_annotation.isSigned()) + detector = string(TRUNCATION_DETECTOR_SIGNED_32_8); + else + detector = string(TRUNCATION_DETECTOR_32_8); + } + + if (p_annotation.isUnsigned()) { + addTestRegisterMask(test_i, p_annotation.getRegister(), mask, jz_i); + Instruction_t* nop_i = allocateNewInstruction(fileID, func); + addJz(jz_i, nop_i, popf_i); // target = popf_i, fall-through = nop_i + + if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) { + addNop(nop_i, saturate_i); + nop_i->setComment("UNSIGNED TRUNC: fallthrough: saturating arithmetic instruction"); + addCallbackHandler(detector, originalInstrumentInstr, nop_i, saturate_i, p_policy, saveAddress); + } + else { + addNop(nop_i, popf_i); + nop_i->setComment(string("UNSIGNED TRUNC: fallthrough: popf")); + addCallbackHandler(detector, originalInstrumentInstr, nop_i, popf_i, p_policy, saveAddress); + } + } + else { + // Signed and unknown signed cases are almost identical: + // 80484ed 3 INSTR CHECK TRUNCATION SIGNED 32 EAX 8 AL ZZ mov [ebp+var_4], al + // 80484ed 3 INSTR CHECK TRUNCATION UNKNOWNSIGN 32 EAX 8 AL ZZ mov [ebp+var_4], al + // example: for signed truncation - 8 bit on AL + // it's ok if 25 upper bits are all 1's or all 0's + // example: for unknownsign truncation - 8 bit on AL + // it's ok if 25 upper bits are all 1's or 24 upper bits all 0's + // + // <save flags> + // test eax, 0xFFFFFF80 ; (for 8 bit) 0xFFFFFF00 for UNKNOWN + // jz <continue> ; upper 25 bits are 0's + // + // cmp eax, 0xFFFFFF80 ;(for 8 bit) + // jae continue ; upper 25 bits are 1's + // (invoke truncation handler) + // nop ; truncation handler callback here + // SAT: saturating-arithmetic ; optional + // + // continue: <restore flags> + // mov [ebp+var_4], al ; <originalInstruction> + // + + if (p_annotation.isSigned()) { + addTestRegisterMask(test_i, p_annotation.getRegister(), mask2, jz_i); + } + else { // must be UNKNOWNSIGN + addTestRegisterMask(test_i, p_annotation.getRegister(), mask, jz_i); + } + Instruction_t* nop_i = allocateNewInstruction(fileID, func); + Instruction_t* s_cmp_i = allocateNewInstruction(fileID, func); + Instruction_t* s_jae_i = allocateNewInstruction(fileID, func); + + addJz(jz_i, s_cmp_i, popf_i); // target = popf_i, fall-through = s_cmp_i + jz_i->setComment(string("jz - SIGNED or UNKNOWNSIGN TRUNC")); + addCmpRegisterMask(s_cmp_i, p_annotation.getRegister(), mask2, s_jae_i); + addJae(s_jae_i, nop_i, popf_i); // target = popf_i, fall-through = nop_i + s_jae_i->setComment(string("jae - SIGNED or UNKNOWNSIGN TRUNC")); + + if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) { + addNop(nop_i, saturate_i); + nop_i->setComment("SIGNED or UNKNOWNSIGN TRUNC: fallthrough: saturating arithmetic instruction"); + addCallbackHandler(detector, originalInstrumentInstr, nop_i, saturate_i, p_policy, saveAddress); + } + else { + addNop(nop_i, popf_i); + nop_i->setComment(string("SIGNED or UNKNOWNSIGN TRUNC: fallthrough: popf")); + addCallbackHandler(detector, originalInstrumentInstr, nop_i, popf_i, p_policy, saveAddress); + } + } // end of SIGNED and UNKNOWNSIGN case + addPopf(popf_i, originalInstrumentInstr); // common to all cases + + m_numTruncations++; + // cerr << "addTruncationCheck(): --- END ---" << endl; +} + +void IntegerTransform32::addSaturation(Instruction_t *p_instruction, RegisterName p_reg, unsigned p_value, const MEDS_InstructionCheckAnnotation& p_annotation, Instruction_t *p_fallthrough) +{ + assert(getFileIR() && p_instruction); + + p_instruction->setFallthrough(p_fallthrough); + + addMovRegisterUnsignedConstant(p_instruction, p_reg, p_value, p_fallthrough); +} + +void IntegerTransform32::addZeroSaturation(Instruction_t *p_instruction, RegisterName p_reg, Instruction_t *p_fallthrough) +{ + assert(getFileIR() && p_instruction); + + p_instruction->setFallthrough(p_fallthrough); + + addMovRegisterUnsignedConstant(p_instruction, p_reg, 0, p_fallthrough); +} + +// +// <instruction to instrument> +// jno <originalFallthroughInstruction> +// jnc <originalFallthroughInstruction> +// nop [attach callback handler] +// saturate target register (if policy dictates) +// <originalFallthroughInstruction> +// +void IntegerTransform32::addOverflowCheckUnknownSign(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) +{ + assert(getFileIR() && p_instruction && p_instruction->getFallthrough()); + + RegisterName targetReg = getTargetRegister(p_instruction); + if (targetReg == rn_UNKNOWN) + { + cerr << "integertransform: OVERFLOW UNKNOWN SIGN: unknown register -- skip instrumentation" << endl; + m_numOverflowsSkipped++; + return; + } + +cerr << __func__ << ": instr: " << p_instruction->getDisassembly() << " address: " << std::hex << p_instruction->getAddress() << " annotation: " << p_annotation.toString() << " policy: " << p_policy << endl; + + // set detector/handler + string detector(OVERFLOW_UNKNOWN_SIGN_DETECTOR); + if (!isMultiplyInstruction(p_instruction)) + { + if (p_annotation.getBitWidth() == 32) + detector = string(ADDSUB_OVERFLOW_DETECTOR_UNKNOWN_32); + else if (p_annotation.getBitWidth() == 16) + detector = string(ADDSUB_OVERFLOW_DETECTOR_UNKNOWN_16); + else if (p_annotation.getBitWidth() == 8) + detector = string(ADDSUB_OVERFLOW_DETECTOR_UNKNOWN_8); + } + + // for now assume we're dealing with add/sub 32 bit + DatabaseID_t fileID = p_instruction->getAddress()->getFileID(); + Function_t* func = p_instruction->GetFunction(); + + Instruction_t* jno_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); + Instruction_t* jnc_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); + Instruction_t* nop_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); + + // save fallthrough from original instruction + Instruction_t* nextOrig_i = p_instruction->getFallthrough(); + + // instrument for both jno and jnc + // redundant for imul, but that's ok, optimize later + p_instruction->setFallthrough(jno_i); + addJno(jno_i, jnc_i, nextOrig_i); + addJnc(jnc_i, nop_i, nextOrig_i); + addNop(nop_i, nextOrig_i); + + if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) + { + Instruction_t* saturate_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); + addCallbackHandler(detector, p_instruction, nop_i, saturate_i, p_policy); + addMaxSaturation(saturate_i, targetReg, p_annotation, nextOrig_i); + } + else + { + addCallbackHandler(detector, p_instruction, nop_i, nextOrig_i, p_policy); + } + + m_numOverflows++; +} + +// +// <instruction to instrument> +// jno|jnc <originalFallthroughInstruction> +// jnc <originalFallthroughInstruction> [UNKNOWNSIGN] +// pusha +// pushf +// push_arg <address original instruction> +// push L1 +// ... setup detector ... +// L1: pop_arg +// popf +// popa +// +// 20111024 Current policy: +// imul, mul -- always check using jno +// add, sub -- use signedness information annotation to emit either jno, jnc +// +// p_addressOriginalInstruction is set when we call method from lea instrumentation +void IntegerTransform32::addOverflowCheckForLea(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy, AddressID_t *p_addressOriginalInstruction) +{ + assert(getFileIR() && p_instruction && p_instruction->getFallthrough()); + +cerr << __func__ << ": comment: " << p_instruction->GetComment() << " annotation: " << p_annotation.toString() << " policy: " << p_policy << endl; + + Instruction_t* jnc_i = NULL; + string detector(INTEGER_OVERFLOW_DETECTOR); + + // this will be either jno or jnc + Instruction_t* jncond_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); + + // set fallthrough for the original instruction + Instruction_t* nextOrig_i = p_instruction->getFallthrough(); + p_instruction->setFallthrough(jncond_i); + + // jncond + int isMultiply = isMultiplyInstruction(p_instruction); + if (isMultiply) + { + // fallthrough will be set by the callback handler + addJno(jncond_i, NULL, nextOrig_i); + if (p_annotation.getBitWidth() == 32) + detector = string(MUL_OVERFLOW_DETECTOR_32); + else if (p_annotation.getBitWidth() == 16) + detector = string(MUL_OVERFLOW_DETECTOR_16); + else if (p_annotation.getBitWidth() == 8) + detector = string(MUL_OVERFLOW_DETECTOR_8); + } + else if (p_annotation.isSigned()) + { + // fallthrough will be set by the callback handler + addJno(jncond_i, NULL, nextOrig_i); + if (p_annotation.getBitWidth() == 32) + detector = string(ADDSUB_OVERFLOW_DETECTOR_UNSIGNED_32); + else if (p_annotation.getBitWidth() == 16) + detector = string(ADDSUB_OVERFLOW_DETECTOR_UNSIGNED_16); + else if (p_annotation.getBitWidth() == 8) + detector = string(ADDSUB_OVERFLOW_DETECTOR_UNSIGNED_8); + } + else if (p_annotation.isUnsigned()) + { + // fallthrough will be set by the callback handler + addJnc(jncond_i, NULL, nextOrig_i); + if (p_annotation.getBitWidth() == 32) + detector = string(ADDSUB_OVERFLOW_DETECTOR_UNSIGNED_32); + else if (p_annotation.getBitWidth() == 16) + detector = string(ADDSUB_OVERFLOW_DETECTOR_UNSIGNED_16); + else if (p_annotation.getBitWidth() == 8) + detector = string(ADDSUB_OVERFLOW_DETECTOR_UNSIGNED_8); + } + else + { + if (p_annotation.getBitWidth() == 32) + detector = string(ADDSUB_OVERFLOW_DETECTOR_UNKNOWN_32); + else if (p_annotation.getBitWidth() == 16) + detector = string(ADDSUB_OVERFLOW_DETECTOR_UNKNOWN_16); + else if (p_annotation.getBitWidth() == 8) + detector = string(ADDSUB_OVERFLOW_DETECTOR_UNKNOWN_8); + + jnc_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); + + addJno(jncond_i, jnc_i, nextOrig_i); + addJnc(jnc_i, NULL, nextOrig_i); // fallthrough will be set by the callback handler + } + + logMessage(__func__, "detector: " + detector); + + if (jnc_i) // unknown add/sub + { + logMessage(__func__, "add callback handler for unknown add/sub"); + addCallbackHandler(detector, p_instruction, jnc_i, nextOrig_i, p_policy, p_addressOriginalInstruction); + } + else + { + // mul, or signed/unsigned add/sub + logMessage(__func__, "add callback handler for mul, or signed/unsigned add/sub"); + addCallbackHandler(detector, p_instruction, jncond_i, nextOrig_i, p_policy, p_addressOriginalInstruction); + } +} + diff --git a/irdb-lib/libIRDB-transform/include-unused-delete-later/integertransform32.hpp b/irdb-lib/libIRDB-transform/include-unused-delete-later/integertransform32.hpp new file mode 100644 index 0000000000000000000000000000000000000000..4617ecfdfb3bd2195a667e5a13ed0f8ab503e43b --- /dev/null +++ b/irdb-lib/libIRDB-transform/include-unused-delete-later/integertransform32.hpp @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013, 2014 - University of Virginia + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#ifndef _LIBTRANSFORM_INTEGERTRANSFORM32_H_ +#define _LIBTRANSFORM_INTEGERTRANSFORM32_H_ + +#include "integertransform.hpp" + +namespace libTransform +{ + +using namespace std; +using namespace libIRDB; + +class IntegerTransform32 : public IntegerTransform +{ + public: + IntegerTransform32(VariantID_t *, FileIR_t*, + MEDS_Annotations_t *p_annotations, set<std::string> *p_filteredFunctions, + set<VirtualOffset> *p_warnings); + + virtual int execute(); + virtual int executePointerInstrumentation() { assert(0); } // not yet implemented + + private: + void handleOverflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy); + void handleUnderflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy); + void handleSignedness(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy); + void handleTruncation(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy); + void handleFISTTruncation(Instruction_t *p_instruction); + + void addFistpTruncationCheck(Instruction_t *p_instruction, int len); + void addFistTruncationCheck(Instruction_t *p_instruction, int len); + + void handleInfiniteLoop(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy); + + void addSignednessCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy); + void addTruncationCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy); + + void addOverflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy); + void addOverflowCheckForLea(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy, AddressID_t *p_original); + void addOverflowCheckUnknownSign(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy); + + void addUnderflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy); + + void addOverflowCheckNoFlag(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy); + void addOverflowCheckNoFlag_RegPlusReg(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const RegisterName&, const RegisterName&, const RegisterName&, int p_policy); + void addOverflowCheckNoFlag_RegPlusConstant(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const RegisterName&, int p_constantValue, const RegisterName&, int p_policy); + void addOverflowCheckNoFlag_RegTimesConstant(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const RegisterName&, int p_constantValue, const RegisterName&, int p_policy); + + void addSaturation(Instruction_t *p_instruction, RegisterName p_reg, unsigned p_value, const MEDS_InstructionCheckAnnotation& p_annotation, Instruction_t *p_fallthrough); + void addZeroSaturation(Instruction_t *p_instruction, RegisterName p_reg, Instruction_t *p_fallthrough); + +}; + +// make sure these match the function names in $STRATA/src/posix/x86_linux/detector_number_handling/overflow_detector.c + +#define INTEGER_OVERFLOW_DETECTOR "integer_overflow_detector" + +#define ADDSUB_OVERFLOW_DETECTOR_SIGNED_32 "addsub_overflow_detector_signed_32" +#define ADDSUB_OVERFLOW_DETECTOR_UNSIGNED_32 "addsub_overflow_detector_unsigned_32" +#define ADDSUB_OVERFLOW_DETECTOR_UNKNOWN_32 "addsub_overflow_detector_unknown_32" + +#define ADDSUB_OVERFLOW_DETECTOR_SIGNED_16 "addsub_overflow_detector_signed_16" +#define ADDSUB_OVERFLOW_DETECTOR_UNSIGNED_16 "addsub_overflow_detector_unsigned_16" +#define ADDSUB_OVERFLOW_DETECTOR_UNKNOWN_16 "addsub_overflow_detector_unknown_16" + +#define ADDSUB_OVERFLOW_DETECTOR_SIGNED_8 "addsub_overflow_detector_signed_8" +#define ADDSUB_OVERFLOW_DETECTOR_UNSIGNED_8 "addsub_overflow_detector_unsigned_8" +#define ADDSUB_OVERFLOW_DETECTOR_UNKNOWN_8 "addsub_overflow_detector_unknown_8" + +#define MUL_OVERFLOW_DETECTOR_32 "mul_overflow_detector_32" +#define MUL_OVERFLOW_DETECTOR_16 "mul_overflow_detector_16" +#define MUL_OVERFLOW_DETECTOR_8 "mul_overflow_detector_8" +#define TRUNCATION_DETECTOR "truncation_detector" +#define TRUNCATION_DETECTOR_32_16 "truncation_detector_32_16" +#define TRUNCATION_DETECTOR_32_8 "truncation_detector_32_8" +#define TRUNCATION_DETECTOR_16_8 "truncation_detector_16_8" +#define TRUNCATION_DETECTOR_UNSIGNED_32_16 "truncation_detector_unsigned_32_16" +#define TRUNCATION_DETECTOR_UNSIGNED_32_8 "truncation_detector_unsigned_32_8" +#define TRUNCATION_DETECTOR_UNSIGNED_16_8 "truncation_detector_unsigned_32_8" +#define TRUNCATION_DETECTOR_SIGNED_32_16 "truncation_detector_signed_32_16" +#define TRUNCATION_DETECTOR_SIGNED_32_8 "truncation_detector_signed_32_8" +#define TRUNCATION_DETECTOR_SIGNED_16_8 "truncation_detector_signed_32_8" +#define SIGNEDNESS_DETECTOR_32 "signedness_detector_32" +#define SIGNEDNESS_DETECTOR_16 "signedness_detector_16" +#define SIGNEDNESS_DETECTOR_8 "signedness_detector_8" +#define UNDERFLOW_DETECTOR_32 "underflow_detector_32" +#define UNDERFLOW_DETECTOR_16 "underflow_detector_16" +#define UNDERFLOW_DETECTOR_8 "underflow_detector_8" +#define UNDERFLOW_DETECTOR_UNSIGNED_32 "underflow_detector_unsigned_32" +#define UNDERFLOW_DETECTOR_UNSIGNED_16 "underflow_detector_unsigned_16" +#define UNDERFLOW_DETECTOR_UNSIGNED_8 "underflow_detector_unsigned_8" +#define UNDERFLOW_DETECTOR_SIGNED_32 "underflow_detector_signed_32" +#define UNDERFLOW_DETECTOR_SIGNED_16 "underflow_detector_signed_16" +#define UNDERFLOW_DETECTOR_SIGNED_8 "underflow_detector_signed_8" +#define INFINITE_LOOP_DETECTOR "infinite_loop_detector" +#define OVERFLOW_UNKNOWN_SIGN_DETECTOR "overflow_unknown_sign_detector" +} + +#endif diff --git a/irdb-lib/libIRDB-transform/include-unused-delete-later/integertransform64.cpp b/irdb-lib/libIRDB-transform/include-unused-delete-later/integertransform64.cpp new file mode 100644 index 0000000000000000000000000000000000000000..06315471f9fce669110366d7a760a1de0fb4d58c --- /dev/null +++ b/irdb-lib/libIRDB-transform/include-unused-delete-later/integertransform64.cpp @@ -0,0 +1,1702 @@ +/* + * Copyright (c) 2013, 2014 - University of Virginia + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#include <assert.h> +#include <sstream> +#include "leapattern.hpp" +#include "integertransform64.hpp" +#include "Rewrite_Utility.hpp" + +#define INSTRUMENT_LEA +#define INSTRUMENT_OVERFLOW +#define INSTRUMENT_UNDERFLOW +#define INSTRUMENT_TRUNCATION +#define INSTRUMENT_SIGNEDNESS + +using namespace libTransform; + +/** +* 64 bit implementation status of the integer transform +* 20140228 64-bit overflows on multiply, signed/unsigned add/sub +* 20140422 callback handlers added +* +* 64-bit signed unsigned unknown +* -------- ------ -------- ------- +* add, sub of c of,c +* mul of of of +* lea @todo @todo @todo +* +* 32-bit signed unsigned unknown +* -------- ------ -------- ------- +* add, sub @todo @todo @todo +* mul of of of +* lea @todo @todo @todo + +* @todo: +* - test unknown +* - test warnings only mode +* - handle LEA instructions +* +**/ + +IntegerTransform64::IntegerTransform64(VariantID_t *p_variantID, FileIR_t *p_fileIR, MEDS_Annotations_t *p_annotations, set<std::string> *p_filteredFunctions, set<VirtualOffset> *p_benignFalsePositives) : IntegerTransform(p_variantID, p_fileIR, p_annotations, p_filteredFunctions, p_benignFalsePositives) +{ +} + +// iterate through all functions +// filter those functions that should be ignored +// iterate through all instructions in function +// if MEDS annotation says to instrument +// add instrumentation +int IntegerTransform64::execute() +{ + if (isWarningsOnly()) + logMessage(__func__, "warnings only mode"); + if (isInstrumentIdioms()) + logMessage(__func__, "override annotations -- instrument IDIOMS"); + + for( + set<Function_t*>::const_iterator itf=getFileIR()->GetFunctions().begin(); + itf!=getFileIR()->GetFunctions().end(); + ++itf + ) + { + Function_t* func=*itf; + + if (getFilteredFunctions()->find(func->GetName()) != getFilteredFunctions()->end()) + { + logMessage(__func__, "filter out: " + func->GetName()); + continue; + } + + if (isBlacklisted(func)) + { + logMessage(__func__, "blacklisted: " + func->GetName()); + m_numBlacklisted++; + continue; + } + + logMessage(__func__, "processing fn: " + func->GetName()); + + for( + set<Instruction_t*>::const_iterator it=func->GetInstructions().begin(); + it!=func->GetInstructions().end(); + ++it) + { + Instruction_t* insn=*it; + + if (insn && insn->getAddress()) + { + int policy = POLICY_DEFAULT; + + if (isSaturatingArithmetic()) + { + // saturating arithmetic is enabled + // only use if instruction is not a potential false positive + policy = POLICY_CONTINUE_SATURATING_ARITHMETIC; + } + + // takes precedence over saturation if conflict + if (isWarningsOnly()) + { + policy = POLICY_CONTINUE; + } + + virtual_offset_t irdb_vo = insn->getAddress()->GetVirtualOffset(); + if (irdb_vo == 0) continue; + + VirtualOffset vo(irdb_vo); + + if (getAnnotations()->count(vo) == 0) + continue; + + std::pair<MEDS_Annotations_t::iterator,MEDS_Annotations_t::iterator> ret; + ret = getAnnotations()->equal_range(vo); + MEDS_InstructionCheckAnnotation annotation; + MEDS_InstructionCheckAnnotation* p_annotation; + for ( MEDS_Annotations_t::iterator it = ret.first; it != ret.second; ++it) + { + MEDS_AnnotationBase *base_type=(it->second); + p_annotation = dynamic_cast<MEDS_InstructionCheckAnnotation*>(base_type); + if( p_annotation == NULL) + continue; + annotation = *p_annotation; + if (!annotation.isValid()) + continue; + else + break; // let's just handle one annotation for now and see how it goes + } + + logMessage(__func__, annotation, "-- instruction: " + insn->getDisassembly()); + m_numAnnotations++; + + if (annotation.isIdiom() && !isInstrumentIdioms()) + { + logMessage(__func__, "skip IDIOM"); + m_numIdioms++; + continue; + } + + if (!insn->getFallthrough()) + { + logMessage(__func__, "Warning: no fall through for instruction -- skipping"); + continue; + } + + if (annotation.isOverflow()) + { +#ifdef INSTRUMENT_OVERFLOW + m_numTotalOverflows++; + handleOverflowCheck(insn, annotation, policy); +#endif + } +#ifdef INSTRUMENT_UNDERFLOW + else + if (annotation.isUnderflow()) + { + m_numTotalUnderflows++; + handleUnderflowCheck(insn, annotation, policy); + } +#endif +#ifdef INSTRUMENT_TRUNCATION + else if (annotation.isTruncation()) + { + m_numTotalTruncations++; + handleTruncation(insn, annotation, policy); + } +#endif +#ifdef INSTRUMENT_SIGNEDNESS + else if (annotation.isSignedness()) + { + m_numTotalSignedness++; + handleSignedness(insn, annotation, policy); + } +#endif + } + } // end iterate over all instructions in a function + } // end iterate over all functions + + return 0; +} + +void IntegerTransform64::handleOverflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) +{ + bool result = false; + + if (isMultiplyInstruction(p_instruction) || (p_annotation.isOverflow() && !p_annotation.isNoFlag())) + { + // handle signed/unsigned add/sub overflows (non lea) + result = addOverflowUnderflowCheck(p_instruction, p_annotation, p_policy); + } +#ifdef INSTRUMENT_LEA + else + if (p_annotation.isNoFlag()) + { + // handle lea + if ((p_annotation.getBitWidth() == 64 || p_annotation.getBitWidth() == 32)) + { + result = addOverflowCheckNoFlag(p_instruction, p_annotation, p_policy); + } + } +#endif + + if (result) + { + m_numOverflows++; + } + else + { + m_numOverflowsSkipped++; + logMessage(__func__, "OVERFLOW type not yet handled"); + } +} + +void IntegerTransform64::handleUnderflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) +{ + bool success = false; + + if (p_annotation.isUnderflow() && !p_annotation.isNoFlag()) + success = addOverflowUnderflowCheck(p_instruction, p_annotation, p_policy); + + if (success) + { + m_numUnderflows++; + } + else + { + m_numUnderflowsSkipped++; + logMessage(__func__, "UNDERFLOW type not yet handled"); + } +} + +void IntegerTransform64::handleTruncation(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) +{ + bool success = false; + + if (!isMovInstruction(p_instruction)) + { + logMessage(__func__, "We only instrument MOV instructions for TRUNCATION annotations"); + return; + } + + if (p_annotation.getTruncationFromWidth() == 64) + { + if (p_annotation.getTruncationToWidth() == 32 || p_annotation.getTruncationToWidth() == 16 || p_annotation.getTruncationToWidth() == 8) + { + success = addTruncationCheck64(p_instruction, p_annotation, p_policy); + } + else + { + logMessage(__func__, "Truncation type not yet handled (64)"); + } + } + else if (p_annotation.getTruncationFromWidth() == 32) + { + if (p_annotation.getTruncationToWidth() == 16 || p_annotation.getTruncationToWidth() == 8) + { + success = addTruncationCheck32(p_instruction, p_annotation, p_policy); + } + else + { + logMessage(__func__, "Truncation type not yet handled (32)"); + } + } + + if (success) + m_numTruncations++; + else + { + m_numTruncationsSkipped++; + logMessage(__func__, "Truncation type not yet handled (2)"); + } +} + +void IntegerTransform64::handleSignedness(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) +{ + if (addSignednessCheck(p_instruction, p_annotation, p_policy)) + { + m_numSignedness++; + } + else + { + logMessage(__func__, "SIGNEDNESS: error: skip instrumentation"); + m_numSignednessSkipped++; + } +} + + +// +// Saturation Policy +// mul a, b ; <instruction to instrument> +// jno <OrigNext> ; if no overflows, jump to original fallthrough instruction +// mov a, MIN/MAX ; policy = min-saturate (underflow) / max-saturate (overflow) +// of64/uf64 handler ; call the callback handler (handle diagnostics) +// OrigNext: <nextInstruction> ; original fallthrugh +// +bool IntegerTransform64::addOverflowUnderflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) +{ + char tmpbuf[1024]; + + assert(getFileIR() && p_instruction && p_instruction->getFallthrough()); + RegisterName targetReg = getTargetRegister(p_instruction); + if (targetReg == rn_UNKNOWN) + { + logMessage(__func__, p_annotation, "unknown target register"); + return false; + } + else if (!instrumentSP() && (targetReg == rn_RSP || targetReg == rn_ESP)) + { + logMessage(__func__, "target register is esp/rsp -- skipping: "); + return false; + } + else if (!instrumentFP() && (targetReg == rn_RBP || targetReg == rn_EBP)) + { + logMessage(__func__, "target register is ebp/rbp -- skipping: "); + return false; + } + + Instruction_t* jncond_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); + Instruction_t* nop_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); + Instruction_t* policy_i; + + Instruction_t* next_i = p_instruction->getFallthrough(); + p_instruction->setFallthrough(jncond_i); + + setAssembly(nop_i, "nop"); + + if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) + { + policy_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); + } + else + { + policy_i = nop_i; + } + + if (p_annotation.isSigned() || isMultiplyInstruction(p_instruction)) + { + addJno(jncond_i, policy_i, next_i); + } + else if (p_annotation.isUnsigned()) + { + addJnc(jncond_i, policy_i, next_i); + } + else + { // unknown sign + Instruction_t* jnc_i = allocateNewInstruction(p_instruction->getAddress()->getFileID(), p_instruction->GetFunction()); + addJno(jncond_i, jnc_i, next_i); + addJnc(jnc_i, policy_i, next_i); + } + + if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) + { + // @todo: + // saturating signed multiply overflow should take into account + // the signs of the operand. If multiplying negative by positive #, + // then we want to sature to MIN_SIGNED_INT + + if (p_annotation.isUnderflow()) + addMinSaturation(policy_i, targetReg, p_annotation, nop_i); + else + addMaxSaturation(policy_i, targetReg, p_annotation, nop_i); + } + + std::string detector = p_annotation.isOverflow() ? OVERFLOW64_DETECTOR : UNDERFLOW64_DETECTOR; + + Instruction_t* cb = addCallbackHandlerSequence(p_instruction, next_i, detector, p_policy); + nop_i->setFallthrough(cb); + cb->setComment("underflow callback/instrumentation"); + + return true; +} + +bool IntegerTransform64::addOverflowCheckNoFlag(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) +{ + LEAPattern leaPattern(p_annotation); + + if (!leaPattern.isValid()) + { + logMessage(__func__, "invalid or unhandled lea pattern - skipping: "); + return false; + } + + if (leaPattern.getRegister1() == rn_UNKNOWN) + { + logMessage(__func__, "destination register is unknown -- skipping: "); + return false; + } + else if(!instrumentSP() && (leaPattern.getRegister1() == rn_RSP || leaPattern.getRegister1() == rn_ESP)) + { + logMessage(__func__, "destination register is r/esp -- skipping: "); + return false; + } + else if(!instrumentFP() && (leaPattern.getRegister1() == rn_RBP || leaPattern.getRegister1() == rn_EBP)) + { + logMessage(__func__, "destination register is r/ebp -- skipping: "); + return false; + } + + if (leaPattern.isRegisterPlusRegister() || leaPattern.isRegisterTimesRegister()) + { + RegisterName reg1 = leaPattern.getRegister1(); + RegisterName reg2 = leaPattern.getRegister2(); + RegisterName target = getTargetRegister(p_instruction); + + if (reg1 == rn_UNKNOWN || reg2 == rn_UNKNOWN || target == rn_UNKNOWN) + { + logMessage(__func__, "lea reg reg pattern: error retrieving register: reg1: " + Register::toString(reg1) + " reg2: " + Register::toString(reg2) + " target: " + Register::toString(target)); + return false; + } + else if (!instrumentSP() && (reg2 == rn_RSP || reg2 == rn_ESP || reg1 == rn_RSP || reg1 == rn_ESP )) + { + logMessage(__func__, "source or target register is esp/rsp -- skipping: "); + return false; + } + else if (!instrumentFP() && (reg2 == rn_RBP || reg2 == rn_EBP || reg1 == rn_RBP || reg1 == rn_EBP )) + { + logMessage(__func__, "source or target register is ebp/rbp -- skipping: "); + return false; + } + else + { + if (leaPattern.isRegisterPlusRegister()) + addOverflowCheckNoFlag_RegPlusReg(p_instruction, p_annotation, reg1, reg2, target, p_policy); + else if (leaPattern.isRegisterTimesRegister()) + addOverflowCheckNoFlag_RegTimesReg(p_instruction, p_annotation, reg1, reg2, target, p_policy); + } + return true; + } + else if (leaPattern.isRegisterPlusConstant() || leaPattern.isRegisterTimesConstant()) + { + RegisterName reg1 = leaPattern.getRegister1(); + int k = leaPattern.getConstant(); + RegisterName target = getTargetRegister(p_instruction); + + if (reg1 == rn_UNKNOWN || target == rn_UNKNOWN) + { + logMessage(__func__, "lea reg const pattern: error retrieving register: reg1: " + Register::toString(reg1) + " target: " + Register::toString(target)); + return false; + } + else if (!instrumentSP() && (target == rn_RSP || target == rn_ESP)) + { + logMessage(__func__, "target register is esp/rsp -- skipping: "); + return false; + } + else if (!instrumentFP() && (target == rn_RBP || target == rn_EBP)) + { + logMessage(__func__, "target register is ebp/rbp -- skipping: "); + return false; + } + else + { + if (leaPattern.isRegisterPlusConstant()) + addOverflowCheckNoFlag_RegPlusConstant(p_instruction, p_annotation, reg1, k, target, p_policy); + else if (leaPattern.isRegisterTimesConstant()) + addOverflowCheckNoFlag_RegTimesConstant(p_instruction, p_annotation, reg1, k, target, p_policy); + } + return true; + } + logMessage(__func__, "not yet handling lea -- placeholder"); + return false; +} + +// +// p_orig original instruction being instrumented +// p_fallthrough fallthrough once we're done with the callback handlers/detectors +// p_detector callback handler function to call +// p_policy instrumentation policy (e.g.: terminate, saturate, ...) +// +// returns first instruction of callback handler sequence +// +Instruction_t* IntegerTransform64::addCallbackHandlerSequence(Instruction_t *p_orig, Instruction_t *p_fallthrough, std::string p_detector, int p_policy) +{ + char tmpbuf[1024]; + + Instruction_t* lea = addNewAssembly("lea rsp, [rsp-128]"); // red zone + lea->setComment("callback: " + p_detector); + + // must save flags as strata will perturb them + Instruction_t* saveFlags = addNewAssembly(lea, "pushf"); + + // pass in PC of instrumented instruction + // pass in p_policy + sprintf(tmpbuf,"push 0x%08x", p_policy); + Instruction_t* instr = addNewAssembly(saveFlags, tmpbuf); + sprintf(tmpbuf,"push 0x%08x", p_orig->getAddress()->GetVirtualOffset()); + instr = addNewAssembly(instr, tmpbuf); + + Instruction_t* call = allocateNewInstruction(p_orig->getAddress()->getFileID(), p_orig->GetFunction()); + instr->setFallthrough(call); + setAssembly(call, "call 0"); + + addCallbackHandler64(call, p_detector, 2); // 2 args for now + + assert(call->getTarget()); + + instr = addNewAssembly(call, "lea rsp, [rsp+16]"); + instr = addNewAssembly(instr, "popf"); + instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); + instr->setFallthrough(p_fallthrough); + + return lea; +} + +// Example annotation to handle +// 804852e 3 INSTR CHECK OVERFLOW NOFLAGSIGNED 32 EDX+EAX ZZ lea eax, [edx+eax] Reg1: EDX Reg2: EAX +// Need to handle both 32-bit and 64-bit versions +// +// Original: +// lea r3, [r1+r2] +// <originalNext> +// +// Instrumentation: +// push r1 ; save r1 +// pushf ; save flags +// add r1, r2 ; r1 = r1 + r2 +// <overflowcheck> ; check for overflow +// (jno|jnc <restore>) ; SIGNED|UNSIGNED +// fallthrough--><policy> +// (jno&jnc <restore>) ; UNKNOWNSIGN check both flags +// fallthrough--><policy> +// +// <restore> +// popf ; restore flags +// pop r1 ; restore register +// +// <orig>: lea r3, [r1+r2] ; original instruction +// <originalNext> ; original next instruction +// +// <policy> +// () callback handler +// popf ; restore flags +// pop r1 ; restore register +// fallthrough-->originalNext (if no saturation) +// saturateMax(r3) ; optional saturation +// fallthrough-->originalNext +// +void IntegerTransform64::addOverflowCheckNoFlag_RegPlusReg(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const RegisterName& p_reg1, const RegisterName& p_reg2, const RegisterName& p_reg3, int p_policy) +{ + assert(p_instruction && p_instruction->getFallthrough()); + + cerr << __func__ << ": r3 <-- r1+r2: r1: " << Register::toString(p_reg1) << " r2: " << Register::toString(p_reg2) << " target register: " << Register::toString(p_reg3) << " annotation: " << p_annotation.toString() << endl; + + Instruction_t *origFallthrough = p_instruction->getFallthrough(); + Instruction_t *instr, *first, *saturation_policy; + Instruction_t *restore = addNewAssembly("popf"); + + saturation_policy = addNewAssembly("nop"); + saturation_policy->setComment("lea overflow instrumentation(reg+reg): policy code sequence"); + + // Original code sequence: + // lea r3, [r1+r2] + // <originalNext> + // + // Instrumentation: + // push r1 ; save r1 + // pushf ; save flags + // add r1, r2 ; r1 = r1 + r2 + // <overflowcheck> ; check for overflow + // (jno|jnc <restore>) ; SIGNED|UNSIGNED + // fallthrough--><policy> + // (jno&jnc <restore>) ; UNKNOWNSIGN check both flags + // fallthrough--><policy> + // +// first = addNewAssembly("push " + Register::toString(p_reg1)); +// first->setComment("lea overflow instrumentation(reg+reg): start"); +// Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, first); + + Instruction_t* originalInstrumentInstr = IRDBUtility::insertAssemblyBefore(getFileIR(), p_instruction, "lea rsp, [rsp-128]" , NULL); + p_instruction->setComment("lea overflow instrumentation(reg+reg): start"); + instr = addNewAssembly(p_instruction, std::string("push ") + Register::toString(p_reg1)); + instr = addNewAssembly(instr, "pushf"); + + instr = addNewAssembly(instr, "add " + Register::toString(p_reg1) + "," + Register::toString(p_reg2)); + if (p_annotation.isSigned()) + { + instr = addNewAssembly(instr, "jno 0x22"); + instr->setFallthrough(saturation_policy); + instr->setTarget(restore); + instr->setComment("signed: lea: reg+reg"); + } + else if (p_annotation.isUnsigned()) + { + instr = addNewAssembly(instr, "jnc 0x22"); + instr->setFallthrough(saturation_policy); + instr->setTarget(restore); + } + else + { + Instruction_t *instr2 = addNewAssembly(instr, "jno 0x22"); // this generates bogus assembly code, why? + instr2->setTarget(restore); + instr = addNewAssembly(instr2, "jnc 0x22"); + instr->setFallthrough(saturation_policy); + instr->setTarget(restore); + } + + // <policy> + // nop ; + // () callback handler ; + // popf ; restore flags + // pop r1 ; restore register + // fallthrough-->originalNext (if no saturation) + // saturateMax(r3) ; optional saturation + // fallthrough-->originalNext + // + // assume 64 bit for now + // + Instruction_t *popf = addNewAssembly("popf"); + Instruction_t *callback = addCallbackHandlerSequence(p_instruction, popf, OVERFLOW64_DETECTOR, p_policy); + saturation_policy->setFallthrough(callback); + instr = addNewAssembly(popf, "pop " + Register::toString(p_reg1)); + if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) + { + instr = addNewMaxSaturation(instr, p_reg3, p_annotation); + instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); + instr->setFallthrough(origFallthrough); + } + else + { + instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); + instr->setFallthrough(originalInstrumentInstr); + } + + // <restore> + // popf ; restore flags + // pop r1 ; restore register + // + // <orig>: lea r3, [r1+r2] ; original instruction + // <originalNext> ; original next instruction + // + restore->setComment("lea overflow instrumentation(reg+reg): restore"); + instr = addNewAssembly(restore, "pop " + Register::toString(p_reg1)); + instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); + instr->setFallthrough(originalInstrumentInstr); +} + +// Example annotation to handle +// 804852e 3 INSTR CHECK OVERFLOW NOFLAGSIGNED 32 EDX+EAX ZZ lea eax, [edx+eax] Reg1: EDX Reg2: EAX +// Need to handle both 32-bit and 64-bit versions +// +// Original: +// lea r3, [r1+r2] +// <originalNext> +// +// Instrumentation: +// push r1 ; save r1 +// pushf ; save flags +// imul r1, r2 ; r1 = r1 * r2 +// <overflowcheck> ; check for overflow +// (jno|jnc <restore>) ; SIGNED|UNSIGNED +// fallthrough--><policy> +// (jno&jnc <restore>) ; UNKNOWNSIGN check both flags +// fallthrough--><policy> +// +// <restore> +// popf ; restore flags +// pop r1 ; restore register +// +// <orig>: lea r3, [r1+r2] ; original instruction +// <originalNext> ; original next instruction +// +// <policy> +// () callback handler +// popf ; restore flags +// pop r1 ; restore register +// fallthrough-->originalNext (if no saturation) +// saturateMax(r3) ; optional saturation +// fallthrough-->originalNext +// +void IntegerTransform64::addOverflowCheckNoFlag_RegTimesReg(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const RegisterName& p_reg1, const RegisterName& p_reg2, const RegisterName& p_reg3, int p_policy) +{ + assert(p_instruction && p_instruction->getFallthrough()); + + cerr << __func__ << ": r3 <-- r1*r2: r1: " << Register::toString(p_reg1) << " r2: " << Register::toString(p_reg2) << " target register: " << Register::toString(p_reg3) << " annotation: " << p_annotation.toString() << endl; + + Instruction_t *origFallthrough = p_instruction->getFallthrough(); + Instruction_t *instr, *first, *saturation_policy; + Instruction_t *restore = addNewAssembly("popf"); + saturation_policy = addNewAssembly("nop"); + saturation_policy->setComment("lea overflow instrumentation(reg*reg): policy code sequence"); + + + // Original code sequence: + // lea r3, [r1*r2] + // <originalNext> + // + // Instrumentation: + // push r1 ; save r1 + // pushf ; save flags + // imul r1, r2 ; r1 = r1 * r2 + // <overflowcheck> ; check for overflow + // jno <restore> ; + // fallthrough--><policy> + // + Instruction_t* originalInstrumentInstr = IRDBUtility::insertAssemblyBefore(getFileIR(), p_instruction, "lea rsp, [rsp-128]" , NULL); + p_instruction->setComment("lea overflow instrumentation(reg*reg): start"); + instr = addNewAssembly(p_instruction, std::string("push ") + Register::toString(p_reg1)); + instr = addNewAssembly(instr, "pushf"); + + instr = addNewAssembly(instr, "imul " + Register::toString(p_reg1) + "," + Register::toString(p_reg2)); + instr = addNewAssembly(instr, "jno 0x22"); + instr->setFallthrough(saturation_policy); + instr->setTarget(restore); + + // <policy> + // nop ; + // () callback handler ; + // popf ; restore flags + // pop r1 ; restore register + // fallthrough-->originalNext (if no saturation) + // saturateMax(r3) ; optional saturation + // fallthrough-->originalNext + // + // assume 64 bit for now + // + Instruction_t *popf = addNewAssembly("popf"); + Instruction_t *callback = addCallbackHandlerSequence(p_instruction, popf, OVERFLOW64_DETECTOR, p_policy); + saturation_policy->setFallthrough(callback); + instr = addNewAssembly(popf, "pop " + Register::toString(p_reg1)); + if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) + { + instr = addNewMaxSaturation(instr, p_reg3, p_annotation); + instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); + instr->setFallthrough(origFallthrough); + } + else + { + instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); + instr->setFallthrough(originalInstrumentInstr); + } + + // <restore> + // popf ; restore flags + // pop r1 ; restore register + // + // <orig>: lea r3, [r1*r2] ; original instruction + // <originalNext> ; original next instruction + // + restore->setComment("lea overflow instrumentation(reg*reg): restore"); + instr = addNewAssembly(restore, "pop " + Register::toString(p_reg1)); + instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); + instr->setFallthrough(originalInstrumentInstr); +} + +// Example annotation to handle +// 804852e 3 INSTR CHECK OVERFLOW NOFLAGSIGNED 32 EDX+EAX ZZ lea eax, [edx+k] Reg1: EDX Reg3: EAX +// Need to handle both 32-bit and 64-bit versions +// +// Original: +// lea r3, [r1+k] +// <originalNext> +// +// Instrumentation: +// push r1 ; save r1 +// pushf ; save flags +// add r1, k ; r1 = r1 + k +// <overflowcheck> ; check for overflow +// (jno|jnc <restore>) ; SIGNED|UNSIGNED +// fallthrough--><policy> +// (jno&jnc <restore>) ; UNKNOWNSIGN check both flags +// fallthrough--><policy> +// +// <restore> +// popf ; restore flags +// pop r1 ; restore register +// +// <orig>: lea r3, [r1+k] ; original instruction +// <originalNext> ; original next instruction +// +// <policy> +// () callback handler +// popf ; restore flags +// pop r1 ; restore register +// fallthrough-->originalNext (if no saturation) +// saturateMax(r3) ; optional saturation +// fallthrough-->originalNext +// +void IntegerTransform64::addOverflowCheckNoFlag_RegPlusConstant(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const RegisterName& p_reg1, const int p_constant, const RegisterName& p_reg3, int p_policy) +{ + assert(p_instruction && p_instruction->getFallthrough()); + + if (p_annotation.isUnsigned() && (p_constant < 0)) { + logMessage(__func__, "lea reg+neg constant pattern: skip this annotation type (prone to false positives)"); + m_numOverflowsSkipped++; + return; + } + + cerr << __func__ << ": r3 <-- r1+k: r1: " << Register::toString(p_reg1) << " k: " << p_constant << " target register: " << Register::toString(p_reg3) << " annotation: " << p_annotation.toString() << endl; + + Instruction_t *origFallthrough = p_instruction->getFallthrough(); + Instruction_t *instr, *first, *saturation_policy; + Instruction_t *restore = addNewAssembly("popf"); + saturation_policy = addNewAssembly("nop"); + saturation_policy->setComment("lea overflow instrumentation(reg+k): policy code sequence"); + + // Original code sequence: + // lea r3, [r1+k] + // <originalNext> + // + // Instrumentation: + // push r1 ; save r1 + // pushf ; save flags + // add r1, k ; r1 = r1 + k + // (or sub r1,-k ; r1 = r1 - (-k) for k < 0) + // <overflowcheck> ; check for overflow + // (jno|jnc <restore>) ; SIGNED|UNSIGNED + // fallthrough--><policy> + // (jno&jnc <restore>) ; UNKNOWNSIGN check both flags + // fallthrough--><policy> + // +/* + first = addNewAssembly("push " + Register::toString(p_reg1)); + first->setComment("lea overflow instrumentation(reg+k): start"); + Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, first); + instr = addNewAssembly(first, "pushf"); + */ + + Instruction_t* originalInstrumentInstr = IRDBUtility::insertAssemblyBefore(getFileIR(), p_instruction, "lea rsp, [rsp-128]" , NULL); + p_instruction->setComment("lea overflow instrumentation(reg+k): start"); + instr = addNewAssembly(p_instruction, std::string("push ") + Register::toString(p_reg1)); + instr = addNewAssembly(instr, "pushf"); +//------------------- + // make sure we set the fallthrough post careful insertion +// first->setFallthrough(instr); + + std::ostringstream s; + if (p_constant >= 0) { + s << "add " << Register::toString(p_reg1) << "," << p_constant; + } + else { + // NOTE: We are short-circuiting this case currently; see top of + // this function. Should never get here. + s << "sub " << Register::toString(p_reg1) << "," << (-p_constant); + } + instr = addNewAssembly(instr, s.str()); + if (p_annotation.isSigned()) + { + instr = addNewAssembly(instr, "jno 0x22"); + instr->setFallthrough(saturation_policy); + instr->setTarget(restore); + } + else if (p_annotation.isUnsigned()) + { + instr = addNewAssembly(instr, "jnc 0x22"); + instr->setFallthrough(saturation_policy); + instr->setTarget(restore); + } + else + { + Instruction_t *instr2 = addNewAssembly(instr, "jno 0x22"); + instr2->setTarget(restore); + instr = addNewAssembly(instr2, "jnc 0x22"); + instr->setFallthrough(saturation_policy); + instr->setTarget(restore); + } + + // <policy> + // nop ; + // () callback handler ; + // popf ; restore flags + // pop r1 ; restore register + // fallthrough-->originalNext (if no saturation) + // saturateMax(r3) ; optional saturation + // fallthrough-->originalNext + // + // assume 64 bit for now + // + Instruction_t *popf = addNewAssembly("popf"); + Instruction_t *callback = addCallbackHandlerSequence(p_instruction, popf, OVERFLOW64_DETECTOR, p_policy); + saturation_policy->setFallthrough(callback); + instr = addNewAssembly(popf, "pop " + Register::toString(p_reg1)); + if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) + { + instr = addNewMaxSaturation(instr, p_reg3, p_annotation); + instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); + instr->setFallthrough(origFallthrough); + } + else + { + instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); + instr->setFallthrough(originalInstrumentInstr); + } + + // <restore> + // popf ; restore flags + // pop r1 ; restore register + // + // <orig>: lea r3, [r1+k] ; original instruction + // <originalNext> ; original next instruction + // + restore->setComment("lea overflow instrumentation(reg+k): restore"); + instr = addNewAssembly(restore, "pop " + Register::toString(p_reg1)); + instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); + instr->setFallthrough(originalInstrumentInstr); + originalInstrumentInstr->setFallthrough(origFallthrough); +} + + +// Example annotation to handle +// 804852e 3 INSTR CHECK OVERFLOW NOFLAGSIGNED 32 EDX+EAX ZZ lea eax, [edx+eax] Reg1: EDX Reg2: EAX +// Need to handle both 32-bit and 64-bit versions +// +// Original: +// lea r3, [r1*k] +// <originalNext> +// +// Instrumentation: +// push r1 ; save r1 +// pushf ; save flags +// imul r1, r2 ; r1 = r1 * r2 +// <overflowcheck> ; check for overflow +// (jno <restore>) ; +// fallthrough--><policy> +// +// <restore> +// popf ; restore flags +// pop r1 ; restore register +// +// <orig>: lea r3, [r1*k] ; original instruction +// <originalNext> ; original next instruction +// +// <policy> +// () callback handler +// popf ; restore flags +// pop r1 ; restore register +// fallthrough-->originalNext (if no saturation) +// saturateMax(r3) ; optional saturation +// fallthrough-->originalNext +// +void IntegerTransform64::addOverflowCheckNoFlag_RegTimesConstant(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const RegisterName& p_reg1, const int p_constant, const RegisterName& p_reg3, int p_policy) +{ + assert(p_instruction && p_instruction->getFallthrough()); + + cerr << __func__ << ": r3 <-- r1*k: r1: " << Register::toString(p_reg1) << " k: " << p_constant << " target register: " << Register::toString(p_reg3) << " annotation: " << p_annotation.toString() << endl; + + Instruction_t *origFallthrough = p_instruction->getFallthrough(); + Instruction_t *instr, *first, *saturation_policy; + Instruction_t *restore = addNewAssembly("popf"); + saturation_policy = addNewAssembly("nop"); + saturation_policy->setComment("lea overflow instrumentation(reg*k): policy code sequence"); + + // Original code sequence: + // lea r3, [r1*k] + // <originalNext> + // + // Instrumentation: + // push r1 ; save r1 + // pushf ; save flags + // imul r1, k ; r1 = r1 * k + // <overflowcheck> ; check for overflow + // jno <restore> ; + // fallthrough--><policy> + // + /* + first = addNewAssembly("push " + Register::toString(p_reg1)); + first->setComment("lea overflow instrumentation(reg*k): start"); + Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, first); + instr = addNewAssembly(first, "pushf"); + */ + + Instruction_t* originalInstrumentInstr = IRDBUtility::insertAssemblyBefore(getFileIR(), p_instruction, "lea rsp, [rsp-128]" , NULL); + p_instruction->setComment("lea overflow instrumentation(reg*k): start"); + instr = addNewAssembly(p_instruction, std::string("push ") + Register::toString(p_reg1)); + instr = addNewAssembly(instr, "pushf"); +/*--------------*/ + // make sure we set the fallthrough post careful insertion +// first->setFallthrough(instr); + + std::ostringstream s; + s << "imul " << Register::toString(p_reg1) << "," << p_constant; + instr = addNewAssembly(instr, s.str()); + instr = addNewAssembly(instr, "jno 0x22"); + instr->setFallthrough(saturation_policy); + instr->setTarget(restore); + + // <policy> + // nop ; + // () callback handler ; + // popf ; restore flags + // pop r1 ; restore register + // fallthrough-->originalNext (if no saturation) + // saturateMax(r3) ; optional saturation + // fallthrough-->originalNext + // + // assume 64 bit for now + // + Instruction_t *popf = addNewAssembly("popf"); + Instruction_t *callback = addCallbackHandlerSequence(p_instruction, popf, OVERFLOW64_DETECTOR, p_policy); + saturation_policy->setFallthrough(callback); + instr = addNewAssembly(popf, "pop " + Register::toString(p_reg1)); + if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) + { + instr = addNewMaxSaturation(instr, p_reg3, p_annotation); + instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); + instr->setFallthrough(origFallthrough); + } + else + { + instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); + instr->setFallthrough(originalInstrumentInstr); + } + + // <restore> + // popf ; restore flags + // pop r1 ; restore register + // + // <orig>: lea r3, [r1*k] ; original instruction + // <originalNext> ; original next instruction + // + restore->setComment("lea overflow instrumentation(reg*reg): restore"); + instr = addNewAssembly(restore, "pop " + Register::toString(p_reg1)); + instr = addNewAssembly(instr, "lea rsp, [rsp+128]"); + instr->setFallthrough(originalInstrumentInstr); + originalInstrumentInstr->setFallthrough(origFallthrough); +} + +// +// STARS has extensive discussion of the logic behind truncation and +// signedness annotations in module SMPInstr.cpp, method EmitIntegerErrorAnnotation(). +// The possible combinations are categorized in terms of the instrumentation +// needed at run time: +// CHECK TRUNCATION UNSIGNED: discarded bits must be all zeroes. +// CHECK TRUNCATION SIGNED: discarded bits must be sign-extension of stored bits. +// CHECK TRUNCATION UNKNOWNSIGN: discarded bits must be all zeroes, OR must +// be the sign-extension of the stored bits. +// All truncation annotations are emitted on stores (mov opcodes in x86). +// Other possibilities might be handled in the future. +// + +bool IntegerTransform64::addTruncationCheck32(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) +{ + assert(p_instruction && p_instruction->getFallthrough() && + p_annotation.getTruncationFromWidth() == 32 && + (p_annotation.getTruncationToWidth() == 16 || p_annotation.getTruncationToWidth() == 8) && + isMovInstruction(p_instruction)); + + // Complicated case: + // 80484ed 3 INSTR CHECK TRUNCATION UNKNOWNSIGN 32 EAX 8 AL ZZ mov [ebp+var_4], al + // example: for unknownsign truncation - 8 bit on AL + // it's ok if 24 upper bits are sign-extension or all 0's + // Re-phrased: upper 24 are 0s, upper 25 are 0s, upper 25 are 1s + // are all OK in the UNKNOWNSIGN case + // Note that upper 24 are 0's means no need to check for the + // case where the upper 25 are 0's; already OK. + // + // <save flags> + // test eax, 0xFFFFFF00 ; (for 8 bit) + // jz <continue> ; upper 24 bits are 0's + // + // cmp eax, 0xFFFFFF80 ;(for 8 bit) + // jae continue ; upper 25 bits are 1's + // (invoke truncation handler) + // nop ; truncation handler returns here + // SAT: saturating-arithmetic ; optional + // + // continue: <restore flags> + // mov [ebp+var_4], al ; <originalInstruction> + // + + // Unsigned case: + // 80484ed 3 INSTR CHECK TRUNCATION UNSIGNED 32 EAX 8 AL ZZ mov [ebp+var_4], al + // example: for unsigned truncation - 8 bit on AL + // it's ok if 24 upper bits are all 0's + // + // <save flags> + // test eax, 0xFFFFFF00 ; (for 8 bit) + // jz <continue> ; upper 24 bits are 0's + // + // (invoke truncation handler) + // nop ; truncation handler returns here + // SAT: saturating-arithmetic ; optional + // + // continue: <restore flags> + // mov [ebp+var_4], al ; <originalInstruction> + // + + string detector; + unsigned mask = 0, mask2 = 0; + string saturationValue = "0x0"; + + p_instruction->setComment("monitor for truncation32"); + + if (p_annotation.getTruncationToWidth() == 16) + { + mask = 0xFFFF0000; + mask2 = 0xFFFF8000; + + if(p_annotation.flowsIntoCriticalSink()) + { + detector = TRUNCATION64_FORCE_EXIT; + } + else if (p_annotation.isUnsigned()) + { + saturationValue = "0xFFFF"; + detector = string(TRUNCATION64_DETECTOR_UNSIGNED_32_16); + } + else if (p_annotation.isSigned()) + { + saturationValue = "0x7FFF"; + detector = string(TRUNCATION64_DETECTOR_SIGNED_32_16); + } + else + { + saturationValue = "0x7FFF"; + detector = string(TRUNCATION64_DETECTOR_UNKNOWN_32_16); + } + } + else if (p_annotation.getTruncationToWidth() == 8) + { + mask = 0xFFFFFF00; + mask2 = 0xFFFFFF80; + if(p_annotation.flowsIntoCriticalSink()) + { + detector = TRUNCATION64_FORCE_EXIT; + } + else if (p_annotation.isUnsigned()) + { + saturationValue = "0xFF"; + detector = string(TRUNCATION64_DETECTOR_UNSIGNED_32_8); + } + else if (p_annotation.isSigned()) + { + saturationValue = "0x7F"; + detector = string(TRUNCATION64_DETECTOR_SIGNED_32_8); + } + else + { + saturationValue = "0x7F"; + detector = string(TRUNCATION64_DETECTOR_UNKNOWN_32_8); + } + } + + // <save flags> + // test eax, 0xFFFFFF00 ; (for 8 bit) + // jz <continue> ; upper 24 bits are 0's + // + // (invoke truncation handler) + // nop ; truncation handler returns here + // SAT: mov [ebp+var_4], <saturate> ; optional + // jmp origFT + // + // continue: <restore flags> + // mov [ebp+var_4], al ; <originalInstruction> + // origFT: <originalFallThroughInstruction> + // + + char buf[MAX_ASSEMBLY_SIZE]; + Instruction_t *origFallthrough = p_instruction->getFallthrough(); + Instruction_t *instr, *save, *test; + Instruction_t *restore = addNewAssembly("popf"); + restore->setComment("trunc: restore flags"); + +/* + save = addNewAssembly("pushf"); + save->setComment("start truncation sequence"); +*/ + + if (p_annotation.isSigned()) + { + sprintf(buf, "test %s, 0x%8x", Register::toString(p_annotation.getRegister()).c_str(), mask2); + } + else + { + sprintf(buf, "test %s, 0x%8x", Register::toString(p_annotation.getRegister()).c_str(), mask); + } + logMessage(__func__, buf); + +/* + Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, save); + test = addNewAssembly(save, buf); +*/ +/*--------------*/ +// Instruction_t* originalInstrumentInstr = IRDBUtility::insertAssemblyBefore(getFileIR(), p_instruction, std::string("pushf"), NULL); + Instruction_t* originalInstrumentInstr = IRDBUtility::insertAssemblyBefore(getFileIR(), p_instruction, "lea rsp, [rsp-128]" , NULL); + p_instruction->setComment("start truncation sequence"); + instr = addNewAssembly(p_instruction, "pushf"); + test = addNewAssembly(instr, buf); +/*--------------*/ + // p_instruction->setFallthrough(test); + +// save->setFallthrough(test); + + instr = addNewAssembly(restore, "lea rsp, [rsp+128]"); + instr->setFallthrough(originalInstrumentInstr); + + if (p_annotation.isUnsigned()) + { + logMessage(__func__, "unsigned annotation"); + Instruction_t *nop = addNewAssembly("nop"); + + instr = addNewAssembly(test, "jz 0x22"); // bogus jump target for now + instr->setTarget(restore); + instr->setFallthrough(nop); + + Instruction_t *callback; + + if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) + { + string saturationInstruction = "mov " + p_annotation.getTarget2() + ", " + saturationValue; + Instruction_t *saturation = addNewAssembly(saturationInstruction); + saturation->setComment("trunc/unsigned/saturate"); + + callback = addCallbackHandlerSequence(p_instruction, saturation, detector, p_policy); + nop->setFallthrough(callback); + saturation->setFallthrough(restore); + } + else + { + callback = addCallbackHandlerSequence(p_instruction, restore, detector, p_policy); + nop->setFallthrough(callback); + } + } + else + { + // Signed and unknown signed cases are almost identical: + // 80484ed 3 INSTR CHECK TRUNCATION SIGNED 32 EAX 8 AL ZZ mov [ebp+var_4], al + // 80484ed 3 INSTR CHECK TRUNCATION UNKNOWNSIGN 32 EAX 8 AL ZZ mov [ebp+var_4], al + // example: for signed truncation - 8 bit on AL + // it's ok if 25 upper bits are all 1's or all 0's + // example: for unknownsign truncation - 8 bit on AL + // it's ok if 25 upper bits are all 1's or 24 upper bits all 0's + // + // <save flags> + // test eax, 0xFFFFFF80 ; (for 8 bit) 0xFFFFFF00 for UNKNOWN + // jz <continue> ; upper 25 bits are 0's + // + // cmp eax, 0xFFFFFF80 ;(for 8 bit) + // jae continue ; upper 25 bits are 1's + // (invoke truncation handler) + // nop ; truncation handler callback here + // SAT: saturating-arithmetic ; optional + // + // continue: <restore flags> + // mov [ebp+var_4], al ; <originalInstruction> + // + logMessage(__func__, "signed/unknown annotation"); + Instruction_t *nop = addNewAssembly("nop"); + + instr = addNewAssembly(test, "jz 0x22"); // bogus jump target for now + instr->setTarget(restore); + + std::ostringstream s; + s << "cmp " << Register::toString(p_annotation.getRegister()) << ", 0x" << hex << mask2 << dec; + instr = addNewAssembly(instr, s.str()); + + instr = addNewAssembly(instr, "jae 0x22"); + instr->setTarget(restore); + instr->setFallthrough(nop); + + Instruction_t *callback; + + if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) + { + string saturationInstruction = "mov " + p_annotation.getTarget2() + ", " + saturationValue; + Instruction_t *saturation = addNewAssembly(saturationInstruction); + if (p_annotation.isSigned()) + saturation->setComment("trunc/signed/saturate"); + else + saturation->setComment("trunc/unknown/saturate"); + + callback = addCallbackHandlerSequence(p_instruction, saturation, detector, p_policy); + nop->setFallthrough(callback); + saturation->setFallthrough(restore); + } + else + { + callback = addCallbackHandlerSequence(p_instruction, restore, detector, p_policy); + nop->setFallthrough(callback); + } + } + + return true; +} + +// we want: 32->16 movzx edx, ax --> movzx edx, 0xFFFF +// 32->8 movzx edx, al --> movzx edx, 0xFF +// +// let's handle 2-operand instructions of the form: +// mov *, <reg> +// + +string IntegerTransform64::buildSaturationAssembly(Instruction_t *p_instruction, string p_pattern, string p_value) +{ + // @todo: verify 2 operands! + + string i = p_instruction->getDisassembly(); + + convertToLowercase(i); + convertToLowercase(p_pattern); + convertToLowercase(p_value); + + size_t commaPos = i.find_last_of(','); + if (commaPos != string::npos) + i.replace(i.find(p_pattern, commaPos), p_pattern.size(), p_value); + else + i.replace(i.find(p_pattern), p_pattern.size(), p_value); + return i; +} + +// +// STARS has extensive discussion of the logic behind truncation and +// signedness annotations in module SMPInstr.cpp, method EmitIntegerErrorAnnotation(). +// The possible combinations are categorized in terms of the instrumentation +// needed at run time: +// CHECK TRUNCATION UNSIGNED: discarded bits must be all zeroes. +// CHECK TRUNCATION SIGNED: discarded bits must be sign-extension of stored bits. +// CHECK TRUNCATION UNKNOWNSIGN: discarded bits must be all zeroes, OR must +// be the sign-extension of the stored bits. +// All truncation annotations are emitted on stores (mov opcodes in x86). +// Other possibilities might be handled in the future. +// + +bool IntegerTransform64::addTruncationCheck64(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) +{ + assert(p_instruction && p_instruction->getFallthrough() && + p_annotation.getTruncationFromWidth() == 64 && + (p_annotation.getTruncationToWidth() == 32 || p_annotation.getTruncationToWidth() == 16 || p_annotation.getTruncationToWidth() == 8) && + isMovInstruction(p_instruction)); + + std::set<RegisterName> takenRegs; + takenRegs.insert(p_annotation.getRegister()); + takenRegs.insert(p_annotation.getRegister2()); + takenRegs.insert(rn_RSP); // don't mess with the stack pointer + takenRegs.insert(rn_RBP); // don't mess with the frame pointer + RegisterName borrowReg = Register::getFreeRegister64(takenRegs); + + if (borrowReg == rn_UNKNOWN) + { + logMessage(__func__, "Could not borrow a 64-bit register"); + return false; + } + + // Main difference between TRUNCATION annotation for 64 bits vs. 32 bits + // is that we need to use a register as IA X86-64 doesn't support 64 bit constants + // for most instructions + + // Complicated case: + // 80484ed 3 INSTR CHECK TRUNCATION UNKNOWNSIGN 32 EAX 8 AL ZZ mov [ebp+var_4], al + // example: for unknownsign truncation - 8 bit on AL + // it's ok if 24 upper bits are sign-extension or all 0's + // Re-phrased: upper 24 are 0s, upper 25 are 0s, upper 25 are 1s + // are all OK in the UNKNOWNSIGN case + // Note that upper 24 are 0's means no need to check for the + // case where the upper 25 are 0's; already OK. + // + // <save reg> + // <save flags> + // mov <reg>, 0xFFFFFFFFFFFFFF00 ; // need to grab register + // test eax, <reg> ; (for 8 bit) + // jz <continue> ; upper 56 bits are 0's + // + // cmp eax, 0xFFFFFFFFFFFFFF80 ; (for 8 bit) + // jae continue ; upper 57 bits are 1's + // (invoke truncation handler) + // nop ; truncation handler returns here + // SAT: saturating-arithmetic ; optional + // + // continue: <restore flags> + // <restore reg> + // mov [ebp+var_4], al ; <originalInstruction> + // + + // Unsigned case: + // 80484ed 3 INSTR CHECK TRUNCATION UNSIGNED 64 RAX 32 EAX ZZ mov [ebp+var_4], al + // + // <save reg> + // <save flags> + // mov <reg>, 0xFFFFFFFFFFFFFF00 ; // need to grab register + // test eax, <reg>; (for 64->32 bit) + // jz <continue> ; upper 32 bits are 0's + // + // (invoke truncation handler) + // nop ; truncation handler returns here + // SAT: saturating-arithmetic ; optional + // + // continue: <restore flags> + // <restore reg> + // mov [ebp+var_4], al ; <originalInstruction> + // + + string detector; + long long unsigned mask = 0, mask2 = 0; + string saturationValue = "0x0"; + + p_instruction->setComment("monitor for truncation64"); + + if (p_annotation.getTruncationToWidth() == 32) + { + mask = 0xFFFFFFFF00000000; + mask2 = 0xFFFFFFFF80000000; + + if(p_annotation.flowsIntoCriticalSink()) + { + detector = TRUNCATION64_FORCE_EXIT; + } + else if (p_annotation.isUnsigned()) + { + saturationValue = "0xFFFFFFFF"; + detector = string(TRUNCATION64_DETECTOR_UNSIGNED_64_32); + } + else if (p_annotation.isSigned()) + { + saturationValue = "0x7FFFFFFF"; + detector = string(TRUNCATION64_DETECTOR_SIGNED_64_32); + } + else + { + saturationValue = "0x7FFFFFFF"; + detector = string(TRUNCATION64_DETECTOR_UNKNOWN_64_32); + } + } + else if (p_annotation.getTruncationToWidth() == 16) + { + mask = 0xFFFFFFFFFFFF0000; + mask2 = 0xFFFFFFFFFFFF8000; + + if(p_annotation.flowsIntoCriticalSink()) + { + detector = TRUNCATION64_FORCE_EXIT; + } + else if (p_annotation.isUnsigned()) + { + saturationValue = "0xFFFF"; + detector = string(TRUNCATION64_DETECTOR_UNSIGNED_64_16); + } + else if (p_annotation.isSigned()) + { + saturationValue = "0x7FFF"; + detector = string(TRUNCATION64_DETECTOR_SIGNED_64_16); + } + else + { + saturationValue = "0x7FFF"; + detector = string(TRUNCATION64_DETECTOR_UNKNOWN_64_16); + } + } + else if (p_annotation.getTruncationToWidth() == 8) + { + mask = 0xFFFFFFFFFFFFFF00; + mask2 = 0xFFFFFFFFFFFFFF80; + if(p_annotation.flowsIntoCriticalSink()) + { + detector = TRUNCATION64_FORCE_EXIT; + } + else if (p_annotation.isUnsigned()) + { + saturationValue = "0xFF"; + detector = string(TRUNCATION64_DETECTOR_UNSIGNED_64_8); + } + else if (p_annotation.isSigned()) + { + saturationValue = "0x7F"; + detector = string(TRUNCATION64_DETECTOR_SIGNED_64_8); + } + else + { + saturationValue = "0x7F"; + detector = string(TRUNCATION64_DETECTOR_UNKNOWN_64_8); + } + } + + // <save reg> + // <save flags> + // mov <reg>, 0xFFFFFFFFFFFFFF00 ; // need to grab register + // test eax, <reg> ; (for 8 bit) + // jz <continue> ; upper 24 bits are 0's + // + // (invoke truncation handler) + // nop ; truncation handler returns here + // SAT: mov [ebp+var_4], <saturate> ; optional + // jmp origFT + // + // continue: <restore flags> + // <restore reg> + // mov [ebp+var_4], al ; <originalInstruction> + // origFT: <originalFallThroughInstruction> + // + + char buf[MAX_ASSEMBLY_SIZE]; + Instruction_t *origFallthrough = p_instruction->getFallthrough(); + Instruction_t *instr, *save, *test, *pushf; + Instruction_t *restore = addNewAssembly("popf"); + restore->setComment("trunc: restore flags"); + Instruction_t *restoreReg = addNewAssembly("pop " + Register::toString(borrowReg)); + +/* + save = addNewAssembly("push " + Register::toString(borrowReg)); + save->setComment("start truncation sequence"); + + pushf = addNewAssembly(save, "pushf"); + + if (p_annotation.isSigned()) + sprintf(buf, "mov %s, 0x%16llx", Register::toString(borrowReg).c_str(), mask2); + else + sprintf(buf, "mov %s, 0x%16llx", Register::toString(borrowReg).c_str(), mask); + + instr = addNewAssembly(pushf, buf); + + sprintf(buf, "test %s, %s", Register::toString(p_annotation.getRegister()).c_str(), Register::toString(borrowReg).c_str()); + +*/ + +/* + Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, save); + test = addNewAssembly(instr, buf); + */ +/*--------------*/ +// Instruction_t* originalInstrumentInstr = IRDBUtility::insertAssemblyBefore(getFileIR(), p_instruction, std::string("push ") + Register::toString(borrowReg), NULL); +// Instruction_t* lea = addNewAssembly("lea rsp, [rsp-128]"); // red zone + Instruction_t* originalInstrumentInstr = IRDBUtility::insertAssemblyBefore(getFileIR(), p_instruction, "lea rsp, [rsp-128]" , NULL); + p_instruction->setComment("start truncation sequence"); + instr = addNewAssembly(p_instruction, std::string("push ") + Register::toString(borrowReg)); + instr = addNewAssembly(instr, "pushf"); + if (p_annotation.isSigned()) + sprintf(buf, "mov %s, 0x%16llx", Register::toString(borrowReg).c_str(), mask2); + else + sprintf(buf, "mov %s, 0x%16llx", Register::toString(borrowReg).c_str(), mask); + instr = addNewAssembly(instr, buf); + sprintf(buf, "test %s, %s", Register::toString(p_annotation.getRegister()).c_str(), Register::toString(borrowReg).c_str()); + test = addNewAssembly(instr, buf); + // <save reg> + // <save flags> + // mov <reg>, 0xFFFFFFFFFFFFFF00 ; // need to grab register + // test eax, <reg> ; (for 8 bit) +/*--------------*/ + +// save->setFallthrough(pushf); + + restore->setFallthrough(restoreReg); + instr = addNewAssembly(restoreReg, "lea rsp, [rsp+128]"); + instr->setFallthrough(originalInstrumentInstr); + + if (p_annotation.isUnsigned()) + { + logMessage(__func__, "unsigned annotation"); + Instruction_t *nop = addNewAssembly("nop"); + + instr = addNewAssembly(test, "jz 0x22"); // bogus jump target for now + instr->setTarget(restore); + instr->setFallthrough(nop); + + Instruction_t *callback; + + if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) + { + string saturationInstruction = "mov " + p_annotation.getTarget2() + ", " + saturationValue; + Instruction_t *saturation = addNewAssembly(saturationInstruction); + saturation->setComment("trunc/unsigned/saturate"); + + callback = addCallbackHandlerSequence(p_instruction, saturation, detector, p_policy); + nop->setFallthrough(callback); + saturation->setFallthrough(restore); + } + else + { + callback = addCallbackHandlerSequence(p_instruction, restore, detector, p_policy); + nop->setFallthrough(callback); + } + } + else + { + // Signed and unknown signed cases are almost identical: + // 80484ed 3 INSTR CHECK TRUNCATION SIGNED 32 EAX 8 AL ZZ mov [ebp+var_4], al + // 80484ed 3 INSTR CHECK TRUNCATION UNKNOWNSIGN 32 EAX 8 AL ZZ mov [ebp+var_4], al + // example: for signed truncation - 8 bit on AL + // it's ok if 25 upper bits are all 1's or all 0's + // example: for unknownsign truncation - 8 bit on AL + // it's ok if 25 upper bits are all 1's or 24 upper bits all 0's + // + // <save reg> + // <save flags> + // mov <reg>, 0xFFFFFFFFFFFFFF80 + // test eax, <reg> ; (for 8 bit) 0xFFFFFFFFFFFFFF00 for UNKNOWN + // jz <continue> ; upper 57 bits are 0's + // + // cmp eax, 0xFFFFFFFFFFFFFF80 ;(for 8 bit) + // jae continue ; upper 57 bits are 1's + // (invoke truncation handler) + // nop ; truncation handler callback here + // SAT: saturating-arithmetic ; optional + // + // continue: <restore flags> + // <restore reg> + // mov [ebp+var_4], al ; <originalInstruction> + // + logMessage(__func__, "signed/unknown annotation"); + Instruction_t *nop = addNewAssembly("nop"); + + instr = addNewAssembly(test, "jz 0x22"); // bogus jump target for now + instr->setTarget(restore); + + std::ostringstream s; + s << "mov " << Register::toString(borrowReg) << ", 0x" << hex << mask2 << dec; + instr = addNewAssembly(instr, s.str()); + + std::ostringstream s2; + s2 << "cmp " << Register::toString(p_annotation.getRegister()) << "," << Register::toString(borrowReg); + instr = addNewAssembly(instr, s2.str()); + + instr = addNewAssembly(instr, "jae 0x22"); + instr->setTarget(restore); + instr->setFallthrough(nop); + + Instruction_t *callback; + + if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) + { + string saturationInstruction = "mov " + p_annotation.getTarget2() + ", " + saturationValue; + Instruction_t *saturation = addNewAssembly(saturationInstruction); + if (p_annotation.isSigned()) + saturation->setComment("trunc/signed/saturate"); + else + saturation->setComment("trunc/unknown/saturate"); + + callback = addCallbackHandlerSequence(p_instruction, saturation, detector, p_policy); + nop->setFallthrough(callback); + saturation->setFallthrough(restore); + } + else + { + callback = addCallbackHandlerSequence(p_instruction, restore, detector, p_policy); + nop->setFallthrough(callback); + } + } + + return true; +} + +// 8048576 5 INSTR CHECK SIGNEDNESS SIGNED 16 AX ZZ mov [esp+28h], ax +// <save flags> +// TEST ax, ax +// jns L1 +// invoke callback handler +// (optional) mov ax, MAX_16 ; saturating arithmetic (Max for bit width/sign/unsigned) +// +// L1: <restore flags> +// mov [esp+28h], ax +// +bool IntegerTransform64::addSignednessCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) +{ + if (p_annotation.getRegister() == rn_UNKNOWN) + return false; + + string detector = p_annotation.isSigned() ? SIGNEDNESS64_DETECTOR_SIGNED : SIGNEDNESS64_DETECTOR_UNSIGNED; + Instruction_t *origFallthrough = p_instruction->getFallthrough(); + + Instruction_t* originalInstrumentInstr = IRDBUtility::insertAssemblyBefore(getFileIR(), p_instruction, std::string("lea rsp, [rsp-128]"), NULL); + Instruction_t *save = addNewAssembly(p_instruction, "pushf"); + // TEST <reg>, <reg> + std::ostringstream s; + s << "test " << Register::toString(p_annotation.getRegister()) << "," << Register::toString(p_annotation.getRegister()); + Instruction_t *test = addNewAssembly(save, s.str()); + originalInstrumentInstr->setFallthrough(origFallthrough); + + Instruction_t *jns = addNewAssembly(test, "jns 0x22"); + Instruction_t *nop = addNewAssembly(jns, "nop"); + Instruction_t *restore = addNewAssembly("popf"); + Instruction_t *learestore = addNewAssembly(restore, "lea rsp, [rsp+128]"); + learestore->setFallthrough(originalInstrumentInstr); + + jns->setTarget(restore); + + Instruction_t *callback = NULL; + + if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) + { + // what value should we saturate with for 64 and 32 bits? + Instruction_t *saturation = addNewMaxSaturation(nop, p_annotation.getRegister(), p_annotation); + + if (p_annotation.isSigned()) + saturation->setComment("signedness/signed/saturate"); + else + saturation->setComment("signedness/unsigned/saturate"); + + callback = addCallbackHandlerSequence(p_instruction, saturation, detector, p_policy); + nop->setFallthrough(callback); + saturation->setFallthrough(restore); + } + else + { + callback = addCallbackHandlerSequence(p_instruction, restore, detector, p_policy); + nop->setFallthrough(callback); + } + + return true; +} diff --git a/irdb-lib/libIRDB-transform/include-unused-delete-later/integertransform64.hpp b/irdb-lib/libIRDB-transform/include-unused-delete-later/integertransform64.hpp new file mode 100644 index 0000000000000000000000000000000000000000..655042e99b4800d10d3e3183b60699ea582fdd6a --- /dev/null +++ b/irdb-lib/libIRDB-transform/include-unused-delete-later/integertransform64.hpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013, 2014 - University of Virginia + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#ifndef _LIBTRANSFORM_INTEGERTRANSFORM64_H_ +#define _LIBTRANSFORM_INTEGERTRANSFORM64_H_ + +#include "integertransform.hpp" + +namespace libTransform +{ + +using namespace std; +using namespace libIRDB; + +class IntegerTransform64 : public IntegerTransform +{ + public: + IntegerTransform64(VariantID_t *, FileIR_t*, MEDS_Annotations_t *p_annotations, set<std::string> *p_filteredFunctions, set<VirtualOffset> *p_warnings); + + virtual int execute(); + + protected: + virtual Instruction_t* addCallbackHandlerSequence(Instruction_t *p_orig, Instruction_t *p_fallthrough, std::string p_detector, int p_policy); + void handleOverflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy); + void handleUnderflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy); + void handleTruncation(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy); + void handleSignedness(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy); + + bool addOverflowUnderflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy); + + void saturateSignedMultiplyOverflow(Instruction_t *p_orig, Instruction_t *p_instruction, Instruction_t* p_fallthrough); + bool addOverflowCheckNoFlag(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy); + void addOverflowCheckNoFlag_RegPlusReg(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const RegisterName& p_reg1, const RegisterName& p_reg2, const RegisterName& p_reg3, int p_policy); + void addOverflowCheckNoFlag_RegTimesReg(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const RegisterName& p_reg1, const RegisterName& p_reg2, const RegisterName& p_reg3, int p_policy); + void addOverflowCheckNoFlag_RegPlusConstant(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const RegisterName& p_reg1, const int p_constant, const RegisterName& p_reg3, int p_policy); + void addOverflowCheckNoFlag_RegTimesConstant(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const RegisterName& p_reg1, const int p_constant, const RegisterName& p_reg3, int p_policy); + bool addTruncationCheck32(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy); + bool addTruncationCheck64(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy); + bool addSignednessCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy); + + string buildSaturationAssembly(Instruction_t *p_instruction, string p_pattern, string p_value); +}; + + +} // end namespace + +#define OVERFLOW64_DETECTOR "overflow_detector_64" +#define UNDERFLOW64_DETECTOR "underflow_detector_64" + +#define TRUNCATION64_DETECTOR_UNSIGNED_64_32 "truncation_detector_64_32" +#define TRUNCATION64_DETECTOR_SIGNED_64_32 "truncation_detector_64_32" +#define TRUNCATION64_DETECTOR_UNKNOWN_64_32 "truncation_detector_64_32" + +#define TRUNCATION64_DETECTOR_UNSIGNED_64_16 "truncation_detector_64_16" +#define TRUNCATION64_DETECTOR_SIGNED_64_16 "truncation_detector_64_16" +#define TRUNCATION64_DETECTOR_UNKNOWN_64_16 "truncation_detector_64_16" + +#define TRUNCATION64_DETECTOR_UNSIGNED_64_8 "truncation_detector_64_8" +#define TRUNCATION64_DETECTOR_SIGNED_64_8 "truncation_detector_64_8" +#define TRUNCATION64_DETECTOR_UNKNOWN_64_8 "truncation_detector_64_8" + +#define TRUNCATION64_DETECTOR_UNSIGNED_32_16 "truncation_detector_32_16" +#define TRUNCATION64_DETECTOR_SIGNED_32_16 "truncation_detector_32_16" +#define TRUNCATION64_DETECTOR_UNKNOWN_32_16 "truncation_detector_32_16" + +#define TRUNCATION64_DETECTOR_UNSIGNED_32_8 "truncation_detector_32_8" +#define TRUNCATION64_DETECTOR_SIGNED_32_8 "truncation_detector_32_8" +#define TRUNCATION64_DETECTOR_UNKNOWN_32_8 "truncation_detector_32_8" + +#define TRUNCATION64_FORCE_EXIT "truncation_force_exit" + +#define SIGNEDNESS64_DETECTOR_SIGNED "signedness_detector_signed" +#define SIGNEDNESS64_DETECTOR_UNSIGNED "signedness_detector_unsigned" + +#endif diff --git a/irdb-lib/libIRDB-transform/include-unused-delete-later/leapattern.cpp b/irdb-lib/libIRDB-transform/include-unused-delete-later/leapattern.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d8a16c304346a126d88473b627dd2e001bc43248 --- /dev/null +++ b/irdb-lib/libIRDB-transform/include-unused-delete-later/leapattern.cpp @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2013, 2014 - University of Virginia + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#include <iostream> +#include <string.h> +#include <stdlib.h> +#include <errno.h> +#include <stdio.h> +#include <sstream> + +#include "leapattern.hpp" + +using namespace std; +using namespace libTransform; + +// +// Supported patterns: +// reg+reg +// reg+k +// reg*reg +// reg*k +// +// Not (yet) supported: +// reg+reg+k +// +LEAPattern::LEAPattern(const MEDS_InstructionCheckAnnotation& p_annotation) +{ + m_isValid = false; + m_isRegPlusReg = false; + m_isRegPlusConstant = false; + m_isRegTimesConstant = false; + m_isRegTimesReg = false; + m_reg1 = rn_UNKNOWN; + m_reg2 = rn_UNKNOWN; + m_constant = 0; + + if(regcomp(&m_regex_reg_plus_reg ,"[eax|ebx|ecx|edx|esi|edi|ebp|rax|rbx|rcx|rdx|rbp|rsi|rdi|r8|r9|r10|r11|r12|r13|r14|r15]\\+[eax|ebx|ecx|edx|esi|edi|ebp|rax|rbx|rcx|rdx|rbp|rsi|rdi|r8|r9|r10|r11|r12|r13|r14|r15]", REG_EXTENDED | REG_ICASE) !=0) + cerr << "Error: regular expression for reg+reg failed" << endl; + + if(regcomp(&m_regex_reg_times_reg ,"[eax|ebx|ecx|edx|esi|edi|ebp|rax|rbx|rcx|rdx|rbp|rsi|rdi|r8|r9|r10|r11|r12|r13|r14|r15]\\*[eax|ebx|ecx|edx|esi|edi|ebp|rax|rbx|rcx|rdx|rbp|rsi|rdi|r8|r9|r10|r11|r12|r13|r14|r15]", REG_EXTENDED | REG_ICASE) !=0) + cerr << "Error: regular expression for reg*reg failed" << endl; + + if(regcomp(&m_regex_reg_plus_constant ,"[eax|ebx|ecx|edx|esi|edi|ebp|rax|rbx|rcx|rdx|rbp|rsi|rdi|r8|r9|r10|r11|r12|r13|r14|r15]\\+[0-9+]", REG_EXTENDED | REG_ICASE) !=0) + cerr << "Error: regular expression for reg+constant failed" << endl; + + if(regcomp(&m_regex_reg_plus_negconstant ,"[eax|ebx|ecx|edx|esi|edi|ebp|rax|rbx|rcx|rdx|rbp|rsi|rdi|r8|r9|r10|r11|r12|r13|r14|r15]\\+\\-[0-9+]", REG_EXTENDED | REG_ICASE) !=0) + cerr << "Error: regular expression for reg+constant failed" << endl; + + if(regcomp(&m_regex_reg_times_constant ,"[eax|ebx|ecx|edx|esi|edi|ebp|rax|rbx|rcx|rdx|rbp|rsi|rdi|r8|r9|r10|r11|r12|r13|r14|r15]\\*[0-9+]", REG_EXTENDED | REG_ICASE) !=0) + cerr << "Error: regular expression for reg+constant failed" << endl; + + const int max = 5; + regmatch_t pmatch[max]; + int countMatch = 0; + + if(regexec(&m_regex_reg_plus_reg, p_annotation.getTarget().c_str(), max, pmatch, 0)==0) + { + // pattern is of the form reg+reg, e.g.: EDX+EAX + // r8+rbp + // r8+r9 + // rax+r9 + string r1, r2; + extractOperands(p_annotation.getTarget(), r1, r2); + cerr << "leapattern: extract ops: " << r1 << " " << r2 << endl; + m_reg1 = Register::getRegister(r1); + m_reg2 = Register::getRegister(r2); + + if (m_reg1 != rn_UNKNOWN && m_reg2 != rn_UNKNOWN) + { + countMatch++; + m_isRegPlusReg = true; + m_isValid = true; + cerr << "leapattern: reg+reg:" << Register::toString(m_reg1) << " " << Register::toString(m_reg2) << endl; + } + } + + if(regexec(&m_regex_reg_times_reg, p_annotation.getTarget().c_str(), max, pmatch, 0)==0) + { + // pattern is of the form reg*reg, e.g.: EDX*EAX + // nb: is this even a valid pattern -- not used + string r1, r2; + extractOperands(p_annotation.getTarget(), r1, r2); + m_reg1 = Register::getRegister(r1); + m_reg2 = Register::getRegister(r2); + cerr << "leapattern: extract ops: " << r1 << " " << r2 << endl; + + if (m_reg1 != rn_UNKNOWN && m_reg2 != rn_UNKNOWN) + { + countMatch++; + m_isRegTimesReg = true; + m_isValid = true; + cerr << "leapattern: reg*reg:" << Register::toString(m_reg1) << " " << Register::toString(m_reg2) << endl; + } + } + +// integertransform: reg+constant: register: EDX constant: 80 target register: EAX annotation: 805525b 6 INSTR CHECK OVERFLOW NOFLAGUNSIGNED 32 EDX+128 ZZ lea eax, [edx+80h] + + if(regexec(&m_regex_reg_plus_constant, p_annotation.getTarget().c_str(), max, pmatch, 0)==0 || + regexec(&m_regex_reg_plus_negconstant, p_annotation.getTarget().c_str(), max, pmatch, 0)==0) + { + // pattern is of the form: reg+constant, e.g.: EDX+16 + // pattern is of the form: reg+-constant, e.g.: EAX+-16 + // note that constant value of annotation is in decimal (not hex) + string r1, k; + extractOperands(p_annotation.getTarget(), r1, k); + m_reg1 = Register::getRegister(r1); + cerr << "leapattern: extract ops: " << r1 << " " << k << endl; + + stringstream constantSS(k); + if (constantSS >> m_constant) + { + m_isRegPlusConstant = true; + m_isValid = true; + countMatch++; + cerr << "leapattern: reg+-constant: stream: " << Register::toString(m_reg1) << " constant: " << dec << m_constant << " annotation: " << p_annotation.toString() << endl; + } + } + + if(regexec(&m_regex_reg_times_constant, p_annotation.getTarget().c_str(), max, pmatch, 0)==0) + { + // pattern is of the form: reg*constant, e.g.: EDX*4 + // note that constant value of annotation is in decimal (not hex) + string r1, k; + extractOperands(p_annotation.getTarget(), r1, k); + cerr << "leapattern: extract ops: " << r1 << " " << k << endl; + m_reg1 = Register::getRegister(r1); + stringstream constantSS(k); + if (constantSS >> m_constant) + { + countMatch++; + cerr << "leapattern: reg*constant: stream: " << p_annotation.getTarget().substr(4) << " constant: " << dec << m_constant << " annotation: " << p_annotation.toString() << endl; + m_isValid = true; + m_isRegTimesConstant = true; + } + } + + if (countMatch == 0 || countMatch > 1) + { + cerr << "leapattern: matching patterns = " << countMatch << " : " << p_annotation.toString() << endl; + m_isValid = false; + } +} + +bool LEAPattern::isValid() const +{ + return m_isValid; +} + +bool LEAPattern::isRegisterPlusRegister() const +{ + return m_isRegPlusReg; +} + +bool LEAPattern::isRegisterTimesRegister() const +{ + return m_isRegTimesReg; +} + +bool LEAPattern::isRegisterPlusConstant() const +{ + return m_isRegPlusConstant; +} + +bool LEAPattern::isRegisterTimesConstant() const +{ + return m_isRegTimesConstant; +} + +RegisterName LEAPattern::getRegister1() const +{ + return m_reg1; +} + +RegisterName LEAPattern::getRegister2() const +{ + return m_reg2; +} + +int LEAPattern::getConstant() const +{ + return m_constant; +} + +// assume is of the form: +// <operand><sign>[minus]<operand> +// where <operand> is a register or constant, +// <sign> is * or + +void LEAPattern::extractOperands(const string target, string& op1, string& op2) +{ + int multiplyPos = target.find('*'); + int plusPos = target.find('+'); + int minusPos = target.find('-'); + + int signPos = -1; + if (multiplyPos >= 0) signPos = multiplyPos; + if (plusPos >= 0) signPos = plusPos; + + op1 = op2 = ""; + + if (signPos < 0) return; + + int op1len = signPos; + int op2len; + + if (minusPos >= 0) + op2len = target.size() - minusPos - 1; + else + op2len = target.size() - signPos - 1; + + op1 = target.substr(0, op1len); + + if (minusPos >= 0) + op2 = target.substr(signPos+2, op2len); // e.g., rax+-5 + else + op2 = target.substr(signPos+1, op2len); +} diff --git a/irdb-lib/libIRDB-transform/include-unused-delete-later/leapattern.hpp b/irdb-lib/libIRDB-transform/include-unused-delete-later/leapattern.hpp new file mode 100644 index 0000000000000000000000000000000000000000..7b25314ad9efba376deda26cb47a760d065b1ae8 --- /dev/null +++ b/irdb-lib/libIRDB-transform/include-unused-delete-later/leapattern.hpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013, 2014 - University of Virginia + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#ifndef _LEA_PATTERN_H_ +#define _LEA_PATTERN_H_ + +#include <regex.h> + +#include "MEDS_InstructionCheckAnnotation.hpp" +#include "MEDS_Register.hpp" + +using namespace MEDS_Annotation; + +namespace libTransform { + +class LEAPattern { + public: + LEAPattern(const MEDS_InstructionCheckAnnotation& p_annotation); + bool isValid() const; + + bool isRegisterPlusRegister() const; + bool isRegisterPlusConstant() const; + bool isRegisterTimesConstant() const; + bool isRegisterTimesRegister() const; // not used + + RegisterName getRegister1() const; + RegisterName getRegister2() const; + int getConstant() const; + + private: + void extractOperands(const string target, string& op1, string& op2); + + private: + bool m_isValid; + bool m_isRegPlusReg; + bool m_isRegPlusConstant; + bool m_isRegTimesReg; + bool m_isRegTimesConstant; + RegisterName m_reg1; + RegisterName m_reg2; + int m_constant; + + regex_t m_regex_reg_plus_reg; + regex_t m_regex_reg_times_reg; + regex_t m_regex_reg_plus_constant; + regex_t m_regex_reg_plus_negconstant; + regex_t m_regex_reg_times_constant; +}; + +} + +#endif diff --git a/irdb-lib/libIRDB-transform/include-unused-delete-later/pointercheck64.cpp b/irdb-lib/libIRDB-transform/include-unused-delete-later/pointercheck64.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3c4ba7d64f82de8ecb949cf94719ef4d69e51ac4 --- /dev/null +++ b/irdb-lib/libIRDB-transform/include-unused-delete-later/pointercheck64.cpp @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2015 - Zephyr Software LLC + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software LLC + * URL : http://www.zephyr-software.com/ + * + */ + +#include <assert.h> +#include <sstream> +#include "pointercheck64.hpp" + +using namespace libTransform; + + +PointerCheck64::PointerCheck64(VariantID_t *p_variantID, FileIR_t *p_fileIR, MEDS_Annotations_t *p_annotations, set<std::string> *p_filteredFunctions, set<VirtualOffset> *p_benignFalsePositives) : IntegerTransform64(p_variantID, p_fileIR, p_annotations, p_filteredFunctions, p_benignFalsePositives) +{ +} + +Instruction_t* PointerCheck64::addCallbackHandlerSequence(Instruction_t *p_orig, Instruction_t *p_fallthrough, std::string p_detector, int p_policy) +{ + if (p_policy == POLICY_EXIT) + { + // exit program + Instruction_t* exit_sequence = addNewAssembly("mov rax, 60"); + Instruction_t* i = addNewAssembly(exit_sequence, "mov rdi, 25"); + i = addNewAssembly(i, "syscall"); + i->setFallthrough(p_fallthrough); + return exit_sequence; + } + else + return IntegerTransform64::addCallbackHandlerSequence(p_orig, p_fallthrough, p_detector, p_policy); +} + +int PointerCheck64::execute() +{ + for( + set<Function_t*>::const_iterator itf=getFileIR()->GetFunctions().begin(); + itf!=getFileIR()->GetFunctions().end(); + ++itf + ) + { + Function_t* func=*itf; + + if (getFilteredFunctions()->find(func->GetName()) != getFilteredFunctions()->end()) + { + logMessage(__func__, "filter out: " + func->GetName()); + continue; + } + + if (isBlacklisted(func)) + { + logMessage(__func__, "blacklisted: " + func->GetName()); + m_numBlacklisted++; + continue; + } + + logMessage(__func__, "processing fn: " + func->GetName()); + + for( + set<Instruction_t*>::const_iterator it=func->GetInstructions().begin(); + it!=func->GetInstructions().end(); + ++it) + { + Instruction_t* insn=*it; + + if (insn && insn->getAddress()) + { + int policy = POLICY_EXIT; + + virtual_offset_t irdb_vo = insn->getAddress()->GetVirtualOffset(); + if (irdb_vo == 0) continue; + + VirtualOffset vo(irdb_vo); + + if (getAnnotations()->count(vo) == 0) + continue; + + std::pair<MEDS_Annotations_t::iterator,MEDS_Annotations_t::iterator> ret; + ret = getAnnotations()->equal_range(vo); + MEDS_InstructionCheckAnnotation annotation; + MEDS_InstructionCheckAnnotation* p_annotation; + for ( MEDS_Annotations_t::iterator it = ret.first; it != ret.second; ++it) + { + MEDS_AnnotationBase *base_type=(it->second); + p_annotation = dynamic_cast<MEDS_InstructionCheckAnnotation*>(base_type); + if(p_annotation == NULL) + continue; + annotation = *p_annotation; + if (!annotation.isValid()) + continue; + else + break; // let's just handle one annotation for now and see how it goes + } + + m_numAnnotations++; + + if (!annotation.isIdiom() || annotation.getIdiomNumber() != IDIOM_POINTER_NUMERIC_WEAKNESS) + { + logMessage(__func__, "skip IDIOM"); + m_numIdioms++; + continue; + } + + if (!insn->getFallthrough()) + { + logMessage(__func__, "Warning: no fall through for instruction -- skipping"); + continue; + } + + if (annotation.isIdiom() && !isInstrumentIdioms()) + { + logMessage(__func__, "skip IDIOM"); + m_numIdioms++; + continue; + } + + // this idiom deals with pointers ==> unsigned + if (!annotation.isUnsigned()) + { + logMessage(__func__, "Warning: only instrument UNSIGNED for this idiom -- skipping"); + continue; + } + + logMessage(__func__, annotation, "-- instruction: " + insn->getDisassembly()); + + if (annotation.isOverflow()) + { + m_numTotalOverflows++; + handleOverflowCheck(insn, annotation, policy); + } + + if (annotation.isUnderflow()) + { + m_numTotalUnderflows++; + handleUnderflowCheck(insn, annotation, policy); + } + } + } // end iterate over all instructions in a function + } // end iterate over all functions + + return 0; +} + diff --git a/irdb-lib/libIRDB-transform/include-unused-delete-later/pointercheck64.hpp b/irdb-lib/libIRDB-transform/include-unused-delete-later/pointercheck64.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b7593b966a241e2b210dcc7d545de930390a7cc2 --- /dev/null +++ b/irdb-lib/libIRDB-transform/include-unused-delete-later/pointercheck64.hpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2015 - Zephyr Software LLC + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software LLC + * URL : http://www.zephyr-software.com/ + */ + +#ifndef _LIBTRANSFORM_POINTERCHECK64_H_ +#define _LIBTRANSFORM_POINTERCHECK64_H_ + +#include "integertransform64.hpp" + +namespace libTransform +{ + +using namespace std; +using namespace libIRDB; + +class PointerCheck64 : public IntegerTransform64 +{ + public: + PointerCheck64(VariantID_t *, FileIR_t*, MEDS_Annotations_t *p_annotations, set<std::string> *p_filteredFunctions, set<VirtualOffset> *p_warnings); + + virtual int execute(); + virtual Instruction_t* addCallbackHandlerSequence(Instruction_t *p_orig, Instruction_t *p_fallthrough, std::string p_detector, int p_policy); + +}; + +} // end namespace + +#endif diff --git a/irdb-lib/libIRDB-transform/include-unused-delete-later/transform.hpp b/irdb-lib/libIRDB-transform/include-unused-delete-later/transform.hpp new file mode 100644 index 0000000000000000000000000000000000000000..325fa40d6e1ae85a3b92efa8b9ad6813543a453c --- /dev/null +++ b/irdb-lib/libIRDB-transform/include-unused-delete-later/transform.hpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013, 2014 - University of Virginia + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#ifndef _LIBTRANSFORM_TRANSFORM_H +#define _LIBTRANSFORM_TRANSFORM_H + +#include <string> +#include <set> +#include <map> + +#include <irdb-core> + +#include "MEDS_InstructionCheckAnnotation.hpp" +#include "VirtualOffset.hpp" + +#define MAX_ASSEMBLY_SIZE 2048 + +namespace libIRDB +{ + class FileIR_t; +} +namespace libTransform +{ +using namespace std; +using namespace IRDB_SDK; +using namespace MEDS_Annotation; + + +class Transform +{ + + public: + Transform(VariantID_t *, FileIR_t *, set<std::string> *p_filteredFunctions); + + protected: + void setAssembly(Instruction_t *p_instr, string p_asm); + Instruction_t* addNewAssembly(string p_asm); + Instruction_t* addNewAssembly(Instruction_t *p_instr, string p_asm); + Instruction_t* registerCallbackHandler64(string p_callbackHandler, int p_numArgs); + void addCallbackHandler64(Instruction_t *p_instr, string p_callbackHandler, int p_numArgs); + void addInstruction(Instruction_t *p_instr, string p_dataBits, Instruction_t *p_fallThrough, Instruction_t *p_target); + Instruction_t* carefullyInsertBefore(Instruction_t* &p_target, Instruction_t* &p_new); + Instruction_t* insertAssemblyBefore(Instruction_t* before, const string &the_asm, Instruction_t* target=nullptr); + Instruction_t* insertAssemblyAfter(Instruction_t* after, const string &the_asm, Instruction_t* target=nullptr); + + void addPushRegister(Instruction_t *p_instr, RegisterName, Instruction_t *p_fallThrough); + void addPopRegister(Instruction_t *p_instr, RegisterName, Instruction_t *p_fallThrough); + void addPusha(Instruction_t *p_instr, Instruction_t *p_fallThrough); + void addPushf(Instruction_t *p_instr, Instruction_t *p_fallThrough); + void addPopa(Instruction_t *p_instr, Instruction_t *p_fallThrough); + void addPopf(Instruction_t *p_instr, Instruction_t *p_fallThrough); + void addNop(Instruction_t *p_instr, Instruction_t *p_fallThrough); + + void addCallbackHandler(string p_detector, Instruction_t *p_instrumented, Instruction_t *p_instr, Instruction_t *p_fallThrough, int p_policy, AddressID_t *addressOriginal = NULL); + + void addTestRegister(Instruction_t *p_instr, RegisterName, Instruction_t *p_fallThrough); + void addTestRegisterMask(Instruction_t *p_instr, RegisterName, unsigned p_mask, Instruction_t *p_fallThrough); + void addCmpRegisterMask(Instruction_t *p_instr, RegisterName, unsigned p_mask, Instruction_t *p_fallThrough); + + void addJns(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target); + void addJz(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target); + void addJo(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target); + void addJno(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target); + void addJc(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target); + void addJnc(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target); + void addJnz(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target); + void addJae(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target); + void addNot(Instruction_t *p_instr, RegisterName, Instruction_t *p_fallThrough); + void addHlt(Instruction_t *p_instr, Instruction_t *p_fallThrough); + + void addAddRegisters(Instruction_t *p_instr, RegisterName p_regTgt, RegisterName p_regSrc, Instruction_t *p_fallThrough); + void addAddRegisterConstant(Instruction_t *p_instr, RegisterName p_regTgt, int p_constantValue, Instruction_t *p_fallThrough); + void addMulRegisterConstant(Instruction_t *p_instr, RegisterName p_regTgt, int p_constantValue, Instruction_t *p_fallThrough); + void addMovRegisters(Instruction_t *p_instr, RegisterName p_regTgt, RegisterName p_regSrc, Instruction_t *p_fallThrough); + + Instruction_t* allocateNewInstruction(DatabaseID_t p_fileID=BaseObj_t::NOT_IN_DATABASE, Function_t* p_func=NULL); + + VirtualOffset_t getAvailableAddress(); + + VariantID_t* getVariantID() { return m_variantID; } + FileIR_t* getFileIR(); // { return dynamic_cast<FileIR_t*>(m_fileIR); } + set<std::string>* getFilteredFunctions() { return m_filteredFunctions; } + + Instruction_t* addNewMaxSaturation(Instruction_t *p_prev, RegisterName p_reg, const MEDS_InstructionCheckAnnotation p_annotation); + void addMinSaturation(Instruction_t *p_instruction, RegisterName p_reg, const MEDS_InstructionCheckAnnotation& p_annotation, Instruction_t *p_fallthrough); + void addMaxSaturation(Instruction_t *p_instruction, RegisterName p_reg, const MEDS_InstructionCheckAnnotation& p_annotation, Instruction_t *p_fallthrough); + void addMovRegisterUnsignedConstant(Instruction_t *p_instr, RegisterName p_regTgt, unsigned long p_constant, Instruction_t *p_fallThrough); + void addMovRegisterSignedConstant(Instruction_t *p_instr, RegisterName p_regTgt, long int p_constant, Instruction_t *p_fallThrough); + void addAndRegister32Mask(Instruction_t *p_instr, RegisterName p_regTgt, unsigned int p_mask, Instruction_t *p_fallThrough); + + protected: + void logMessage(const std::string &p_method, const std::string &p_msg); + void logMessage(const std::string &p_method, const MEDS_InstructionCheckAnnotation&, const std::string &p_msg); + + private: + void addTestRegister8(Instruction_t *p_instr, RegisterName, Instruction_t *p_fallThrough); + void addTestRegister16(Instruction_t *p_instr, RegisterName, Instruction_t *p_fallThrough); + void addTestRegister32(Instruction_t *p_instr, RegisterName, Instruction_t *p_fallThrough); + void addTestRegisterMask32(Instruction_t *p_instr, RegisterName, unsigned p_mask, Instruction_t *p_fallThrough); + void addCmpRegisterMask32(Instruction_t *p_instr, RegisterName, unsigned p_mask, Instruction_t *p_fallThrough); + + VariantID_t *m_variantID; + libIRDB::FileIR_t *m_fileIR; + set<std::string> *m_filteredFunctions; + std::map<std::string, Instruction_t*> m_handlerMap; +}; + +// make sure these match values in detector_handlers.h in the strata library +#define POLICY_DEFAULT 0 +#define POLICY_CONTINUE 1 +#define POLICY_EXIT 2 +#define POLICY_CONTINUE_SATURATING_ARITHMETIC 3 + +#define DEBUG_CALLBACK_HANDLER "debug_handler" + +// utility function +void convertToLowercase(string&); + +} + +#endif + diff --git a/irdb-lib/libIRDB-transform/src/SConscript b/irdb-lib/libIRDB-transform/src/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..0c250bfeb153f70a9b77739937e968904158601a --- /dev/null +++ b/irdb-lib/libIRDB-transform/src/SConscript @@ -0,0 +1,31 @@ +import os + + + +Import('env') +myenv=env.Clone() +myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) + +files="rewrite_util.cpp transform.cpp" + +cpppath=''' + $IRDB_SDK/include + $SECURITY_TRANSFORMS_HOME/include + $SECURITY_TRANSFORMS_HOME/libIRDB-core/include + $SECURITY_TRANSFORMS_HOME/libIRDB-cfg/include + $SECURITY_TRANSFORMS_HOME/libIRDB-util/include + $SECURITY_TRANSFORMS_HOME/libMEDSannotation/include/ + ''' + + +LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" +LIBS=Split("irdb-core irdb-cfg irdb-util MEDSannotation") + +myenv=myenv.Clone(CPPPATH=Split(cpppath)) +myenv.Append(CXXFLAGS = " -std=c++11 ") + +lib=myenv.SharedLibrary("irdb-transform", Split(files), LIBPATH=LIBPATH, LIBS=LIBS) +install=myenv.Install("$SECURITY_TRANSFORMS_HOME/lib/", lib) +Default(install) +Return('install') + diff --git a/irdb-lib/libIRDB-transform/src/SConstruct b/irdb-lib/libIRDB-transform/src/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..c96332f0422ad5df0853931209219d9a2e20bc17 --- /dev/null +++ b/irdb-lib/libIRDB-transform/src/SConstruct @@ -0,0 +1,6 @@ + + + +env=Environment() +Export('env') +lib=SConscript("SConscript") diff --git a/irdb-lib/libIRDB-transform/src/rewrite_util.cpp b/irdb-lib/libIRDB-transform/src/rewrite_util.cpp new file mode 100644 index 0000000000000000000000000000000000000000..443236f80fd64c1cda89e5171160824d553c1dd0 --- /dev/null +++ b/irdb-lib/libIRDB-transform/src/rewrite_util.cpp @@ -0,0 +1,276 @@ + +#include <irdb-transform> +#include <libIRDB-core.hpp> + +// Copied from PnTransform +// @todo: create a utility library with the one interface + + +using namespace std; +using namespace IRDB_SDK; + +void copyInstruction(Instruction_t* src, Instruction_t* dest); +Instruction_t* copyInstruction(FileIR_t* virp, Instruction_t* instr); +Instruction_t* allocateNewInstruction(FileIR_t* virp, DatabaseID_t p_fileID,Function_t* func); +Instruction_t* allocateNewInstruction(FileIR_t* virp, Instruction_t *template_instr); + + + +void setInstructionsDetails(FileIR_t* virp, Instruction_t *p_instr, string p_dataBits, Instruction_t *p_fallThrough, Instruction_t *p_target) +{ + if (p_instr == NULL) return; + + p_instr->setDataBits(p_dataBits); + p_instr->setComment(p_instr->getDisassembly()); + p_instr->setFallthrough(p_fallThrough); + p_instr->setTarget(p_target); + + auto real_virp=dynamic_cast<libIRDB::FileIR_t*>(virp); + assert(real_virp); + + real_virp->GetAddresses().insert(p_instr->getAddress()); + real_virp->GetInstructions().insert(p_instr); +} + + +//For all insertBefore functions: +//The "first" instruction will have its contents replaced and a duplicate of "first" will be in the follow of first. +//This duplicate is returned since the user already has a pointer to first. +//To insert before an instruction is the same as modifying the original instruction, and inserting after it +//a copy of the original instruction +Instruction_t* IRDB_SDK::insertAssemblyBefore(FileIR_t* virp, Instruction_t* first, string assembly, Instruction_t *target) +{ + Instruction_t* next = copyInstruction(virp,first); + + //In case the fallthrough is null, generate spri has to have a + //place to jump, which is determined by the original address. + //This code is not placed in copyInstruction since this is only needed + //when inserting before + next->setOriginalAddressID(first->getOriginalAddressID()); + //"Null" out the original address (it should be as if the instruction was not in the database). + first->setOriginalAddressID(BaseObj_t::NOT_IN_DATABASE); + auto real_first=dynamic_cast<libIRDB::Instruction_t*>(first); + assert(real_first); + real_first->GetRelocations().clear(); + first->setIBTargets(NULL); + //Note that the instruction just inserted should have the same exception handling + //info as the instructions immediately around it. + //Thus the exception handling information (EhCallSite and EhProgram) are kept the + //same from the copy of first (unlike with relocations and IBT's). + + virp->changeRegistryKey(first,next); + IRDB_SDK::setInstructionAssembly(virp,first,assembly,next,target); + + return next; +} + +#if 0 +Instruction_t* insertAssemblyBefore(FileIR_t* virp, Instruction_t* first, string assembly) +{ + return insertAssemblyBefore(virp,first,assembly,NULL); +} + + +Instruction_t* insertDataBitsBefore(FileIR_t* virp, Instruction_t* first, string dataBits) +{ + return insertDataBitsBefore(virp,first,dataBits,NULL); +} +#endif + +Instruction_t* IRDB_SDK::insertDataBitsBefore(FileIR_t* virp, Instruction_t* first, string dataBits, Instruction_t *target) +{ + Instruction_t* next = copyInstruction(virp,first); + + //In case the fallthrough is null, generate spri has to have a + //place to jump, which is determined by the original address. + //This code is not placed in copyInstruction since this is only needed + //when inserting before + next->setOriginalAddressID(first->getOriginalAddressID()); + //"Null" out the original address (it should be as if the instruction was not in the database). + first->setOriginalAddressID(BaseObj_t::NOT_IN_DATABASE); + auto real_first=dynamic_cast<libIRDB::Instruction_t*>(first); + assert(real_first); + real_first->GetRelocations().clear(); + first->setIBTargets(NULL); + //Note that the instruction just inserted should have the same exception handling + //info as the instructions immediately around it. + //Thus the exception handling information (EhCallSite and EhProgram) are kept the + //same from the copy of first (unlike with relocations and IBT's). + + virp->changeRegistryKey(first,next); + setInstructionsDetails(virp,first,dataBits,next,target); + + return next; +} + +Instruction_t* IRDB_SDK::insertAssemblyAfter(FileIR_t* virp, Instruction_t* first, string assembly, Instruction_t *target) +{ + Instruction_t *new_instr = allocateNewInstruction(virp,first); + IRDB_SDK::setInstructionAssembly(virp,new_instr,assembly,first->getFallthrough(), target); + first->setFallthrough(new_instr); + return new_instr; +} + +#if 0 +Instruction_t* insertAssemblyAfter(FileIR_t* virp, Instruction_t* first, string assembly) +{ + return insertAssemblyAfter(virp,first,assembly,NULL); + +} +#endif + +Instruction_t* IRDB_SDK::insertDataBitsAfter(FileIR_t* virp, Instruction_t* first, string dataBits, Instruction_t *target) +{ + Instruction_t *new_instr = allocateNewInstruction(virp,first); + setInstructionsDetails(virp,new_instr,dataBits,first->getFallthrough(), target); + first->setFallthrough(new_instr); + + return new_instr; +} + +#if 0 +Instruction_t* insertDataBitsAfter(FileIR_t* virp, Instruction_t* first, string dataBits) +{ + return insertDataBitsAfter(virp,first,dataBits,NULL); +} +#endif + +Instruction_t* IRDB_SDK::addNewDataBits(FileIR_t* firp, Instruction_t *p_instr, string p_bits) +{ + Instruction_t* newinstr; + if (p_instr) + newinstr = allocateNewInstruction(firp,p_instr->getAddress()->getFileID(), p_instr->getFunction()); + else + newinstr = allocateNewInstruction(firp,firp->getFile()->getFileID(), NULL); + + newinstr->setDataBits(p_bits); + + if (p_instr) + { + newinstr->setFallthrough(p_instr->getFallthrough()); + p_instr->setFallthrough(newinstr); + } + + return newinstr; +} + +Instruction_t* IRDB_SDK::addNewDataBits(FileIR_t* firp, string p_bits) +{ + return IRDB_SDK::addNewDataBits(firp,nullptr,p_bits); +} + + +Instruction_t* IRDB_SDK::addNewAssembly(FileIR_t* firp, Instruction_t *p_instr, string p_asm) +{ + Instruction_t* newinstr; + if (p_instr) + newinstr = allocateNewInstruction(firp,p_instr->getAddress()->getFileID(), p_instr->getFunction()); + else + newinstr = allocateNewInstruction(firp,firp->getFile()->getFileID(), NULL); + + firp->registerAssembly(newinstr, p_asm); + + if (p_instr) + { + newinstr->setFallthrough(p_instr->getFallthrough()); + p_instr->setFallthrough(newinstr); + } + + return newinstr; +} + +Instruction_t* IRDB_SDK::addNewAssembly(FileIR_t* firp, string p_asm) +{ + return IRDB_SDK::addNewAssembly(firp,nullptr,p_asm); +} + + +//Does not insert into any variant +Instruction_t* copyInstruction(Instruction_t* instr) +{ + Instruction_t* cpy = new libIRDB::Instruction_t(); + + copyInstruction(instr,cpy); + + return cpy; +} + +Instruction_t* copyInstruction(FileIR_t* virp, Instruction_t* instr) +{ + Instruction_t* cpy = allocateNewInstruction(virp,instr); + + copyInstruction(instr,cpy); + + return cpy; +} + +void copyInstruction(Instruction_t* src, Instruction_t* dest) +{ + auto real_dest=dynamic_cast<libIRDB::Instruction_t*>(dest); + dest->setDataBits(src->getDataBits()); + dest->setComment(src->getComment()); + dest->setCallback(src->getCallback()); + dest->setFallthrough(src->getFallthrough()); + dest->setTarget(src->getTarget()); + dest->setIBTargets(src->getIBTargets()); + real_dest->GetRelocations()=src->getRelocations(); + dest->setEhProgram(src->getEhProgram()); + dest->setEhCallSite(src->getEhCallSite()); +} + +Instruction_t* allocateNewInstruction(FileIR_t* virp, DatabaseID_t p_fileID,Function_t* func) +{ + auto instr = new libIRDB::Instruction_t(); + auto a = new libIRDB::AddressID_t(); + + a->setFileID(p_fileID); + + instr->setFunction(func); + instr->setAddress(a); + if(func) + { + auto real_func=dynamic_cast<libIRDB::Function_t*>(func); + assert(func); + real_func->GetInstructions().insert(instr); + } + + auto real_virp=dynamic_cast<libIRDB::FileIR_t*>(virp); + assert(real_virp); + real_virp->GetInstructions().insert(instr); + real_virp->GetAddresses().insert(a); + +// inserted_instr[func].insert(instr); +// inserted_addr[func].insert(a); + + return instr; +} + +Instruction_t* allocateNewInstruction(FileIR_t* virp, Instruction_t *template_instr) +{ + Function_t *func = template_instr->getFunction(); + DatabaseID_t fileID = template_instr->getAddress()->getFileID(); + return allocateNewInstruction(virp, fileID, func); +} + +void IRDB_SDK::setInstructionAssembly(FileIR_t* virp,Instruction_t *p_instr, const string& p_assembly, Instruction_t *p_fallThrough, Instruction_t *p_target) +{ + if (p_instr == NULL) return; + + ///TODO: what if bad assembly? + virp->registerAssembly(p_instr,p_assembly); + p_instr->setComment(p_assembly); + p_instr->setFallthrough(p_fallThrough); + p_instr->setTarget(p_target); + + auto real_virp=dynamic_cast<libIRDB::FileIR_t*>(virp); + assert(real_virp); + real_virp->GetAddresses().insert(p_instr->getAddress()); + real_virp->GetInstructions().insert(p_instr); +} + +void IRDB_SDK::setInstructionAssembly(FileIR_t* virp,Instruction_t *p_instr, const string& p_assembly) +{ + IRDB_SDK::setInstructionAssembly(virp,p_instr,p_assembly, p_instr->getFallthrough(), p_instr->getTarget()); +} + + diff --git a/irdb-lib/libIRDB-transform/src/transform.cpp b/irdb-lib/libIRDB-transform/src/transform.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fb70acbcdd23e41ad6abf9b94c90eb4997d289fa --- /dev/null +++ b/irdb-lib/libIRDB-transform/src/transform.cpp @@ -0,0 +1,1590 @@ +/* + * Copyright (c) 2013, 2014 - University of Virginia + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#include <irdb-transform> + +using namespace IRDB_SDK; + +Transform::Transform(FileIR_t *p_fileIR) + : + m_fileIR (p_fileIR) +{ + assert(m_fileIR); +} + +FileIR_t* Transform::getFileIR() +{ + return m_fileIR; +} + +const FileIR_t* Transform::getFileIR() const +{ + return m_fileIR; +} + +Instruction_t* Transform::insertAssemblyBefore(Instruction_t* before, const string &the_asm, Instruction_t* target) +{ + return IRDB_SDK::insertAssemblyBefore(getFileIR(), before, the_asm, target); +} + + +Instruction_t* Transform::insertAssemblyAfter(Instruction_t* before, const string &the_asm, Instruction_t* target) +{ + return IRDB_SDK::insertAssemblyAfter(getFileIR(), before, the_asm, target); +} + +Instruction_t* Transform::insertDataBitsBefore(Instruction_t* before, const string &the_asm, Instruction_t* target) +{ + return IRDB_SDK::insertDataBitsBefore(getFileIR(), before, the_asm, target); +} + +Instruction_t* Transform::insertDataBitsAfter(Instruction_t* before, const string &the_asm, Instruction_t* target) +{ + return IRDB_SDK::insertDataBitsAfter(getFileIR(), before, the_asm, target); +} + +Instruction_t* Transform::addNewDataBits(const string& p_bits) +{ + return IRDB_SDK::addNewDataBits(getFileIR(), p_bits); +} + +Instruction_t* Transform::addNewAssembly(const string& p_bits) +{ + return IRDB_SDK::addNewAssembly(getFileIR(), p_bits); +} + +void Transform::setInstructionAssembly(Instruction_t* instr, const string& p_asm, Instruction_t *p_new_fallthrough, Instruction_t* p_new_target) +{ + return IRDB_SDK::setInstructionAssembly(getFileIR(), instr, p_asm, p_new_fallthrough, p_new_target); +} + +void Transform::setInstructionAssembly(Instruction_t* instr, const string& p_asm) +{ + return IRDB_SDK::setInstructionAssembly(getFileIR(), instr, p_asm); +} + + + +#if 0 +void Transform::addInstruction(Instruction_t *p_instr, string p_dataBits, Instruction_t *p_fallThrough, Instruction_t *p_target) +{ + if (p_instr == NULL) return; + + p_instr->setDataBits(p_dataBits); + p_instr->setComment(p_instr->getDisassembly()); + p_instr->setFallthrough(p_fallThrough); + p_instr->setTarget(p_target); + m_fileIR->GetAddresses().insert(p_instr->getAddress()); + m_fileIR->GetInstructions().insert(p_instr); +} + +#define BENSWAY + +// +// Before: After: +// <p_instrumented> ["mov edx,1"] <p_newInstr> [] +// <dupInstr> ["mov edx,1"] <-- returns +// +Instruction_t* Transform::carefullyInsertBefore(Instruction_t* &p_instrumented, Instruction_t * &p_newInstr) +{ + +//For all insertBefore functions: +//The "first" instruction will have its contents replaced and a duplicate of "first" will be in the follow of first. +//This duplicate is returned since the user already has a pointer to first. +//To insert before an instruction is the same as modifying the original instruction, and inserting after it +//a copy of the original instruction + +#ifdef BENSWAY + Instruction_t* i2 = IRDBUtility::insertAssemblyBefore(m_fileIR, p_instrumented, m_fileIR->lookupAssembly(p_newInstr), p_newInstr->getTarget()); +cerr << "carefullyInsertBefore (Ben's Way): @: 0x" << std::hex << p_instrumented->getAddress() << std::dec << " old instruction: " << p_instrumented->getDisassembly() << " new instruction: " << m_fileIR->lookupAssembly(p_newInstr) << endl; + return i2; +#else + DatabaseID_t fileID = p_instrumented->getAddress()->getFileID(); + Function_t* func = p_instrumented->getFunction(); + + assert(p_instrumented && p_newInstr && p_instrumented->getAddress()); + +// why is old instrunction blank? +cerr << "(1) carefullyInsertBefore: @: 0x" << std::hex << p_instrumented->getAddress() << std::dec << " old instruction: " << p_instrumented->getDisassembly() << " new instruction: " << m_fileIR->lookupAssembly(p_newInstr) << endl; + + // duplicate old instrumented instruction + Instruction_t* dupInstr = allocateNewInstruction(fileID, func); + + dupInstr->setDataBits(p_instrumented->GetDataBits()); + dupInstr->setComment(p_instrumented->getComment()); + dupInstr->setCallback(p_instrumented->getCallback()); + dupInstr->setFallthrough(p_instrumented->getFallthrough()); + dupInstr->setTarget(p_instrumented->getTarget()); + dupInstr->setOriginalAddressID(p_instrumented->getOriginalAddressID()); + AddressID_t *saveIBTA = p_instrumented->GetIndirectBranchTargetAddress(); + dupInstr->setIndirectBranchTargetAddress(NULL); + + // + // pre: p_instrument --> "mov edx, 1" + // + // post: p_instrument no longer in map + // new --> "mov edx, 1" + // + // this function is equivalent to: + // m_fileIR->UnregisterAssembly(p_instrumented); + // m_fileIR->registerAssembly(dupInstr, newAssemblyCode); + // + m_fileIR->ChangeRegistryKey(p_instrumented, dupInstr); + + if (p_newInstr->GetDataBits().size() == 0) + m_fileIR->registerAssembly(p_instrumented, m_fileIR->lookupAssembly(p_newInstr)); + else + p_instrumented->setDataBits(p_newInstr->GetDataBits()); + + p_instrumented->setComment(p_newInstr->getComment()); + p_instrumented->setCallback(p_newInstr->getCallback()); + p_instrumented->setFallthrough(dupInstr); + + p_instrumented->setOriginalAddressID(BaseObj_t::NOT_IN_DATABASE); + p_instrumented->setIndirectBranchTargetAddress(saveIBTA); + p_instrumented->GetRelocations().clear(); + + p_newInstr = p_instrumented; + +cerr << "(2) carefullyInsertBefore: @: 0x" << std::hex << p_instrumented->getAddress() << std::dec << " old instruction: " << dupInstr->getDisassembly() << " new instruction: " << m_fileIR->lookupAssembly(p_newInstr) << endl; + return dupInstr; +#endif +} + + +void Transform::addPushf(Instruction_t *p_pushf_i, Instruction_t *p_fallThrough) +{ + string dataBits; + dataBits.resize(1); + dataBits[0] = 0x9c; + addInstruction(p_pushf_i, dataBits, p_fallThrough, NULL); +} + +void Transform::addPushRegister(Instruction_t *p_instr, RegisterName p_reg, Instruction_t *p_fallThrough) +{ + string dataBits; + dataBits.resize(1); + + if (p_reg == rn_EAX || p_reg == rn_RAX) + { + dataBits[0] = 0x50; + } + else if (p_reg == rn_EBX || p_reg == rn_RBX) + { + dataBits[0] = 0x53; + } + else if (p_reg == rn_ECX || p_reg == rn_RCX) + { + dataBits[0] = 0x51; + } + else if (p_reg == rn_EDX || p_reg == rn_RDX) + { + dataBits[0] = 0x52; + } + else if (p_reg == rn_ESI || p_reg == rn_RSI) + { + dataBits[0] = 0x56; + } + else if (p_reg == rn_EDI || p_reg == rn_RDI) + { + dataBits[0] = 0x57; + } + else if (p_reg == rn_EBP || p_reg == rn_RBP) + { + dataBits[0] = 0x55; + } + else if (p_reg == rn_ESP || p_reg == rn_RSP) + { + dataBits[0] = 0x54; + } + else + { + dataBits.resize(2); + dataBits[0] = 0x41; + if (p_reg == rn_R8) + { + dataBits[1] = 0x50; + } + else if (p_reg == rn_R9) + { + dataBits[1] = 0x51; + } + else if (p_reg == rn_R10) + { + dataBits[1] = 0x52; + } + else if (p_reg == rn_R11) + { + dataBits[1] = 0x53; + } + else if (p_reg == rn_R12) + { + dataBits[1] = 0x54; + } + else if (p_reg == rn_R13) + { + dataBits[1] = 0x55; + } + else if (p_reg == rn_R14) + { + dataBits[1] = 0x56; + } + else if (p_reg == rn_R15) + { + dataBits[1] = 0x57; + } + else + { + cerr << "Transform::addPushRegister: unhandled register: " << p_reg << endl; + assert(0); + return; + } + } + + addInstruction(p_instr, dataBits, p_fallThrough, NULL); +} + +void Transform::addPopRegister(Instruction_t *p_instr, RegisterName p_reg, Instruction_t *p_fallThrough) +{ + string dataBits; + dataBits.resize(1); + + if (p_reg == rn_EAX || p_reg == rn_RAX) + { + dataBits[0] = 0x58; + } + else if (p_reg == rn_EBX || p_reg == rn_RBX) + { + dataBits[0] = 0x5b; + } + else if (p_reg == rn_ECX || p_reg == rn_RCX) + { + dataBits[0] = 0x59; + } + else if (p_reg == rn_EDX || p_reg == rn_RDX) + { + dataBits[0] = 0x5a; + } + else if (p_reg == rn_ESI || p_reg == rn_RSI) + { + dataBits[0] = 0x5e; + } + else if (p_reg == rn_EDI || p_reg == rn_RDI) + { + dataBits[0] = 0x5f; + } + else if (p_reg == rn_EBP || p_reg == rn_RBP) + { + dataBits[0] = 0x5d; + } + else if (p_reg == rn_ESP || p_reg == rn_RSP) + { + dataBits[0] = 0x5c; + } + else + { + dataBits.resize(2); + dataBits[0] = 0x41; + if (p_reg == rn_R8) + { + dataBits[1] = 0x58; + } + else if (p_reg == rn_R9) + { + dataBits[1] = 0x59; + } + else if (p_reg == rn_R10) + { + dataBits[1] = 0x5a; + } + else if (p_reg == rn_R11) + { + dataBits[1] = 0x5b; + } + else if (p_reg == rn_R12) + { + dataBits[1] = 0x5c; + } + else if (p_reg == rn_R13) + { + dataBits[1] = 0x5d; + } + else if (p_reg == rn_R14) + { + dataBits[1] = 0x5e; + } + else if (p_reg == rn_R15) + { + dataBits[1] = 0x5f; + } + else + { + cerr << "Transform::addPopRegister: unhandled register"; + assert(0); + return; + } + } + + addInstruction(p_instr, dataBits, p_fallThrough, NULL); +} + +void Transform::addPusha(Instruction_t *p_pusha_i, Instruction_t *p_fallThrough) +{ + string dataBits; + dataBits.resize(1); + dataBits[0] = 0x60; + addInstruction(p_pusha_i, dataBits, p_fallThrough, NULL); +} + +void Transform::addPopf(Instruction_t *p_popf_i, Instruction_t *p_fallThrough) +{ + string dataBits; + dataBits.resize(1); + dataBits[0] = 0x9d; + addInstruction(p_popf_i, dataBits, p_fallThrough, NULL); +} + +void Transform::addPopa(Instruction_t *p_popa_i, Instruction_t *p_fallThrough) +{ + string dataBits; + dataBits.resize(1); + dataBits[0] = 0x61; + addInstruction(p_popa_i, dataBits, p_fallThrough, NULL); +} + +void Transform::addNop(Instruction_t *p_nop_i, Instruction_t *p_fallThrough) +{ + string dataBits; + dataBits.resize(1); + dataBits[0] = 0x90; + p_nop_i->setComment(string("NOP")); + addInstruction(p_nop_i, dataBits, p_fallThrough, NULL); +} + +Instruction_t* Transform::allocateNewInstruction(DatabaseID_t p_fileID, Function_t* p_func) +{ + Instruction_t *instr = new libIRDB::Instruction_t(); + AddressID_t *a = new libIRDB::AddressID_t(); + + a->setFileID(p_fileID); + + instr->setFunction(p_func); + instr->setAddress(a); + + m_fileIR->GetInstructions().insert(instr); + m_fileIR->GetAddresses().insert(a); + return instr; +} + +VirtualOffset_t Transform::getAvailableAddress() +{ +/* + // traverse all instructions + // grab address + + // @todo: lookup instruction size so that we don't waste any space + // for some reason the max available address is incorrect! was ist los? + + VirtualOffset_t availableAddressOffset = 0; + for( + set<Instruction_t*>::const_iterator it=p_virp->GetInstructions().begin(); + it!=p_virp->GetInstructions().end(); + ++it + ) + { + Instruction_t* insn=*it; + if (!insn) continue; + + AddressID_t* addr = insn->getAddress(); + VirtualOffset_t offset = addr->setVirtualOffset(); + + if (offset > availableAddressOffset) + { + availableAddressOffset = offset; + } + } +// availableAddressOffset + 16; +*/ + + static int counter = -16; + counter += 16; + return 0xf0000000 + counter; +} + +void Transform::addCallbackHandler(string p_detector, Instruction_t *p_instrumentedInstruction, Instruction_t *p_instruction, Instruction_t *p_fallThrough, int p_policy, AddressID_t *p_addressOriginalInstruction) +{ + + assert(getFileIR() && p_instruction && p_fallThrough); + + string dataBits; + + DatabaseID_t fileID = p_instruction->getAddress()->getFileID(); + Function_t* func = p_instruction->getFunction(); + + // create and register new instructions (and addresses) + Instruction_t* pushf_i = allocateNewInstruction(fileID, func); + Instruction_t* pusha_i = allocateNewInstruction(fileID, func); + Instruction_t* pushPolicy_i = allocateNewInstruction(fileID, func); + Instruction_t* pusharg_i = allocateNewInstruction(fileID, func); + Instruction_t* pushret_i = allocateNewInstruction(fileID, func); + Instruction_t* poparg_i = allocateNewInstruction(fileID, func); + Instruction_t* popPolicy_i = allocateNewInstruction(fileID, func); + Instruction_t* popa_i = allocateNewInstruction(fileID, func); + Instruction_t* popf_i = allocateNewInstruction(fileID, func); + + // pin the poparg instruction + VirtualOffset_t postDetectorReturn = getAvailableAddress(); + poparg_i->getAddress()->setVirtualOffset(postDetectorReturn); + + // link callback handler sequence to instrumented instruction + p_instruction->setFallthrough(pushf_i); + p_instruction->setComment(p_instruction->getComment() + " -- start of callback handler sequence"); + + // pushf + addPushf(pushf_i, pusha_i); + + // pusha + addPusha(pusha_i, pushPolicy_i); + + // push detector exit policy + // 0 - default + // 1 - continue + // 2 - exit + // 3 - saturating arithmetic + dataBits.resize(5); + dataBits[0] = 0x68; + int *tmpi = (int *) &dataBits[1]; + *tmpi = p_policy; + pushPolicy_i->setDataBits(dataBits); + pushPolicy_i->setComment(pushPolicy_i->getDisassembly() + string(" - policy spec")); + pushPolicy_i->setFallthrough(pusharg_i); + + // push (PC of instrumented instruction) + dataBits.resize(5); + dataBits[0] = 0x68; + VirtualOffset_t *tmp = (VirtualOffset_t *) &dataBits[1]; + if (p_addressOriginalInstruction) + *tmp = p_addressOriginalInstruction->getVirtualOffset(); + else + *tmp = p_instrumentedInstruction->getAddress()->getVirtualOffset(); + pusharg_i->setDataBits(dataBits); + pusharg_i->setComment(pusharg_i->getDisassembly()); + pusharg_i->setFallthrough(pushret_i); + + // pushret + dataBits.resize(5); + dataBits[0] = 0x68; + tmp = (VirtualOffset_t *) &dataBits[1]; + *tmp = postDetectorReturn; + pushret_i->setDataBits(dataBits); + pushret_i->setComment(pushret_i->getDisassembly()); + pushret_i->setFallthrough(poparg_i); + + // poparg + dataBits.resize(1); + dataBits[0] = 0x58; + poparg_i->setDataBits(dataBits); + poparg_i->setComment(poparg_i->getDisassembly() + " -- with callback to " + p_detector + " orig: " + p_instruction->getComment()) ; + poparg_i->setFallthrough(popPolicy_i); + poparg_i->setCallback(p_detector); + auto poparg_i_indTarg =new libIRDB::AddressID_t(); + m_fileIR->GetAddresses().insert(poparg_i_indTarg); + poparg_i_indTarg->setVirtualOffset(poparg_i->getAddress()->getVirtualOffset()); + poparg_i_indTarg->setFileID(BaseObj_t::NOT_IN_DATABASE); + poparg_i->setIndirectBranchTargetAddress(poparg_i_indTarg); + + // popPolicy + dataBits.resize(1); + dataBits[0] = 0x58; + popPolicy_i->setDataBits(dataBits); + popPolicy_i->setFallthrough(popa_i); + + // popa + addPopa(popa_i, popf_i); + + // popf + addPopf(popf_i, p_fallThrough); +} + + +#if 0 +// returns true if BeaEngine says arg1 of the instruction is a register +bool Transform::hasTargetRegister(Instruction_t *p_instruction, int p_argNo) +{ + if (!p_instruction) + return false; + + DISASM disasm; + Disassemble(p_instruction,disasm); + + if (p_argNo == 1) + return disasm.Argument1.ArgType & 0xFFFF0000 & REGISTER_TYPE; + else if (p_argNo == 2) + return disasm.Argument2.ArgType & 0xFFFF0000 & REGISTER_TYPE; + else if (p_argNo == 3) + return disasm.Argument3.ArgType & 0xFFFF0000 & REGISTER_TYPE; + else + return false; +} + + +RegisterName Transform::getTargetRegister(Instruction_t *p_instruction, int p_argNo) +{ + if (hasTargetRegister(p_instruction, p_argNo)) + { + DISASM disasm; + Disassemble(p_instruction,disasm); + + if (p_argNo == 1) + return Register::getRegister(disasm.Argument1.ArgMnemonic); + else if (p_argNo == 2) + return Register::getRegister(disasm.Argument2.ArgMnemonic); + else if (p_argNo == 3) + return Register::getRegister(disasm.Argument3.ArgMnemonic); + } + else + return rn_UNKNOWN; +} + +// +// Returns true iff instruction is MUL (according to BeaEngine) +// +bool Transform::isMultiplyInstruction(Instruction_t *p_instruction) +{ + if (!p_instruction) + return false; + + std::string assembly = m_fileIR->lookupAssembly(p_instruction); + if (assembly.length() > 0) + { + return my_strcasestr(assembly.c_str(), "MUL") != NULL; + } + + DISASM disasm; + Disassemble(p_instruction,disasm); + + // beaengine adds space at the end of the mnemonic string + return my_strcasestr(disasm.Instruction.Mnemonic, "MUL ") != NULL; +} + + +// +// Returns true iff instruction is a MOV (according to BeaEngine) +// +bool Transform::isMovInstruction(Instruction_t *p_instruction) +{ + if (!p_instruction) + return false; + + std::string assembly = m_fileIR->lookupAssembly(p_instruction); + if (assembly.length() > 0) + { + return my_strcasestr(assembly.c_str(), "MOV") != NULL; + } + + DISASM disasm; + Disassemble(p_instruction,disasm); + + // nb: beaengine adds space at the end of the mnemonic string + return my_strcasestr(disasm.Instruction.Mnemonic, "MOV") != NULL; +} + +// +// Returns true iff instruction is ADD or SUB (according to BeaEngine) +// +bool Transform::isAddSubNonEspInstruction(Instruction_t *p_instruction) +{ + if (!p_instruction) + return false; + + DISASM disasm; + Disassemble(p_instruction,disasm); + + // beaengine adds space at the end of the mnemonic string + if (my_strcasestr(disasm.Instruction.Mnemonic, "ADD ")) + { + return true; + } + else if (my_strcasestr(disasm.Instruction.Mnemonic, "SUB ")) + { + if (my_strcasestr(disasm.Argument1.ArgMnemonic,"esp") && + (disasm.Argument2.ArgType & 0xFFFF0000 & (CONSTANT_TYPE | ABSOLUTE_))) + { + // optimization: filter out "sub esp, K" + return false; + } + return true; + } + + return false; +} +#endif + +void Transform::addTestRegister8(Instruction_t *p_instr, RegisterName p_reg, Instruction_t *p_fallThrough) +{ + string dataBits; + dataBits.resize(2); + if (p_reg == rn_AL) + { + dataBits[0] = 0x84; + dataBits[1] = 0xc0; + } + else if (p_reg == rn_BL) + { + dataBits[0] = 0x84; + dataBits[1] = 0xdb; + } + else if (p_reg == rn_CL) + { + dataBits[0] = 0x84; + dataBits[1] = 0xc9; + } + else if (p_reg == rn_DL) + { + dataBits[0] = 0x84; + dataBits[1] = 0xd2; + } + else if (p_reg == rn_AH) + { + dataBits[0] = 0x84; + dataBits[1] = 0xe4; + } + else if (p_reg == rn_BH) + { + dataBits[0] = 0x84; + dataBits[1] = 0xff; + } + else if (p_reg == rn_CH) + { + dataBits[0] = 0x84; + dataBits[1] = 0xed; + } + else if (p_reg == rn_DH) + { + dataBits[0] = 0x84; + dataBits[1] = 0xf6; + } + else + { + cerr << "Transform::addTestRegister8(): unhandled register" << endl; + assert(0); + return; + } + + addInstruction(p_instr, dataBits, p_fallThrough, NULL); +} + +void Transform::addTestRegister16(Instruction_t *p_instr, RegisterName p_reg, Instruction_t *p_fallThrough) +{ + string dataBits; + dataBits.resize(3); + if (p_reg == rn_AX) + { + dataBits[0] = 0x66; + dataBits[1] = 0x85; + dataBits[2] = 0xc0; + } + else if (p_reg == rn_BX) + { + dataBits[0] = 0x66; + dataBits[1] = 0x85; + dataBits[2] = 0xdb; + } + else if (p_reg == rn_CX) + { + dataBits[0] = 0x66; + dataBits[1] = 0x85; + dataBits[2] = 0xc9; + } + else if (p_reg == rn_DX) + { + dataBits[0] = 0x66; + dataBits[1] = 0x85; + dataBits[2] = 0xd2; + } + else if (p_reg == rn_BP) + { + assert(0); + } + else if (p_reg == rn_SP) + { + assert(0); + } + else if (p_reg == rn_SI) + { + assert(0); + } + else if (p_reg == rn_DI) + { + assert(0); + } + else + { + cerr << "Transform::addTestRegister16(): unhandled register" << endl; + assert(0); + return; + } + + addInstruction(p_instr, dataBits, p_fallThrough, NULL); +} + +// test <reg32>, <reg32> +void Transform::addTestRegister32(Instruction_t *p_instr, RegisterName p_reg, Instruction_t *p_fallThrough) +{ + string dataBits; + dataBits.resize(2); + if (p_reg == rn_EAX) + { + dataBits[0] = 0x85; + dataBits[1] = 0xc0; + } + else if (p_reg == rn_EBX) + { + dataBits[0] = 0x85; + dataBits[1] = 0xdb; + } + else if (p_reg == rn_ECX) + { + dataBits[0] = 0x85; + dataBits[1] = 0xc9; + } + else if (p_reg == rn_EDX) + { + dataBits[0] = 0x85; + dataBits[1] = 0xd2; + } + else if (p_reg == rn_ESI) + { + dataBits[0] = 0x85; + dataBits[1] = 0xf6; + } + else if (p_reg == rn_EDI) + { + dataBits[0] = 0x85; + dataBits[1] = 0xff; + } + else if (p_reg == rn_EBP) + { + dataBits[0] = 0x85; + dataBits[1] = 0xed; + } + else if (p_reg == rn_ESP) + { + dataBits[0] = 0x85; + dataBits[1] = 0xe4; + } + else + { + cerr << "Transform::addTestRegister32(): unhandled register" << endl; + assert(0); + return; + } + + addInstruction(p_instr, dataBits, p_fallThrough, NULL); +} + + +void Transform::addTestRegister(Instruction_t *p_instr, RegisterName p_reg, Instruction_t *p_fallThrough) +{ + if (Register::is8bit(p_reg)) + addTestRegister8(p_instr, p_reg, p_fallThrough); + else if (Register::is16bit(p_reg)) + addTestRegister16(p_instr, p_reg, p_fallThrough); + else if (Register::is32bit(p_reg)) + addTestRegister32(p_instr, p_reg, p_fallThrough); +} + +void Transform::addTestRegisterMask(Instruction_t *p_instr, RegisterName p_reg, unsigned p_mask, Instruction_t *p_fallThrough) +{ + if (Register::is32bit(p_reg)) + addTestRegisterMask32(p_instr, p_reg, p_mask, p_fallThrough); +} + +void Transform::addTestRegisterMask32(Instruction_t *p_instr, RegisterName p_reg, unsigned p_mask, Instruction_t *p_fallThrough) +{ + string dataBits; + dataBits.resize(6); // all but EAX take 6 bytes + unsigned *tmp; + + if (p_reg == rn_EAX) + { + dataBits.resize(5); + dataBits[0] = 0xa9; + tmp = (unsigned *) &dataBits[1]; + *tmp = p_mask; + } + else if (p_reg == rn_EBX) + { + dataBits[0] = 0xf7; + dataBits[1] = 0xc3; + tmp = (unsigned *) &dataBits[2]; + *tmp = p_mask; + } + else if (p_reg == rn_ECX) + { + dataBits[0] = 0xf7; + dataBits[1] = 0xc1; + tmp = (unsigned *) &dataBits[2]; + *tmp = p_mask; + } + else if (p_reg == rn_EDX) + { + dataBits[0] = 0xf7; + dataBits[1] = 0xc2; + tmp = (unsigned *) &dataBits[2]; + *tmp = p_mask; + } + else if (p_reg == rn_ESI) + { + dataBits[0] = 0xf7; + dataBits[1] = 0xc6; + tmp = (unsigned *) &dataBits[2]; + *tmp = p_mask; + } + else if (p_reg == rn_EDI) + { + dataBits[0] = 0xf7; + dataBits[1] = 0xc7; + tmp = (unsigned *) &dataBits[2]; + *tmp = p_mask; + } + else if (p_reg == rn_EBP) + { + dataBits[0] = 0xf7; + dataBits[1] = 0xc5; + tmp = (unsigned *) &dataBits[2]; + *tmp = p_mask; + } + else if (p_reg == rn_ESP) + { + dataBits[0] = 0xf7; + dataBits[1] = 0xc4; + tmp = (unsigned *) &dataBits[2]; + *tmp = p_mask; + } + else + { + cerr << "Transform::addTestRegisterMask32(): unhandled register: " << p_reg << endl; + assert(0); + return; + } + + addInstruction(p_instr, dataBits, p_fallThrough, NULL); +} + +void Transform::addCmpRegisterMask(Instruction_t *p_instr, RegisterName p_reg, unsigned p_mask, Instruction_t *p_fallThrough) +{ + if (Register::is32bit(p_reg)) + addCmpRegisterMask32(p_instr, p_reg, p_mask, p_fallThrough); +} + +void Transform::addCmpRegisterMask32(Instruction_t *p_instr, RegisterName p_reg, unsigned p_mask, Instruction_t *p_fallThrough) +{ + string dataBits; + unsigned *tmp; + + if (p_reg == rn_EAX) + { + dataBits.resize(5); // EAX gets compact encoding + dataBits[0] = 0x3d; + tmp = (unsigned *) &dataBits[1]; + *tmp = p_mask; + } + else + { // common code for non-EAX cases first + dataBits.resize(6); // all but EAX take 6 bytes + dataBits[0] = 0x81; + tmp = (unsigned *) &dataBits[2]; + *tmp = p_mask; + if (p_reg == rn_EBX) + { + dataBits[1] = 0xfb; + } + else if (p_reg == rn_ECX) + { + dataBits[1] = 0xf9; + } + else if (p_reg == rn_EDX) + { + dataBits[1] = 0xfa; + } + else if (p_reg == rn_EBP) + { + dataBits[1] = 0xfd; + } + else if (p_reg == rn_ESI) + { + dataBits[1] = 0xfe; + } + else if (p_reg == rn_EDI) + { + dataBits[1] = 0xff; + } + else + { + cerr << "Transform::addCmpRegisterMask32(): unhandled register" << endl; + assert(0); + return; + } + } + + addInstruction(p_instr, dataBits, p_fallThrough, NULL); +} + +// jns - jump not signed +void Transform::addJns(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target) +{ + string dataBits; + dataBits.resize(2); + dataBits[0] = 0x79; + dataBits[1] = 0x00; // value doesn't matter -- we will fill it in later + addInstruction(p_instr, dataBits, p_fallThrough, p_target); +} + +// jz - jump zero (same as je - jump if equal) +void Transform::addJz(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target) +{ + string dataBits; + dataBits.resize(2); + dataBits[0] = 0x74; + dataBits[1] = 0x00; // value doesn't matter -- we will fill it in later + + addInstruction(p_instr, dataBits, p_fallThrough, p_target); +} + +// jnz - jump not zero (same as jne - jump if not equal) +void Transform::addJnz(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target) +{ + string dataBits; + dataBits.resize(2); + dataBits[0] = 0x75; + dataBits[1] = 0x00; // value doesn't matter -- we will fill it in later + + addInstruction(p_instr, dataBits, p_fallThrough, p_target); +} + +// jae - jump if above or equal (unsigned) (same as jnb and jnc) +void Transform::addJae(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target) +{ + string dataBits; + dataBits.resize(2); + dataBits[0] = 0x73; + dataBits[1] = 0x00; // value doesn't matter -- we will fill it in later + + addInstruction(p_instr, dataBits, p_fallThrough, p_target); +} + +// jo - jump overflow +void Transform::addJo(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target) +{ + string dataBits; + dataBits.resize(2); + dataBits[0] = 0x70; + dataBits[1] = 0x00; // value doesn't matter -- we will fill it in later + + addInstruction(p_instr, dataBits, p_fallThrough, p_target); +} +// jc - jump carry +void Transform::addJc(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target) +{ + string dataBits; + dataBits.resize(2); + dataBits[0] = 0x72; + dataBits[1] = 0x00; // value doesn't matter -- we will fill it in later + + addInstruction(p_instr, dataBits, p_fallThrough, p_target); +} + +// not <reg> -- negate register +void Transform::addNot(Instruction_t *p_instr, RegisterName p_reg, Instruction_t *p_fallThrough) +{ + string dataBits; + dataBits.resize(2); + + if (p_reg == rn_EAX) + { + dataBits[0] = 0xf7; + dataBits[1] = 0xd0; + } + else if (p_reg == rn_EBX) + { + dataBits[0] = 0xf7; + dataBits[1] = 0xd3; + } + else if (p_reg == rn_ECX) + { + dataBits[0] = 0xf7; + dataBits[1] = 0xd1; + } + else if (p_reg == rn_EDX) + { + dataBits[0] = 0xf7; + dataBits[1] = 0xd2; + } + else if (p_reg == rn_ESI) + { + dataBits[0] = 0xf7; + dataBits[1] = 0xd6; + } + else if (p_reg == rn_EDI) + { + dataBits[0] = 0xf7; + dataBits[1] = 0xd7; + } + else if (p_reg == rn_AX) + { + dataBits.resize(3); + dataBits[0] = 0x66; + dataBits[1] = 0xf7; + dataBits[2] = 0xd0; + } + else if (p_reg == rn_BX) + { + dataBits.resize(3); + dataBits[0] = 0x66; + dataBits[1] = 0xf7; + dataBits[2] = 0xd3; + } + else if (p_reg == rn_CX) + { + dataBits.resize(3); + dataBits[0] = 0x66; + dataBits[1] = 0xf7; + dataBits[2] = 0xd1; + } + else if (p_reg == rn_DX) + { + dataBits.resize(3); + dataBits[0] = 0x66; + dataBits[1] = 0xf7; + dataBits[2] = 0xd2; + } + else if (p_reg == rn_AL) + { + dataBits[0] = 0xf6; + dataBits[1] = 0xd0; + } + else if (p_reg == rn_BL) + { + dataBits[0] = 0xf6; + dataBits[1] = 0xd3; + } + else if (p_reg == rn_CL) + { + dataBits[0] = 0xf6; + dataBits[1] = 0xd1; + } + else if (p_reg == rn_DL) + { + dataBits[0] = 0xf6; + dataBits[1] = 0xd2; + } + else if (p_reg == rn_AH) + { + dataBits[0] = 0xf6; + dataBits[1] = 0xd4; + } + else if (p_reg == rn_BH) + { + dataBits[0] = 0xf6; + dataBits[1] = 0xd7; + } + else if (p_reg == rn_CH) + { + dataBits[0] = 0xf6; + dataBits[1] = 0xd5; + } + else if (p_reg == rn_DH) + { + dataBits[0] = 0xf6; + dataBits[1] = 0xd6; + } + + else + { + cerr << "Transform::addNot(): unhandled register" << endl; + assert(0); + return; + } + + addInstruction(p_instr, dataBits, p_fallThrough, NULL); +} + +// add r1, r2 +void Transform::addAddRegisters(Instruction_t *p_instr, RegisterName p_regTgt, RegisterName p_regSrc, Instruction_t *p_fallThrough) +{ + // too many combinations, just use the assembler + string assembly = "add " + Register::toString(p_regTgt) + ", " + Register::toString(p_regSrc); +#ifdef OPTIMIZE_ASSEMBLY + m_fileIR->registerAssembly(p_instr, assembly); +#else + if (!p_instr->assemble(assembly)) + { + cerr << "addAddRegisters(): error in assembling instruction: " << assembly << endl; + assert(0); + return; + } +#endif + + p_instr->setFallthrough(p_fallThrough); +} + +// add r1, constant +void Transform::addAddRegisterConstant(Instruction_t *p_instr, RegisterName p_reg, int p_constantValue, Instruction_t *p_fallThrough) +{ + // too many combinations, just use the assembler + char buf[256]; + sprintf(buf, "add %s, %d", Register::toString(p_reg).c_str(), p_constantValue); + string assembly(buf); +#ifdef OPTIMIZE_ASSEMBLY + m_fileIR->registerAssembly(p_instr, assembly); +#else + if (!p_instr->assemble(assembly)) + { + cerr << "Transform::addAddConstant(): error in assembling instruction: " << assembly << endl; + assert(0); + return; + } +#endif + +// cerr << "Transform::addAddConstant(): " << p_instr->getDisassembly() << endl; + p_instr->setFallthrough(p_fallThrough); +} + +// imul r1, constant +void Transform::addMulRegisterConstant(Instruction_t *p_instr, RegisterName p_reg, int p_constantValue, Instruction_t *p_fallThrough) +{ + // too many combinations, just use the assembler + char buf[256]; + sprintf(buf, "imul %s, %d", Register::toString(p_reg).c_str(), p_constantValue); + string assembly(buf); +#ifdef OPTIMIZE_ASSEMBLY + m_fileIR->registerAssembly(p_instr, assembly); +#else + if (!p_instr->Assemble(assembly)) + { + cerr << "Transform::addMulRegisterConstant(): error in assembling instruction: " << assembly << endl; + assert(0); + return; + } +#endif + +// cerr << "Transform::addMulRegisterConstant(): " << p_instr->getDisassembly() << endl; + p_instr->setFallthrough(p_fallThrough); +} + + +// mov r1, r2 +void Transform::addMovRegisters(Instruction_t *p_instr, RegisterName p_regTgt, RegisterName p_regSrc, Instruction_t *p_fallThrough) +{ + // too many combinations, just use the assembler + string assembly = "mov " + Register::toString(p_regTgt) + ", " + Register::toString(p_regSrc); +#ifdef OPTIMIZE_ASSEMBLY + m_fileIR->registerAssembly(p_instr, assembly); +#else + if (!p_instr->Assemble(assembly)) + { + cerr << "addMovRegisters(): error in assembling instruction: " << assembly << endl; + assert(0); + return; + } +#endif + p_instr->setFallthrough(p_fallThrough); +// cerr << "addMovRegisters(): " << p_instr->getDisassembly() << endl; +} + +void Transform::addMovRegisterSignedConstant(Instruction_t *p_instr, RegisterName p_regTgt, long int p_constant, Instruction_t *p_fallThrough) +{ + p_instr->setFallthrough(p_fallThrough); + + char buf[128]; + + sprintf(buf,"mov %s, %ld", Register::toString(p_regTgt).c_str(), p_constant); + + string assembly(buf); + m_fileIR->registerAssembly(p_instr, assembly); + + p_instr->setComment("Saturating arithmetic"); +} + +void Transform::addMovRegisterUnsignedConstant(Instruction_t *p_instr, RegisterName p_regTgt, unsigned long int p_constant, Instruction_t *p_fallThrough) +{ + p_instr->setFallthrough(p_fallThrough); + + char buf[128]; + sprintf(buf,"mov %s, %lu", Register::toString(p_regTgt).c_str(), p_constant); + + string assembly(buf); + m_fileIR->registerAssembly(p_instr, assembly); + + p_instr->setComment("Saturating arithmetic"); +} + +void Transform::addAndRegister32Mask(Instruction_t *p_instr, RegisterName p_regTgt, unsigned int p_mask, Instruction_t *p_fallThrough) +{ + p_instr->setFallthrough(p_fallThrough); + + char buf[128]; + sprintf(buf,"and %s, 0x%08X", Register::toString(p_regTgt).c_str(), p_mask); + + string assembly(buf); + cerr << "addAndRegisterMask(): assembling instruction: " << assembly << endl; +#ifdef OPTIMIZE_ASSEMBLY + m_fileIR->registerAssembly(p_instr, assembly); +#else + if (!p_instr->Assemble(assembly)) + { + cerr << "addAndRegisterMask(): error in assembling instruction: " << assembly << endl; + assert(0); + return; + } +#endif + + p_instr->setComment("Saturating arithmetic by masking"); +} + +//----------------------------------------------------- +// known to be used on x86-64 +//----------------------------------------------------- + +// hlt +void Transform::addHlt(Instruction_t *p_instr, Instruction_t *p_fallThrough) +{ + string assembly("hlt"); + m_fileIR->registerAssembly(p_instr, assembly); + p_instr->setFallthrough(p_fallThrough); +} + +// jno - jump not overflow +void Transform::addJno(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target) +{ + string assembly("jno 0x22"); + m_fileIR->registerAssembly(p_instr, assembly); + p_instr->setFallthrough(p_fallThrough); + p_instr->setTarget(p_target); +} + +// jnc - jump not carry +void Transform::addJnc(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target) +{ + string assembly("jnc 0x22"); + m_fileIR->registerAssembly(p_instr, assembly); + p_instr->setFallthrough(p_fallThrough); + p_instr->setTarget(p_target); +} + +Instruction_t* Transform::addNewMaxSaturation(Instruction_t *p_prev, RegisterName p_reg, const MEDS_InstructionCheckAnnotation p_annotation) +{ + Instruction_t *mov = allocateNewInstruction(p_prev->getAddress()->getFileID(), p_prev->getFunction()); + if (p_prev) + p_prev->setFallthrough(mov); + addMaxSaturation(mov, p_reg, p_annotation, NULL); + return mov; +} + +void Transform::addMaxSaturation(Instruction_t *p_instruction, RegisterName p_reg, const MEDS_InstructionCheckAnnotation& p_annotation, Instruction_t *p_fallthrough) +{ +#if 0 + assert(getFileIR() && p_instruction); + + p_instruction->setFallthrough(p_fallthrough); + + if (p_annotation.isUnsigned()) + { + // use MAX_UNSIGNED for the bit width + switch (Register::getBitWidth(p_reg)) + { + case 64: + addMovRegisterUnsignedConstant(p_instruction, p_reg, 0xFFFFFFFFFFFFFFFF, p_fallthrough); + break; + case 32: + addMovRegisterUnsignedConstant(p_instruction, p_reg, 0xFFFFFFFF, p_fallthrough); + break; + case 16: + addMovRegisterUnsignedConstant(p_instruction, p_reg, 0xFFFF, p_fallthrough); + break; + case 8: + addMovRegisterUnsignedConstant(p_instruction, p_reg, 0xFF, p_fallthrough); + break; + default: + cerr << "Transform::addMaxSaturation(): invalid bit width: " << p_annotation.getBitWidth() << endl; + break; + } + } + else + { + // treat unknown and signed the same way for overflows + // use MAX_SIGNED for the bit width + switch (Register::getBitWidth(p_reg)) + { + case 64: + addMovRegisterSignedConstant(p_instruction, p_reg, 0x7FFFFFFFFFFFFFFF, p_fallthrough); + break; + case 32: + addMovRegisterSignedConstant(p_instruction, p_reg, 0x7FFFFFFF, p_fallthrough); + break; + case 16: + addMovRegisterSignedConstant(p_instruction, p_reg, 0x7FFF, p_fallthrough); + break; + case 8: + addMovRegisterSignedConstant(p_instruction, p_reg, 0x7F, p_fallthrough); + break; + default: + cerr << "Transform::addMaxSaturation(): invalid bit width: " << p_annotation.getBitWidth() << endl; + break; + } + } +#else + // not used, and had compiler errors. + assert(0); +#endif +} + +void Transform::addMinSaturation(Instruction_t *p_instruction, RegisterName p_reg, const MEDS_InstructionCheckAnnotation& p_annotation, Instruction_t *p_fallthrough) +{ +#if 0 + assert(getFileIR() && p_instruction); + + p_instruction->setFallthrough(p_fallthrough); + + if (p_annotation.isUnsigned()) + { + // use MIN_UNSIGNED + addMovRegisterUnsignedConstant(p_instruction, p_reg, 0, p_fallthrough); + } + else + { + // treat unknown and signed the same way for overflows + // use MIN_SIGNED for the bit width + switch (Register::getBitWidth(p_reg)) + { + case 64: + addMovRegisterSignedConstant(p_instruction, p_reg, 0x8000000000000000, p_fallthrough); + break; + case 32: + addMovRegisterSignedConstant(p_instruction, p_reg, 0x80000000, p_fallthrough); + break; + case 16: + addMovRegisterSignedConstant(p_instruction, p_reg, 0x8000, p_fallthrough); + break; + case 8: + addMovRegisterSignedConstant(p_instruction, p_reg, 0x80, p_fallthrough); + break; + default: + cerr << "Transform::addMinSaturation(): invalid bit width: " << p_annotation.getBitWidth() << endl; + break; + } + } +#else + // not used, and had compiler errors. + assert(0); +#endif +} + +void Transform::setAssembly(Instruction_t *p_instr, string p_asm) +{ + m_fileIR->registerAssembly(p_instr, p_asm); +} + +// +// Allocate and add new instruction given its assembly form +// If <p_instr> not NULL, then set fallthrough appropriately +// +// Returns the newly added instruction +// +// <p_instr> defined: +// <p_instr> <p_instr> +// <fallthrough> ==> <newinstr>(<p_asm>) +// <fallthrough> +// +// <p_instr> is NULL: +// ==> <newinstr>(<p_asm>) +// +Instruction_t* Transform::addNewAssembly(Instruction_t *p_instr, string p_asm) +{ + Instruction_t* newinstr; + if (p_instr) + newinstr = allocateNewInstruction(p_instr->getAddress()->getFileID(), p_instr->getFunction()); + else + newinstr = allocateNewInstruction(m_fileIR->getFile()->getFileID(), NULL); + + m_fileIR->registerAssembly(newinstr, p_asm); + + if (p_instr) + { + newinstr->setFallthrough(p_instr->getFallthrough()); + p_instr->setFallthrough(newinstr); + } + else + { + newinstr->setFallthrough(NULL); + } + + return newinstr; +} + +// register instruction in IRDB +// 20140421 +Instruction_t* Transform::addNewAssembly(string p_asm) +{ + return addNewAssembly(NULL, p_asm); +} + +// x86-64 +// 20140421 +void Transform::addCallbackHandler64(Instruction_t *p_orig, string p_callbackHandler, int p_numArgs) +{ + // nb: if first time, register and cache callback handler sequence + if (m_handlerMap.count(p_callbackHandler) == 0) + { + m_handlerMap[p_callbackHandler] = registerCallbackHandler64(p_callbackHandler, p_numArgs); + } + + if (p_orig) + p_orig->setTarget(m_handlerMap[p_callbackHandler]); +} + +// x86-64 +// register callback handler sequence +// +// This following note is slightly out of date. +// We DO save flags here so that our callbacks are +// able to look at register values using a reg_values_t. +// HOWEVER, the caller of this function should still be sure +// to save flags themselves. +// +// nb: strata semantics is that it does not save flags, so we don't bother +// saving/restoring flags either in the callback handler +// saving/restoring flags must be done outside of this routine +// 20140416 +Instruction_t* Transform::registerCallbackHandler64(string p_callbackHandler, int p_numArgs) +{ + Instruction_t *instr; + Instruction_t *first; + char tmpbuf[1024]; + + // save flags and 16 registers (136 bytes) + // call pushes 8 bytes + // Total: 8 * 18 = 144 + first = instr = addNewAssembly("push rsp"); + instr = addNewAssembly(instr, "push rbp"); + instr = addNewAssembly(instr, "push rdi"); + instr = addNewAssembly(instr, "push rsi"); + instr = addNewAssembly(instr, "push rdx"); + instr = addNewAssembly(instr, "push rcx"); + instr = addNewAssembly(instr, "push rbx"); + instr = addNewAssembly(instr, "push rax"); + instr = addNewAssembly(instr, "push r8"); + instr = addNewAssembly(instr, "push r9"); + instr = addNewAssembly(instr, "push r10"); + instr = addNewAssembly(instr, "push r11"); + instr = addNewAssembly(instr, "push r12"); + instr = addNewAssembly(instr, "push r13"); + instr = addNewAssembly(instr, "push r14"); + instr = addNewAssembly(instr, "push r15"); + instr = addNewAssembly(instr, "pushf"); + + // handle the arguments (if any): rdi, rsi, rdx, rcx, r8, r9 + // first arg starts at byte +144 + // now at +136??? b/c we took out the push + instr = addNewAssembly(instr, "mov rdi, rsp"); + + if (p_numArgs >= 1) + instr = addNewAssembly(instr, "mov rsi, [rsp+136]"); + if (p_numArgs >= 2) + instr = addNewAssembly(instr, "mov rdx, [rsp+144]"); + if (p_numArgs >= 3) + instr = addNewAssembly(instr, "mov rcx, [rsp+152]"); + if (p_numArgs >= 4) + instr = addNewAssembly(instr, "mov r8, [rsp+160]"); + if (p_numArgs > 4) + assert(0); // only handle up to 5 args + + // pin the instruction that follows the callback handler + Instruction_t* postCallback = allocateNewInstruction(); + VirtualOffset_t postCallbackReturn = getAvailableAddress(); + postCallback->getAddress()->setVirtualOffset(postCallbackReturn); + + // push the address to return to once the callback handler is invoked + sprintf(tmpbuf,"mov rax, 0x%x", (uint32_t)postCallbackReturn); + instr = addNewAssembly(instr, tmpbuf); + + instr = addNewAssembly(instr, "push rax"); + + // use a nop instruction for the actual callback + instr = addNewAssembly(instr, "nop"); + instr->setComment(" -- callback: " + p_callbackHandler); + instr->setCallback(p_callbackHandler); + instr->setFallthrough(postCallback); + + // need to make sure the post callback address is pinned + // (so that ILR and other transforms do not relocate it) + AddressID_t *indTarg = new libIRDB::AddressID_t(); + m_fileIR->GetAddresses().insert(indTarg); + indTarg->setVirtualOffset(postCallback->getAddress()->getVirtualOffset()); + indTarg->setFileID(BaseObj_t::NOT_IN_DATABASE); // SPRI global namespace + postCallback->setIndirectBranchTargetAddress(indTarg); + + // restore registers + setAssembly(postCallback, "popf"); + instr = addNewAssembly(postCallback, "pop r15"); + instr = addNewAssembly(instr, "pop r14"); + instr = addNewAssembly(instr, "pop r13"); + instr = addNewAssembly(instr, "pop r12"); + instr = addNewAssembly(instr, "pop r11"); + instr = addNewAssembly(instr, "pop r10"); + instr = addNewAssembly(instr, "pop r9"); + instr = addNewAssembly(instr, "pop r8"); + instr = addNewAssembly(instr, "pop rax"); + instr = addNewAssembly(instr, "pop rbx"); + instr = addNewAssembly(instr, "pop rcx"); + instr = addNewAssembly(instr, "pop rdx"); + instr = addNewAssembly(instr, "pop rsi"); + instr = addNewAssembly(instr, "pop rdi"); + instr = addNewAssembly(instr, "pop rbp"); + instr = addNewAssembly(instr, "lea rsp, [rsp+8]"); + + instr = addNewAssembly(instr, "ret"); + + // return first instruction in the callback handler chain + return first; +} + +void Transform::logMessage(const std::string &p_method, const std::string &p_msg) +{ + std::cerr << p_method << ": " << p_msg << std::endl; +} + +void Transform::logMessage(const std::string &p_method, const MEDS_InstructionCheckAnnotation& p_annotation, const std::string &p_msg) +{ + logMessage(p_method, p_msg + " annotation: " + p_annotation.toString()); +} + +void libTransform::convertToLowercase(string &str) +{ + for (auto i = 0U; i < str.length(); ++i) + { + str[i] = tolower(str[i]); + } +} + +#endif + + diff --git a/irdb-lib/libIRDB-util/include/IBT_Provenance.hpp b/irdb-lib/libIRDB-util/include/IBT_Provenance.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3aba669af6eca86d5688f0d144cf5a5fb35c3339 --- /dev/null +++ b/irdb-lib/libIRDB-util/include/IBT_Provenance.hpp @@ -0,0 +1,43 @@ +#ifndef IBT_Provenance_h +#define IBT_Provenance_h + +#include "Provenance.hpp" + +class IBTProvenance_t : public IRDB_SDK::IBTProvenance_t +{ + private: + + // types + using InsnProvMap_t = std::map<const IRDB_SDK::Instruction_t*, Provenance_t>; + + // data + InsnProvMap_t prov_map; + static Provenance_t empty; + + // methods + void Init() {}; + void AddProvs(const Provenance_t& p, const InstructionSet_t& after) ; + + public: + IBTProvenance_t(const IRDB_SDK::FileIR_t* f=NULL) {Init(); if(f) addFile(f);} + virtual ~IBTProvenance_t() {} // default destructor not OK for some reason? + void addFile(const IRDB_SDK::FileIR_t* ); + + const Provenance_t& getProvenance (const IRDB_SDK::Instruction_t* i) const + { + return (*this)[i]; + } + + const Provenance_t& operator[] (const IRDB_SDK::Instruction_t* i) const + { + const auto it=prov_map.find(i); + if (it!= prov_map.end()) + return it->second; + return empty; + } + + +}; + +#endif + diff --git a/irdb-lib/libIRDB-util/include/Provenance.hpp b/irdb-lib/libIRDB-util/include/Provenance.hpp new file mode 100644 index 0000000000000000000000000000000000000000..520ac73da6518bbcc6faa7dcfae436d9c795d306 --- /dev/null +++ b/irdb-lib/libIRDB-util/include/Provenance.hpp @@ -0,0 +1,53 @@ +#ifndef Provenance_h +#define Provenance_h + +#include <bitset> + +class Provenance_t : public IRDB_SDK::Provenance_t +{ + private: + // ProvType enum values are explicit to show they are in bounds of the bitset + enum class ProvType { IndJump = 0, IndCall = 1, Ret = 2 }; + std::bitset<3> prov; + public: + Provenance_t() {prov = std::bitset<3>();} + virtual ~Provenance_t() {;} + + void addReturn() + { + prov.set((size_t) ProvType::Ret); + } + + void addIndirectJump() + { + prov.set((size_t) ProvType::IndJump); + } + + void addIndirectCall() + { + prov.set((size_t) ProvType::IndCall); + } + + void addProv(const Provenance_t& other) + { + prov |= other.prov; + } + + bool hasReturn() const + { + return prov.test((size_t) ProvType::Ret); + } + + + bool hasIndirectJump() const + { + return prov.test((size_t) ProvType::IndJump); + } + + bool hasIndirectCall() const + { + return prov.test((size_t) ProvType::IndCall); + } +}; + +#endif diff --git a/irdb-lib/libIRDB-util/include/insn_preds.hpp b/irdb-lib/libIRDB-util/include/insn_preds.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3078d25b8272aa235781261306fe033e106f9298 --- /dev/null +++ b/irdb-lib/libIRDB-util/include/insn_preds.hpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2014-2015 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef insn_preds_h +#define insn_preds_h + + +class InstructionPredecessors_t : public IRDB_SDK::InstructionPredecessors_t +{ + private: + typedef std::map<const IRDB_SDK::Instruction_t*, InstructionSet_t> PredMap_t; + + public: + InstructionPredecessors_t(const IRDB_SDK::FileIR_t* f=NULL) {Init(); if(f) AddFile(f);} + virtual ~InstructionPredecessors_t() {;} + virtual void AddFile(const IRDB_SDK::FileIR_t* ); + + virtual const InstructionSet_t& getPredecessors(const IRDB_SDK::Instruction_t* i) const { return (*this)[i]; } + + InstructionSet_t& operator[] (const IRDB_SDK::Instruction_t* i) + { + return pred_map[i]; + } + const InstructionSet_t& operator[] (const IRDB_SDK::Instruction_t* i) const + { + PredMap_t::const_iterator it=pred_map.find(i); + if (it!= pred_map.end()) + return it->second; + static InstructionSet_t empty; + return empty; + } + + protected: + virtual void Init() {}; + + private: + + virtual void AddPred(const IRDB_SDK::Instruction_t* before, const IRDB_SDK::Instruction_t* after); + virtual void AddPreds(const IRDB_SDK::Instruction_t* before, const IRDB_SDK::InstructionSet_t& after); + + PredMap_t pred_map; +}; + +#endif diff --git a/irdb-lib/libIRDB-util/include/libIRDB-util.hpp b/irdb-lib/libIRDB-util/include/libIRDB-util.hpp new file mode 100644 index 0000000000000000000000000000000000000000..5b091d1165fab6cc1aa9edf3060a2a88e908c445 --- /dev/null +++ b/irdb-lib/libIRDB-util/include/libIRDB-util.hpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef libIRDB_util +#define libIRDB_util + + +/* Building a CFG depends on core functionality */ +#include <irdb-core> +#include <irdb-util> +#include <libIRDB-core.hpp> + +#include <vector> +#include <set> +#include <map> +#include <ostream> + +namespace libIRDB +{ + +#include <insn_preds.hpp> +#include <IBT_Provenance.hpp> +#include <params.hpp> + +}; + +#endif diff --git a/irdb-lib/libIRDB-util/include/params.hpp b/irdb-lib/libIRDB-util/include/params.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/irdb-lib/libIRDB-util/src/IBT_Provenance.cpp b/irdb-lib/libIRDB-util/src/IBT_Provenance.cpp new file mode 100644 index 0000000000000000000000000000000000000000..978fdc9d5ffe7df5e151dc4d98554f0a1f3f74a5 --- /dev/null +++ b/irdb-lib/libIRDB-util/src/IBT_Provenance.cpp @@ -0,0 +1,70 @@ +#include <map> +#include <bitset> +#include <libIRDB-core.hpp> +#include <libIRDB-util.hpp> +#include <irdb-util> + +using namespace libIRDB; +using namespace std; + + +Provenance_t IBTProvenance_t::empty; + + +void IBTProvenance_t::addFile(const IRDB_SDK::FileIR_t* firp) +{ + + using ICFSProvMap_t = std::map<const IRDB_SDK::ICFS_t*, Provenance_t>; + + auto icfs_prov_map = ICFSProvMap_t(); + + // collect before info for each icfs into icfs_prov_map + for(auto insn : firp->getInstructions()) + { + const auto &ibTargets=insn->getIBTargets(); + if(!ibTargets) + continue; + + libIRDB::Provenance_t this_prov; + const auto p_IndBranchAsm=DecodedInstruction_t::factory(insn); + const auto &IndBranchAsm=*p_IndBranchAsm; + const auto isIndJmp = IndBranchAsm.isUnconditionalBranch() && !IndBranchAsm.getOperand(0)->isConstant(); + const auto isIndCall = IndBranchAsm.isCall() && !IndBranchAsm.getOperand(0)->isConstant(); + const auto isRet = IndBranchAsm.isReturn(); + + if(isIndJmp) + { + this_prov.addIndirectJump(); + } + else if(isIndCall) + { + this_prov.addIndirectCall(); + } + else if(isRet) + { + this_prov.addReturn(); + } + else + { + assert(0); + } + + icfs_prov_map[ibTargets].addProv(this_prov); + } + + // deploy info for each target of the icfs + for(const auto &icfs : firp->getAllICFS()) + { + assert(icfs); + for(const auto &insn : *icfs) + { + prov_map[insn].addProv(icfs_prov_map[icfs]); + } + } +} + +unique_ptr<IRDB_SDK::IBTProvenance_t> IRDB_SDK::IBTProvenance_t::factory(const IRDB_SDK::FileIR_t* f) +{ + return unique_ptr<IRDB_SDK::IBTProvenance_t>(new libIRDB::IBTProvenance_t(f)); +} + diff --git a/irdb-lib/libIRDB-util/src/Makefile b/irdb-lib/libIRDB-util/src/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..964ec5464c1c65bcd3a0c75f4ea40d8a420553d9 --- /dev/null +++ b/irdb-lib/libIRDB-util/src/Makefile @@ -0,0 +1,15 @@ + +LIB=../../lib/libIRDB-util.a + +OBJS=insn_preds.o + +all: $(OBJS) + +$(OBJS): ../../include/core/*.hpp ../../include/util/*.hpp ../../include/*.hpp + +clean: + rm -f $(OBJS) + +.cpp.o: + $(CXX) -fPIC -g -c -I. -I../../include -I../../../beaengine/include $< + ar rc $(LIB) $@ diff --git a/irdb-lib/libIRDB-util/src/SConscript b/irdb-lib/libIRDB-util/src/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..fee25b597ad027296a0ee24b950916fb0105c8e0 --- /dev/null +++ b/irdb-lib/libIRDB-util/src/SConscript @@ -0,0 +1,31 @@ +import os + +Import('env') +myenv=env +myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) + + +libname="irdb-util" +files= ''' + insn_preds.cpp + IBT_Provenance.cpp + params.cpp + registers.cpp + ''' +cpppath=''' + $IRDB_SDK/include/ + $SECURITY_TRANSFORMS_HOME/include/ + $SECURITY_TRANSFORMS_HOME/libIRDB-core/include/ + $SECURITY_TRANSFORMS_HOME/libIRDB-util/include/ + ''' + +#myenv.Append(CCFLAGS=" -Wall -W -Wextra -Wconversion ") + +myenv=myenv.Clone(CPPPATH=Split(cpppath)) +myenv.Append(CXXFLAGS = " -std=c++11 ") +lib=myenv.SharedLibrary(libname, Split(files), LIBS=Split("irdb-core"), LIBPATH=Split("$SECURITY_TRANSFORMS_HOME/lib")) + +install=env.Install("$SECURITY_TRANSFORMS_HOME/lib/", lib) +Default(install) + +Return('install') diff --git a/irdb-lib/libIRDB-util/src/SConstruct b/irdb-lib/libIRDB-util/src/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..17f632b8c29cd420163897b1eb044ca3486df362 --- /dev/null +++ b/irdb-lib/libIRDB-util/src/SConstruct @@ -0,0 +1,7 @@ + + + +env=Environment() +Export('env') +install=SConscript("SConscript") +Return('install') diff --git a/irdb-lib/libIRDB-util/src/insn_preds.cpp b/irdb-lib/libIRDB-util/src/insn_preds.cpp new file mode 100644 index 0000000000000000000000000000000000000000..405b737afddce242139f4dc332ba1cb95e633c28 --- /dev/null +++ b/irdb-lib/libIRDB-util/src/insn_preds.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014-2015 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +#include <map> +#include <libIRDB-core.hpp> +#include <libIRDB-util.hpp> +#include <irdb-util> + +using namespace libIRDB; +using namespace std; + + + +void InstructionPredecessors_t::AddPreds(const IRDB_SDK::Instruction_t* before, const InstructionSet_t& afterset) +{ + for(auto it=afterset.begin(); it!=afterset.end(); ++it) + { + pred_map[*it].insert(const_cast<IRDB_SDK::Instruction_t*>(before)); + } +} + +void InstructionPredecessors_t::AddPred(const IRDB_SDK::Instruction_t* before, const IRDB_SDK::Instruction_t* after) +{ + assert(before); + if(!after) return; + + if(getenv("DUMP_PRED_CREATE")) + cout<<"Found "<<after->getBaseID()<<":"<<after->getDisassembly() << " follows "<< before->getBaseID()<<":"<<before->getDisassembly()<<endl; + pred_map[after].insert(const_cast<IRDB_SDK::Instruction_t*>(before)); + +} + +void InstructionPredecessors_t::AddFile(const IRDB_SDK::FileIR_t* firp2) +{ + auto firp=const_cast<IRDB_SDK::FileIR_t*>(firp2); // discarding const qualifier because we know we won't change the set + for(auto it=firp->getInstructions().begin(); + it!=firp->getInstructions().end(); + ++it) + { + auto insn=*it; + AddPred(insn, insn->getTarget()); + AddPred(insn, insn->getFallthrough()); + + // if we have a complete list, then explicitly add them. + if(insn->getIBTargets() && insn->getIBTargets()->isComplete()) + AddPreds(insn, *insn->getIBTargets()); + + } +} + +unique_ptr<IRDB_SDK::InstructionPredecessors_t> IRDB_SDK::InstructionPredecessors_t::factory(IRDB_SDK::FileIR_t* firp) +{ + return unique_ptr<IRDB_SDK::InstructionPredecessors_t>(new libIRDB::InstructionPredecessors_t(firp)); +} + diff --git a/irdb-lib/libIRDB-util/src/params.cpp b/irdb-lib/libIRDB-util/src/params.cpp new file mode 100644 index 0000000000000000000000000000000000000000..68bab5b3aa27ff385ba45e3b893c8eac37eaa7cc --- /dev/null +++ b/irdb-lib/libIRDB-util/src/params.cpp @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2014-2017 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +#include <libIRDB-core.hpp> +#include <libIRDB-util.hpp> +#include <irdb-util> +#include <algorithm> + +using namespace libIRDB; +using namespace std; + +// Does instruction potentially write to a parameter to a call? +bool IRDB_SDK::isParameterWrite(const IRDB_SDK::FileIR_t *firp, IRDB_SDK::Instruction_t* insn, string& output_dst) +{ + const auto p_d=DecodedInstruction_t::factory(insn); + const auto &d=*p_d; + + if(!d.hasOperand(0)) + return false; + if(!d.getOperand(0)->isWritten()) + return false; + + /* 64 bit machines use regs to pass parameters */ + if(firp->getArchitectureBitWidth()==64) + { + // if it's a register + if(d.getOperand(0)->isGeneralPurposeRegister()) + { + int regno=d.getOperand(0)->getRegNumber(); + switch(regno) + { + case 1: // rcx? + case 2: // rdx? + case 6: // rsi? + case 7: // rdi? + case 8: // r8? + case 9: // r9? + output_dst=d.getOperand(0)->getString(); + return true; + + // other regsiters == no. + default: + return false; + } + + } + } + + // not a register or not 64-bit. check for [esp+k] + + // check for memory type + if(!d.getOperand(0)->isMemory()) + return false; + + // check that base reg is esp. + if(!d.getOperand(0)->hasBaseRegister()) + return false; + if(d.getOperand(0)->getBaseRegister() != 4) + return false; + + // check that there's no index reg + if(d.getOperand(0)->hasIndexRegister()) + return false; + + // get k out of [esp + k ] + if (!d.getOperand(0)->hasMemoryDisplacement()) + return false; + const auto k=d.getOperand(0)->getMemoryDisplacement(); + + // check that we know the frame layout. + if(insn->getFunction() == NULL) + return false; + + if(k < insn->getFunction()->getOutArgsRegionSize()) + { + output_dst=string("[")+d.getOperand(0)->getString()+string("]"); + return true; + } + + // return we didn't find a memory of the right type + return false; +} + +// +// we look for: +// (1) call instruction +// (2) call converted to push/jmp pair +// +IRDB_SDK::Instruction_t* isOrWasCall(const IRDB_SDK::FileIR_t *firp, IRDB_SDK::Instruction_t* insn) +{ + if (firp == NULL || insn == NULL) + return NULL; + + const auto p_d=DecodedInstruction_t::factory(insn); + const auto &d=*p_d; + + if(d.isCall()) + { + return insn->getTarget(); + } + else + { + // look for "push64" or "fix_call_fallthrough" reloc + auto it = std::find_if(insn->getRelocations().begin(),insn->getRelocations().end(),[&](const IRDB_SDK::Relocation_t* reloc) + { + return (reloc && ((reloc->getType() == string("push64")) || reloc->getType() == string("fix_call_fallthrough"))); + }); + + // find actual target + if (it != insn->getRelocations().end()) + { + if (insn->getTarget()) + return insn->getTarget(); + else if (insn->getFallthrough()) + return insn->getFallthrough()->getTarget(); + } + } + + return NULL; +} + +// Does a call follow the instruction? +bool IRDB_SDK::callFollows(const IRDB_SDK::FileIR_t *firp, IRDB_SDK::Instruction_t* insn, const string& reg_arg_str, const std::string &fn_pattern) +{ + const std::set<std::string> param_regs = {"rdi", "rsi", "rdx", "rcx", "r8", "r9"}; + const bool original_is_param_register = param_regs.find(reg_arg_str) != param_regs.end(); + + std::set<std::string> live_params; + live_params.insert(reg_arg_str); + + for(auto ptr=insn->getFallthrough(); ptr!=NULL; ptr=ptr->getFallthrough()) + { + const auto p_d=DecodedInstruction_t::factory(ptr); + const auto &d=*p_d; + const auto tgt = isOrWasCall(firp, ptr); + + if (tgt) + { + if (fn_pattern.size() == 0) + { + // don't care about function name +// std::cout << "CallFollows(): yes, parameter to call" << endl; + return true; + } + else + { + // look for specific function + + // check the target has a function + if(tgt->getFunction()==NULL) + return false; + + const auto fname = tgt->getFunction()->getName(); +// std::cout << "CallFollows(): yes, parameter to call: function name: " << fname << endl; + return fname.find(fn_pattern)!=string::npos; + } + } + + // found reference to argstring, original code would just stop the search + // need more sophisticated heuristic + if(d.getDisassembly().find(reg_arg_str)!= string::npos) + { + if (original_is_param_register) + { + std::string arg; + if (isParameterWrite(firp, ptr, arg)) + { +// std::cout << "CallFollows(): " << ptr->getDisassembly() << ": detected write parameter" << std::endl; + if (arg == reg_arg_str) + { +// std::cout << "CallFollows(): " << ptr->getDisassembly() << ": same parameter as original: remove from live list: " << reg_arg_str << std::endl; + live_params.erase(reg_arg_str); + } + else + { + if (d.hasOperand(1) && d.getOperand(1)->getString() == reg_arg_str) + { +// std::cout << "CallFollows(): " << ptr->getDisassembly() << ": copy of original detected: add to live list: " << arg << std::endl; + live_params.insert(arg); + } + } + } + + std::cout << "CallFollows(): " << ptr->getDisassembly() << ": #live_param: " << dec << live_params.size() << std::endl; + if (live_params.size() == 0) + { +// std::cout << "CallFollows(): not a parameter to call" << endl; + return false; + } + } + else + { +// std::cout << "\tassume it's a write and exit" << std::endl; + return false; + } + + } + } + +// std::cout << "CallFollows(): no more fallthroughs, not a parameter to call" << endl; + return false; +} + +bool IRDB_SDK::flowsIntoCall(const IRDB_SDK::FileIR_t *firp, IRDB_SDK::Instruction_t* insn) +{ + string param_write; + if (!isParameterWrite(firp, insn, param_write)) + return false; + + return callFollows(firp, insn, param_write); +} + +bool IRDB_SDK::leaFlowsIntoCall(const IRDB_SDK::FileIR_t *firp, IRDB_SDK::Instruction_t* insn) +{ + const auto d=DecodedInstruction_t::factory(insn); + + if (d->getMnemonic()!="lea") + return false; + + return flowsIntoCall(firp, insn); +} + +bool IRDB_SDK::leaFlowsIntoPrintf(const IRDB_SDK::FileIR_t *firp, IRDB_SDK::Instruction_t* insn) +{ + const auto d=DecodedInstruction_t::factory(insn); + + if (d->getMnemonic()!="lea") + return false; + +// std::cout << "LeaFlowsIntoCall(): investigating " << insn->getDisassembly() << endl; + + string param_write; + if (!isParameterWrite(firp, insn, param_write)) + return false; + + return callFollows(firp, insn, param_write, "printf"); +} diff --git a/irdb-lib/libIRDB-util/src/registers.cpp b/irdb-lib/libIRDB-util/src/registers.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b9ee000e008a2e4cb46da90bd747d80a348769cc --- /dev/null +++ b/irdb-lib/libIRDB-util/src/registers.cpp @@ -0,0 +1,423 @@ + + +#include <string> +#include <irdb-util> + +using namespace std; +using namespace IRDB_SDK; + +RegisterID_t IRDB_SDK::strToRegister(const char *p_reg) +{ + return strToRegister(string(p_reg)); +} + +bool IRDB_SDK::isValidRegister(const RegisterID_t p_reg) +{ + return p_reg != rn_UNKNOWN; +} + +RegisterID_t IRDB_SDK::strToRegister(const string& p_reg) +{ + if (strcasecmp(p_reg.c_str(), "EFLAGS") ==0) + return rn_EFLAGS; + else if (strcasecmp(p_reg.c_str(), "RAX") == 0) + return rn_RAX; + else if (strcasecmp(p_reg.c_str(), "RBX") == 0) + return rn_RBX; + else if (strcasecmp(p_reg.c_str(), "RCX") == 0) + return rn_RCX; + else if (strcasecmp(p_reg.c_str(), "RDX") == 0) + return rn_RDX; + else if (strcasecmp(p_reg.c_str(), "RSI") == 0) + return rn_RSI; + else if (strcasecmp(p_reg.c_str(), "RDI") == 0) + return rn_RDI; + else if (strcasecmp(p_reg.c_str(), "RBP") == 0) + return rn_RBP; + else if (strcasecmp(p_reg.c_str(), "RSP") == 0) + return rn_RSP; + else if (strcasecmp(p_reg.c_str(), "R8") == 0) + return rn_R8; + else if (strcasecmp(p_reg.c_str(), "R9") == 0) + return rn_R9; + else if (strcasecmp(p_reg.c_str(), "R10") == 0) + return rn_R10; + else if (strcasecmp(p_reg.c_str(), "R11") == 0) + return rn_R11; + else if (strcasecmp(p_reg.c_str(), "R12") == 0) + return rn_R12; + else if (strcasecmp(p_reg.c_str(), "R13") == 0) + return rn_R13; + else if (strcasecmp(p_reg.c_str(), "R14") == 0) + return rn_R14; + else if (strcasecmp(p_reg.c_str(), "R15") == 0) + return rn_R15; + else if (strcasecmp(p_reg.c_str(), "RIP") == 0) + return rn_RIP; + + else if (strcasecmp(p_reg.c_str(), "EAX") == 0) + return rn_EAX; + else if (strcasecmp(p_reg.c_str(), "EBX") == 0) + return rn_EBX; + else if (strcasecmp(p_reg.c_str(), "ECX") == 0) + return rn_ECX; + else if (strcasecmp(p_reg.c_str(), "EDX") == 0) + return rn_EDX; + else if (strcasecmp(p_reg.c_str(), "ESI") == 0) + return rn_ESI; + else if (strcasecmp(p_reg.c_str(), "EDI") == 0) + return rn_EDI; + else if (strcasecmp(p_reg.c_str(), "EBP") == 0) + return rn_EBP; + else if (strcasecmp(p_reg.c_str(), "ESP") == 0) + return rn_ESP; + else if (strcasecmp(p_reg.c_str(), "R8D") == 0) + return rn_R8D; + else if (strcasecmp(p_reg.c_str(), "R9D") == 0) + return rn_R9D; + else if (strcasecmp(p_reg.c_str(), "R10D") == 0) + return rn_R10D; + else if (strcasecmp(p_reg.c_str(), "R11D") == 0) + return rn_R11D; + else if (strcasecmp(p_reg.c_str(), "R12D") == 0) + return rn_R12D; + else if (strcasecmp(p_reg.c_str(), "R13D") == 0) + return rn_R13D; + else if (strcasecmp(p_reg.c_str(), "R14D") == 0) + return rn_R14D; + else if (strcasecmp(p_reg.c_str(), "R15D") == 0) + return rn_R15D; + + else if (strcasecmp(p_reg.c_str(), "AX") == 0) + return rn_AX; + else if (strcasecmp(p_reg.c_str(), "BX") == 0) + return rn_BX; + else if (strcasecmp(p_reg.c_str(), "CX") == 0) + return rn_CX; + else if (strcasecmp(p_reg.c_str(), "DX") == 0) + return rn_DX; + else if (strcasecmp(p_reg.c_str(), "BP") == 0) + return rn_BP; + else if (strcasecmp(p_reg.c_str(), "SP") == 0) + return rn_SP; + else if (strcasecmp(p_reg.c_str(), "SI") == 0) + return rn_SI; + else if (strcasecmp(p_reg.c_str(), "DI") == 0) + return rn_DI; + else if (strcasecmp(p_reg.c_str(), "R8W") == 0) + return rn_R8W; + else if (strcasecmp(p_reg.c_str(), "R9W") == 0) + return rn_R9W; + else if (strcasecmp(p_reg.c_str(), "R10W") == 0) + return rn_R10W; + else if (strcasecmp(p_reg.c_str(), "R11W") == 0) + return rn_R11W; + else if (strcasecmp(p_reg.c_str(), "R12W") == 0) + return rn_R12W; + else if (strcasecmp(p_reg.c_str(), "R13W") == 0) + return rn_R13W; + else if (strcasecmp(p_reg.c_str(), "R14W") == 0) + return rn_R14W; + else if (strcasecmp(p_reg.c_str(), "R15W") == 0) + return rn_R15W; + + else if (strcasecmp(p_reg.c_str(), "AH") == 0) + return rn_AL; + else if (strcasecmp(p_reg.c_str(), "BH") == 0) + return rn_BL; + else if (strcasecmp(p_reg.c_str(), "CH") == 0) + return rn_CL; + else if (strcasecmp(p_reg.c_str(), "DH") == 0) + return rn_DL; + else if (strcasecmp(p_reg.c_str(), "AL") == 0) + return rn_AL; + else if (strcasecmp(p_reg.c_str(), "BL") == 0) + return rn_BL; + else if (strcasecmp(p_reg.c_str(), "CL") == 0) + return rn_CL; + else if (strcasecmp(p_reg.c_str(), "DL") == 0) + return rn_DL; + else if (strcasecmp(p_reg.c_str(), "SIL") == 0) + return rn_SIL; + else if (strcasecmp(p_reg.c_str(), "DIL") == 0) + return rn_DIL; + else if (strcasecmp(p_reg.c_str(), "BPL") == 0) + return rn_BPL; + else if (strcasecmp(p_reg.c_str(), "SPL") == 0) + return rn_SPL; + else if (strcasecmp(p_reg.c_str(), "R8B") == 0) + return rn_R8B; + else if (strcasecmp(p_reg.c_str(), "R9B") == 0) + return rn_R9B; + else if (strcasecmp(p_reg.c_str(), "R10B") == 0) + return rn_R10B; + else if (strcasecmp(p_reg.c_str(), "R11B") == 0) + return rn_R11B; + else if (strcasecmp(p_reg.c_str(), "R12B") == 0) + return rn_R12B; + else if (strcasecmp(p_reg.c_str(), "R13B") == 0) + return rn_R13B; + else if (strcasecmp(p_reg.c_str(), "R14B") == 0) + return rn_R14B; + else if (strcasecmp(p_reg.c_str(), "R15B") == 0) + return rn_R15B; + else + return rn_UNKNOWN; +} + +bool IRDB_SDK::is8bitRegister(const RegisterID_t p_reg) +{ + return p_reg == rn_AL || p_reg == rn_BL || p_reg == rn_CL || p_reg == rn_DL || + p_reg == rn_AH || p_reg == rn_BH || p_reg == rn_CH || p_reg == rn_DH || + p_reg == rn_SIL || p_reg == rn_DIL || p_reg == rn_BPL || p_reg == rn_SPL || + p_reg == rn_R8B || p_reg == rn_R9B || p_reg == rn_R10B || p_reg == rn_R11B || + p_reg == rn_R12B || p_reg == rn_R13B || p_reg == rn_R14B || p_reg == rn_R15B; +} + +bool IRDB_SDK::is16bitRegister(const RegisterID_t p_reg) +{ + return p_reg == rn_AX || p_reg == rn_BX || p_reg == rn_CX || p_reg == rn_DX || + p_reg == rn_BP || p_reg == rn_SP || p_reg == rn_SI || p_reg == rn_DI || + p_reg == rn_R8W || p_reg == rn_R9W || p_reg == rn_R10W || p_reg == rn_R11W || + p_reg == rn_R12W || p_reg == rn_R13W || p_reg == rn_R14W || p_reg == rn_R15W; +} + +bool IRDB_SDK::is32bitRegister(const RegisterID_t p_reg) +{ + return p_reg == rn_EAX || p_reg == rn_EBX || p_reg == rn_ECX || p_reg == rn_EDX || + p_reg == rn_ESI || p_reg == rn_EDI || p_reg == rn_ESP || p_reg == rn_EBP || + p_reg == rn_R8D || p_reg == rn_R9D || p_reg == rn_R10D || p_reg == rn_R11D || + p_reg == rn_R12D || p_reg == rn_R13D || p_reg == rn_R14D || p_reg == rn_R15D; +} + +bool IRDB_SDK::is64bitRegister(const RegisterID_t p_reg) +{ + return p_reg == rn_RAX || p_reg == rn_RBX || p_reg == rn_RCX || p_reg == rn_RDX || + p_reg == rn_RSI || p_reg == rn_RDI || p_reg == rn_RBP || p_reg == rn_RSP || + p_reg == rn_R8 || p_reg == rn_R9 || p_reg == rn_R10 || p_reg == rn_R11 || + p_reg == rn_R12 || p_reg == rn_R13 || p_reg == rn_R14 || p_reg == rn_R15 || p_reg == rn_RIP; +} + +string IRDB_SDK::registerToString(const RegisterID_t p_reg) +{ + if (p_reg == rn_UNKNOWN) return string("UNKNOWN"); + + else if (p_reg == rn_EFLAGS) return string("EFLAGS"); + + else if (p_reg == rn_RAX) return string("RAX"); + else if (p_reg == rn_RBX) return string("RBX"); + else if (p_reg == rn_RCX) return string("RCX"); + else if (p_reg == rn_RDX) return string("RDX"); + else if (p_reg == rn_RSI) return string("RSI"); + else if (p_reg == rn_RDI) return string("RDI"); + else if (p_reg == rn_RBP) return string("RBP"); + else if (p_reg == rn_RSP) return string("RSP"); + else if (p_reg == rn_R8) return string("R8"); + else if (p_reg == rn_R9) return string("R9"); + else if (p_reg == rn_R10) return string("R10"); + else if (p_reg == rn_R11) return string("R11"); + else if (p_reg == rn_R12) return string("R12"); + else if (p_reg == rn_R13) return string("R13"); + else if (p_reg == rn_R14) return string("R14"); + else if (p_reg == rn_R15) return string("R15"); + else if (p_reg == rn_RIP) return string("RIP"); + + else if (p_reg == rn_EAX) return string("EAX"); + else if (p_reg == rn_EBX) return string("EBX"); + else if (p_reg == rn_ECX) return string("ECX"); + else if (p_reg == rn_EDX) return string("EDX"); + else if (p_reg == rn_EDI) return string("EDI"); + else if (p_reg == rn_ESI) return string("ESI"); + else if (p_reg == rn_EBP) return string("EBP"); + else if (p_reg == rn_ESP) return string("ESP"); + else if (p_reg == rn_R8D) return string("R8D"); + else if (p_reg == rn_R9D) return string("R9D"); + else if (p_reg == rn_R10D) return string("R10D"); + else if (p_reg == rn_R11D) return string("R11D"); + else if (p_reg == rn_R12D) return string("R12D"); + else if (p_reg == rn_R13D) return string("R13D"); + else if (p_reg == rn_R14D) return string("R14D"); + else if (p_reg == rn_R15D) return string("R15D"); + + else if (p_reg == rn_AX) return string("AX"); + else if (p_reg == rn_BX) return string("BX"); + else if (p_reg == rn_CX) return string("CX"); + else if (p_reg == rn_DX) return string("DX"); + else if (p_reg == rn_BP) return string("BP"); + else if (p_reg == rn_SP) return string("SP"); + else if (p_reg == rn_SI) return string("SI"); + else if (p_reg == rn_DI) return string("DI"); + else if (p_reg == rn_R8W) return string("R8W"); + else if (p_reg == rn_R9W) return string("R9W"); + else if (p_reg == rn_R10W) return string("R10W"); + else if (p_reg == rn_R11W) return string("R11W"); + else if (p_reg == rn_R12W) return string("R12W"); + else if (p_reg == rn_R13W) return string("R13W"); + else if (p_reg == rn_R14W) return string("R14W"); + else if (p_reg == rn_R15W) return string("R15W"); + + else if (p_reg == rn_AH) return string("AH"); + else if (p_reg == rn_BH) return string("BH"); + else if (p_reg == rn_CH) return string("CH"); + else if (p_reg == rn_DH) return string("DH"); + else if (p_reg == rn_AL) return string("AL"); + else if (p_reg == rn_BL) return string("BL"); + else if (p_reg == rn_CL) return string("CL"); + else if (p_reg == rn_DL) return string("DL"); + else if (p_reg == rn_SIL) return string("SIL"); + else if (p_reg == rn_DIL) return string("DIL"); + else if (p_reg == rn_BPL) return string("BPL"); + else if (p_reg == rn_SPL) return string("SPL"); + else if (p_reg == rn_R8B) return string("R8B"); + else if (p_reg == rn_R9B) return string("R9B"); + else if (p_reg == rn_R10B) return string("R10B"); + else if (p_reg == rn_R11B) return string("R11B"); + else if (p_reg == rn_R12B) return string("R12B"); + else if (p_reg == rn_R13B) return string("R13B"); + else if (p_reg == rn_R14B) return string("R14B"); + else if (p_reg == rn_R15B) return string("R15B"); + + else return string("UNEXPECTED REGISTER VALUE"); +} + + +RegisterID_t IRDB_SDK::convertRegisterTo64bit(const RegisterID_t p_reg) +{ + if (is64bitRegister(p_reg)) + return p_reg; + + switch (p_reg) + { + case rn_AL: + case rn_AH: + case rn_AX: + case rn_EAX: + return rn_RAX; + case rn_BL: + case rn_BH: + case rn_BX: + case rn_EBX: + return rn_RBX; + case rn_CL: + case rn_CH: + case rn_CX: + case rn_ECX: + return rn_RCX; + case rn_DL: + case rn_DH: + case rn_DX: + case rn_EDX: + return rn_RDX; + case rn_DIL: + case rn_DI: + case rn_EDI: + return rn_RDI; + case rn_SIL: + case rn_SI: + case rn_ESI: + return rn_RSI; + case rn_BPL: + case rn_BP: + case rn_EBP: + return rn_RBP; + case rn_SPL: + case rn_SP: + case rn_ESP: + return rn_RSP; + case rn_R8B: + case rn_R8W: + case rn_R8D: + return rn_R8; + case rn_R9B: + case rn_R9W: + case rn_R9D: + return rn_R9; + case rn_R10B: + case rn_R10W: + case rn_R10D: + return rn_R10; + case rn_R11B: + case rn_R11W: + case rn_R11D: + return rn_R11; + case rn_R12B: + case rn_R12W: + case rn_R12D: + return rn_R12; + case rn_R13B: + case rn_R13W: + case rn_R13D: + return rn_R13; + case rn_R14B: + case rn_R14W: + case rn_R14D: + return rn_R14; + case rn_R15B: + case rn_R15W: + case rn_R15D: + return rn_R15; + + default: + return rn_UNKNOWN; + break; + } +} + +RegisterID_t IRDB_SDK::convertRegisterTo32bit(const RegisterID_t p_reg) +{ + if (is32bitRegister(p_reg)) + return p_reg; + + switch (p_reg) + { + case rn_RAX: return rn_EAX; + case rn_RBX: return rn_EBX; + case rn_RCX: return rn_ECX; + case rn_RDX: return rn_EDX; + case rn_RBP: return rn_EBP; + case rn_RSP: return rn_ESP; + case rn_RSI: return rn_ESI; + case rn_RDI: return rn_EDI; + case rn_R8: return rn_R8D; + case rn_R9: return rn_R9D; + case rn_R10: return rn_R10D; + case rn_R11: return rn_R11D; + case rn_R12: return rn_R12D; + case rn_R13: return rn_R13D; + case rn_R14: return rn_R14D; + case rn_R15: return rn_R15D; + default: + return rn_UNKNOWN; + break; + } +} + +RegisterID_t IRDB_SDK::convertRegisterTo16bit(const RegisterID_t p_reg) +{ + if (is16bitRegister(p_reg)) + return p_reg; + + switch (p_reg) + { + case rn_RAX: case rn_EAX: return rn_AX; + case rn_RBX: case rn_EBX: return rn_BX; + case rn_RCX: case rn_ECX: return rn_CX; + case rn_RDX: case rn_EDX: return rn_DX; + case rn_RBP: case rn_EBP: return rn_BP; + case rn_RSP: case rn_ESP: return rn_SP; + case rn_RSI: case rn_ESI: return rn_SI; + case rn_RDI: case rn_EDI: return rn_DI; + case rn_R8: case rn_R8D: return rn_R8W; + case rn_R9: case rn_R9D: return rn_R9W; + case rn_R10: case rn_R10D: return rn_R10W; + case rn_R11: case rn_R11D: return rn_R11W; + case rn_R12: case rn_R12D: return rn_R12W; + case rn_R13: case rn_R13D: return rn_R13W; + case rn_R14: case rn_R14D: return rn_R14W; + case rn_R15: case rn_R15D: return rn_R15W; + default: + return rn_UNKNOWN; + break; + } +} + diff --git a/irdb-lib/libMEDSannotation/LICENSE.txt b/irdb-lib/libMEDSannotation/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..312fba3fce32ba9e8a488ac58885ca41c59c2aa8 --- /dev/null +++ b/irdb-lib/libMEDSannotation/LICENSE.txt @@ -0,0 +1,14 @@ +************************************************************************************* +* +* Unless otherwise specified, software artifacts in this directory and its +* subdirectories are subject to: +* +* GOVERNMENT PURPOSE RIGHTS +* +* The Government's rights to use, modify, reproduce, release, perform, display, or +* disclose this software are restricted by GOVERNMENT PURPOSE RIGHTS. +* +* Any reproduction of the software or portions thereof marked with this legend +* must also reproduce the markings. +* +************************************************************************************* diff --git a/irdb-lib/libMEDSannotation/Makefile.in b/irdb-lib/libMEDSannotation/Makefile.in new file mode 100644 index 0000000000000000000000000000000000000000..f9227c74436aa0f6905cc8f054691394a2db56ac --- /dev/null +++ b/irdb-lib/libMEDSannotation/Makefile.in @@ -0,0 +1,9 @@ + +CC=@CC@ +CXX=@CXX@ + +all: + cd src;make CC=$(CC) CXX=$(CXX) + +clean: + cd src; make clean diff --git a/irdb-lib/libMEDSannotation/SConscript b/irdb-lib/libMEDSannotation/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..cb89f07ae1ff32592f4b06405da21d792395931f --- /dev/null +++ b/irdb-lib/libMEDSannotation/SConscript @@ -0,0 +1,36 @@ +import os + +Import('env') +myenv=env.Clone() +myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) + +lib="MEDSannotation" + +files= ''' + src/FuncExitAnnotation.cpp + src/MEDS_AnnotationParser.cpp + src/MEDS_FPTRShadowAnnotation.cpp + src/MEDS_DeadRegAnnotation.cpp + src/MEDS_FRSafeAnnotation.cpp + src/MEDS_FuncPrototypeAnnotation.cpp + src/MEDS_InstructionCheckAnnotation.cpp + src/MEDS_MemoryRangeAnnotation.cpp + src/MEDS_ProblemFuncAnnotation.cpp + src/MEDS_Register.cpp + src/MEDS_SafeFuncAnnotation.cpp + src/VirtualOffset.cpp + ''' +cpppath=''' + ./include/ + $IRDB_SDK/include/ + ''' + +#CFLAGS="-fPIC " + +myenv=myenv.Clone(CPPPATH=Split(cpppath)) +myenv.Append(CXXFLAGS=" -std=c++11 -Wall -Werror ") +lib=myenv.SharedLibrary(lib, Split(files)) + +install=myenv.Install("$SECURITY_TRANSFORMS_HOME/lib/", lib) +Default(install) +Return('install') diff --git a/irdb-lib/libMEDSannotation/SConstruct b/irdb-lib/libMEDSannotation/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..b3bd01322f2b78089fd86e0e9b0ae01897c9c8a5 --- /dev/null +++ b/irdb-lib/libMEDSannotation/SConstruct @@ -0,0 +1,7 @@ + + + +env=Environment() +Export('env') +lib=SConscript("SConscript") +Return('lib') diff --git a/irdb-lib/libMEDSannotation/include/FuncExitAnnotation.hpp b/irdb-lib/libMEDSannotation/include/FuncExitAnnotation.hpp new file mode 100644 index 0000000000000000000000000000000000000000..39ffd69cf289e282596c115ec76e04ed3d5d3e50 --- /dev/null +++ b/irdb-lib/libMEDSannotation/include/FuncExitAnnotation.hpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef _FUNCEXITANNOTATION_H_ +#define _FUNCEXITANNOTATION_H_ + +#include <string> +#include "VirtualOffset.hpp" +#include "MEDS_Register.hpp" +#include "MEDS_AnnotationBase.hpp" + + +namespace MEDS_Annotation +{ + +using namespace std; +using namespace MEDS_Annotation; + +// +// Class to handle one MEDS annotation +// +class MEDS_FuncExitAnnotation : public MEDS_AnnotationBase +{ + public: + MEDS_FuncExitAnnotation() {}; + MEDS_FuncExitAnnotation(const string &p_rawLine); + virtual ~MEDS_FuncExitAnnotation(){} + + virtual const string toString() const { return "tail call: "+m_rawInputLine; } + + private: + void init(); + void parse(); + + private: + std::string m_rawInputLine; +}; + +} +#endif diff --git a/irdb-lib/libMEDSannotation/include/MEDS.hpp b/irdb-lib/libMEDSannotation/include/MEDS.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c3b9388027ed400a4f87f290cabde852688f5546 --- /dev/null +++ b/irdb-lib/libMEDSannotation/include/MEDS.hpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef _MEDS_H +#define _MEDS_H + +namespace MEDS_Annotation +{ + +class MEDS +{ + public: + enum Register { UNKNOWN, EAX, EBX, ECX, EDX }; +}; + + +} +#endif + diff --git a/irdb-lib/libMEDSannotation/include/MEDS_AnnotationBase.hpp b/irdb-lib/libMEDSannotation/include/MEDS_AnnotationBase.hpp new file mode 100644 index 0000000000000000000000000000000000000000..1c1a2cdcd41d1f12350b2a7c1cb8b7719c764780 --- /dev/null +++ b/irdb-lib/libMEDSannotation/include/MEDS_AnnotationBase.hpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef MEDS_ANNOTATION_BASE_HPP +#define MEDS_ANNOTATION_BASE_HPP + + +#include <assert.h> +#include "VirtualOffset.hpp" + + +namespace MEDS_Annotation +{ + + +// base class for deriving objects. +class MEDS_AnnotationBase +{ + public: + MEDS_AnnotationBase() { init(); } + virtual ~MEDS_AnnotationBase() { } + + /* i'd rather make this a pure virtual func, but can't figure out why it won't compile */ + virtual const std::string toString() const =0; + + // valid annotation? + virtual bool isValid() const { return m_isValid; } + virtual void setValid() { m_isValid = true; } + virtual void setInvalid() { m_isValid = false; } + + // virtual offset + virtual VirtualOffset getVirtualOffset() const { return m_virtualOffset; } + virtual void setVirtualOffset(VirtualOffset p_vo) { m_virtualOffset = p_vo; } + + virtual void setInstructionSize(int p_size) { m_size = p_size; } + virtual int getInstructionSize() { return m_size; } + + virtual void init() { m_isValid = false; m_size = 0; } + + virtual bool isFuncAnnotation() const { return false; } // false by default + + protected: + bool m_isValid; + int m_size; + VirtualOffset m_virtualOffset; +}; + +} + +#endif diff --git a/irdb-lib/libMEDSannotation/include/MEDS_AnnotationParser.hpp b/irdb-lib/libMEDSannotation/include/MEDS_AnnotationParser.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a65a88db46f47686f318dd583323bd9eb1d57c51 --- /dev/null +++ b/irdb-lib/libMEDSannotation/include/MEDS_AnnotationParser.hpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef _MEDS_ANNOTATION_PARSER_H_ +#define _MEDS_ANNOTATION_PARSER_H_ + +#include <map> +#include <iostream> + +#include "MEDS_AnnotationBase.hpp" +#include "VirtualOffset.hpp" + +namespace MEDS_Annotation +{ + +typedef std::multimap<const VirtualOffset, MEDS_AnnotationBase*> MEDS_Annotations_t; +typedef std::pair<const VirtualOffset, MEDS_AnnotationBase*> MEDS_Annotations_Pair_t; + +typedef std::multimap<const std::string, MEDS_AnnotationBase*> MEDS_FuncAnnotations_t; +typedef std::pair<const std::string, MEDS_AnnotationBase*> MEDS_Annotations_FuncPair_t; + +class MEDS_AnnotationParser +{ + public: + MEDS_AnnotationParser() {}; + MEDS_AnnotationParser(std::istream &); /* pass opened file */ + void parseFile(std::istream &); + void parseFile(const std::string &); /* pass filename */ + MEDS_Annotations_t & getAnnotations() { return m_annotations; } + MEDS_FuncAnnotations_t & getFuncAnnotations() { return m_func_annotations; } + + private: + // helpers + template <class type> bool add_if_valid(std::string line); + + // data + MEDS_Annotations_t m_annotations; + MEDS_FuncAnnotations_t m_func_annotations; +}; + +} + +#endif diff --git a/irdb-lib/libMEDSannotation/include/MEDS_DeadRegAnnotation.hpp b/irdb-lib/libMEDSannotation/include/MEDS_DeadRegAnnotation.hpp new file mode 100644 index 0000000000000000000000000000000000000000..087bd687327740b067f75b4b4fda4f3ae98997eb --- /dev/null +++ b/irdb-lib/libMEDSannotation/include/MEDS_DeadRegAnnotation.hpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef _MEDS_DEADREGSANNOTATION_H_ +#define _MEDS_DEADREGSANNOTATION_H_ + +#include <algorithm> +#include <string> +#include <stdint.h> +#include "VirtualOffset.hpp" +#include "MEDS_Register.hpp" +#include "MEDS_AnnotationBase.hpp" + +namespace MEDS_Annotation +{ + +using namespace std; +using namespace MEDS_Annotation; + + +// +// Class to handle one MEDS limited function pointer shadow annotation +// +class MEDS_DeadRegAnnotation : public MEDS_AnnotationBase +{ + public: + MEDS_DeadRegAnnotation(); + MEDS_DeadRegAnnotation(const string& p_rawLine); + virtual ~MEDS_DeadRegAnnotation() {} + virtual const string toString() const { return "deadregs: " + m_rawInputLine; } + + RegisterSet_t& getRegisterSet() { return regset; } + + private: + // base class requirements. + void parse(); + + private: + RegisterSet_t regset; + string m_rawInputLine; +}; + +} + +#endif diff --git a/irdb-lib/libMEDSannotation/include/MEDS_FPTRShadowAnnotation.hpp b/irdb-lib/libMEDSannotation/include/MEDS_FPTRShadowAnnotation.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b6647248ecc7fa7363eefb5cb39b77f688020a80 --- /dev/null +++ b/irdb-lib/libMEDSannotation/include/MEDS_FPTRShadowAnnotation.hpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef _MEDS_FPTRSHADOWANNOTATION_H_ +#define _MEDS_FPTRSHADOWANNOTATION_H_ + +#include <algorithm> +#include <string> +#include <stdint.h> +#include "VirtualOffset.hpp" +#include "MEDS_ShadowAnnotation.hpp" +#include "MEDS_Register.hpp" + +namespace MEDS_Annotation +{ + +using namespace std; +using namespace MEDS_Annotation; + + +#define MEDS_ANNOT_FPTRSHADOW "FPTRSHADOW" +#define MEDS_ANNOT_FPTRCHECK "FPTRCHECK" +#define MEDS_ANNOT_ARGSHADOW "ARGSHADOW" +#define MEDS_ANNOT_ARGCHECK "ARGCHECK" + +// +// Class to handle one MEDS limited function pointer shadow annotation +// +// Examples: +// 8057fa7 3 INSTR FPTRSHADOW [EAX+8] SHADOWID 5 +// 805829d 3 INSTR FPTRCHECK [EBP-40] SHADOWID 5 +// 80822aa 7 INSTR FPTRSHADOW 0 SHADOWID 6 +// 80822cc 3 INSTR FPTRSHADOW EAX SHADOWID 6 +// 8480faa 9 INSTR FPTRSHADOW 4721886 SHADOWID 75 +// +class MEDS_FPTRShadowAnnotation : public MEDS_ShadowAnnotation +{ + public: + MEDS_FPTRShadowAnnotation(); + MEDS_FPTRShadowAnnotation(const string& p_rawLine); + virtual ~MEDS_FPTRShadowAnnotation() {} + virtual const string toString() const { return "fptr/arg shadow: " + m_rawInputLine; } + + bool isRIPRelative() const; + uintptr_t computeRIPAddress(); + + bool isConstant() const; + long long getConstantValue(bool&) const; + + bool isRegister() const; + bool isMemoryExpression() const; + + const RegisterName getRegister() const; + const string& getExpression() const { return m_expression; } + + const bool isFunctionPointerShadow() const { return m_functionPointerShadow; } + const bool isCriticalArgumentShadow() const { return m_criticalArgumentShadow; } + private: + void parse(); + void setExpression(const string p_expression) { + m_expression = p_expression; + std::transform(m_expression.begin(), m_expression.end(), m_expression.begin(), ::tolower); + } + bool verifyCheckShadowExpression(const string& expression); + int parseRegisterOffset(const char*); + void parseRegister(const char *p_buf, RegisterName *p_register, int *p_registerOffset); + + void setFunctionPointerShadow(const bool p_val) { m_functionPointerShadow = p_val; } + void setCriticalArgumentShadow(const bool p_val) { m_criticalArgumentShadow = p_val; } + + private: + string m_rawInputLine; + string m_expression; + bool m_functionPointerShadow; + bool m_criticalArgumentShadow; +}; + +} + +#endif diff --git a/irdb-lib/libMEDSannotation/include/MEDS_FRSafeAnnotation.hpp b/irdb-lib/libMEDSannotation/include/MEDS_FRSafeAnnotation.hpp new file mode 100644 index 0000000000000000000000000000000000000000..129cf727c81c862061dcb41e6bebd8e964cf1e9e --- /dev/null +++ b/irdb-lib/libMEDSannotation/include/MEDS_FRSafeAnnotation.hpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef _MEDS_FRSAFEANNOTATION_H_ +#define _MEDS_FRSAFEANNOTATION_H_ + +#include <string> +#include "VirtualOffset.hpp" +#include "MEDS_Register.hpp" +#include "MEDS_AnnotationBase.hpp" + + +namespace MEDS_Annotation +{ + +using namespace std; +using namespace MEDS_Annotation; + +// +// Class to handle one MEDS (integer vulnerability) annotation +// +class MEDS_FRSafeAnnotation : public MEDS_AnnotationBase +{ + public: + MEDS_FRSafeAnnotation() {}; + MEDS_FRSafeAnnotation(const string &p_rawLine); + virtual ~MEDS_FRSafeAnnotation(){} + + virtual const string toString() const { return "fr safe func: "+m_rawInputLine; } + + private: + void init(); + void parse(); + + private: + std::string m_rawInputLine; +}; + +} +#endif diff --git a/irdb-lib/libMEDSannotation/include/MEDS_FuncAnnotation.hpp b/irdb-lib/libMEDSannotation/include/MEDS_FuncAnnotation.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e4dc9347c531c14729f85d769f56b08bc729a5eb --- /dev/null +++ b/irdb-lib/libMEDSannotation/include/MEDS_FuncAnnotation.hpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef _MEDS_FUNCANNOTATION_H_ +#define _MEDS_FUNCANNOTATION_H_ + +#include <string> +#include "VirtualOffset.hpp" +#include "MEDS_Register.hpp" +#include "MEDS_AnnotationBase.hpp" + + +namespace MEDS_Annotation +{ + +// These strings must match those emitted by MEDS in the information annotation file exactly +#define MEDS_ANNOT_FUNC "FUNC" + +using namespace std; +using namespace MEDS_Annotation; + +// +// Class to handle one MEDS annotation +// +class MEDS_FuncAnnotation : public MEDS_AnnotationBase +{ + public: + MEDS_FuncAnnotation() {} + virtual ~MEDS_FuncAnnotation(){} + + virtual bool isFuncAnnotation() const { return true; } + + virtual string getFuncName() const { return m_func_name; } + virtual void setFuncName(const string &p_func_name) { m_func_name=p_func_name; } + + virtual bool isLeaf() const { return m_isleaf; } + virtual void setLeaf(const bool p_leaf) { m_isleaf = p_leaf; } + + virtual bool hasFramePointer() const { return m_hasfp; } + virtual void setHasFramePointer(const bool p_hasfp) { m_hasfp = p_hasfp; } + + private: + string m_func_name; + bool m_isleaf; + bool m_hasfp; +}; + +} +#endif diff --git a/irdb-lib/libMEDSannotation/include/MEDS_FuncPrototypeAnnotation.hpp b/irdb-lib/libMEDSannotation/include/MEDS_FuncPrototypeAnnotation.hpp new file mode 100644 index 0000000000000000000000000000000000000000..4e94a0200ba10799ebfcff7a036119aa536baf45 --- /dev/null +++ b/irdb-lib/libMEDSannotation/include/MEDS_FuncPrototypeAnnotation.hpp @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef _MEDS_FUNCPROTOTYPEANNOTATION_H_ +#define _MEDS_FUNCPROTOTYPEANNOTATION_H_ + +#include <string> +#include <vector> +#include "VirtualOffset.hpp" +#include "MEDS_Register.hpp" +#include "MEDS_FuncAnnotation.hpp" + + +namespace MEDS_Annotation +{ + +using namespace std; +using namespace MEDS_Annotation; + +// +// Must match STARS type system +// UNINIT = 0, // Operand type not yet analyzed; type lattice top +// NUMERIC = 1, // Definitely holds non-pointer value (char, int, etc.) +// CODEPTR = 2, // Definitely holds a code address; mmStrata considers this NUMERIC +// POINTER = 4, // Definitely holds a data address +// STACKPTR = 8, // Definitely holds a stack data address (refinement of POINTER) +// GLOBALPTR = 16, // Definitely holds a global static data address (refinement of POINTER) +// HEAPPTR = 32, // Definitely holds a heap data address (refinement of POINTER) +// PTROFFSET = 64, // Offset from a pointer, e.g. a difference between two pointers +// NEGATEDPTR = 65, // Temporary ptr arithmetic leaves NUMERIC-POINTER; should get +POINTER later to make PTROFFSET +// UNKNOWN = 96, // Might hold an address, might not (Bad!); type lattice bottom +// +typedef enum { + MEDS_TYPE_UNINIT = 0, + MEDS_TYPE_NUMERIC = 1, + MEDS_TYPE_CODEPTR = 2, + MEDS_TYPE_POINTER = 4, + MEDS_TYPE_STACKPTR = 8, + MEDS_TYPE_GLOBALPTR = 16, + MEDS_TYPE_HEAPPTR = 32, + MEDS_TYPE_PTROFFSET = 64, + MEDS_TYPE_NEGATEDPTR = 65, + MEDS_TYPE_UNKNOWN = 96 +} MEDS_ArgType; + +// wrapper class around MEDS typing system +class MEDS_Arg { + public: + MEDS_Arg() { m_type = MEDS_TYPE_UNKNOWN; m_reg = IRDB_SDK::rn_UNKNOWN; } + MEDS_Arg(int p_type, RegisterName p_reg = IRDB_SDK::rn_UNKNOWN) { m_type = (MEDS_ArgType) p_type; m_reg = p_reg; } + virtual ~MEDS_Arg() {} + bool isNumericType() { return m_type == MEDS_TYPE_NUMERIC; } + bool isPointerType() { + return m_type == MEDS_TYPE_CODEPTR || m_type == MEDS_TYPE_POINTER || + m_type == MEDS_TYPE_STACKPTR || m_type == MEDS_TYPE_GLOBALPTR || + m_type == MEDS_TYPE_HEAPPTR; + } + bool isUnknownType() { return !(isNumericType() || isPointerType()); } + + private: + MEDS_ArgType m_type; + RegisterName m_reg; +}; + +// +// Class to handle one function prototype annotations +// +class MEDS_FuncPrototypeAnnotation : public MEDS_AnnotationBase +{ + public: + MEDS_FuncPrototypeAnnotation() { init(); }; + MEDS_FuncPrototypeAnnotation(const string &p_rawLine); + virtual ~MEDS_FuncPrototypeAnnotation() {} +// virtual bool isFuncPrototypeAnnotation() const { return true; } + + virtual const string toString() const { return "func proto: " + m_rawInputLine; } + + int getNumArgs() const { return m_arguments ? m_arguments->size() : 0; } + std::vector<MEDS_Arg>* getArgs() { return m_arguments; } + void addArg(MEDS_Arg p_arg) { + if (!m_arguments) m_arguments = new std::vector<MEDS_Arg>; + m_arguments->push_back(p_arg); + } + void setReturnArg(MEDS_Arg p_arg) { + if (!m_returnArg) m_returnArg = new MEDS_Arg; + *m_returnArg = p_arg; + } + MEDS_Arg* getReturnArg() const { return m_returnArg; } + + private: + void init(); + void parse(); + + private: + string m_rawInputLine; + + std::vector<MEDS_Arg> *m_arguments; + MEDS_Arg *m_returnArg; +}; + +} + +#endif diff --git a/irdb-lib/libMEDSannotation/include/MEDS_IBAnnotation.hpp b/irdb-lib/libMEDSannotation/include/MEDS_IBAnnotation.hpp new file mode 100644 index 0000000000000000000000000000000000000000..727bb696a9070dcbcba74fbb008dc63705aae32b --- /dev/null +++ b/irdb-lib/libMEDSannotation/include/MEDS_IBAnnotation.hpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef _MEDS_IBANNOTATION_H_ +#define _MEDS_IBANNOTATION_H_ + +#include <string> +#include "VirtualOffset.hpp" +#include "MEDS_AnnotationBase.hpp" + +namespace MEDS_Annotation +{ + +using namespace std; +using namespace MEDS_Annotation; + +// +// Class to handle one MEDS shadow annotation +// +class MEDS_IBAnnotation : public MEDS_AnnotationBase +{ + public: + typedef enum { SWITCH, RET, UNKNOWN } ib_type_t; + + MEDS_IBAnnotation( const string& p_rawLine) : the_type(UNKNOWN), count(0), complete(false) + { + setInvalid(); + parse(p_rawLine); + + }; + + ib_type_t GetType() const { return the_type; } + int GetCount() const { return count; } + bool IsComplete() const { return complete; } + + virtual const std::string toString() const + { + std::string ret="IB"; + if(IsComplete()) ret+=" COMPLETE"; + ret+=" Count=<na> type=<na>"; + return ret; + } + + protected: + + void parse(const string& p_rawLine) + { + string tofind="INSTR XREF FROMIB"; + size_t pos=p_rawLine.find(tofind); + if(pos==string::npos) + return; + + VirtualOffset vo(p_rawLine); + m_virtualOffset = vo; + + + // she be valid + setValid(); + + tofind="COMPLETE"; + size_t pos2=p_rawLine.find(tofind); + if(pos2!=string::npos) + { + pos=pos2; + complete=true; + } + + string rest=p_rawLine.substr(pos+tofind.length()); + istringstream is(rest); + is>>count; /* get count */ + + if(p_rawLine.find("RETURNTARGET")) set_type(RET); + if(p_rawLine.find("SWITCHTABLE")) set_type(SWITCH); + + } + + void set_type(ib_type_t t) + { + assert(the_type==UNKNOWN); + } + + private: + + ib_type_t the_type; + int count; + bool complete; +}; + +} + +#endif diff --git a/irdb-lib/libMEDSannotation/include/MEDS_IBTAnnotation.hpp b/irdb-lib/libMEDSannotation/include/MEDS_IBTAnnotation.hpp new file mode 100644 index 0000000000000000000000000000000000000000..8fd05f8f0e2ffb4568090e65b037c549abbea9c6 --- /dev/null +++ b/irdb-lib/libMEDSannotation/include/MEDS_IBTAnnotation.hpp @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBTILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef _MEDS_IBTANNOTATION_H_ +#define _MEDS_IBTANNOTATION_H_ + +#include <string> +#include "VirtualOffset.hpp" +#include "MEDS_AnnotationBase.hpp" + +namespace MEDS_Annotation +{ + +using namespace std; +using namespace MEDS_Annotation; + +// +// Class to handle one MEDS shadow annotation +// +class MEDS_IBTAnnotation : public MEDS_AnnotationBase +{ + public: + typedef enum { SWITCH, RET, DATA, UNREACHABLE, ADDRESSED, INDIRCALL, UNKNOWN } ibt_reason_code_t; + + MEDS_IBTAnnotation()=delete; + MEDS_IBTAnnotation( const string& p_rawLine) + : xref_addr(0), reason(UNKNOWN) + { + setInvalid(); + parse(p_rawLine); + + }; + + ApplicationAddress GetXrefAddr() { return xref_addr; } + ibt_reason_code_t GetReason() { return reason; } + + virtual const std::string toString() const + { + return "IBT"; + } + + protected: + + void parse(const string& p_rawLine) + { + string tofind="INSTR XREF IBT"; + size_t pos=p_rawLine.find(tofind); + if(pos==string::npos) + return; + + setValid(); + + VirtualOffset vo(p_rawLine); + m_virtualOffset = vo; + + + stringstream stream(p_rawLine.substr(pos+tofind.length())); + + string from_type; + stream >> from_type; + + if(string("FROMIB") == from_type) + { + stream >> hex >> xref_addr; + //cout<<"fromib: '"<<p_rawLine<<"'"<<endl; + } + else if(string("FROMDATA") == from_type) + { + stream >> hex >> xref_addr; + reason=DATA; + //cout<<"fromdata: '"<<p_rawLine<<"'"<<endl; + return; + } + else if(string("FROMUNKNOWN") == from_type) + { + // no other fields for from UNKNOWN + xref_addr=0; + //cout<<"fromunknown: '"<<p_rawLine<<"'"<<endl; + } + + string reason_code; + stream >> reason_code; + + if(string("RETURNTARGET") == reason_code) + { reason=RET; } + else if(string("TAILCALLRETURNTARGET") == reason_code) + { reason=RET; } + else if(string("SWITCHTABLE") == reason_code) + { reason=SWITCH; } + else if(string("UNREACHABLEBLOCK") == reason_code) + { reason=UNREACHABLE; } + else if(string("CODEADDRESSTAKEN") == reason_code) + { reason=ADDRESSED; } + else if(string("INDIRCALL") == reason_code) + { reason=INDIRCALL; } + else + { reason=UNKNOWN; } + + if(reason==UNKNOWN) + cout<<"unknown reason code: '"<<reason_code<<"'"<<endl; + + } + + private: + + ApplicationAddress xref_addr; + ibt_reason_code_t reason; +}; + +} + +#endif diff --git a/irdb-lib/libMEDSannotation/include/MEDS_InstructionCheckAnnotation.hpp b/irdb-lib/libMEDSannotation/include/MEDS_InstructionCheckAnnotation.hpp new file mode 100644 index 0000000000000000000000000000000000000000..023cf5776277b0a69246993734e1fa515b407120 --- /dev/null +++ b/irdb-lib/libMEDSannotation/include/MEDS_InstructionCheckAnnotation.hpp @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef _MEDS_INSTRUCTIONCHECKANNOTATION_H_ +#define _MEDS_INSTRUCTIONCHECKANNOTATION_H_ + +#include <string> +#include "VirtualOffset.hpp" +#include "MEDS_Register.hpp" +#include "MEDS_AnnotationBase.hpp" + + +namespace MEDS_Annotation +{ + +// These strings must match those emitted by MEDS in the information annotation file exactly +#define MEDS_ANNOT_INSTR "INSTR" +#define MEDS_ANNOT_CHECK "CHECK" +#define MEDS_ANNOT_OVERFLOW "OVERFLOW" +#define MEDS_ANNOT_UNDERFLOW "UNDERFLOW" +#define MEDS_ANNOT_SIGNEDNESS "SIGNEDNESS" +#define MEDS_ANNOT_TRUNCATION "TRUNCATION" +#define MEDS_ANNOT_SIGNED "SIGNED" +#define MEDS_ANNOT_UNSIGNED "UNSIGNED" +#define MEDS_ANNOT_UNKNOWNSIGN "UNKNOWNSIGN" +#define MEDS_ANNOT_NOFLAG "NOFLAG" +#define MEDS_ANNOT_INFINITELOOP "INFINITELOOP" +#define MEDS_ANNOT_SEVERE "SEVERE" +#define MEDS_ANNOT_FLOWS_INTO_CRITICAL_SINK "SINKMALLOC" +#define MEDS_ANNOT_MEMSET "MEMSET" +#define MEDS_ANNOT_IDIOM "IDIOM" + +using namespace std; +using namespace MEDS_Annotation; + +// +// Class to handle one MEDS (integer vulnerability) annotation +// +class MEDS_InstructionCheckAnnotation : public MEDS_AnnotationBase +{ + public: + MEDS_InstructionCheckAnnotation(); + MEDS_InstructionCheckAnnotation(const string &p_rawLine); + virtual ~MEDS_InstructionCheckAnnotation(){} + + // integer vulnerability types + bool isOverflow() const { return m_isOverflow; } + bool isUnderflow() const { return m_isUnderflow; } + bool isTruncation() const { return m_isTruncation; } + bool isSignedness() const { return m_isSignedness; } + bool isSevere() const { return m_isSevere; } + void setOverflow() { m_isOverflow = true; } + + // signed vs. unsigned + bool isUnsigned() const { return m_isUnsigned; } + bool isSigned() const { return m_isSigned; } + bool isUnknownSign() const { return m_isUnknownSign; } + + void setSigned() { m_isSigned = true; } + void setUnsigned() { m_isUnsigned = true; } + void setUnknownSign() { m_isUnknownSign = true; } + + // overflow with no flags, e.g. lea + bool isNoFlag() const { return m_isNoFlag; } + + // infinite loop annotation? + bool isInfiniteLoop() const { return m_isInfiniteLoop; } + + // memset annotation? + bool isMemset() const { return m_isMemset; } + bool isEspOffset() const { return m_isEspOffset; } + bool isEbpOffset() const { return m_isEbpOffset; } + int getStackOffset() const { return m_stackOffset; } + int getObjectSize() const { return m_objectSize; } + + // is idiom? + bool isIdiom() const { return m_isIdiom; } + int getIdiomNumber() const { return m_idiomNumber; } + void setIdiomNumber(int number) { m_idiomNumber = number; } + + // get bitwidth + int getBitWidth() const { return m_bitWidth; } + void setBitWidth(int p_bitWidth) { m_bitWidth = p_bitWidth; } + int getTruncationFromWidth() const { return m_truncationFromWidth; } + int getTruncationToWidth() const { return m_truncationToWidth; } + + // get register + MEDS_Annotation::RegisterName getRegister() const { return m_register; } + MEDS_Annotation::RegisterName getRegister2() const { return m_register2; } + + const string getTarget() const { return m_target; } + const string getTarget2() const { return m_target2; } + + const string toString() const { return m_rawInputLine; } + + // data flow + // @todo: expand the set, allow getter functions to retrieve name of sink + bool flowsIntoCriticalSink() const { return m_flowsIntoCriticalSink; } + + private: + void init(); + void parse(); + + private: + string m_rawInputLine; + bool m_isOverflow; + bool m_isUnderflow; + bool m_isSignedness; + bool m_isTruncation; + bool m_isSigned; + bool m_isUnsigned; + bool m_isUnknownSign; + bool m_isNoFlag; + bool m_isInfiniteLoop; + bool m_isMemset; + bool m_isSevere; + int m_bitWidth; + int m_truncationFromWidth; + int m_truncationToWidth; + bool m_isEspOffset; + bool m_isEbpOffset; + int m_stackOffset; + int m_objectSize; + bool m_isValid; + bool m_flowsIntoCriticalSink; + bool m_isIdiom; + int m_idiomNumber; + MEDS_Annotation::RegisterName m_register; + MEDS_Annotation::RegisterName m_register2; + string m_target; + string m_target2; +}; + +} +#endif diff --git a/irdb-lib/libMEDSannotation/include/MEDS_MemoryRangeAnnotation.hpp b/irdb-lib/libMEDSannotation/include/MEDS_MemoryRangeAnnotation.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3dd234fe9e6f4ebb55d6369730b08abea05d475c --- /dev/null +++ b/irdb-lib/libMEDSannotation/include/MEDS_MemoryRangeAnnotation.hpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2018 - University of Virginia + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.edu + * + */ + +#ifndef _MEDS_MEMORYRANGEANNOTATION_H_ +#define _MEDS_MEMORYRANGEANNOTATION_H_ + +#include <algorithm> +#include <string> +#include <stdint.h> +#include "VirtualOffset.hpp" +#include "MEDS_ShadowAnnotation.hpp" +#include "MEDS_Register.hpp" + +namespace MEDS_Annotation +{ + +using namespace std; +using namespace MEDS_Annotation; + +#define MEDS_ANNOT_STATICMEMWRITE "STATICMEMWRITE" +#define MEDS_ANNOT_STACKMEMRANGE "STACKMEMRANGE" +#define MEDS_ANNOT_SENTINEL "SENTINEL" + +// +// Class to handle one MEDS memory range annotation +// +// Examples: +// 417748 12 INSTR STATICMEMWRITE MIN 3c60320 LIMIT 4e53730 ZZ +// Meaning: instruction at 0x417748 is 12 bytes in length and writes to +// a static memory data scoop includes the MIN address 0x3c60320. +// The LIMIT address 0x4e53730 is beyond the range written to by +// this instruction. The assembly language instruction is: +// +// mov 0x3c3d630[RAX + RDX*8], 0 ; zero out buffer in 434.zeusmp +// +// Note that 0x3c3d630 in the assembly language could trick an +// IRDB transform, such as the move_globals defense, into thinking +// that the instruction writes to the data scoop containing address +// 0x3c3d630, when in fact the initial value of register RDX is large +// enough to push the initial memory address up to 0x3c60320, which is +// a different data scoop in global static memory. The annotation provides +// enough info to associate the instruction with the data scoop written. +// +// 4992ea 4 INSTR STACKMEMRANGE MIN RSP-568 LIMIT RSP-48 INSTRSPDELTA -592 ZZ +// Meaning: instruction at 0x4992ea is 4 bytes in length and writes +// to a stack memory location from RSP-568 to just below RSP-48, where +// the stack offsets are relative to the value of the stack pointer on +// function entry. The stack pointer has a current value at this instruction +// that is -592 from the function entry value. This means that the instruction +// writes a minimum of 24 bytes higher than the current stack pointer value. +// The assembly language instruction is: +// +// mov 0x8[R8],RCX ; store RCX into [R8]+8 in busybox.psexe +// +// It is not apparent from the assembly language that stack memory is involved, +// but STARS loop analysis and symbolic analysis have determined that the memory +// write is to the range [MIN..LIMIT-1] as seen in the annotation. +// +// 4992ea 4 INSTR SENTINEL BASE 43d920 OFFSET -8 ZZ +// Meaning: Address (BASE + OFFSET) is used as a loop sentinel in instruction at 0x4992ea. +// The loop only accesses memory at BASE, so the address of BASE should be used +// as the data scoop referred to by this instruction, e.g. cmp rax,0x43d918 could be +// the instruction, followed by jg top_of_loop. When RAX reaches value 0x43d918, the loop +// exits without using that value except as a sentinel to terminate the loop. 0x43d918 is +// in a different data scoop than 0x43d920, and 0x43d920 is the relevant scoop for the loop. +// + +class MEDS_MemoryRangeAnnotation : public MEDS_AnnotationBase +{ + public: + MEDS_MemoryRangeAnnotation(); + MEDS_MemoryRangeAnnotation(const string& p_rawLine); + virtual ~MEDS_MemoryRangeAnnotation() {}; + virtual const string toString() const { return "Memory Range: " + m_rawInputLine; }; + + uint64_t getRangeMin() const { return m_rangeMin; }; + uint64_t getRangeLimit() const { return m_rangeLimit; }; + int64_t getSentinelOffset() const { return m_sentinelOffset; }; + + const bool isStackRange() const { return m_stackRange; }; + const bool isStaticGlobalRange() const { return m_staticGlobalRange; }; + const bool isSentinel() const { return m_sentinel; }; + + private: // methods + void parse(); + void setStackRange(const bool p_val) { m_stackRange = p_val; }; + void setStaticGlobalRange(const bool p_val) { m_staticGlobalRange = p_val; }; + void setSentinel(const bool p_val) { m_sentinel = p_val; }; + void setRangeMin(const uint64_t p_val) { m_rangeMin = p_val; }; + void setRangeLimit(const uint64_t p_val) { m_rangeLimit = p_val; }; + void setSentinelOffset(const int64_t p_val) { m_sentinelOffset = p_val; }; + + private: // data + string m_rawInputLine; + bool m_stackRange; + bool m_staticGlobalRange; + bool m_sentinel; + uint64_t m_rangeMin; + uint64_t m_rangeLimit; + int64_t m_sentinelOffset; +}; + +} + +#endif diff --git a/irdb-lib/libMEDSannotation/include/MEDS_ProblemFuncAnnotation.hpp b/irdb-lib/libMEDSannotation/include/MEDS_ProblemFuncAnnotation.hpp new file mode 100644 index 0000000000000000000000000000000000000000..1bf520be751f63742aab39137b0656b8c042068b --- /dev/null +++ b/irdb-lib/libMEDSannotation/include/MEDS_ProblemFuncAnnotation.hpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef _MEDS_PROBLEMFUNCANNOTATION_H_ +#define _MEDS_PROBLEMFUNCANNOTATION_H_ + +#include <string> +#include "VirtualOffset.hpp" +#include "MEDS_Register.hpp" +#include "MEDS_FuncAnnotation.hpp" + + +namespace MEDS_Annotation +{ + +// These strings must match those emitted by MEDS in the information annotation file exactly +#define MEDS_ANNOT_FUNC "FUNC" + +using namespace std; +using namespace MEDS_Annotation; + +// +// Class to handle one MEDS (integer vulnerability) annotation +// +class MEDS_ProblemFuncAnnotation : public MEDS_FuncAnnotation +{ + + public: + enum ProblemType { pt_CallUnresolved, pt_JumpUnresolved, pt_BadStackAnalysis, pt_BadRTLs, pt_Unknown }; + + MEDS_ProblemFuncAnnotation() {}; + MEDS_ProblemFuncAnnotation(const string &p_rawLine); + virtual ~MEDS_ProblemFuncAnnotation(){} + + virtual const string toString() const { return "problem func: "+m_rawInputLine; } + + virtual void markCallUnresolved() { pt = pt_CallUnresolved; setValid(); } + virtual void markJumpUnresolved() { pt = pt_JumpUnresolved; setValid(); } + virtual bool isCallUnresolved() { return pt==pt_CallUnresolved; } + virtual bool isJumpUnresolved() { return pt==pt_JumpUnresolved; } + + ProblemType getProblemType() { return pt; } + void setProblemType( ProblemType _pt) { pt=_pt; } + + private: + void init(); + void parse(); + void matches(std::string line, string pattern, ProblemType prob_type); + + private: + std::string m_rawInputLine; + + ProblemType pt; + +}; + +} +#endif diff --git a/irdb-lib/libMEDSannotation/include/MEDS_Register.hpp b/irdb-lib/libMEDSannotation/include/MEDS_Register.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c1207a0608112e35dfa5a5bab123aed9f4f08ea6 --- /dev/null +++ b/irdb-lib/libMEDSannotation/include/MEDS_Register.hpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef _MEDS_REGISTER_H +#define _MEDS_REGISTER_H + +#include <string> +#include <set> +#include <irdb-util> +#include <irdb-deep> + +namespace MEDS_Annotation +{ + + +#if 0 +enum RegisterName +{ + IRDB_SDK::rn_UNKNOWN, + IRDB_SDK::rn_EFLAGS, + IRDB_SDK::rn_RIP, + IRDB_SDK::rn_EAX, IRDB_SDK::rn_EBX, IRDB_SDK::rn_ECX, IRDB_SDK::rn_EDX, IRDB_SDK::rn_ESI, IRDB_SDK::rn_EDI, IRDB_SDK::rn_EBP, IRDB_SDK::rn_ESP, IRDB_SDK::rn_R8D, IRDB_SDK::rn_R9D, IRDB_SDK::rn_R10D, IRDB_SDK::rn_R11D, IRDB_SDK::rn_R12D, IRDB_SDK::rn_R13D, IRDB_SDK::rn_R14D, IRDB_SDK::rn_R15D, + IRDB_SDK::rn_RAX, IRDB_SDK::rn_RBX, IRDB_SDK::rn_RCX, IRDB_SDK::rn_RDX, IRDB_SDK::rn_RBP, IRDB_SDK::rn_RSP, IRDB_SDK::rn_RSI, IRDB_SDK::rn_RDI, IRDB_SDK::rn_R8, IRDB_SDK::rn_R9, IRDB_SDK::rn_R10, IRDB_SDK::rn_R11, IRDB_SDK::rn_R12, IRDB_SDK::rn_R13, IRDB_SDK::rn_R14, IRDB_SDK::rn_R15, + IRDB_SDK::rn_AX, IRDB_SDK::rn_BX, IRDB_SDK::rn_CX, IRDB_SDK::rn_DX, IRDB_SDK::rn_BP, IRDB_SDK::rn_SP, IRDB_SDK::rn_SI, IRDB_SDK::rn_DI, IRDB_SDK::rn_R8W, IRDB_SDK::rn_R9W, IRDB_SDK::rn_R10W, IRDB_SDK::rn_R11W, IRDB_SDK::rn_R12W, IRDB_SDK::rn_R13W, IRDB_SDK::rn_R14W, IRDB_SDK::rn_R15W, + IRDB_SDK::rn_AH, IRDB_SDK::rn_BH, IRDB_SDK::rn_CH, IRDB_SDK::rn_DH, IRDB_SDK::rn_SIH, IRDB_SDK::rn_DIH, IRDB_SDK::rn_BPH, IRDB_SDK::rn_SPH, /* 'H' versions of regs only exist for lower 8 regs */ + IRDB_SDK::rn_AL, IRDB_SDK::rn_BL, IRDB_SDK::rn_CL, IRDB_SDK::rn_DL, IRDB_SDK::rn_SIL, IRDB_SDK::rn_DIL, IRDB_SDK::rn_BPL, IRDB_SDK::rn_SPL, IRDB_SDK::rn_R8B, IRDB_SDK::rn_R9B, IRDB_SDK::rn_R10B, IRDB_SDK::rn_R11B, IRDB_SDK::rn_R12B, IRDB_SDK::rn_R13B, IRDB_SDK::rn_R14B, IRDB_SDK::rn_R15B, +}; + +typedef std::set<RegisterName> RegisterSet_t; +#endif +using RegisterName = IRDB_SDK::RegisterID; +using RegisterName_t = IRDB_SDK::RegisterID_t; +using RegisterSet_t = IRDB_SDK::RegisterIDSet_t; + + + + +class Register +{ + + public: + static RegisterName getRegister(std::string); + static RegisterName getRegister(char *str); + static bool isValidRegister(std::string); + static bool isValidRegister(const RegisterName); + static bool is64bit(RegisterName); + static bool is32bit(RegisterName); + static bool is16bit(RegisterName); + static bool is8bit(RegisterName); + static int getBitWidth(RegisterName); + static std::string toString(RegisterName); + static RegisterName getFreeRegister64(const RegisterSet_t &p_used); + static std::string readRegisterSet(const std::string &in, RegisterSet_t &out); + static RegisterName promoteTo64(const RegisterName p_reg); + static RegisterName demoteTo32(const RegisterName p_reg); + static RegisterName demoteTo16(const RegisterName p_reg); + +}; + +} + +#endif diff --git a/irdb-lib/libMEDSannotation/include/MEDS_SafeFuncAnnotation.hpp b/irdb-lib/libMEDSannotation/include/MEDS_SafeFuncAnnotation.hpp new file mode 100644 index 0000000000000000000000000000000000000000..835233166c99620d0fd5daa74dc654420aebbce2 --- /dev/null +++ b/irdb-lib/libMEDSannotation/include/MEDS_SafeFuncAnnotation.hpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef _MEDS_SAFEFUNCANNOTATION_H_ +#define _MEDS_SAFEFUNCANNOTATION_H_ + +#include <string> +#include "VirtualOffset.hpp" +#include "MEDS_Register.hpp" +#include "MEDS_FuncAnnotation.hpp" + + +namespace MEDS_Annotation +{ + +// These strings must match those emitted by MEDS in the information annotation file exactly +#define MEDS_ANNOT_FUNC "FUNC" + +using namespace std; +using namespace MEDS_Annotation; + +// +// Class to handle one MEDS (integer vulnerability) annotation +// +class MEDS_SafeFuncAnnotation : public MEDS_FuncAnnotation +{ + public: + MEDS_SafeFuncAnnotation() {m_safe_func=false;} + MEDS_SafeFuncAnnotation(const string &p_rawLine); + virtual ~MEDS_SafeFuncAnnotation(){} + + virtual const string toString() const { return "safe func: "+m_rawInputLine; } + + virtual void markSafe() { m_safe_func = true; setValid(); } + virtual void markUnsafe() { m_safe_func = false; setValid(); } + virtual bool isSafe() { return m_safe_func; } + + + private: + void init(); + void parse(); + + private: + std::string m_rawInputLine; + + bool m_safe_func; +}; + +} +#endif diff --git a/irdb-lib/libMEDSannotation/include/MEDS_ShadowAnnotation.hpp b/irdb-lib/libMEDSannotation/include/MEDS_ShadowAnnotation.hpp new file mode 100644 index 0000000000000000000000000000000000000000..7a987d98cc3d49dc7c6ea0a429f60c441c367dd1 --- /dev/null +++ b/irdb-lib/libMEDSannotation/include/MEDS_ShadowAnnotation.hpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef _MEDS_SHADOWANNOTATION_H_ +#define _MEDS_SHADOWANNOTATION_H_ + +#include <string> +#include "VirtualOffset.hpp" +#include "MEDS_AnnotationBase.hpp" + +namespace MEDS_Annotation +{ + +using namespace std; +using namespace MEDS_Annotation; + +// +// Class to handle one MEDS shadow annotation +// +class MEDS_ShadowAnnotation : public MEDS_AnnotationBase +{ + public: + MEDS_ShadowAnnotation() { + m_shadowDefine = false; + m_shadowCheck = false; + m_shadowId = -1; + }; + virtual ~MEDS_ShadowAnnotation() {} + + const bool isDefineShadowId() const { return m_shadowDefine; } + const bool isCheckShadowId() const { return m_shadowCheck; } + const int getShadowId() const { return m_shadowId; } + + protected: + void setDefineShadowId() { m_shadowDefine = true; } + void setCheckShadowId() { m_shadowCheck = true; } + void setShadowId(int p_id) { m_shadowId = p_id; } + + private: + bool m_shadowDefine; + bool m_shadowCheck; + int m_shadowId; +}; + +} + +#endif diff --git a/irdb-lib/libMEDSannotation/include/MEDS_TakesAddressAnnotation.hpp b/irdb-lib/libMEDSannotation/include/MEDS_TakesAddressAnnotation.hpp new file mode 100644 index 0000000000000000000000000000000000000000..524b100ac030bfbba02a15512540e9912d792029 --- /dev/null +++ b/irdb-lib/libMEDSannotation/include/MEDS_TakesAddressAnnotation.hpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef _MEDS_TAKENADDRESSANNOTATION_H_ +#define _MEDS_TAKENADDRESSANNOTATION_H_ + +#include <string> +#include "VirtualOffset.hpp" +#include "MEDS_AnnotationBase.hpp" +#include <iostream> + +namespace MEDS_Annotation +{ + +using namespace std; +using namespace MEDS_Annotation; + +// +// Class to handle one MEDS shadow annotation +// +class MEDS_TakesAddressAnnotation : public MEDS_AnnotationBase +{ + public: + typedef enum { SWITCH, RET, UNKNOWN } ib_type_t; + + MEDS_TakesAddressAnnotation( const string& p_rawLine) : + referenced_address(0), + m_isCode(false) + { + setInvalid(); + parse(p_rawLine); + + }; + + + virtual const std::string toString() const + { + std::string ret="TakesAddress="+to_string(referenced_address); + return ret; + } + + ApplicationAddress GetReferencedAddress() const { return referenced_address; } + bool isCode() const { return m_isCode; } + bool isData() const { return !m_isCode; } + + protected: + + void parse(const string& p_rawLine) + { + const auto tofind=string("INSTR XREF TAKES_ADDRESS_OF "); + const auto codestring=string("CODE"); + const auto pos=p_rawLine.find(tofind); + if(pos==string::npos) + return; + + // she be valid + setValid(); + + m_isCode=(p_rawLine.find(codestring)!=string::npos); + m_virtualOffset = VirtualOffset(p_rawLine); + + // skips over INSTR*{code|data} + const auto rest=p_rawLine.substr(pos+tofind.length()+codestring.length()); + istringstream is(rest); + is >> hex >>referenced_address; /* get the address */ + + // cout<<"Found takes_address of "<<m_virtualOffset.to_string() << " to " + // << hex << referenced_address<< " from '" << rest << "'"<<endl; + + + } + + + private: + + ApplicationAddress referenced_address; + bool m_isCode; +}; + +} + +#endif diff --git a/irdb-lib/libMEDSannotation/include/VirtualOffset.hpp b/irdb-lib/libMEDSannotation/include/VirtualOffset.hpp new file mode 100644 index 0000000000000000000000000000000000000000..cabc12f221cbe13f9e8744bbb0e02468894f1a47 --- /dev/null +++ b/irdb-lib/libMEDSannotation/include/VirtualOffset.hpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef _VIRTUAL_OFFSET_H_ +#define _VIRTUAL_OFFSET_H_ + +#include <string> +#include <sstream> + +namespace MEDS_Annotation +{ + +typedef unsigned long long ApplicationAddress; + +#define DEFAULT_LIBRARY_NAME "a.out" + +class VirtualOffset +{ + public: + VirtualOffset(); + VirtualOffset(const std::string &p_offset, const std::string &p_libraryName); + VirtualOffset(const std::string &p_offset); + VirtualOffset(const int p_offset); + + ApplicationAddress getOffset() const; + std::string getLibraryName() const; + + bool operator < (const VirtualOffset &p_other) const; + bool operator == (const VirtualOffset &p_other) const; + VirtualOffset& operator = (const VirtualOffset &p_other); + + const std::string to_string() const { std::ostringstream oss; oss<<getLibraryName() << "+0x"<<std::hex<<getOffset(); return oss.str(); } + const std::string toString() const { return to_string(); } + + private: + ApplicationAddress m_offset; + std::string m_libraryName; +}; + +} + +#endif diff --git a/irdb-lib/libMEDSannotation/include/libMEDSAnnotation.h b/irdb-lib/libMEDSannotation/include/libMEDSAnnotation.h new file mode 100644 index 0000000000000000000000000000000000000000..a4f17f37c494c7f2e0d8b5279b617ecc553999e0 --- /dev/null +++ b/irdb-lib/libMEDSannotation/include/libMEDSAnnotation.h @@ -0,0 +1,24 @@ +#ifndef LIBMEDSAnnotation_h +#define LIBMEDSAnnotation_h + +#include "FuncExitAnnotation.hpp" +#include "MEDS_AnnotationBase.hpp" +#include "MEDS_AnnotationParser.hpp" +#include "MEDS_DeadRegAnnotation.hpp" +#include "MEDS_FPTRShadowAnnotation.hpp" +#include "MEDS_FRSafeAnnotation.hpp" +#include "MEDS_FuncAnnotation.hpp" +#include "MEDS_FuncPrototypeAnnotation.hpp" +#include "MEDS.hpp" +#include "MEDS_TakesAddressAnnotation.hpp" +#include "MEDS_IBAnnotation.hpp" +#include "MEDS_IBAnnotation.hpp" +#include "MEDS_IBTAnnotation.hpp" +#include "MEDS_InstructionCheckAnnotation.hpp" +#include "MEDS_ProblemFuncAnnotation.hpp" +#include "MEDS_Register.hpp" +#include "MEDS_SafeFuncAnnotation.hpp" +#include "MEDS_ShadowAnnotation.hpp" +#include "VirtualOffset.hpp" + +#endif diff --git a/irdb-lib/libMEDSannotation/src/FuncExitAnnotation.cpp b/irdb-lib/libMEDSannotation/src/FuncExitAnnotation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5f5662cff565181511cd1177cd7a911ef3dc354f --- /dev/null +++ b/irdb-lib/libMEDSannotation/src/FuncExitAnnotation.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <stdlib.h> + +#include <iostream> +#include <cstdio> +#include <string> +#include <string.h> + +#include "MEDS_Register.hpp" +#include "FuncExitAnnotation.hpp" + +using namespace std; +using namespace MEDS_Annotation; + + + + + +MEDS_FuncExitAnnotation::MEDS_FuncExitAnnotation(const string &p_rawLine) +{ + init(); + m_rawInputLine=p_rawLine; + parse(); +} + +void MEDS_FuncExitAnnotation::init() +{ +} + + +/* + Example format -- subject to change: + 804925b 5 INSTR CALL TAILCALL jmp check_one_fd + + +*/ +void MEDS_FuncExitAnnotation::parse() +{ + + if (m_rawInputLine.find(" INSTR ")==string::npos) + return; + + if ( + m_rawInputLine.find(" INSTR RETURN ")==string::npos && + m_rawInputLine.find(" INSTR CALL TAILCALL ")==string::npos + ) + { + /* INSTR that's not for a safe fast return */ + return; + } + + // get offset + VirtualOffset vo(m_rawInputLine); + m_virtualOffset = vo; + + setValid(); // no additional info recorded for right now. + +// if(getenv("VERBOSE")!=NULL) + cout<<"Found TAILCALL annotation for "<<vo.to_string()<<endl; + +} + diff --git a/irdb-lib/libMEDSannotation/src/MEDS_AnnotationParser.cpp b/irdb-lib/libMEDSannotation/src/MEDS_AnnotationParser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..85e85a2e4cba5465bf6f576786d1e5c518754329 --- /dev/null +++ b/irdb-lib/libMEDSannotation/src/MEDS_AnnotationParser.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <string> +#include <fstream> + +#include "MEDS_AnnotationParser.hpp" +#include "MEDS_InstructionCheckAnnotation.hpp" +#include "FuncExitAnnotation.hpp" +#include "MEDS_FuncPrototypeAnnotation.hpp" +#include "MEDS_SafeFuncAnnotation.hpp" +#include "MEDS_ProblemFuncAnnotation.hpp" +#include "MEDS_FRSafeAnnotation.hpp" +#include "MEDS_FPTRShadowAnnotation.hpp" +#include "MEDS_DeadRegAnnotation.hpp" +#include "MEDS_TakesAddressAnnotation.hpp" +#include "MEDS_IBAnnotation.hpp" +#include "MEDS_IBTAnnotation.hpp" +#include "MEDS_MemoryRangeAnnotation.hpp" + +// @todo: multiple annotation per instruction + +using namespace std; +using namespace MEDS_Annotation; + +MEDS_AnnotationParser::MEDS_AnnotationParser(istream &p_inputStream) +{ + parseFile(p_inputStream); +} + +void MEDS_AnnotationParser::parseFile(const std::string &input_filename) +{ + ifstream infile(input_filename.c_str(), ifstream::in); + + if(!infile.is_open()) + throw string("File not found"); + + parseFile(infile); +} + + + +template <class type> bool MEDS_AnnotationParser::add_if_valid(string line) +{ + type * annot=new type(line); + if (annot->isValid()) + { + // note that this should _NOT_ be an if/else for every possible Annotation + // this _should_ list the major categorizations of annotations + // currently we have annotations that can be looked up by VirtualOffset and looked up by Function + if(annot->isFuncAnnotation()) + { + MEDS_FuncAnnotation* fannot=dynamic_cast<MEDS_FuncAnnotation*>(annot); + assert(fannot); + string nam=fannot->getFuncName(); + m_func_annotations.insert(MEDS_Annotations_FuncPair_t(nam, annot)); + } + else + { + VirtualOffset vo = annot->getVirtualOffset(); + m_annotations.insert(MEDS_Annotations_Pair_t(vo, annot)); + } + return true; + } + else + { + delete annot; + return false; + } +} + +void MEDS_AnnotationParser::parseFile(istream &p_inputStream) +{ + while (!p_inputStream.eof()) + { + auto line=string(); + getline(p_inputStream, line); + if (line.empty()) continue; + + if(add_if_valid<MEDS_DeadRegAnnotation> (line)) continue; + if(add_if_valid<MEDS_FPTRShadowAnnotation> (line)) continue; + if(add_if_valid<MEDS_InstructionCheckAnnotation> (line)) continue; + if(add_if_valid<MEDS_FuncPrototypeAnnotation> (line)) continue; + if(add_if_valid<MEDS_SafeFuncAnnotation> (line)) continue; + if(add_if_valid<MEDS_ProblemFuncAnnotation> (line)) continue; + if(add_if_valid<MEDS_FRSafeAnnotation> (line)) continue; + if(add_if_valid<MEDS_FuncExitAnnotation> (line)) continue; + if(add_if_valid<MEDS_TakesAddressAnnotation> (line)) continue; + if(add_if_valid<MEDS_IBAnnotation> (line)) continue; + if(add_if_valid<MEDS_IBTAnnotation> (line)) continue; + if(add_if_valid<MEDS_MemoryRangeAnnotation> (line)) continue; + } +} + diff --git a/irdb-lib/libMEDSannotation/src/MEDS_DeadRegAnnotation.cpp b/irdb-lib/libMEDSannotation/src/MEDS_DeadRegAnnotation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cf2c43872262206ecccfb830555792a331d9d95a --- /dev/null +++ b/irdb-lib/libMEDSannotation/src/MEDS_DeadRegAnnotation.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <stdlib.h> + +#include <iostream> +#include <cstdio> +#include <string> +#include <string.h> + +#include "MEDS_DeadRegAnnotation.hpp" + +using namespace std; +using namespace MEDS_Annotation; + +/* +example: + + 4010f0 4 INSTR DEADREGS EFLAGS RAX ZZ sub rsp, 8 ; _init + + need to parse out eflags, and rax into the regset variable. + + +*/ + +MEDS_DeadRegAnnotation::MEDS_DeadRegAnnotation() +{ + setInvalid(); +} + +MEDS_DeadRegAnnotation::MEDS_DeadRegAnnotation(const string &p_rawLine) +{ + setInvalid(); + m_rawInputLine=p_rawLine; + parse(); +} + +void MEDS_DeadRegAnnotation::parse() +{ + string tofind=" INSTR DEADREGS "; + size_t pos=m_rawInputLine.find(tofind); + if (pos==string::npos) + return; + + // get offset + VirtualOffset vo(m_rawInputLine); + m_virtualOffset = vo; + + if (getenv("DEADREGS_VERBOSE")) { + cout <<"Found deadreg annotation in: "<<m_rawInputLine<<endl; + } + // ignore result of getRegisterSet method because + // we don't need to parse the rest of the line. + Register::readRegisterSet(m_rawInputLine.substr(pos+tofind.length()), regset); + setValid(); +} + diff --git a/irdb-lib/libMEDSannotation/src/MEDS_FPTRShadowAnnotation.cpp b/irdb-lib/libMEDSannotation/src/MEDS_FPTRShadowAnnotation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..017efc30d20ffcaf09ba08b78f9a08e224043bac --- /dev/null +++ b/irdb-lib/libMEDSannotation/src/MEDS_FPTRShadowAnnotation.cpp @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <stdlib.h> + +#include <iostream> +#include <cstdio> +#include <string> +#include <string.h> + +#include "MEDS_FPTRShadowAnnotation.hpp" + +using namespace std; +using namespace MEDS_Annotation; + +/* + Example format -- subject to change: + + 804b3a6 5 INSTR FPTRSHADOW [rsp+12] SHADOWID 7 + 804c941 5 INSTR FPTRCHECK [rsp+12] SHADOWID 7 + 804c945 5 INSTR FPTRCHECK [rsp] SHADOWID 8 + + 0x4006ca 7 INSTR FPTRSHADOW {memory addressing expression} SHADOWID <id> + +0x80487a0[RBX] +0x8047aa0[RBX+RCX] +0x8098f80[RAX+RDX*2] (NOTE: could be *4 or *8 instead of *2) +[RBX+RDX*4] +[RAX+RCX*8+12] +[RDX+RAX*2-64] +[R8+R15] +[R9+R11+48] +[R13+72] +[R12*4] +[R14*2-12] + + 805829d 3 INSTR FPTRCHECK [EBP-40] SHADOWID 5 + 8057fa7 3 INSTR FPTRSHADOW [EAX+8] SHADOWID 5 + 80822aa 7 INSTR FPTRSHADOW 0 SHADOWID 6 + 80822cc 3 INSTR FPTRSHADOW EAX SHADOWID 6 + 480faa 9 INSTR FPTRSHADOW 4721886 SHADOWID 75 +*/ + +MEDS_FPTRShadowAnnotation::MEDS_FPTRShadowAnnotation() : MEDS_ShadowAnnotation() +{ + setInvalid(); + setCriticalArgumentShadow(false); + setFunctionPointerShadow(false); +} + +MEDS_FPTRShadowAnnotation::MEDS_FPTRShadowAnnotation(const string &p_rawLine) : MEDS_ShadowAnnotation() +{ + setInvalid(); + setCriticalArgumentShadow(false); + setFunctionPointerShadow(false); + m_rawInputLine=p_rawLine; + parse(); +} + +void MEDS_FPTRShadowAnnotation::parse() +{ + if (m_rawInputLine.find(" INSTR ")==string::npos) + return; + + if (m_rawInputLine.find(MEDS_ANNOT_FPTRSHADOW)!=string::npos) + { + setFunctionPointerShadow(true); + setDefineShadowId(); + } + + if (m_rawInputLine.find(MEDS_ANNOT_ARGSHADOW)!=string::npos) + { + setCriticalArgumentShadow(true); + setDefineShadowId(); + } + + if (m_rawInputLine.find(MEDS_ANNOT_FPTRCHECK)!=string::npos) + { + setFunctionPointerShadow(true); + setCheckShadowId(); + } + + if (m_rawInputLine.find(MEDS_ANNOT_ARGCHECK)!=string::npos) + { + setCriticalArgumentShadow(true); + setCheckShadowId(); + } + + if (!isDefineShadowId() && !isCheckShadowId()) + { + /* invalid annotation */ + setInvalid(); + return; + } + + // get offset + VirtualOffset vo(m_rawInputLine); + setVirtualOffset(vo); + + int shadowId; + char buf[2048] = ""; + int instrSize; + + // 804b3a6 5 INSTR FPTRSHADOW [esp+12] SHADOWID 7 + // 804c941 5 INSTR FPTRCHECK [rdx] SHADOWID 7 + sscanf(m_rawInputLine.c_str(), "%*x %d %*s %*s %s SHADOWID %d", &instrSize, buf, &shadowId); + + setInstructionSize(instrSize); + setExpression(std::string(buf)); + setShadowId(shadowId); + + cout << "virtual offset: " << hex << getVirtualOffset().getOffset() << dec << endl; + cout << "size: " << getInstructionSize() << endl; + cout << "expr: " << getExpression() << endl; + cout << "shadow id: " << getShadowId() << endl; + + if (shadowId < 0) + { + setInvalid(); + cout << "invalid shadow id" << endl; + return; + } + + if (isCheckShadowId()) + { + cout << "is check shadow id" << endl; + if (!verifyCheckShadowExpression(getExpression())) + { + setInvalid(); + cout << "invalid expression" << endl; + return; + } + } + + cout << "valid annotation" << endl; + setValid(); +} + +// 8057fa7 3 INSTR FPTRSHADOW [EAX+8] SHADOWID 5 +// 80822aa 7 INSTR FPTRSHADOW 0 SHADOWID 6 +// 80822cc 3 INSTR FPTRSHADOW EAX SHADOWID 6 +// 8480faa 9 INSTR FPTRSHADOW 4721886 SHADOWID 75 +bool MEDS_FPTRShadowAnnotation::verifyCheckShadowExpression(const string& expression) +{ + return isMemoryExpression() || isRegister() || isConstant(); +} + +// 80822aa 7 INSTR FPTRSHADOW 0 SHADOWID 6 +bool MEDS_FPTRShadowAnnotation::isConstant() const +{ + if (isRegister() || isMemoryExpression()) return false; + + long long val = 0; + std::stringstream ss(getExpression()); + ss >> val; + return !ss.bad(); +} + +long long MEDS_FPTRShadowAnnotation::getConstantValue(bool &p_valid) const +{ + p_valid = false; + if (!isConstant()) + return 0; + + long long val = 0; + std::stringstream ss(getExpression()); + ss >> val; + p_valid = !ss.bad(); + return val; +} + +// 80822cc 3 INSTR FPTRSHADOW EAX SHADOWID 6 +bool MEDS_FPTRShadowAnnotation::isRegister() const +{ + return Register::getRegister(getExpression()) != IRDB_SDK::rn_UNKNOWN; +} + +// 805829d 3 INSTR FPTRCHECK [EBP-40] SHADOWID 5 +bool MEDS_FPTRShadowAnnotation::isMemoryExpression() const +{ + return (m_expression.find('[') != std::string::npos && + m_expression.find(']') != std::string::npos); +} + +const RegisterName MEDS_FPTRShadowAnnotation::getRegister() const +{ + if (isRegister()) + { + return Register::getRegister(getExpression()); + } + else + { + return IRDB_SDK::rn_UNKNOWN; + } +} + +bool MEDS_FPTRShadowAnnotation::isRIPRelative() const +{ + return m_expression.find("rip") != string::npos; +} + +// expect of the form: +// [rip+constant] +// [rip-constant] +uintptr_t MEDS_FPTRShadowAnnotation::computeRIPAddress() +{ + RegisterName reg=RegisterName(); + int offset=0; + + parseRegister(getExpression().c_str(), ®, &offset); + + if (reg == IRDB_SDK::rn_RIP) + { + return getVirtualOffset().getOffset() + getInstructionSize() + offset; + } + else + return 0; +} + + +int MEDS_FPTRShadowAnnotation::parseRegisterOffset(const char *p_buf) +{ + // e.g.: [rsp] [esp+12] [esp-12] + for (auto i = 0U; i < strlen(p_buf); ++i) + { + if (p_buf[i] == '-' || p_buf[i] == '+') + { + return atoi(&p_buf[i]); + } + } + return 0; +} + +// e.g.: [rsp] [esp+12] [esp-12] +void MEDS_FPTRShadowAnnotation::parseRegister(const char *p_buf, RegisterName *p_register, int *p_registerOffset) +{ + int startReg = -1; + int endReg = -1; + int signPos = -1; + for (auto i = 0U; i < strlen(p_buf); ++i) + { + if (p_buf[i] == '[') startReg = i+1; + if (p_buf[i] == ']') + { + endReg = i-1; + } + if (p_buf[i] == '-' || p_buf[i] == '+') + { + *p_registerOffset = atoi(&p_buf[i]); + signPos = i; + } + } + + if (signPos >= 0) + endReg = signPos - 1; + if (startReg >= 0 && endReg >= startReg) + { + char registerBuf[1024]; + int size = endReg - startReg + 1; + strncpy(registerBuf, &p_buf[startReg], size); + registerBuf[size] = '\0'; + cout << "register buffer detected: " << registerBuf << endl; + *p_register = Register::getRegister(registerBuf); + } + + *p_registerOffset = parseRegisterOffset(p_buf); +} diff --git a/irdb-lib/libMEDSannotation/src/MEDS_FRSafeAnnotation.cpp b/irdb-lib/libMEDSannotation/src/MEDS_FRSafeAnnotation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0b5ed83af64066b91cb78688e5d586325889bd7c --- /dev/null +++ b/irdb-lib/libMEDSannotation/src/MEDS_FRSafeAnnotation.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <stdlib.h> + +#include <iostream> +#include <cstdio> +#include <string> +#include <string.h> + +#include "MEDS_Register.hpp" +#include "MEDS_FRSafeAnnotation.hpp" + +using namespace std; +using namespace MEDS_Annotation; + + + + + +MEDS_FRSafeAnnotation::MEDS_FRSafeAnnotation(const string &p_rawLine) +{ + init(); + m_rawInputLine=p_rawLine; + parse(); +} + +void MEDS_FRSafeAnnotation::init() +{ +} + + +/* + Example format (as of July 31, 2014 ) -- subject to change: + + 804b3a6 5 INSTR CALL NOFASTRETURN RAUNSAFE ZZ call frame_dummy + 804c941 5 INSTR CALL FASTRETURN ZZ call _ZN7GString3cmpEPKc; GString::cmp(char const*) + 804c511 3 INSTR INDIRCALL NOFASTRETURN INDIRECT ZZ call dword ptr [eax+8] + 804c6fa 1 INSTR RETURN NOFASTRETURN NOCALLERS ZZ retn + +*/ +void MEDS_FRSafeAnnotation::parse() +{ + + if (m_rawInputLine.find(" INSTR ")==string::npos) + return; + + if ( + m_rawInputLine.find(" INSTR CALL FASTRETURN ")==string::npos && + m_rawInputLine.find(" INSTR INDCALL FASTRETURN ")==string::npos && + m_rawInputLine.find(" INSTR RETURN FASTRETURN ")==string::npos + ) + { + /* INSTR that's not for a safe fast return */ + return; + } + + // get offset + VirtualOffset vo(m_rawInputLine); + m_virtualOffset = vo; + + setValid(); // no additional info recorded for right now. + +// if(getenv("VERBOSE")!=NULL) + cout<<"Found FASTRETURN annotation for "<<vo.to_string()<<endl; + +} + diff --git a/irdb-lib/libMEDSannotation/src/MEDS_FuncPrototypeAnnotation.cpp b/irdb-lib/libMEDSannotation/src/MEDS_FuncPrototypeAnnotation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8c0ae2c41b1a093f4d8c826669c38ae491d9d755 --- /dev/null +++ b/irdb-lib/libMEDSannotation/src/MEDS_FuncPrototypeAnnotation.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2014, 2015 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <stdlib.h> + +#include <iostream> +#include <cstdio> +#include <string> +#include <string.h> + +#include "MEDS_Register.hpp" +#include "MEDS_FuncPrototypeAnnotation.hpp" + +using namespace std; +using namespace MEDS_Annotation; + +MEDS_FuncPrototypeAnnotation::MEDS_FuncPrototypeAnnotation(const string &p_rawLine) +{ + init(); + m_rawInputLine=p_rawLine; + parse(); +} + +void MEDS_FuncPrototypeAnnotation::init() +{ + MEDS_AnnotationBase::init(); + m_returnArg = NULL; + m_arguments = NULL; +} + + +/* +4046e0 71 FUNC INARGS 4 ARG0 1 ARG1 0 ARG2 0 ARG3 0 +404740 697 FUNC RETURNTYPE RAX 1 +*/ +void MEDS_FuncPrototypeAnnotation::parse() +{ + bool about_inargs = false; + bool about_return = false; + + if (m_rawInputLine.find("FUNC ")==string::npos) + return; + + if (m_rawInputLine.find("INARGS")!=string::npos) + { + about_inargs = true; + } + + if (m_rawInputLine.find("RETURNTYPE")!=string::npos) + { + about_return = true; + } + + if (!about_inargs && !about_return) + return; + + // get offset + VirtualOffset vo(m_rawInputLine); + m_virtualOffset = vo; + + const int maxbufsize = m_rawInputLine.size()*2; + + if (about_inargs) + { +// 4046e0 71 FUNC INARGS 4 ARG0 1 ARG1 0 ARG2 0 ARG3 0 + int numargs = 0; + char buf[maxbufsize]; bzero(buf, maxbufsize); + strncpy(buf, m_rawInputLine.c_str(), maxbufsize-1); + buf[maxbufsize-1] = '\0'; + sscanf(buf, "%*x %*d %*s %*s %d %*s", &numargs); + for (int i = 0; i < numargs; ++i) + { + char arg[24]; + sprintf(arg, "ARG%d", i); + char *zarg = strstr(buf, arg); + if (zarg) + { + int meds_type; + sscanf(zarg,"%*s %d", &meds_type); + MEDS_Arg marg(meds_type); + addArg(marg); + } + else + { + setInvalid(); + return; + } + } + } + else if (about_return) + { + // 404740 697 FUNC RETURNTYPE RAX 1 + char regbuf[maxbufsize]; bzero(regbuf, maxbufsize); + int meds_retType; + sscanf(m_rawInputLine.c_str(), "%*x %*d %*s %*s %s %d", regbuf, &meds_retType); + RegisterName reg = Register::getRegister(regbuf); + MEDS_Arg marg(meds_retType, reg); + setReturnArg(marg); +// cout << " adding return argument: " << Register::toString(reg) << " type: " << meds_retType << endl; + } + else + { + assert(0); + return; + } + + setValid(); +} + diff --git a/irdb-lib/libMEDSannotation/src/MEDS_InstructionCheckAnnotation.cpp b/irdb-lib/libMEDSannotation/src/MEDS_InstructionCheckAnnotation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..719ebb5f70f1508c8234783e52f26e2c8b0f1ceb --- /dev/null +++ b/irdb-lib/libMEDSannotation/src/MEDS_InstructionCheckAnnotation.cpp @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <iostream> +#include <cstdio> +#include <string> +#include <stdlib.h> +#include <string.h> + +#include "MEDS_Register.hpp" +#include "MEDS_InstructionCheckAnnotation.hpp" + +using namespace std; +using namespace MEDS_Annotation; + +/* +Example format (as of 10/18/2011) -- subject to change: + +80482bc 3 INSTR CHECK OVERFLOW UNSIGNED 32 EAX ZZ add eax, 1 +8048325 6 INSTR CHECK OVERFLOW SIGNED 16 [esp+2AH] ZZ add word ptr [esp+2Ah], 1 +804832b 6 INSTR CHECK OVERFLOW UNSIGNED 16 [esp+2CH] ZZ add word ptr [esp+2Ch], 1 +8048336 5 INSTR CHECK SIGNEDNESS SIGNED 16 AX ZZ mov [esp+28h], ax +80483db 5 INSTR CHECK UNDERFLOW SIGNED 32 EAX ZZ sub eax, 7FFFFFFFh +80483fd 3 INSTR CHECK UNDERFLOW SIGNED 32 EAX ZZ sub eax, 1 +8048492 5 INSTR CHECK TRUNCATION 32 EAX 16 AX ZZ mov [esp+26h], ax +8048492 5 INSTR CHECK SIGNEDNESS SIGNED 16 AX ZZ mov [esp+26h], ax +8048892 4 INSTR INFINITELOOP add [ebp+var_25], 1 +8048293 3 INSTR MEMSET STACKOFFSET 12 SIZE 24 ZZ call memset +*/ + +void MEDS_InstructionCheckAnnotation::init() +{ + m_isValid = false; + m_isOverflow = false; + m_isUnderflow = false; + m_isTruncation = false; + m_isSignedness = false; + m_isSigned = false; + m_isUnsigned = false; + m_isUnknownSign = true; + m_isNoFlag = false; + m_isInfiniteLoop = false; + m_isSevere = false; + m_isMemset = false; + m_flowsIntoCriticalSink = false; + m_isIdiom = false; + m_bitWidth = -1; + m_truncationFromWidth = -1; + m_truncationToWidth = -1; + m_register = IRDB_SDK::rn_UNKNOWN; + m_register2 = IRDB_SDK::rn_UNKNOWN; + m_stackOffset = -1; + m_objectSize = -1; + m_isEspOffset = false; + m_isEbpOffset = false; + m_idiomNumber = -1; +} + +MEDS_InstructionCheckAnnotation::MEDS_InstructionCheckAnnotation(const std::string &p_rawInputLine) +{ + init(); + m_rawInputLine = p_rawInputLine; + parse(); +} + +MEDS_InstructionCheckAnnotation::MEDS_InstructionCheckAnnotation() +{ + init(); +} + +// parse and set all the member variables +void MEDS_InstructionCheckAnnotation::parse() +{ + + // format: + // field 1 - instruction address + // field 2 - instruction size (ignore) + // field 3 - INSTR + // field 4 - CHECK | INFINITELOOP | MEMSET + // field 5 - {OVERFLOW | UNDERFLOW | SIGNEDNESS | TRUNCATION } + // field 6 - {SIGNED | UNSIGNED | UNKNOWNSIGN | 16 | 32} + // field 7 - {<register> | <memory reference>} + + if (m_rawInputLine.find(MEDS_ANNOT_INSTR)==string::npos) + return; + + if (m_rawInputLine.find(MEDS_ANNOT_INFINITELOOP)==string::npos && + m_rawInputLine.find(MEDS_ANNOT_CHECK)==string::npos && + m_rawInputLine.find(MEDS_ANNOT_MEMSET)==string::npos) + { + return; + } + + // get offset + VirtualOffset vo(m_rawInputLine); + m_virtualOffset = vo; + + // The annotation format is very simple so we don't bother with any fancy parsing + // 8048913 3 INSTR CHECK OVERFLOW NOFLAGSIGNED 32 EDX+ECX ZZ lea eax, [edx+ecx] + // Later, this may need to be changed + + // get check type + if (m_rawInputLine.find(MEDS_ANNOT_OVERFLOW)!=string::npos) + m_isOverflow = true; + + if (m_rawInputLine.find(MEDS_ANNOT_UNDERFLOW)!=string::npos) + m_isUnderflow = true; + + if (m_rawInputLine.find(MEDS_ANNOT_SIGNEDNESS)!=string::npos) + m_isSignedness = true; + + if (m_rawInputLine.find(MEDS_ANNOT_TRUNCATION)!=string::npos) + m_isTruncation = true; + + if (m_rawInputLine.find(MEDS_ANNOT_NOFLAG)!=string::npos) + m_isNoFlag = true; + + if (m_rawInputLine.find(MEDS_ANNOT_MEMSET)!=string::npos) + m_isMemset = true; + + if (m_rawInputLine.find(MEDS_ANNOT_FLOWS_INTO_CRITICAL_SINK)!=string::npos) + m_flowsIntoCriticalSink = true; + + auto idiom_pos = m_rawInputLine.find(MEDS_ANNOT_IDIOM); + if (idiom_pos != string::npos) + { + idiom_pos += strlen(MEDS_ANNOT_IDIOM); + setIdiomNumber(atoi(m_rawInputLine.substr(idiom_pos).c_str())); + m_isIdiom = true; + } + + // signed vs. unsigned + if (m_rawInputLine.find(MEDS_ANNOT_UNSIGNED)!=string::npos) + { + m_isUnsigned = true; + m_isUnknownSign = false; + } + else if (m_rawInputLine.find(MEDS_ANNOT_SIGNED)!=string::npos) + { + m_isSigned = true; + m_isUnknownSign = false; + } + else if (m_rawInputLine.find(MEDS_ANNOT_UNKNOWNSIGN)!=string::npos) + { + m_isUnsigned = false; + m_isSigned = false; + m_isUnknownSign = true; + } + + // check for infinite loop annotation + // 8048565 3 INSTR INFINITELOOP + if (m_rawInputLine.find(MEDS_ANNOT_INFINITELOOP)!=string::npos) + { + m_isInfiniteLoop = true; + } + + const int maxbufsize = m_rawInputLine.size()*2; + + // get bit width information for overflow & underflow + if (m_isOverflow || m_isUnderflow) + { + // 8048565 6 INSTR CHECK OVERFLOW SIGNED 16 [ESP]+38 ZZ add word ptr [esp+26h], 1 + // 804856b 6 INSTR CHECK OVERFLOW UNSIGNED 16 [ESP]+36 ZZ add word ptr [esp+24h], 1 + // 80483bb 4 INSTR CHECK OVERFLOW UNKNOWNSIGN 16 AX ZZ add ax, 7FBCh + // 80483d5 3 INSTR CHECK UNDERFLOW SIGNED 16 CX ZZ sub cx, ax + // 804d51d 2 INSTR CHECK OVERFLOW UNSIGNED 32 EBX ZZ add ebx, eax + + char buf[maxbufsize]; bzero(buf, maxbufsize); + + sscanf(m_rawInputLine.c_str(), "%*s %*d %*s %*s %*s %*s %d %s", &m_bitWidth, buf); + m_target = string(buf); + if (m_isNoFlag) + { + m_register = Register::getRegister(m_target); + } + } + else if (m_isTruncation) // get bid width from/to information for truncation + { + char buf[maxbufsize]; bzero(buf, maxbufsize); + char buf2[maxbufsize]; bzero(buf2, maxbufsize); + // [ADDR] [SIZE] INSTR CHECK TRUNCATION UNKNOWNSIGN 32 EAX 16 AX ZZ mov [esp+2Ah], ax + sscanf(m_rawInputLine.c_str(), "%*s %*d %*s %*s %*s %*s %d %s %d %s", &m_truncationFromWidth, buf, &m_truncationToWidth, buf2); + + m_target = string(buf); + m_target2 = string(buf2); + + m_register = Register::getRegister(m_target); + m_register2 = Register::getRegister(m_target2); + + // 20120410 STARS added SEVERE field to TRUNC annotations to specify that we must use a terminating/saturating policy + if (m_rawInputLine.find(MEDS_ANNOT_SEVERE)!=string::npos) + { + m_isSevere = true; + } + } + else if (m_isSignedness) + { + char buf[maxbufsize]; bzero(buf, maxbufsize); + // [ADDR] [SIZE] INSTR CHECK SIGNEDNESS SIGNED 16 AX ZZ mov [esp+28h], ax + // [ADDR] [SIZE] INSTR CHECK SIGNEDNESS UNSIGNED 16 AX ZZ mov [esp+28h], ax + sscanf(m_rawInputLine.c_str(), "%*s %*d %*s %*s %*s %*s %d %s", &m_bitWidth, buf); + m_target = string(buf); + m_register = Register::getRegister(m_target); + } + + if (m_isMemset) + { + // 8048293 3 INSTR MEMSET STACKOFFSET_EBP 12 SIZE 24 ZZ call memset + // 8048293 3 INSTR MEMSET STACKOFFSET_ESP 12 SIZE 24 ZZ call memset + if (m_rawInputLine.find("STACKOFFSET")!=string::npos) + { + char buf[maxbufsize]; bzero(buf, maxbufsize); + sscanf(m_rawInputLine.c_str(), "%*s %*d %*s %*s %*s %d %*s %d", &m_stackOffset, &m_objectSize); + if (m_rawInputLine.find("STACKOFFSET_EBP")!=string::npos) + { + m_isEbpOffset = true; + } + else if (m_rawInputLine.find("STACKOFFSET_ESP")!=string::npos) + { + m_isEspOffset = true; + } + } + } + + setValid(); // m_isValid = true; +} + diff --git a/irdb-lib/libMEDSannotation/src/MEDS_MemoryRangeAnnotation.cpp b/irdb-lib/libMEDSannotation/src/MEDS_MemoryRangeAnnotation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d3475148d00396c1de0ed0da0f9512464cb95e7e --- /dev/null +++ b/irdb-lib/libMEDSannotation/src/MEDS_MemoryRangeAnnotation.cpp @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2018 - University of Virginia + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.edu + * + */ + +#include <stdlib.h> + +#include <iostream> +#include <cstdio> +#include <string> +#include <string.h> +#include <cinttypes> + +#include "MEDS_MemoryRangeAnnotation.hpp" + +using namespace std; +using namespace MEDS_Annotation; + +/* + Example format -- subject to change: + + 417748 12 INSTR STATICMEMWRITE MIN 3c60320 LIMIT 4e53730 ZZ + 4992ea 4 INSTR STACKMEMRANGE MIN RSP-568 LIMIT RSP-48 INSTRSPDELTA -592 ZZ + 4992ea 4 INSTR SENTINEL BASE 43d920 OFFSET -8 ZZ + + See explanations in the header file MEDS_MemoryRangeAnnotation.hpp. + +*/ + +MEDS_MemoryRangeAnnotation::MEDS_MemoryRangeAnnotation() : MEDS_AnnotationBase() +{ + this->setInvalid(); + this->setStackRange(false); + this->setStaticGlobalRange(false); + this->setSentinel(false); +} + +MEDS_MemoryRangeAnnotation::MEDS_MemoryRangeAnnotation(const string &p_rawLine) : MEDS_AnnotationBase() +{ + this->setInvalid(); + this->setStackRange(false); + this->setStaticGlobalRange(false); + this->setSentinel(false); + this->m_rawInputLine = p_rawLine; + this->parse(); +} + +void MEDS_MemoryRangeAnnotation::parse() +{ + if (this->m_rawInputLine.find(" INSTR ") == string::npos) + return; + + if (this->m_rawInputLine.find(MEDS_ANNOT_STATICMEMWRITE) != string::npos) + { + this->setStaticGlobalRange(true); + } + + if (this->m_rawInputLine.find(MEDS_ANNOT_STACKMEMRANGE) != string::npos) + { + this->setStackRange(true); + } + + if (this->m_rawInputLine.find(MEDS_ANNOT_SENTINEL) != string::npos) + { + this->setSentinel(true); + } + + if (!this->isStackRange() && !this->isStaticGlobalRange() && !this->isSentinel()) + { + /* invalid annotation */ + this->setInvalid(); + return; + } + + // get offset + VirtualOffset vo(m_rawInputLine); + this->setVirtualOffset(vo); // in base class + + uint64_t MinVal, LimitVal; + int64_t OffsetVal; + int instrSize; + + // 417748 12 INSTR STATICMEMWRITE MIN 3c60320 LIMIT 4e53730 ZZ + // 4992ea 4 INSTR STACKMEMRANGE MIN RSP - 568 LIMIT RSP - 48 INSTRSPDELTA - 592 ZZ + if (this->isStaticGlobalRange()) { + int ItemsFilled = sscanf(m_rawInputLine.c_str(), "%*x %d %*s %*s MIN %" SCNx64 " LIMIT %" SCNx64, &instrSize, &MinVal, &LimitVal); + if (3 != ItemsFilled) { + this->setInvalid(); + cerr << "Error on sscanf of annotation: ItemsFilled = " << ItemsFilled << " line: " << m_rawInputLine << endl; + return; + } + else { + cerr << "Parsed STATICMEMWRITE annotation: MIN = " << hex << MinVal << " LIMIT = " << LimitVal << endl; + } + } + else if (this->isStackRange()) { +#if 0 + int ItemsFilled = sscanf(m_rawInputLine.c_str(), "%*x %d %*s %*s MIN %" SCNx64 " LIMIT %" SCNx64, &instrSize, &MinVal, &LimitVal); + if (3 != ItemsFilled) { + this->setInvalid(); + cerr << "Error on sscanf of annotation: ItemsFilled = " << ItemsFilled << " line: " << m_rawInputLine << endl; + return; + } +#else + this->setInvalid(); + cerr << "Not yet parsing STACKMEMRANGE annotations " << endl; + return; +#endif + } + else { // SENTINEL + int ItemsFilled = sscanf(m_rawInputLine.c_str(), "%*x %d %*s %*s BASE %" SCNx64 " OFFSET %" SCNd64, &instrSize, &MinVal, &OffsetVal); + if (3 != ItemsFilled) { + this->setInvalid(); + cerr << "Error on sscanf of annotation: ItemsFilled = " << ItemsFilled << " line: " << m_rawInputLine << endl; + return; + } + } + + this->setInstructionSize(instrSize); // in base class + this->setRangeMin(MinVal); + if (this->isSentinel()) { + this->setSentinelOffset(OffsetVal); + } + else { + this->setRangeLimit(LimitVal); + } + + cout << "virtual offset: " << hex << this->getVirtualOffset().getOffset() << dec << endl; + cout << "size: " << this->getInstructionSize() << endl; + cout << "min: " << this->getRangeMin() << endl; + if (this->isSentinel()) { + cout << "offset: " << this->getSentinelOffset() << endl; + } + else { + cout << "limit: " << this->getRangeLimit() << endl; + + if (LimitVal <= MinVal) + { + setInvalid(); + cerr << "invalid range limit" << endl; + return; + } + } + + cout << "valid annotation" << endl; + this->setValid(); +} // end of MEDS_MemoryRangeAnnotation::parse() + diff --git a/irdb-lib/libMEDSannotation/src/MEDS_ProblemFuncAnnotation.cpp b/irdb-lib/libMEDSannotation/src/MEDS_ProblemFuncAnnotation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b42d0d1af848a2d0488fbf30feadd7d040c788ce --- /dev/null +++ b/irdb-lib/libMEDSannotation/src/MEDS_ProblemFuncAnnotation.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <stdlib.h> +#include <string.h> +#include <iostream> +#include <cstdio> +#include <string> + +#include "MEDS_Register.hpp" +#include "MEDS_ProblemFuncAnnotation.hpp" + +using namespace std; +using namespace MEDS_Annotation; + + + + + +MEDS_ProblemFuncAnnotation::MEDS_ProblemFuncAnnotation(const string &p_rawLine) +{ + init(); + m_rawInputLine=p_rawLine; + parse(); +} + +void MEDS_ProblemFuncAnnotation::init() +{ + MEDS_FuncAnnotation::init(); +} + + +/* + Example format (as of August 15, 2014 ) -- subject to change: + + 400420 6 FUNC PROBLEM .__libc_start_main JUMPUNRESOLVED + 400430 6 FUNC PROBLEM .__printf_chk CHUNKS JUMPUNRESOLVED + 400490 100 FUNC PROBLEM __do_global_dtors_aux CALLUNRESOLVED + + +*/ +void MEDS_ProblemFuncAnnotation::parse() +{ + + if (m_rawInputLine.find("FUNC ")==string::npos) + return; + + size_t pos=m_rawInputLine.find("FUNC PROBLEM"); + if ( pos==string::npos ) + { + /* FUNC line that's not local or global? I'm confused. */ + /* could be a FUNC GLOBAL, etc. line */ + return; + } + + size_t func_name_start_pos=pos+strlen("FUNC PROBLEM "); + size_t func_end_pos=m_rawInputLine.find(" ", func_name_start_pos); + assert(func_end_pos!=string::npos); + string func_name=m_rawInputLine.substr(func_name_start_pos, func_end_pos-func_name_start_pos); + + // get offset + setFuncName(func_name); + cout<<"Found problem func name='"<<func_name<<"'"<<endl; + + if(!isValid()) matches(m_rawInputLine,"JUMPUNRSOLVED", pt_JumpUnresolved); + if(!isValid()) matches(m_rawInputLine,"CALLUNRSOLVED", pt_CallUnresolved); + if(!isValid()) matches(m_rawInputLine,"STACKANALYSIS", pt_BadStackAnalysis); + if(!isValid()) matches(m_rawInputLine,"BADRTLS", pt_BadRTLs); + if(!isValid()) + { + pt=pt_Unknown; + setValid(); + } + +} + +void MEDS_ProblemFuncAnnotation::matches(string line, string pattern, ProblemType prob_type) +{ + + if (line.find(pattern)!=string::npos) + { + if(getenv("VERBOSE")) + cout<<"Found "<<pattern<<" problem annotation for "<<getFuncName() << endl; + pt=prob_type; + setValid(); + } +} diff --git a/irdb-lib/libMEDSannotation/src/MEDS_Register.cpp b/irdb-lib/libMEDSannotation/src/MEDS_Register.cpp new file mode 100644 index 0000000000000000000000000000000000000000..36741f094d56be4bb96f549c7fd16a28eeeb4ef3 --- /dev/null +++ b/irdb-lib/libMEDSannotation/src/MEDS_Register.cpp @@ -0,0 +1,588 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <string> +#include <sstream> +#include <strings.h> +#include <assert.h> + +#include "MEDS_Register.hpp" + +using namespace MEDS_Annotation; +using namespace std; + +RegisterName Register::getRegister(char *p_reg) +{ + return Register::getRegister(std::string(p_reg)); +} + +bool Register::isValidRegister(std::string p_reg) +{ + return getRegister(p_reg) != IRDB_SDK::rn_UNKNOWN; +} + +bool Register::isValidRegister(const RegisterName p_reg) +{ + return isValidRegister(Register::toString(p_reg)); +} + +RegisterName Register::getRegister(std::string p_reg) +{ + if (strcasecmp(p_reg.c_str(), "EFLAGS") ==0) + return IRDB_SDK::rn_EFLAGS; + else if (strcasecmp(p_reg.c_str(), "RAX") == 0) + return IRDB_SDK::rn_RAX; + else if (strcasecmp(p_reg.c_str(), "RBX") == 0) + return IRDB_SDK::rn_RBX; + else if (strcasecmp(p_reg.c_str(), "RCX") == 0) + return IRDB_SDK::rn_RCX; + else if (strcasecmp(p_reg.c_str(), "RDX") == 0) + return IRDB_SDK::rn_RDX; + else if (strcasecmp(p_reg.c_str(), "RSI") == 0) + return IRDB_SDK::rn_RSI; + else if (strcasecmp(p_reg.c_str(), "RDI") == 0) + return IRDB_SDK::rn_RDI; + else if (strcasecmp(p_reg.c_str(), "RBP") == 0) + return IRDB_SDK::rn_RBP; + else if (strcasecmp(p_reg.c_str(), "RSP") == 0) + return IRDB_SDK::rn_RSP; + else if (strcasecmp(p_reg.c_str(), "R8") == 0) + return IRDB_SDK::rn_R8; + else if (strcasecmp(p_reg.c_str(), "R9") == 0) + return IRDB_SDK::rn_R9; + else if (strcasecmp(p_reg.c_str(), "R10") == 0) + return IRDB_SDK::rn_R10; + else if (strcasecmp(p_reg.c_str(), "R11") == 0) + return IRDB_SDK::rn_R11; + else if (strcasecmp(p_reg.c_str(), "R12") == 0) + return IRDB_SDK::rn_R12; + else if (strcasecmp(p_reg.c_str(), "R13") == 0) + return IRDB_SDK::rn_R13; + else if (strcasecmp(p_reg.c_str(), "R14") == 0) + return IRDB_SDK::rn_R14; + else if (strcasecmp(p_reg.c_str(), "R15") == 0) + return IRDB_SDK::rn_R15; + else if (strcasecmp(p_reg.c_str(), "RIP") == 0) + return IRDB_SDK::rn_RIP; + + else if (strcasecmp(p_reg.c_str(), "EAX") == 0) + return IRDB_SDK::rn_EAX; + else if (strcasecmp(p_reg.c_str(), "EBX") == 0) + return IRDB_SDK::rn_EBX; + else if (strcasecmp(p_reg.c_str(), "ECX") == 0) + return IRDB_SDK::rn_ECX; + else if (strcasecmp(p_reg.c_str(), "EDX") == 0) + return IRDB_SDK::rn_EDX; + else if (strcasecmp(p_reg.c_str(), "ESI") == 0) + return IRDB_SDK::rn_ESI; + else if (strcasecmp(p_reg.c_str(), "EDI") == 0) + return IRDB_SDK::rn_EDI; + else if (strcasecmp(p_reg.c_str(), "EBP") == 0) + return IRDB_SDK::rn_EBP; + else if (strcasecmp(p_reg.c_str(), "ESP") == 0) + return IRDB_SDK::rn_ESP; + else if (strcasecmp(p_reg.c_str(), "R8D") == 0) + return IRDB_SDK::rn_R8D; + else if (strcasecmp(p_reg.c_str(), "R9D") == 0) + return IRDB_SDK::rn_R9D; + else if (strcasecmp(p_reg.c_str(), "R10D") == 0) + return IRDB_SDK::rn_R10D; + else if (strcasecmp(p_reg.c_str(), "R11D") == 0) + return IRDB_SDK::rn_R11D; + else if (strcasecmp(p_reg.c_str(), "R12D") == 0) + return IRDB_SDK::rn_R12D; + else if (strcasecmp(p_reg.c_str(), "R13D") == 0) + return IRDB_SDK::rn_R13D; + else if (strcasecmp(p_reg.c_str(), "R14D") == 0) + return IRDB_SDK::rn_R14D; + else if (strcasecmp(p_reg.c_str(), "R15D") == 0) + return IRDB_SDK::rn_R15D; + + else if (strcasecmp(p_reg.c_str(), "AX") == 0) + return IRDB_SDK::rn_AX; + else if (strcasecmp(p_reg.c_str(), "BX") == 0) + return IRDB_SDK::rn_BX; + else if (strcasecmp(p_reg.c_str(), "CX") == 0) + return IRDB_SDK::rn_CX; + else if (strcasecmp(p_reg.c_str(), "DX") == 0) + return IRDB_SDK::rn_DX; + else if (strcasecmp(p_reg.c_str(), "BP") == 0) + return IRDB_SDK::rn_BP; + else if (strcasecmp(p_reg.c_str(), "SP") == 0) + return IRDB_SDK::rn_SP; + else if (strcasecmp(p_reg.c_str(), "SI") == 0) + return IRDB_SDK::rn_SI; + else if (strcasecmp(p_reg.c_str(), "DI") == 0) + return IRDB_SDK::rn_DI; + else if (strcasecmp(p_reg.c_str(), "R8W") == 0) + return IRDB_SDK::rn_R8W; + else if (strcasecmp(p_reg.c_str(), "R9W") == 0) + return IRDB_SDK::rn_R9W; + else if (strcasecmp(p_reg.c_str(), "R10W") == 0) + return IRDB_SDK::rn_R10W; + else if (strcasecmp(p_reg.c_str(), "R11W") == 0) + return IRDB_SDK::rn_R11W; + else if (strcasecmp(p_reg.c_str(), "R12W") == 0) + return IRDB_SDK::rn_R12W; + else if (strcasecmp(p_reg.c_str(), "R13W") == 0) + return IRDB_SDK::rn_R13W; + else if (strcasecmp(p_reg.c_str(), "R14W") == 0) + return IRDB_SDK::rn_R14W; + else if (strcasecmp(p_reg.c_str(), "R15W") == 0) + return IRDB_SDK::rn_R15W; + + else if (strcasecmp(p_reg.c_str(), "AH") == 0) + return IRDB_SDK::rn_AL; + else if (strcasecmp(p_reg.c_str(), "BH") == 0) + return IRDB_SDK::rn_BL; + else if (strcasecmp(p_reg.c_str(), "CH") == 0) + return IRDB_SDK::rn_CL; + else if (strcasecmp(p_reg.c_str(), "DH") == 0) + return IRDB_SDK::rn_DL; + else if (strcasecmp(p_reg.c_str(), "AL") == 0) + return IRDB_SDK::rn_AL; + else if (strcasecmp(p_reg.c_str(), "BL") == 0) + return IRDB_SDK::rn_BL; + else if (strcasecmp(p_reg.c_str(), "CL") == 0) + return IRDB_SDK::rn_CL; + else if (strcasecmp(p_reg.c_str(), "DL") == 0) + return IRDB_SDK::rn_DL; + else if (strcasecmp(p_reg.c_str(), "SIL") == 0) + return IRDB_SDK::rn_SIL; + else if (strcasecmp(p_reg.c_str(), "DIL") == 0) + return IRDB_SDK::rn_DIL; + else if (strcasecmp(p_reg.c_str(), "BPL") == 0) + return IRDB_SDK::rn_BPL; + else if (strcasecmp(p_reg.c_str(), "SPL") == 0) + return IRDB_SDK::rn_SPL; + else if (strcasecmp(p_reg.c_str(), "R8B") == 0) + return IRDB_SDK::rn_R8B; + else if (strcasecmp(p_reg.c_str(), "R9B") == 0) + return IRDB_SDK::rn_R9B; + else if (strcasecmp(p_reg.c_str(), "R10B") == 0) + return IRDB_SDK::rn_R10B; + else if (strcasecmp(p_reg.c_str(), "R11B") == 0) + return IRDB_SDK::rn_R11B; + else if (strcasecmp(p_reg.c_str(), "R12B") == 0) + return IRDB_SDK::rn_R12B; + else if (strcasecmp(p_reg.c_str(), "R13B") == 0) + return IRDB_SDK::rn_R13B; + else if (strcasecmp(p_reg.c_str(), "R14B") == 0) + return IRDB_SDK::rn_R14B; + else if (strcasecmp(p_reg.c_str(), "R15B") == 0) + return IRDB_SDK::rn_R15B; + else + return IRDB_SDK::rn_UNKNOWN; +} + +bool Register::is8bit(RegisterName p_reg) +{ + return p_reg == IRDB_SDK::rn_AL || p_reg == IRDB_SDK::rn_BL || p_reg == IRDB_SDK::rn_CL || p_reg == IRDB_SDK::rn_DL || + p_reg == IRDB_SDK::rn_AH || p_reg == IRDB_SDK::rn_BH || p_reg == IRDB_SDK::rn_CH || p_reg == IRDB_SDK::rn_DH || + p_reg == IRDB_SDK::rn_SIL || p_reg == IRDB_SDK::rn_DIL || p_reg == IRDB_SDK::rn_BPL || p_reg == IRDB_SDK::rn_SPL || + p_reg == IRDB_SDK::rn_R8B || p_reg == IRDB_SDK::rn_R9B || p_reg == IRDB_SDK::rn_R10B || p_reg == IRDB_SDK::rn_R11B || + p_reg == IRDB_SDK::rn_R12B || p_reg == IRDB_SDK::rn_R13B || p_reg == IRDB_SDK::rn_R14B || p_reg == IRDB_SDK::rn_R15B; +} + +bool Register::is16bit(RegisterName p_reg) +{ + return p_reg == IRDB_SDK::rn_AX || p_reg == IRDB_SDK::rn_BX || p_reg == IRDB_SDK::rn_CX || p_reg == IRDB_SDK::rn_DX || + p_reg == IRDB_SDK::rn_BP || p_reg == IRDB_SDK::rn_SP || p_reg == IRDB_SDK::rn_SI || p_reg == IRDB_SDK::rn_DI || + p_reg == IRDB_SDK::rn_R8W || p_reg == IRDB_SDK::rn_R9W || p_reg == IRDB_SDK::rn_R10W || p_reg == IRDB_SDK::rn_R11W || + p_reg == IRDB_SDK::rn_R12W || p_reg == IRDB_SDK::rn_R13W || p_reg == IRDB_SDK::rn_R14W || p_reg == IRDB_SDK::rn_R15W; +} + +bool Register::is32bit(RegisterName p_reg) +{ + return p_reg == IRDB_SDK::rn_EAX || p_reg == IRDB_SDK::rn_EBX || p_reg == IRDB_SDK::rn_ECX || p_reg == IRDB_SDK::rn_EDX || + p_reg == IRDB_SDK::rn_ESI || p_reg == IRDB_SDK::rn_EDI || p_reg == IRDB_SDK::rn_ESP || p_reg == IRDB_SDK::rn_EBP || + p_reg == IRDB_SDK::rn_R8D || p_reg == IRDB_SDK::rn_R9D || p_reg == IRDB_SDK::rn_R10D || p_reg == IRDB_SDK::rn_R11D || + p_reg == IRDB_SDK::rn_R12D || p_reg == IRDB_SDK::rn_R13D || p_reg == IRDB_SDK::rn_R14D || p_reg == IRDB_SDK::rn_R15D; +} + +bool Register::is64bit(RegisterName p_reg) +{ + return p_reg == IRDB_SDK::rn_RAX || p_reg == IRDB_SDK::rn_RBX || p_reg == IRDB_SDK::rn_RCX || p_reg == IRDB_SDK::rn_RDX || + p_reg == IRDB_SDK::rn_RSI || p_reg == IRDB_SDK::rn_RDI || p_reg == IRDB_SDK::rn_RBP || p_reg == IRDB_SDK::rn_RSP || + p_reg == IRDB_SDK::rn_R8 || p_reg == IRDB_SDK::rn_R9 || p_reg == IRDB_SDK::rn_R10 || p_reg == IRDB_SDK::rn_R11 || + p_reg == IRDB_SDK::rn_R12 || p_reg == IRDB_SDK::rn_R13 || p_reg == IRDB_SDK::rn_R14 || p_reg == IRDB_SDK::rn_R15 || p_reg == IRDB_SDK::rn_RIP; +} + +std::string Register::toString(RegisterName p_reg) +{ + if (p_reg == IRDB_SDK::rn_UNKNOWN) return std::string("UNKNOWN"); + + else if (p_reg == IRDB_SDK::rn_EFLAGS) return std::string("EFLAGS"); + + else if (p_reg == IRDB_SDK::rn_RAX) return std::string("RAX"); + else if (p_reg == IRDB_SDK::rn_RBX) return std::string("RBX"); + else if (p_reg == IRDB_SDK::rn_RCX) return std::string("RCX"); + else if (p_reg == IRDB_SDK::rn_RDX) return std::string("RDX"); + else if (p_reg == IRDB_SDK::rn_RSI) return std::string("RSI"); + else if (p_reg == IRDB_SDK::rn_RDI) return std::string("RDI"); + else if (p_reg == IRDB_SDK::rn_RBP) return std::string("RBP"); + else if (p_reg == IRDB_SDK::rn_RSP) return std::string("RSP"); + else if (p_reg == IRDB_SDK::rn_R8) return std::string("R8"); + else if (p_reg == IRDB_SDK::rn_R9) return std::string("R9"); + else if (p_reg == IRDB_SDK::rn_R10) return std::string("R10"); + else if (p_reg == IRDB_SDK::rn_R11) return std::string("R11"); + else if (p_reg == IRDB_SDK::rn_R12) return std::string("R12"); + else if (p_reg == IRDB_SDK::rn_R13) return std::string("R13"); + else if (p_reg == IRDB_SDK::rn_R14) return std::string("R14"); + else if (p_reg == IRDB_SDK::rn_R15) return std::string("R15"); + else if (p_reg == IRDB_SDK::rn_RIP) return std::string("RIP"); + + else if (p_reg == IRDB_SDK::rn_EAX) return std::string("EAX"); + else if (p_reg == IRDB_SDK::rn_EBX) return std::string("EBX"); + else if (p_reg == IRDB_SDK::rn_ECX) return std::string("ECX"); + else if (p_reg == IRDB_SDK::rn_EDX) return std::string("EDX"); + else if (p_reg == IRDB_SDK::rn_EDI) return std::string("EDI"); + else if (p_reg == IRDB_SDK::rn_ESI) return std::string("ESI"); + else if (p_reg == IRDB_SDK::rn_EBP) return std::string("EBP"); + else if (p_reg == IRDB_SDK::rn_ESP) return std::string("ESP"); + else if (p_reg == IRDB_SDK::rn_R8D) return std::string("R8D"); + else if (p_reg == IRDB_SDK::rn_R9D) return std::string("R9D"); + else if (p_reg == IRDB_SDK::rn_R10D) return std::string("R10D"); + else if (p_reg == IRDB_SDK::rn_R11D) return std::string("R11D"); + else if (p_reg == IRDB_SDK::rn_R12D) return std::string("R12D"); + else if (p_reg == IRDB_SDK::rn_R13D) return std::string("R13D"); + else if (p_reg == IRDB_SDK::rn_R14D) return std::string("R14D"); + else if (p_reg == IRDB_SDK::rn_R15D) return std::string("R15D"); + + else if (p_reg == IRDB_SDK::rn_AX) return std::string("AX"); + else if (p_reg == IRDB_SDK::rn_BX) return std::string("BX"); + else if (p_reg == IRDB_SDK::rn_CX) return std::string("CX"); + else if (p_reg == IRDB_SDK::rn_DX) return std::string("DX"); + else if (p_reg == IRDB_SDK::rn_BP) return std::string("BP"); + else if (p_reg == IRDB_SDK::rn_SP) return std::string("SP"); + else if (p_reg == IRDB_SDK::rn_SI) return std::string("SI"); + else if (p_reg == IRDB_SDK::rn_DI) return std::string("DI"); + else if (p_reg == IRDB_SDK::rn_R8W) return std::string("R8W"); + else if (p_reg == IRDB_SDK::rn_R9W) return std::string("R9W"); + else if (p_reg == IRDB_SDK::rn_R10W) return std::string("R10W"); + else if (p_reg == IRDB_SDK::rn_R11W) return std::string("R11W"); + else if (p_reg == IRDB_SDK::rn_R12W) return std::string("R12W"); + else if (p_reg == IRDB_SDK::rn_R13W) return std::string("R13W"); + else if (p_reg == IRDB_SDK::rn_R14W) return std::string("R14W"); + else if (p_reg == IRDB_SDK::rn_R15W) return std::string("R15W"); + + else if (p_reg == IRDB_SDK::rn_AH) return std::string("AH"); + else if (p_reg == IRDB_SDK::rn_BH) return std::string("BH"); + else if (p_reg == IRDB_SDK::rn_CH) return std::string("CH"); + else if (p_reg == IRDB_SDK::rn_DH) return std::string("DH"); + else if (p_reg == IRDB_SDK::rn_AL) return std::string("AL"); + else if (p_reg == IRDB_SDK::rn_BL) return std::string("BL"); + else if (p_reg == IRDB_SDK::rn_CL) return std::string("CL"); + else if (p_reg == IRDB_SDK::rn_DL) return std::string("DL"); + else if (p_reg == IRDB_SDK::rn_SIL) return std::string("SIL"); + else if (p_reg == IRDB_SDK::rn_DIL) return std::string("DIL"); + else if (p_reg == IRDB_SDK::rn_BPL) return std::string("BPL"); + else if (p_reg == IRDB_SDK::rn_SPL) return std::string("SPL"); + else if (p_reg == IRDB_SDK::rn_R8B) return std::string("R8B"); + else if (p_reg == IRDB_SDK::rn_R9B) return std::string("R9B"); + else if (p_reg == IRDB_SDK::rn_R10B) return std::string("R10B"); + else if (p_reg == IRDB_SDK::rn_R11B) return std::string("R11B"); + else if (p_reg == IRDB_SDK::rn_R12B) return std::string("R12B"); + else if (p_reg == IRDB_SDK::rn_R13B) return std::string("R13B"); + else if (p_reg == IRDB_SDK::rn_R14B) return std::string("R14B"); + else if (p_reg == IRDB_SDK::rn_R15B) return std::string("R15B"); + + else return std::string("UNEXPECTED REGISTER VALUE"); +} + +int Register::getBitWidth(RegisterName p_reg) +{ + switch (p_reg) + { + case IRDB_SDK::rn_RAX: + case IRDB_SDK::rn_RBX: + case IRDB_SDK::rn_RCX: + case IRDB_SDK::rn_RDX: + case IRDB_SDK::rn_RSI: + case IRDB_SDK::rn_RDI: + case IRDB_SDK::rn_RBP: + case IRDB_SDK::rn_RSP: + case IRDB_SDK::rn_R8: + case IRDB_SDK::rn_R9: + case IRDB_SDK::rn_R10: + case IRDB_SDK::rn_R11: + case IRDB_SDK::rn_R12: + case IRDB_SDK::rn_R13: + case IRDB_SDK::rn_R14: + case IRDB_SDK::rn_R15: + case IRDB_SDK::rn_RIP: + return 64; + break; + case IRDB_SDK::rn_EAX: + case IRDB_SDK::rn_EBX: + case IRDB_SDK::rn_ECX: + case IRDB_SDK::rn_EDX: + case IRDB_SDK::rn_EDI: + case IRDB_SDK::rn_ESI: + case IRDB_SDK::rn_EBP: + case IRDB_SDK::rn_ESP: + case IRDB_SDK::rn_R8D: + case IRDB_SDK::rn_R9D: + case IRDB_SDK::rn_R10D: + case IRDB_SDK::rn_R11D: + case IRDB_SDK::rn_R12D: + case IRDB_SDK::rn_R13D: + case IRDB_SDK::rn_R14D: + case IRDB_SDK::rn_R15D: + return 32; + break; + + case IRDB_SDK::rn_AX: + case IRDB_SDK::rn_BX: + case IRDB_SDK::rn_CX: + case IRDB_SDK::rn_DX: + case IRDB_SDK::rn_BP: + case IRDB_SDK::rn_SP: + case IRDB_SDK::rn_SI: + case IRDB_SDK::rn_DI: + case IRDB_SDK::rn_R8W: + case IRDB_SDK::rn_R9W: + case IRDB_SDK::rn_R10W: + case IRDB_SDK::rn_R11W: + case IRDB_SDK::rn_R12W: + case IRDB_SDK::rn_R13W: + case IRDB_SDK::rn_R14W: + case IRDB_SDK::rn_R15W: + return 16; + break; + + case IRDB_SDK::rn_AH: + case IRDB_SDK::rn_BH: + case IRDB_SDK::rn_CH: + case IRDB_SDK::rn_DH: + case IRDB_SDK::rn_AL: + case IRDB_SDK::rn_BL: + case IRDB_SDK::rn_CL: + case IRDB_SDK::rn_DL: + case IRDB_SDK::rn_SIL: + case IRDB_SDK::rn_DIL: + case IRDB_SDK::rn_BPL: + case IRDB_SDK::rn_SPL: + case IRDB_SDK::rn_R8B: + case IRDB_SDK::rn_R9B: + case IRDB_SDK::rn_R10B: + case IRDB_SDK::rn_R11B: + case IRDB_SDK::rn_R12B: + case IRDB_SDK::rn_R13B: + case IRDB_SDK::rn_R14B: + case IRDB_SDK::rn_R15B: + return 8; + break; + + default: + return -1; + break; + } +} + + +// favor registers R10..R15 +RegisterName Register::getFreeRegister64(const RegisterSet_t& p_taken) +{ + +#define ret_if_free4(a, b, c, d)\ + if (p_taken.count(a) == 0 && p_taken.count(b) == 0 && p_taken.count(c) == 0 && p_taken.count(d) == 0 ) \ + return a; \ + +#define ret_if_free5(a, b, c, d, e)\ + if (p_taken.count(a) == 0 && p_taken.count(b) == 0 && p_taken.count(c) == 0 && p_taken.count(d) == 0 && p_taken.count(e)==0) \ + return a; \ + + ret_if_free4(IRDB_SDK::rn_R8, IRDB_SDK::rn_R8D, IRDB_SDK::rn_R8W, IRDB_SDK::rn_R8B); + ret_if_free4(IRDB_SDK::rn_R9, IRDB_SDK::rn_R9D, IRDB_SDK::rn_R9W, IRDB_SDK::rn_R9B); + ret_if_free4(IRDB_SDK::rn_R10, IRDB_SDK::rn_R10D, IRDB_SDK::rn_R10W, IRDB_SDK::rn_R10B); + ret_if_free4(IRDB_SDK::rn_R11, IRDB_SDK::rn_R11D, IRDB_SDK::rn_R11W, IRDB_SDK::rn_R11B); + ret_if_free4(IRDB_SDK::rn_R12, IRDB_SDK::rn_R12D, IRDB_SDK::rn_R12W, IRDB_SDK::rn_R12B); + ret_if_free4(IRDB_SDK::rn_R13, IRDB_SDK::rn_R13D, IRDB_SDK::rn_R13W, IRDB_SDK::rn_R13B); + ret_if_free4(IRDB_SDK::rn_R14, IRDB_SDK::rn_R14D, IRDB_SDK::rn_R14W, IRDB_SDK::rn_R14B); + ret_if_free4(IRDB_SDK::rn_R15, IRDB_SDK::rn_R15D, IRDB_SDK::rn_R15W, IRDB_SDK::rn_R15B); + ret_if_free5(IRDB_SDK::rn_RAX, IRDB_SDK::rn_EAX, IRDB_SDK::rn_AX, IRDB_SDK::rn_AL, IRDB_SDK::rn_AH); + ret_if_free5(IRDB_SDK::rn_RCX, IRDB_SDK::rn_ECX, IRDB_SDK::rn_CX, IRDB_SDK::rn_CL, IRDB_SDK::rn_CH); + ret_if_free5(IRDB_SDK::rn_RDX, IRDB_SDK::rn_EDX, IRDB_SDK::rn_DX, IRDB_SDK::rn_DL, IRDB_SDK::rn_DH); + ret_if_free5(IRDB_SDK::rn_RBX, IRDB_SDK::rn_EBX, IRDB_SDK::rn_BX, IRDB_SDK::rn_BL, IRDB_SDK::rn_BH); + ret_if_free5(IRDB_SDK::rn_RSI, IRDB_SDK::rn_ESI, IRDB_SDK::rn_SI, IRDB_SDK::rn_SIL, IRDB_SDK::rn_SIH); + ret_if_free5(IRDB_SDK::rn_RDI, IRDB_SDK::rn_EDI, IRDB_SDK::rn_DI, IRDB_SDK::rn_DIL, IRDB_SDK::rn_DIH); + ret_if_free5(IRDB_SDK::rn_RSP, IRDB_SDK::rn_ESP, IRDB_SDK::rn_SP, IRDB_SDK::rn_SPL, IRDB_SDK::rn_SPH); + ret_if_free5(IRDB_SDK::rn_RBP, IRDB_SDK::rn_EBP, IRDB_SDK::rn_BP, IRDB_SDK::rn_BPL, IRDB_SDK::rn_BPH); + return IRDB_SDK::rn_UNKNOWN; +} + +string Register::readRegisterSet(const string &in, RegisterSet_t &out) +{ + size_t pos=in.find("ZZ"); + string regname; + stringstream ss(in); + + while ( ss>>regname ) + { + if( regname=="ZZ") + return in.substr(pos+3); + + out.insert(getRegister(regname)); + } + + assert(0 && "No terminator found for register list"); +} + +RegisterName Register::promoteTo64(const RegisterName p_reg) +{ + if (is64bit(p_reg)) + return p_reg; + + switch (p_reg) + { + case IRDB_SDK::rn_AL: + case IRDB_SDK::rn_AH: + case IRDB_SDK::rn_AX: + case IRDB_SDK::rn_EAX: + return IRDB_SDK::rn_RAX; + case IRDB_SDK::rn_BL: + case IRDB_SDK::rn_BH: + case IRDB_SDK::rn_BX: + case IRDB_SDK::rn_EBX: + return IRDB_SDK::rn_RBX; + case IRDB_SDK::rn_CL: + case IRDB_SDK::rn_CH: + case IRDB_SDK::rn_CX: + case IRDB_SDK::rn_ECX: + return IRDB_SDK::rn_RCX; + case IRDB_SDK::rn_DL: + case IRDB_SDK::rn_DH: + case IRDB_SDK::rn_DX: + case IRDB_SDK::rn_EDX: + return IRDB_SDK::rn_RDX; + case IRDB_SDK::rn_DIL: + case IRDB_SDK::rn_DI: + case IRDB_SDK::rn_EDI: + return IRDB_SDK::rn_RDI; + case IRDB_SDK::rn_SIL: + case IRDB_SDK::rn_SI: + case IRDB_SDK::rn_ESI: + return IRDB_SDK::rn_RSI; + case IRDB_SDK::rn_BPL: + case IRDB_SDK::rn_BP: + case IRDB_SDK::rn_EBP: + return IRDB_SDK::rn_RBP; + case IRDB_SDK::rn_SPL: + case IRDB_SDK::rn_SP: + case IRDB_SDK::rn_ESP: + return IRDB_SDK::rn_RSP; + case IRDB_SDK::rn_R8B: + case IRDB_SDK::rn_R8W: + case IRDB_SDK::rn_R8D: + return IRDB_SDK::rn_R8; + case IRDB_SDK::rn_R9B: + case IRDB_SDK::rn_R9W: + case IRDB_SDK::rn_R9D: + return IRDB_SDK::rn_R9; + case IRDB_SDK::rn_R10B: + case IRDB_SDK::rn_R10W: + case IRDB_SDK::rn_R10D: + return IRDB_SDK::rn_R10; + case IRDB_SDK::rn_R11B: + case IRDB_SDK::rn_R11W: + case IRDB_SDK::rn_R11D: + return IRDB_SDK::rn_R11; + case IRDB_SDK::rn_R12B: + case IRDB_SDK::rn_R12W: + case IRDB_SDK::rn_R12D: + return IRDB_SDK::rn_R12; + case IRDB_SDK::rn_R13B: + case IRDB_SDK::rn_R13W: + case IRDB_SDK::rn_R13D: + return IRDB_SDK::rn_R13; + case IRDB_SDK::rn_R14B: + case IRDB_SDK::rn_R14W: + case IRDB_SDK::rn_R14D: + return IRDB_SDK::rn_R14; + case IRDB_SDK::rn_R15B: + case IRDB_SDK::rn_R15W: + case IRDB_SDK::rn_R15D: + return IRDB_SDK::rn_R15; + + default: + return IRDB_SDK::rn_UNKNOWN; + break; + } +} + +RegisterName Register::demoteTo32(const RegisterName p_reg) +{ + if (is32bit(p_reg)) + return p_reg; + + switch (p_reg) + { + case IRDB_SDK::rn_RAX: return IRDB_SDK::rn_EAX; + case IRDB_SDK::rn_RBX: return IRDB_SDK::rn_EBX; + case IRDB_SDK::rn_RCX: return IRDB_SDK::rn_ECX; + case IRDB_SDK::rn_RDX: return IRDB_SDK::rn_EDX; + case IRDB_SDK::rn_RBP: return IRDB_SDK::rn_EBP; + case IRDB_SDK::rn_RSP: return IRDB_SDK::rn_ESP; + case IRDB_SDK::rn_RSI: return IRDB_SDK::rn_ESI; + case IRDB_SDK::rn_RDI: return IRDB_SDK::rn_EDI; + case IRDB_SDK::rn_R8: return IRDB_SDK::rn_R8D; + case IRDB_SDK::rn_R9: return IRDB_SDK::rn_R9D; + case IRDB_SDK::rn_R10: return IRDB_SDK::rn_R10D; + case IRDB_SDK::rn_R11: return IRDB_SDK::rn_R11D; + case IRDB_SDK::rn_R12: return IRDB_SDK::rn_R12D; + case IRDB_SDK::rn_R13: return IRDB_SDK::rn_R13D; + case IRDB_SDK::rn_R14: return IRDB_SDK::rn_R14D; + case IRDB_SDK::rn_R15: return IRDB_SDK::rn_R15D; + default: + return IRDB_SDK::rn_UNKNOWN; + break; + } +} + +RegisterName Register::demoteTo16(const RegisterName p_reg) +{ + if (is16bit(p_reg)) + return p_reg; + + switch (p_reg) + { + case IRDB_SDK::rn_RAX: case IRDB_SDK::rn_EAX: return IRDB_SDK::rn_AX; + case IRDB_SDK::rn_RBX: case IRDB_SDK::rn_EBX: return IRDB_SDK::rn_BX; + case IRDB_SDK::rn_RCX: case IRDB_SDK::rn_ECX: return IRDB_SDK::rn_CX; + case IRDB_SDK::rn_RDX: case IRDB_SDK::rn_EDX: return IRDB_SDK::rn_DX; + case IRDB_SDK::rn_RBP: case IRDB_SDK::rn_EBP: return IRDB_SDK::rn_BP; + case IRDB_SDK::rn_RSP: case IRDB_SDK::rn_ESP: return IRDB_SDK::rn_SP; + case IRDB_SDK::rn_RSI: case IRDB_SDK::rn_ESI: return IRDB_SDK::rn_SI; + case IRDB_SDK::rn_RDI: case IRDB_SDK::rn_EDI: return IRDB_SDK::rn_DI; + case IRDB_SDK::rn_R8: case IRDB_SDK::rn_R8D: return IRDB_SDK::rn_R8W; + case IRDB_SDK::rn_R9: case IRDB_SDK::rn_R9D: return IRDB_SDK::rn_R9W; + case IRDB_SDK::rn_R10: case IRDB_SDK::rn_R10D: return IRDB_SDK::rn_R10W; + case IRDB_SDK::rn_R11: case IRDB_SDK::rn_R11D: return IRDB_SDK::rn_R11W; + case IRDB_SDK::rn_R12: case IRDB_SDK::rn_R12D: return IRDB_SDK::rn_R12W; + case IRDB_SDK::rn_R13: case IRDB_SDK::rn_R13D: return IRDB_SDK::rn_R13W; + case IRDB_SDK::rn_R14: case IRDB_SDK::rn_R14D: return IRDB_SDK::rn_R14W; + case IRDB_SDK::rn_R15: case IRDB_SDK::rn_R15D: return IRDB_SDK::rn_R15W; + default: + return IRDB_SDK::rn_UNKNOWN; + break; + } +} + diff --git a/irdb-lib/libMEDSannotation/src/MEDS_SafeFuncAnnotation.cpp b/irdb-lib/libMEDSannotation/src/MEDS_SafeFuncAnnotation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..de7af940b984d1d2daf2694bdaf419f9c962f5d2 --- /dev/null +++ b/irdb-lib/libMEDSannotation/src/MEDS_SafeFuncAnnotation.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <stdlib.h> + +#include <iostream> +#include <cstdio> +#include <string> +#include <string.h> + +#include "MEDS_Register.hpp" +#include "MEDS_SafeFuncAnnotation.hpp" + +using namespace std; +using namespace MEDS_Annotation; + + + + + +MEDS_SafeFuncAnnotation::MEDS_SafeFuncAnnotation(const string &p_rawLine) +{ + init(); + m_rawInputLine=p_rawLine; + setLeaf(false); + setHasFramePointer(true); + parse(); +} + +void MEDS_SafeFuncAnnotation::init() +{ + MEDS_FuncAnnotation::init(); +} + + +/* + Example format (as of July 31, 2014 ) -- subject to change: + + 400448 24 FUNC GLOBAL .init_proc FUNC_UNSAFE NOFP RET 40045f + 400470 6 FUNC GLOBAL .__stack_chk_fail FUNC_UNSAFE NOFP NORET FUNC_LEAF 400475 + 400480 6 FUNC GLOBAL .__libc_start_main FUNC_UNSAFE NOFP RET FUNC_LEAF 400485 + 400490 6 FUNC GLOBAL .__printf_chk FUNC_UNSAFE NOFP RET FUNC_LEAF 400495 + +*/ +void MEDS_SafeFuncAnnotation::parse() +{ + + if (m_rawInputLine.find("FUNC ")==string::npos) + return; + + if (m_rawInputLine.find("FUNC GLOBAL")==string::npos && + m_rawInputLine.find("FUNC LOCAL")==string::npos ) + { + /* FUNC line that's not local or global? I'm confused. */ + /* could be a FUNC PROBLEM line */ + return; + } + + // get offset + VirtualOffset vo(m_rawInputLine); + m_virtualOffset = vo; + + size_t func_name_start_pos=0, pos=0; + if ((pos=m_rawInputLine.find("FUNC GLOBAL"))!=string::npos) + func_name_start_pos=pos+strlen("FUNC GLOBAL "); + else if ((pos=m_rawInputLine.find("FUNC LOCAL"))!=string::npos) + func_name_start_pos=pos+strlen("FUNC LOCAL "); + + size_t func_end_pos=m_rawInputLine.find(" ", func_name_start_pos); + assert(func_end_pos!=string::npos); + string func_name=m_rawInputLine.substr(func_name_start_pos, func_end_pos-func_name_start_pos); + + // cout<<"Found safe func name='"<<func_name<<"'"<<endl; + + // get offset + setFuncName(func_name); + + + if (m_rawInputLine.find(" FUNC_SAFE ")!=string::npos) + { + if(getenv("VERBOSE")) + cout<<"Found FUNC_SAFE annotation for "<<vo.to_string()<<endl; + markSafe(); // sets valid + } + else if (m_rawInputLine.find(" FUNC_UNSAFE ")!=string::npos) + { + if(getenv("VERBOSE")) + cout<<"Found FUNC_UNSAFE annotation for "<<vo.to_string()<<endl; + markUnsafe(); // sets valid + } + + if (m_rawInputLine.find(" FUNC_LEAF ")!=string::npos) + { + if(getenv("VERBOSE")) + cout<<"Found FUNC_LEAF for "<<vo.to_string()<<endl; + setLeaf(true); + } + else + { + setLeaf(false); + } + + if (m_rawInputLine.find(" NOFP ")!=string::npos) + { + if(getenv("VERBOSE")) + cout<<"Found NOFP (no frame pointer) for "<<vo.to_string()<<endl; + setHasFramePointer(false); + } + else + { + setHasFramePointer(true); + } + +} + diff --git a/irdb-lib/libMEDSannotation/src/Makefile.in b/irdb-lib/libMEDSannotation/src/Makefile.in new file mode 100644 index 0000000000000000000000000000000000000000..352725e672c9b0b3ac708cb0103cf6b7bfe9e4a6 --- /dev/null +++ b/irdb-lib/libMEDSannotation/src/Makefile.in @@ -0,0 +1,20 @@ + + +CC=@CC@ +CXX=@CXX@ + +LIB=../lib/libMEDSannotation.a + +OBJS=VirtualOffset.o MEDS_Register.o MEDS_AnnotationParser.o MEDS_InstructionCheckAnnotation.o MEDS_SafeFuncAnnotation.o MEDS_ProblemFuncAnnotation.o MEDS_FRSafeAnnotation.o FuncExitAnnotation.o MEDS_FPTRShadowAnnotation.o MEDS_FuncPrototypeAnnotation.o + +all: $(OBJS) + +$(OBJS): ../include/*.hpp + +clean: + rm -f $(OBJS) *.o + +.cpp.o: + $(CXX) -g -c -I. -I../include $< + ar rc $(LIB) $@ + cp $(LIB) ../../lib diff --git a/irdb-lib/libMEDSannotation/src/VirtualOffset.cpp b/irdb-lib/libMEDSannotation/src/VirtualOffset.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1e4ca4f6442438a4de9ec91f326e9c3e4aa25859 --- /dev/null +++ b/irdb-lib/libMEDSannotation/src/VirtualOffset.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <cstdio> +#include <iostream> + +#include "VirtualOffset.hpp" + +using namespace std; +using namespace MEDS_Annotation; + +VirtualOffset::VirtualOffset() +{ + m_offset = 0; + m_libraryName = std::string(DEFAULT_LIBRARY_NAME); +} + +VirtualOffset::VirtualOffset(const std::string &p_offset, const std::string &p_libraryName) +{ + sscanf(p_offset.c_str(), "%llx", &m_offset); + m_libraryName = p_libraryName; +} + +VirtualOffset::VirtualOffset(const std::string &p_offset) +{ + sscanf(p_offset.c_str(), "%llx", &m_offset); + m_libraryName = std::string(DEFAULT_LIBRARY_NAME); +} + +VirtualOffset::VirtualOffset(const int p_offset) +{ + m_offset = p_offset; + m_libraryName = std::string(DEFAULT_LIBRARY_NAME); +} + +ApplicationAddress VirtualOffset::getOffset() const +{ + return m_offset; +} + +std::string VirtualOffset::getLibraryName() const +{ + return m_libraryName; +} + +bool VirtualOffset::operator < (const VirtualOffset &p_other) const +{ + if (&p_other == this) return false; + return m_offset < p_other.getOffset(); +} + +bool VirtualOffset::operator == (const VirtualOffset &p_other) const +{ + if (&p_other == this) + return true; + else + { + return (m_offset == p_other.getOffset() && m_libraryName == p_other.getLibraryName()); + } +} + +VirtualOffset& VirtualOffset::operator = (const VirtualOffset &p_other) +{ + if (&p_other == this) + { + return *this; + } + else + { + m_offset = p_other.getOffset(); + m_libraryName = p_other.getLibraryName(); + return *this; + } +} diff --git a/irdb-lib/libStructDiv/SConscript b/irdb-lib/libStructDiv/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..8b38ac43f269caea3edfc01cb1863e5ffdbc1a49 --- /dev/null +++ b/irdb-lib/libStructDiv/SConscript @@ -0,0 +1,10 @@ +import os + +Import('env') + + +lib1=SConscript("src/SConscript") +#lib2=SConscript("test/SConscript") + +rets = [ lib1 ] +Return('rets') diff --git a/irdb-lib/libStructDiv/SConstruct b/irdb-lib/libStructDiv/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..4d6381b5999d3e6d4e4687fc95f444ea2c4c5747 --- /dev/null +++ b/irdb-lib/libStructDiv/SConstruct @@ -0,0 +1,8 @@ + + + +env=Environment() +Export('env') +lib=SConscript("SConscript") + +Return(lib) diff --git a/irdb-lib/libStructDiv/include/filebased.h b/irdb-lib/libStructDiv/include/filebased.h new file mode 100644 index 0000000000000000000000000000000000000000..0c6cbd0bae792fd090cd4c72c49d9793169853c9 --- /dev/null +++ b/irdb-lib/libStructDiv/include/filebased.h @@ -0,0 +1,30 @@ +#ifndef sd_filebased_h +#define sd_filebased_h + +#include <string> +#include <structured_diversity.h> + +namespace libStructDiv +{ + +using namespace std; + + +class FileBased_StructuredDiversity_t : public StructuredDiversity_t +{ + public: + + FileBased_StructuredDiversity_t(string key, int varid, int total_variants, string p_config); + + + protected: + virtual vector<string> DoBarrier(string value); + + string m_shared_dir; + int m_barrier_count; + +}; + +} + +#endif diff --git a/irdb-lib/libStructDiv/include/libStructDiv.h b/irdb-lib/libStructDiv/include/libStructDiv.h new file mode 100644 index 0000000000000000000000000000000000000000..d643a2a135634806cc4e050736d26f9ecbb0dd03 --- /dev/null +++ b/irdb-lib/libStructDiv/include/libStructDiv.h @@ -0,0 +1,6 @@ +#ifndef SD_STRUCTDIV_H +#define SD_STRUCTDIV_H + +#include <structured_diversity.h> + +#endif diff --git a/irdb-lib/libStructDiv/include/structured_diversity.h b/irdb-lib/libStructDiv/include/structured_diversity.h new file mode 100644 index 0000000000000000000000000000000000000000..a6eddd8e7c5b86e804d0fff4de6ba0153e973403 --- /dev/null +++ b/irdb-lib/libStructDiv/include/structured_diversity.h @@ -0,0 +1,81 @@ +#ifndef SD_SDBASE_H +#define SD_SDBASE_H + +#include <string> +#include <vector> +#include <assert.h> +#include <sstream> + +namespace libStructDiv +{ + +using namespace std; + + +class StructuredDiversity_t +{ + public: + + // STatic factory + static StructuredDiversity_t* factory(string key, string p_ipc_config); + + + // cannot use directly since there are abstract methods. + // use from children classes. + StructuredDiversity_t(string p_key, int p_variant_num, int p_total_variants) : + m_variant_num(p_variant_num), m_total_variants(p_total_variants), m_key(p_key) + { + // nothing else to do. + } + virtual ~StructuredDiversity_t() { } + + + // Perform a barrier of type T. T should be marshable + // via the << and >> operators. To avoid this, the caller can self-marshal + // (Will recommends a protocol buffer package for self-marshalling) + // and invoke Barrier with a string. + template<class T> vector<T> Barrier(T value) + { + /* marshal value into stream s */ + stringstream s; + s<<value; + + // pass marshalled value to DoBarrier + const vector<string> &string_res=DoBarrier(s.str()); + + assert((size_t)string_res.size()==(size_t)m_total_variants); + + /* declare a result */ + vector<T> t_res; + + // for each item + for(int i=0;i<m_total_variants;i++) + { + stringstream t; + T res; + t.str(string_res[i]); + t>>res; + t_res.push_back(res); + } + + return t_res; + } + + + + // Getters that most cfar things will need. + int GetVariantID() const { return m_variant_num; } + int GetNumberOfVariants() const { return m_total_variants; } + string GetKey() const { return m_key; } + + protected: + virtual vector<string> DoBarrier(string value)=0; + + int m_variant_num; + int m_total_variants; + string m_key; + +}; + +} +#endif diff --git a/irdb-lib/libStructDiv/src/SConscript b/irdb-lib/libStructDiv/src/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..11fce4d5b8a15fa99b3a6044b971a5bbbd3616c2 --- /dev/null +++ b/irdb-lib/libStructDiv/src/SConscript @@ -0,0 +1,24 @@ +import os + + + +Import('env') +myenv=env.Clone() +myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) + +files="filebased.cpp structured_diversity.cpp" + +cpppath=''' + $SECURITY_TRANSFORMS_HOME/libStructDiv/include/ + ''' + + +LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" + +myenv=myenv.Clone(CPPPATH=Split(cpppath)) +myenv.Append(CXXFLAGS="-fPIC") +lib=myenv.SharedLibrary("StructDiv", Split(files)) +install=myenv.Install("$SECURITY_TRANSFORMS_HOME/lib/", lib) +Default(install) + +Return('install') diff --git a/irdb-lib/libStructDiv/src/SConstruct b/irdb-lib/libStructDiv/src/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..c96332f0422ad5df0853931209219d9a2e20bc17 --- /dev/null +++ b/irdb-lib/libStructDiv/src/SConstruct @@ -0,0 +1,6 @@ + + + +env=Environment() +Export('env') +lib=SConscript("SConscript") diff --git a/irdb-lib/libStructDiv/src/filebased.cpp b/irdb-lib/libStructDiv/src/filebased.cpp new file mode 100644 index 0000000000000000000000000000000000000000..78b50f0a28068d688843eebe860ddb4042447497 --- /dev/null +++ b/irdb-lib/libStructDiv/src/filebased.cpp @@ -0,0 +1,165 @@ + + +#include <string> +#include <structured_diversity.h> +#include <filebased.h> +#include <fstream> +#include <iostream> +#include <stdlib.h> + + + +#if defined(__linux__) +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#endif + +using namespace std; +using namespace libStructDiv; + + +template <class T> +void ignore_result(T /* res */ ) {} + + +template<typename T> std::string toString(const T& value) +{ + std::ostringstream oss; + oss << value; + return oss.str(); +} + + +FileBased_StructuredDiversity_t::FileBased_StructuredDiversity_t(string key, int varid, int total_variants, string p_config) + : StructuredDiversity_t(key, varid, total_variants), m_barrier_count(0) +{ + + assert(varid>=0 && varid<total_variants); + +#if defined(__linux__) + char* uname = getenv("USER"); + if(!uname) { + uname = getenv("USERNAME"); + } + if(!uname) { + uname = getlogin(); + } + // assume p_config, which previously started with "dir://" already has the protocol stripped. + m_shared_dir=p_config; + + // check path exists. + struct stat info = {}; + if( stat(m_shared_dir.c_str(), &info ) != 0 ) + { + // dir doesn't exist, make it. + if(mkdir(m_shared_dir.c_str(),0755)!=0) + { + // OK if this fails, because maybe another variant did it since we last checked. + } + } + + // but now, _we_ have tried to make the dir, and so it should be there, or we give up. + if( stat(m_shared_dir.c_str(), &info ) != 0 ) + { + // at this point, we tried to make it and couldn't. + // and no one else did either. Thus, it's an error. + perror("FileBased_StructuredDiversity_t::FileBased_StructuredDiversity_t"); + cerr<<"Cannot create dir:"<<m_shared_dir<<endl; + exit(1); + } + + if(!S_ISDIR(info.st_mode)) + { + cerr<<"FileBased_StructuredDiversity_t::FileBased_StructuredDiversity_t: " + <<m_shared_dir<<" is not a directory."<<endl; + exit(1); + + } + + + // dir exists, + // remove any old Barriers file for my variant.. + string base_filespec=m_shared_dir+"/Barriers_"+uname+"_"+GetKey()+"_*_"+toString(GetVariantID())+".*"; + string rm_cmd="/bin/rm -f "+base_filespec; + int res=system(rm_cmd.c_str()); + if(res!=0) + { + perror("FileBased_StructuredDiversity_t::FileBased_StructuredDiversity_t"); + cerr<<"Cannot remove files, cmd="<<rm_cmd<<endl; + exit(1); + } + + cout<<"Initing shared path: "<<m_shared_dir<<endl<<"Contents:"<<endl; + string ls_cmd="ls "+m_shared_dir; + ignore_result(system(ls_cmd.c_str())); +#else + assert(0); // filesystem sharing not implement on non-linux platforms yet +#endif + +} + + +static bool fexists(const char *filename) { + ifstream ifile(filename); + return (!!ifile); +} + +vector<string> FileBased_StructuredDiversity_t::DoBarrier(string value) +{ + char* uname = getenv("USER"); + if(!uname) { + uname = getenv("USERNAME"); + } +#if defined(__linux__) + if(!uname) { + uname = getlogin(); + } +#endif + assert(uname); + string base_filename=m_shared_dir+"/Barriers_"+uname+"_"+GetKey()+"_"+toString(m_barrier_count)+"_"+toString(GetVariantID()); + string data_filename=base_filename+".data"; + string done_filename=base_filename+".done"; + + vector<string> vres; + + cout<<"Writing shared (base) filename: "<<base_filename<<endl; + + + ofstream data_file(data_filename.c_str()); + if(!data_file) + assert(0); + data_file<<value; + data_file.close(); + + ofstream done_file(done_filename.c_str()); + if(!done_file) + assert(0); + done_file<<1; + done_file.close(); + + for(int i=0;i<GetNumberOfVariants();i++) + { + string var_base_filename=m_shared_dir+"/Barriers_"+uname+"_"+GetKey()+"_"+toString(m_barrier_count)+"_"+toString(i); + string var_data_filename=var_base_filename+".data"; + string var_done_filename=var_base_filename+".done"; + + cout<<"Waiting for shared (base) filename: "<<var_base_filename<<endl; + + while(!fexists(var_done_filename.c_str())) + sleep(1); + + ifstream infile(var_data_filename.c_str()); + string res; + infile>>res; + infile.close(); + vres.push_back(res); + } + + // next time, we'll use different file names. + m_barrier_count++; + + return vres; +} + + diff --git a/irdb-lib/libStructDiv/src/structured_diversity.cpp b/irdb-lib/libStructDiv/src/structured_diversity.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d5b41905b1b11c7eed40751d752002ca30943e4c --- /dev/null +++ b/irdb-lib/libStructDiv/src/structured_diversity.cpp @@ -0,0 +1,67 @@ + + +#include <string> +#include <sstream> +#include <iostream> +#include <stdlib.h> +#include <assert.h> + +#include <libStructDiv.h> +#include <filebased.h> + + +using namespace std; +using namespace libStructDiv; + +static string get_next_field(string& input, string delim, bool& success) +{ + success=false; + + size_t pos=input.find(delim, 0); + + if(pos==string::npos) + return string(); // report failure. + + string rest=input.substr(pos+delim.length()); + string beginning=input.substr(0,pos); + + + input=rest; // set output parameter. + success=true; // report success. + return beginning; // return the field we parsed out. +} + + +StructuredDiversity_t* StructuredDiversity_t::factory(string key, string p_ipc_config) +{ + string parse_string=p_ipc_config; + bool success=true; + string var_id=get_next_field(parse_string,":", success); + if(!success) { cout<<"cannot parse variant id from "<<p_ipc_config<<". Expected format: var_id:tot_vars:url"<<endl;exit(1);} + string tot_vars=get_next_field(parse_string,":", success); + if(!success) { cout<<"cannot parse total # of variants from "<<p_ipc_config<<". Expected format: var_id:tot_vars:url"<<endl;exit(1);} + string protocol_type=get_next_field(parse_string,"://", success); + if(!success) { cout<<"cannot protocol from "<<p_ipc_config<<". Expected format: var_id:tot_vars:protocol://path"<<endl;exit(1);} + string config=parse_string; + + + cout<<"Varid: "<<var_id<<endl; + cout<<"Total Variants: "<<tot_vars<<endl; + cout<<"Protocol Type: '"<<protocol_type<<"'"<<endl; + cout<<"config: "<<config<<endl; + + if(protocol_type=="dir") + { + return new FileBased_StructuredDiversity_t(key, strtoul(var_id.c_str(),0,0), strtoul(tot_vars.c_str(),0,0), config); + } + else + { + cerr<<"Cannot parse '"<<protocol_type<<"' k into a protocol name."<<endl; + exit(1); + } + + + + +} + diff --git a/irdb-lib/libStructDiv/test/SConscript b/irdb-lib/libStructDiv/test/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..bb0d3ecc9d7f465928e0125101d5e792f9ec5279 --- /dev/null +++ b/irdb-lib/libStructDiv/test/SConscript @@ -0,0 +1,33 @@ +import os + + +Import('env') +myenv=env.Clone() +myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) + +installed=[] +if 'build_tools' not in myenv or myenv['build_tools'] is None or int(myenv['build_tools']) == 1: + + cpppath=''' + $SECURITY_TRANSFORMS_HOME/libStructDiv/include + ''' + + LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" + LIBS=Split( "StructDiv" ) + + # add cpp path + myenv=myenv.Clone(CPPPATH=Split(cpppath)) + + + pgms="simple_sd_driver" + for i in Split(pgms): + print "building "+str(i) + pgm=myenv.Program(target=i+".exe", source=Split(i+".cpp"), LIBPATH=LIBPATH, LIBS=LIBS) + install=myenv.Install("$SECURITY_TRANSFORMS_HOME/libStructDiv/test/", pgm) + Default(install) + installed=installed+[install] + + + + +Return('installed') diff --git a/irdb-lib/libStructDiv/test/SConstruct b/irdb-lib/libStructDiv/test/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..c96332f0422ad5df0853931209219d9a2e20bc17 --- /dev/null +++ b/irdb-lib/libStructDiv/test/SConstruct @@ -0,0 +1,6 @@ + + + +env=Environment() +Export('env') +lib=SConscript("SConscript") diff --git a/irdb-lib/libStructDiv/test/simple_sd_driver.cpp b/irdb-lib/libStructDiv/test/simple_sd_driver.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2b9f3f4f8bed365b0fda70f53b80a9aeb54c211e --- /dev/null +++ b/irdb-lib/libStructDiv/test/simple_sd_driver.cpp @@ -0,0 +1,54 @@ + +#include <libStructDiv.h> + +#include <iostream> +#include <stdlib.h> +#include <libgen.h> + + +using namespace std; +using namespace libStructDiv; + + + +template<class t> void print_res(int round, StructuredDiversity_t* p, const vector<t> &res) +{ + for(int i=0;i<res.size();i++) + cout<<"round="<<round<<" myid="<<p->GetVariantID()<<":res["<<i<<"]="<<res[i]<<endl; +} + +int main(int argc, char* argv[]) +{ + if(argc!=2) + { + cerr<<"Usage: "<<argv[0]<<" varId:totVars:url"<<endl; + exit(1); + } + + StructuredDiversity_t* p=StructuredDiversity_t::factory(basename(argv[0]), argv[1]); + + int sign=1; + if(p->GetVariantID()==1) + sign=-sign; + + for(int i=1;i<10;i++) + { + + if( i&1 ) + { + const vector<double> &res=p->Barrier<double>((3.14+i)*sign); + print_res(i,p,res); + } + else + { + const vector<int> &res=p->Barrier<int>(i *sign ); + print_res(i,p,res); + } + + } + + + delete p; + + return 0; +} diff --git a/irdb-lib/manifest.txt b/irdb-lib/manifest.txt new file mode 100644 index 0000000000000000000000000000000000000000..e0a42281f4ea89962b20b74251e882ecfc31397d --- /dev/null +++ b/irdb-lib/manifest.txt @@ -0,0 +1,6 @@ + +directory plugins_install ps +directory lib ps +directory bin ps +directory lib ps + diff --git a/irdb-lib/meds2pdb/SConscript b/irdb-lib/meds2pdb/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..ca7f560339534ff8749ed39cf64c61fe4aa62cff --- /dev/null +++ b/irdb-lib/meds2pdb/SConscript @@ -0,0 +1,34 @@ +import os + + + +Import('env') +myenv=env.Clone() +myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) + +cpppath=''' + $IRDB_SDK/include + $SECURITY_TRANSFORMS_HOME/include + $SECURITY_TRANSFORMS_HOME/libIRDB-core/include + $SECURITY_TRANSFORMS_HOME/libEXEIO/include + $SECURITY_TRANSFORMS_HOME/libMEDSannotation/include + ''' + +files=Glob( Dir('.').srcnode().abspath+"/*.cpp") + Glob(Dir('.').srcnode().abspath+"/*.c") + + +pgm="meds2pdb" + +myenv.Append(CXXFLAGS = " -std=c++11 ") +LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" +LIBS=Split(" irdb-cfg irdb-util irdb-transform EXEIO MEDSannotation "+env.subst('$BASE_IRDB_LIBS')) +myenv=myenv.Clone(CPPPATH=Split(cpppath)) +pgm=myenv.Program(pgm, files, LIBPATH=LIBPATH, LIBS=LIBS) +install1=myenv.Install("$SECURITY_TRANSFORMS_HOME/bin/", pgm) +install2=myenv.Install("$SECURITY_TRANSFORMS_HOME/tools/meds2pdb/", pgm) + +Default(install1) +Default(install2) + +install=[]+install1+install2 +Return('install') diff --git a/irdb-lib/meds2pdb/SConstruct b/irdb-lib/meds2pdb/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..17f632b8c29cd420163897b1eb044ca3486df362 --- /dev/null +++ b/irdb-lib/meds2pdb/SConstruct @@ -0,0 +1,7 @@ + + + +env=Environment() +Export('env') +install=SConscript("SConscript") +Return('install') diff --git a/irdb-lib/meds2pdb/aspri.h b/irdb-lib/meds2pdb/aspri.h new file mode 100644 index 0000000000000000000000000000000000000000..0da73ac38278996f05b96385b1601619145e8327 --- /dev/null +++ b/irdb-lib/meds2pdb/aspri.h @@ -0,0 +1,41 @@ +/* + * aspri.h - main SPRI header file + * + * Copyright (c) 2000, 2001, 2010, 2011 - Zephyr Software + * + * This file is part of the Strata dynamic code modification infrastructure. + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +/* + * aspri.h + * author: Jason Hiser, Anh Nguyen-Tuong + */ + +#ifndef aspri_h +#define aspri_h + +typedef struct aspri_address aspri_address_t; +struct aspri_address +{ + char *library_name; + VirtualOffset_t offset; + bool isCurrentPC; +}; + +#endif diff --git a/irdb-lib/meds2pdb/bitvector.cpp b/irdb-lib/meds2pdb/bitvector.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e3c627724516c9570e1b49a364595222cbac4fe8 --- /dev/null +++ b/irdb-lib/meds2pdb/bitvector.cpp @@ -0,0 +1,151 @@ +/* + * bitvector.c - bit vector routines. + * + * Copyright (c) 2000, 2001, 2010 - University of Virginia + * + * This file is part of the Memory Error Detection System (MEDS) infrastructure. + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +/* bitvector.c + * + * Author: mc2zk + * Description: bit vector implementation using chars + */ + + +#include "meds_all.h" + + +/* + * allocate memory for the bitvector given number of + * bit fields, number of data chunks + */ +bitvector_t * allocate_bitvector(int num_fields, int num_data_chunks) +{ + /* round number of bits up to 8 then convert to bytes */ + int num_bytes_to_allocate=(((num_fields*num_data_chunks) + 7) &~7)/8; + + bitvector_t * the_bitvector = (bitvector_t*)spri_allocate_type(sizeof(bitvector_t)); + /* allocate the_bits + * the number of bits needed is num_fields * num_data_chunks + * rounded to nearest 8 (num bits in a char) + * to get bytes, need to divide by 8 bits + */ + the_bitvector->the_bits = (char*)spri_allocate_type(num_bytes_to_allocate*sizeof(char)); + the_bitvector->size = num_fields*num_data_chunks; + the_bitvector->num_bytes = num_bytes_to_allocate; + + return the_bitvector; +} + +/* reclaim the allocated memory */ +void free_bitvector(bitvector_t *the_bitvector_to_be_freed) +{ +#ifndef NDEBUG +// STRATA_LOG("profile_fields_allocate","bitvector address: 0x%x size: %d\n", the_bitvector_to_be_freed, the_bitvector_to_be_freed->size); +#endif + /* first free the_bits vector */ + spri_deallocate_type((void *)the_bitvector_to_be_freed->the_bits, ((the_bitvector_to_be_freed->size+7)&~7)/8); + + /* then free the bitvector_t memory */ + spri_deallocate_type((void *)the_bitvector_to_be_freed, sizeof(bitvector_t)); + +} + +/* set the bit to 1 */ +void set_bitvector(bitvector_t *the_vector, int the_bit_to_set){ + + /* check to make sure that the bounds are not being exceeded */ + if(the_vector &&(the_bit_to_set >= the_vector->size)) + { + /* don't set the bit if out of bounds */ + return; + } + the_vector->the_bits[the_bit_to_set >> 3] |= 1 << (the_bit_to_set & 7); +} + +/* clear the bit */ +void clear_bit(bitvector_t *the_vector, int the_bit_to_clear){ + the_vector->the_bits[the_bit_to_clear >> 3] &= ~(1 << (the_bit_to_clear & 7)); +} + + +/* get a bit from the bit vector: returns 1 if bit is 1, 0 if bit is 0 */ +char get_bit(bitvector_t *the_vector, int the_bit){ + return (the_vector->the_bits[the_bit >> 3] & (1 << (the_bit & 7))) !=0; + +} + +/* function to print the bit vector in hexadecimal */ +void print_bitvector_hex(FILE * fout, bitvector_t *the_vector) +{ + int i=0; + int num_elems_in_bytes=the_vector->num_bytes; + + /* how many elements should be in the int array? */ + int num_elems_in_int=(num_elems_in_bytes+3)/4 /* bytes per int */; + + /* print out the number of elements in the integer array */ + fprintf(fout, "%d %d ", the_vector->size, num_elems_in_int); + + /* convert to int array */ + /* iterate through bitvector and populate intArray */ + for(i=0; i<num_elems_in_bytes; i+=sizeof(int)) + { + fprintf(fout, "%x ", *(int*)(&the_vector->the_bits[i])); + } + + fprintf(fout, "\n"); +} + +/* print/dump the bit vector in binary */ +void print_bitvector_binary(FILE * fout, bitvector_t *the_vector) +{ + fprintf(fout, "%d ", the_vector->size /* size in bits */); + + /* print out the bits */ + fwrite(the_vector->the_bits, sizeof(char), the_vector->num_bytes, fout); + + fprintf(fout, "\n"); +} + +/* print/dump the bit vector one bit at a time for debug purposes */ +void print_bitvector_bits(FILE * fout, bitvector_t *the_vector) +{ + int i=0; + fprintf(fout, "size in bits: %d \n", the_vector->size /* size in bits */); + + /* print out the bits */ + for(i=0; i < the_vector->size; i++) + { + fprintf(fout, "%d ", get_bit(the_vector, i) ); + } + + fprintf(fout, "\n"); +} + + +/* find_bit_number(): Calculate the bit number in the vector to find */ +int find_bit_number(int num_fields, int which_data_chunk, int which_field_to_get +) +{ + int the_bit_number=(which_data_chunk*num_fields)+which_field_to_get; + + return the_bit_number; +} + diff --git a/irdb-lib/meds2pdb/bitvector.h b/irdb-lib/meds2pdb/bitvector.h new file mode 100644 index 0000000000000000000000000000000000000000..56ad45e37e1fed077c798524751070b8db3a479e --- /dev/null +++ b/irdb-lib/meds2pdb/bitvector.h @@ -0,0 +1,72 @@ +/* + * bitvector.h - bit vector headers. + * + * Copyright (c) 2000, 2001, 2010 - University of Virginia + * + * This file is part of the Memory Error Detection System (MEDS) infrastructure. + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +/* bitvector.h + * + * Author: mc2zk + * Description: bit vector implementation using chars + */ + +#ifndef bitvector_h +#define bitvector_h + +struct bitvector +{ + char * the_bits; + int size; /* size of the bit vector - number of bits represented */ + int num_bytes; +}; +typedef struct bitvector bitvector_t; + + +/* + * allocate memory for the bitvector given number of + * bit fields, number of data chunks + */ +bitvector_t * allocate_bitvector(int num_fields, int num_data_chunks); + +/* reclaim the allocated memory */ +void free_bitvector(bitvector_t *the_bitvector_to_be_freed); + +/* set the bit to 1 */ +void set_bitvector(bitvector_t *the_vector, int the_bit_to_set); + +/* clear the bit */ +void clear_bit(bitvector_t *the_vector, int the_bit_to_clear); + +/* get a bit from the bit vector */ +char get_bit(bitvector_t *the_vector, int the_bit); + +/* print/dump the bit vector: hexadecimal format */ +void print_bitvector_hex(FILE *fout, bitvector_t *the_vector); + +/* print/dump the bit vector: binary format */ +void print_bitvector_binary(FILE *fout, bitvector_t *the_vector); + +/* print the bit vector one bit at a time */ +void print_bitvector_bits(FILE *fout, bitvector_t *the_vector); + +/* find_bit_number(): Calculate the bit number in the vector to find */ +int find_bit_number(int num_fields, int which_data_chunk, int which_field_to_get); + +#endif diff --git a/irdb-lib/meds2pdb/constant_hash.cpp b/irdb-lib/meds2pdb/constant_hash.cpp new file mode 100644 index 0000000000000000000000000000000000000000..368ccbeb3da3e624c8d42b24081d6c17f2f2f5b6 --- /dev/null +++ b/irdb-lib/meds2pdb/constant_hash.cpp @@ -0,0 +1,90 @@ +/* + * constant_hash.c - hashtable for contants. + * + * Copyright (c) 2000, 2001, 2010 - University of Virginia + * + * This file is part of the Memory Error Detection System (MEDS) infrastructure. + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#include "meds_all.h" + +Hashtable *constants_hash=NULL; + +long constants_compute_hash(void* key1) +{ + constant_hash_key_t * a_key=(constant_hash_key_t *)key1; + + return a_key->pc ^ a_key->the_const ^ (a_key->field << 4); +} + +long constants_key_compare(void* key1, void* key2) +{ + constant_hash_key_t * a_key=(constant_hash_key_t *)key1; + constant_hash_key_t * b_key=(constant_hash_key_t *)key2; + + if(a_key->pc == b_key->pc) + { + if(a_key->field==b_key->field) + return a_key->the_const == b_key->the_const; + else + return a_key->field == b_key->field; + } + return a_key->pc == b_key->pc; +} + + +constant_hash_value_t * add_constant_ref(VirtualOffset_t pc,int the_const, constant_hash_field_t the_field, constant_hash_type_t the_type) +{ + constant_hash_key_t *chk=(constant_hash_key_t*)spri_allocate_type(sizeof(constant_hash_key_t )); + constant_hash_value_t *chv=(constant_hash_value_t*)spri_allocate_type(sizeof(constant_hash_value_t )); + /* set the key */ + chk->pc=pc; + chk->the_const=the_const; + chk->field=the_field; + /* set the data */ + chv->type=the_type; + + Hashtable_put(constants_hash, chk, chv); + return chv; + +} + +constant_hash_value_t * get_constant_ref(VirtualOffset_t pc, int the_const, constant_hash_field_t the_field) +{ + constant_hash_key_t chk={pc, the_const, the_field}; + constant_hash_value_t *chv=(constant_hash_value_t*)Hashtable_get(constants_hash, &chk); + + return chv ? chv : 0; + +} + + +const char* constant_hash_type_to_string(constant_hash_type_t type) +{ + switch(type) + { + case cht_ESP: return "PTRIMMEDESP2 STACK"; + case cht_EBP: return "PTRIMMEDEBP2 STACK"; + case cht_GLOBAL: return "PTRIMMEDABSOLUTE GLOBAL"; + case cht_NUMBER: return "NUMIMMED GLOBAL"; + case cht_UNKNOWN: return "UNKNOWNIMMED GLOBAL"; + default: + assert(0); + } +} + diff --git a/irdb-lib/meds2pdb/constant_hash.h b/irdb-lib/meds2pdb/constant_hash.h new file mode 100644 index 0000000000000000000000000000000000000000..2159265286a583ab50e80984b3d908189489bb3a --- /dev/null +++ b/irdb-lib/meds2pdb/constant_hash.h @@ -0,0 +1,58 @@ +/* + * constant_hash.h - hashtable for contants. + * + * Copyright (c) 2000, 2001, 2010 - University of Virginia + * + * This file is part of the Memory Error Detection System (MEDS) infrastructure. + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#ifndef constant_hash_h +#define constant_hash_h + + +enum constant_hash_type { cht_ESP, cht_EBP, cht_GLOBAL, cht_NUMBER, cht_UNKNOWN }; +typedef enum constant_hash_type constant_hash_type_t; +enum constant_hash_field {chf_DISPLACEMENT='d', chf_IMMEDIATE='i', chf_SCALE='s', chf_IMPLICIT='m', chf_OTHER='o'}; +typedef enum constant_hash_field constant_hash_field_t; + +extern Hashtable *constants_hash; +struct constant_hash_key +{ + VirtualOffset_t pc; + int the_const; + constant_hash_field_t field; +}; +typedef struct constant_hash_key constant_hash_key_t; +struct constant_hash_value +{ + constant_hash_type_t type; + int real_const; +}; +typedef struct constant_hash_value constant_hash_value_t; + +long constants_compute_hash(void* key1); + +long constants_key_compare(void* key1, void* key2); + +constant_hash_value_t * add_constant_ref(VirtualOffset_t pc,int the_const, constant_hash_field_t the_field, constant_hash_type_t the_type); + +constant_hash_value_t * get_constant_ref(VirtualOffset_t pc, int the_const, constant_hash_field_t the_field); + +const char* constant_hash_type_to_string(constant_hash_type_t type); + +#endif diff --git a/irdb-lib/meds2pdb/elfreader.cpp b/irdb-lib/meds2pdb/elfreader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..51f10cecea32d236fba283975abc44cf1b47f029 --- /dev/null +++ b/irdb-lib/meds2pdb/elfreader.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2014, 2015 - University of Virginia + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#include <iostream> +#include <string.h> +#include <stdio.h> +#include <irdb-core> +#include <libIRDB-core.hpp> +#include "elfreader.h" + +using namespace std; +using namespace IRDB_SDK; +using namespace EXEIO; + +ElfReader::ElfReader(char *p_elfFile) +{ +// m_reader=new elfio; + m_reader=new EXEIO::exeio(p_elfFile); + assert(m_reader); + + EXEIO::dump::header(cout, *m_reader); + EXEIO::dump::section_headers(cout, *m_reader); + + // Initialize it +/* + bool ok = m_reader->load( p_elfFile ); + if ( ! ok ) { + std::cerr << "Can't open file:" << p_elfFile << std::endl; + assert(0); + exit(-1); + } + + + if(m_reader->get_class() == ELFCLASS32) + std::cout << "Input file is ELF32" << std::endl; + else + std::cout << "Input file is ELF64" << std::endl; + + + // List all sections of the file + int i; + ELFIO::Elf_Half nSecNo = m_reader->sections.size(); + for ( i = 0; i < nSecNo; ++i ) + { // For all sections + section* psec = m_reader->sections[i]; + m_sections.push_back(psec); + std::cout << " [" << i << "] " + << psec->get_name() + << "\t" + << psec->get_size() + << std::endl; + + } + std::cout << std::endl; +*/ +} + +ElfReader::~ElfReader() +{ + delete m_reader; +} + +/* +* Read <p_numBytes> from ELF file for location <p_pc> +*/ +string ElfReader::read(VirtualOffset_t p_pc, unsigned p_numBytes) const +{ + for ( int i = 0; i < m_reader->sections.size(); ++i ) + { + section* pSec = m_reader->sections[i]; + if (pSec->get_address() + pSec->get_size() < 1) continue; + if (p_pc >= pSec->get_address() && p_pc <= (pSec->get_address() + pSec->get_size() - 1)) + { + // found the section, now read off the data + long offset = p_pc - pSec->get_address(); + + // caution! This may result in an overflow of the section and fault if called with p_numBytes too big. + return string(pSec->get_data() + offset, p_numBytes); + } + } + return string(); +} + +/* +* Read <p_numBytes> from ELF file for location <p_pc> +* No bounds checking is done on <p_buf> +* Return false if address not in valid sections +*/ +bool ElfReader::read(VirtualOffset_t p_pc, unsigned p_numBytes, char* p_buf) const +{ + for ( int i = 0; i < m_reader->sections.size(); ++i ) + { + section* pSec = m_reader->sections[ i ]; + + if (pSec->get_address() + pSec->get_size() < 1) continue; + if (p_pc >= pSec->get_address() && p_pc <= (pSec->get_address() + pSec->get_size() - 1)) + { + // found the section, now read off the data + long offset = p_pc - pSec->get_address(); + memcpy(p_buf, pSec->get_data() + offset, p_numBytes); + return true; + } + } + return false; +} + +/* +* Return buffer for instruction off the ELF file +*/ +const char* ElfReader::getInstructionBuffer(VirtualOffset_t p_pc) const +{ + for ( int i = 0; i < m_reader->sections.size(); ++i ) + { + const section* pSec = m_reader->sections[ i ]; + + if (pSec->get_address() + pSec->get_size() < 1) continue; + if (p_pc >= pSec->get_address() && p_pc <= (pSec->get_address() + pSec->get_size() - 1)) + { + // found the section, now read off the data + long offset = p_pc - pSec->get_address(); + return (char*) (pSec->get_data() + offset); + } + } + return NULL; +} + +void ElfReader::SetArchitecture() +{ + const auto width = + (isElf32() || isPe32()) ? 32 : + (isElf64() || isPe64()) ? 64 : + throw std::invalid_argument("Unknown architecture."); + const auto mt = m_reader->getMachineType() == EXEIO::mtI386 ? IRDB_SDK::admtI386 : + m_reader->getMachineType() == EXEIO::mtX86_64 ? IRDB_SDK::admtX86_64 : + m_reader->getMachineType() == EXEIO::mtAarch64 ? IRDB_SDK::admtAarch64 : + throw std::invalid_argument("Unknown architecture."); + + libIRDB::FileIR_t::setArchitecture(width,mt); +} + diff --git a/irdb-lib/meds2pdb/elfreader.h b/irdb-lib/meds2pdb/elfreader.h new file mode 100644 index 0000000000000000000000000000000000000000..87b4ac4a71b303008e96b265d1885f5828c49804 --- /dev/null +++ b/irdb-lib/meds2pdb/elfreader.h @@ -0,0 +1,38 @@ +#ifndef _elfreader_H_ +#define _elfreader_H_ + +#include <vector> +#include "exeio.h" +#include <irdb-core> +#include <assert.h> +#include <exception> +#include <irdb-core> + + +// doing this is very bad. +// using namespace std; +// using namespace ELFIO; + +class ElfReader +{ + public: + + ElfReader(char *); + virtual ~ElfReader(); + + std::string read(IRDB_SDK::VirtualOffset_t p_pc, unsigned p_numBytes) const ; + bool read(IRDB_SDK::VirtualOffset_t p_pc, unsigned p_numBytes, char* p_buf) const ; + const char* getInstructionBuffer(IRDB_SDK::VirtualOffset_t p_pc) const ; + + bool isElf32() const { assert(m_reader); return m_reader->get_class()==EXEIO::ELF32; } + bool isElf64() const { assert(m_reader); return m_reader->get_class()==EXEIO::ELF64; } + bool isPe32() const { assert(m_reader); return m_reader->get_class()==EXEIO::PE32; } + bool isPe64() const { assert(m_reader); return m_reader->get_class()==EXEIO::PE64; } + void SetArchitecture() ; + + private: + EXEIO::exeio* m_reader; + +}; + +#endif diff --git a/irdb-lib/meds2pdb/framerestore_hash.cpp b/irdb-lib/meds2pdb/framerestore_hash.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d7c2d400fda6c41c9a0d98b81706bcb22c7a1230 --- /dev/null +++ b/irdb-lib/meds2pdb/framerestore_hash.cpp @@ -0,0 +1,142 @@ +/* + * framerestore_hash.c - how to unwind frames. + * + * Copyright (c) 2000, 2001, 2010 - University of Virginia + * + * This file is part of the Memory Error Detection System (MEDS) infrastructure. + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#include <string.h> +#include "framerestore_hash.h" + +Hashtable *framerestores_hash=NULL; + +long framerestores_compute_hash(void* key1) +{ + framerestore_hash_key_t * a_key=(framerestore_hash_key_t *)key1; + + return a_key->pc; +} + +long framerestores_key_compare(void* key1, void* key2) +{ + framerestore_hash_key_t * a_key=(framerestore_hash_key_t *)key1; + framerestore_hash_key_t * b_key=(framerestore_hash_key_t *)key2; + + return a_key->pc == b_key->pc; +} + + +/* + * frame_restore_set_return_address - set the offset of the return address for this frame + */ +void frame_restore_set_return_address(VirtualOffset_t pc, int offset) +{ + instrmap_hash_value_t *imhv=(instrmap_hash_value_t*)Hashtable_get(instrmaps_hash,&pc); + + if(!imhv) + return; + + framerestore_hash_value_t *frhv=(framerestore_hash_value_t*)Hashtable_get(framerestores_hash,&imhv->func_addr); + + if(!frhv) + { + framerestore_hash_key_t * frhk=(framerestore_hash_key_t*)spri_allocate_type(sizeof(framerestore_hash_key_t)); + frhv=(framerestore_hash_value_t*)spri_allocate_type(sizeof(framerestore_hash_value_t)); + assert(frhv); + memset(frhv,0, sizeof(*frhv)); + + + frhk->pc=imhv->func_addr; + + Hashtable_put(framerestores_hash, frhk, frhv); + } + + frhv->ret_offset=offset; +} + + + +/* + * frame_restore_hash_add_reg_restore - add info to the frame restore hash about the type and offset of saved registers + */ +void frame_restore_hash_add_reg_restore(VirtualOffset_t addr, int reg_num, int reg_offset, int reg_type) +{ + + framerestore_hash_value_t *frhv=(framerestore_hash_value_t*) Hashtable_get(framerestores_hash,&addr); + + if(!frhv) + { + framerestore_hash_key_t * frhk=(framerestore_hash_key_t*)spri_allocate_type(sizeof(framerestore_hash_key_t)); + frhv=(framerestore_hash_value_t*)spri_allocate_type(sizeof(framerestore_hash_value_t)); + + assert(frhv); + memset(frhv,0, sizeof(*frhv)); + + + frhk->pc=addr; + + Hashtable_put(framerestores_hash, frhk, frhv); + } + + frhv->reg_offsets[reg_num]=reg_offset; + frhv->reg_types[reg_num]=reg_type; + + assert(reg_num>=0 && reg_num<=15); + assert(reg_type>=0 && reg_type<=255); + assert(reg_offset<=0); + +} + + +void frame_restore_hash_set_safe_bit(VirtualOffset_t addr, int is_safe) +{ + + framerestore_hash_value_t *frhv=(framerestore_hash_value_t*)Hashtable_get(framerestores_hash,&addr); + + if(!frhv) + { + framerestore_hash_key_t * frhk=(framerestore_hash_key_t*)spri_allocate_type(sizeof(framerestore_hash_key_t)); + frhv=(framerestore_hash_value_t*)spri_allocate_type(sizeof(framerestore_hash_value_t)); + + assert(frhv); + memset(frhv,0, sizeof(*frhv)); + + + frhk->pc=addr; + + Hashtable_put(framerestores_hash, frhk, frhv); + } + + frhv->static_analyzer_believes_safe=is_safe; +} + +int is_safe_function(VirtualOffset_t pc) +{ + instrmap_hash_value_t *imhv=(instrmap_hash_value_t*)Hashtable_get(instrmaps_hash,&pc); + + if(!imhv) + return FALSE; + + framerestore_hash_value_t *frhv=(framerestore_hash_value_t*)Hashtable_get(framerestores_hash,&imhv->func_addr); + + if(!frhv) + return FALSE; + + return frhv->static_analyzer_believes_safe; +} diff --git a/irdb-lib/meds2pdb/framerestore_hash.h b/irdb-lib/meds2pdb/framerestore_hash.h new file mode 100644 index 0000000000000000000000000000000000000000..df466ba832ce3990f077e541ef9897650ffbd4ec --- /dev/null +++ b/irdb-lib/meds2pdb/framerestore_hash.h @@ -0,0 +1,61 @@ +/* + * framerestore_hash.h - how to unwind frames. + * + * Copyright (c) 2000, 2001, 2010 - University of Virginia + * + * This file is part of the Memory Error Detection System (MEDS) infrastructure. + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#ifndef framerestore_hash_h +#define framerestore_hash_h + +#include "meds_all.h" + + +extern Hashtable *framerestores_hash; +struct framerestore_hash_key +{ + int pc; // function address +}; +typedef struct framerestore_hash_key framerestore_hash_key_t; + +struct framerestore_hash_value +{ + int reg_offsets[16]; /* index by MD_REG_*, 0=do not restore, else add offset to ret_addr offset */ + int reg_types[16]; /* index by MD_REG_*, return type of each register */ + + int ret_offset; + + int static_analyzer_believes_safe; +}; + +typedef struct framerestore_hash_value framerestore_hash_value_t; + +long framerestores_compute_hash(void* key1); + +long framerestores_key_compare(void* key1, void* key2); + +void frame_restore_hash_add_reg_restore(VirtualOffset_t addr, int reg_num, int reg_offset, int reg_type); + +void frame_restore_hash_set_safe_bit(VirtualOffset_t addr, int is_safe); + +void frame_restore_hash_set_frame_size(VirtualOffset_t addr, int is_safe); +void frame_restore_set_return_address(VirtualOffset_t pc, int offset); + + +#endif diff --git a/irdb-lib/meds2pdb/framesize_hash.cpp b/irdb-lib/meds2pdb/framesize_hash.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e6f3a8de4c64fdf4bdcdaabe32cb9502f1286f5a --- /dev/null +++ b/irdb-lib/meds2pdb/framesize_hash.cpp @@ -0,0 +1,61 @@ +#include "framesize_hash.h" + +Hashtable *framesizes_hash=NULL; + +long framesizes_compute_hash(void* key1) +{ + framesize_hash_key_t * a_key=(framesize_hash_key_t *)key1; + + return a_key->pc; +} + +long framesizes_key_compare(void* key1, void* key2) +{ + framesize_hash_key_t * a_key=(framesize_hash_key_t *)key1; + framesize_hash_key_t * b_key=(framesize_hash_key_t *)key2; + + return a_key->pc == b_key->pc; +} + +void set_frame_size(int pc, int frame_size) +{ + framesize_hash_key_t fshk={pc}; + framesize_hash_value_t *fshv=(framesize_hash_value_t*)Hashtable_get(framesizes_hash, &fshk); + + if(fshv) + { + if(fshv->frame_size != frame_size) + { + fshv->var_sized=TRUE; + } + return; + } + + framesize_hash_key_t *fshk2=(framesize_hash_key_t*)spri_allocate_type(sizeof(*fshk2)); + framesize_hash_value_t *fshv2=(framesize_hash_value_t*)spri_allocate_type(sizeof(*fshv2)); + + *fshk2=fshk; + fshv2->frame_size=frame_size; + fshv2->var_sized=FALSE; + + Hashtable_put(framesizes_hash, fshk2, fshv2); + +} + + +int is_var_sized_frame(int pc) +{ + framesize_hash_key_t fshk={pc}; + framesize_hash_value_t *fshv=(framesize_hash_value_t*)Hashtable_get(framesizes_hash, &fshk); + + if(fshv) + { + return fshv->var_sized; + } + + /* if we didn't find it, it's not var-sized yet */ + return FALSE; +} + + + diff --git a/irdb-lib/meds2pdb/framesize_hash.h b/irdb-lib/meds2pdb/framesize_hash.h new file mode 100644 index 0000000000000000000000000000000000000000..a379e485217426b6ed8c38c6a578fc8d6fec67ac --- /dev/null +++ b/irdb-lib/meds2pdb/framesize_hash.h @@ -0,0 +1,29 @@ +#ifndef framesize_hash_h +#define framesize_hash_h + +#include "meds_all.h" + + +extern Hashtable *framesizes_hash; +struct framesize_hash_key +{ + int pc; +}; +typedef struct framesize_hash_key framesize_hash_key_t; + +struct framesize_hash_value +{ + int frame_size; + int var_sized; +}; +typedef struct framesize_hash_value framesize_hash_value_t; + +long framesizes_compute_hash(void* key1); + +long framesizes_key_compare(void* key1, void* key2); + +void set_frame_size(int pc, int frame_size); +int is_var_sized_frame(int pc); + + +#endif diff --git a/irdb-lib/meds2pdb/funclist_hash.cpp b/irdb-lib/meds2pdb/funclist_hash.cpp new file mode 100644 index 0000000000000000000000000000000000000000..00db7aa1c0b3e6bc9494c0c47db41a46365fa0d1 --- /dev/null +++ b/irdb-lib/meds2pdb/funclist_hash.cpp @@ -0,0 +1,51 @@ +/* + * funclist_hash.c - list of functions hashtable. + * + * Copyright (c) 2000, 2001, 2010 - University of Virginia + * + * This file is part of the Memory Error Detection System (MEDS) infrastructure. + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#include <string.h> +#include "funclist_hash.h" + +Hashtable *funclists_hash=NULL; + +long funclists_compute_hash(void* key1) +{ + funclist_hash_key_t * a_key=(funclist_hash_key_t *)key1; + char *s =a_key->name; + + int h = 0; + while (*s) + { + h = 31*h + *s; + s++; + } + return h; +} + +long funclists_key_compare(void* key1, void* key2) +{ + funclist_hash_key_t * a_key=(funclist_hash_key_t *)key1; + funclist_hash_key_t * b_key=(funclist_hash_key_t *)key2; + + return !strcmp(a_key->name, b_key->name); +} + + diff --git a/irdb-lib/meds2pdb/funclist_hash.h b/irdb-lib/meds2pdb/funclist_hash.h new file mode 100644 index 0000000000000000000000000000000000000000..7e3f618e398120c2850bb46be237d09c74f65baa --- /dev/null +++ b/irdb-lib/meds2pdb/funclist_hash.h @@ -0,0 +1,48 @@ +/* + * funclist_hash.h - list of functions hashtable. + * + * Copyright (c) 2000, 2001, 2010 - University of Virginia + * + * This file is part of the Memory Error Detection System (MEDS) infrastructure. + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#ifndef funclist_hash_h +#define funclist_hash_h + +#include "meds_all.h" + + +extern Hashtable *funclists_hash; +struct funclist_hash_key +{ + char* name; + +}; +typedef struct funclist_hash_key funclist_hash_key_t; + +struct funclist_hash_value +{ + int pc; +}; +typedef struct funclist_hash_value funclist_hash_value_t; + +long funclists_compute_hash(void* key1); + +long funclists_key_compare(void* key1, void* key2); + +#endif diff --git a/irdb-lib/meds2pdb/function_descriptor.cpp b/irdb-lib/meds2pdb/function_descriptor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e81dd459c053143cb97465f05c4595cc3dd6f6c1 --- /dev/null +++ b/irdb-lib/meds2pdb/function_descriptor.cpp @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2014, 2015 - University of Virginia + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#include <string> +#include <cstdio> + +#include "function_descriptor.h" +using namespace IRDB_SDK; + +void wahoo::Function::_init() +{ + m_name = ""; + m_address = -1; + m_size = -1; + m_frameSize = 0; + m_isSafe = false; + m_useFP = false; + m_outArgsRegionSize = 0; + m_functionID = -1; +} + +wahoo::Function::Function() +{ + _init(); +} + +wahoo::Function::Function(VirtualOffset_t p_start) +{ + _init(); + setAddress(p_start); +} + +wahoo::Function::Function(string p_name, VirtualOffset_t p_start, int p_size) +{ + _init(); + setName(p_name); + setAddress(p_start); + setSize(p_size); +} + +wahoo::Function::~Function() +{ +} + +bool wahoo::Function::operator == (const Function &other) +{ + return (other.m_name == this->m_name && other.m_address == this->m_address); +} + +bool wahoo::Function::operator == (const VirtualOffset_t p_addr) +{ + return (this->m_address == p_addr); +} + +bool wahoo::Function::operator != (const Function &other) +{ + return (other.m_name != this->m_name || other.m_address != this->m_address); +} + +bool wahoo::Function::operator != (const VirtualOffset_t p_addr) +{ + return (this->m_address != p_addr); +} + +void wahoo::Function::addInstruction(wahoo::Instruction* p_instr) +{ + m_allInstructions.push_back(p_instr); +} + +void wahoo::Function::addStackAllocationInstruction(wahoo::Instruction* p_instr) +{ + m_stackAllocInstructions.push_back(p_instr); +} + +void wahoo::Function::addStackDeallocationInstruction(wahoo::Instruction* p_instr) +{ + m_stackDeallocInstructions.push_back(p_instr); +} + +void wahoo::Function::addStackReferenceInstruction(wahoo::Instruction* p_instr) +{ + m_stackRefsInstructions.push_back(p_instr); +} + +vector<wahoo::Instruction*> wahoo::Function::getInstructions() +{ + return m_allInstructions; +} + +vector<wahoo::Instruction*> wahoo::Function::getStackAllocationInstructions() +{ + return m_stackAllocInstructions; +} + +vector<wahoo::Instruction*> wahoo::Function::getStackDeallocationInstructions() +{ + return m_stackDeallocInstructions; +} + +vector<wahoo::Instruction*> wahoo::Function::getStackReferencesInstructions() +{ + return m_stackRefsInstructions; +} + +double wahoo::Function::getInstructionCoverage(int *p_count, int *p_total) +{ + unsigned count = 0; + if (m_allInstructions.size() == 0) + return 0.0; + for (auto i = 0U; i < m_allInstructions.size(); ++i) + { + if (m_allInstructions[i]->isVisited()) + count++; + } + + *p_count = count; + *p_total = m_allInstructions.size(); + return (double) count / (double) m_allInstructions.size(); +} + +double wahoo::Function::getInstructionCoverage() +{ + int count, total; + return getInstructionCoverage(&count, &total); +} diff --git a/irdb-lib/meds2pdb/function_descriptor.h b/irdb-lib/meds2pdb/function_descriptor.h new file mode 100644 index 0000000000000000000000000000000000000000..502c175e6c7ebc4898260b25c4adc6b99ec257ce --- /dev/null +++ b/irdb-lib/meds2pdb/function_descriptor.h @@ -0,0 +1,86 @@ +#include <string> +#include <vector> +#include <string> + +#include <irdb-core> +#include <irdb-core> +#include "instruction_descriptor.h" + +//class wahoo::Instruction; + +using namespace std; + +namespace wahoo { + +class Function +{ + public: + Function(); + Function(IRDB_SDK::VirtualOffset_t); + Function(string, IRDB_SDK::VirtualOffset_t, int); + ~Function(); + + string getName() const { return m_name; } + void setName(const string p_name) { m_name = p_name; } + IRDB_SDK::VirtualOffset_t getAddress() const { return m_address; } + void setAddress(const IRDB_SDK::VirtualOffset_t p_address) { m_address = p_address; } + int getSize() const { return m_size; } + void setSize(const int p_size) { m_size = p_size; } + int getFrameSize() const { return m_frameSize; } + void setFrameSize(const int p_size) { m_frameSize = p_size; } + int getFunctionID() const { return m_functionID; } + void setFunctionID(const int id) { m_functionID = id; } + + + bool operator == (const Function &); + bool operator == (const IRDB_SDK::VirtualOffset_t); + bool operator != (const Function &); + bool operator != (const IRDB_SDK::VirtualOffset_t); + + bool isSafe() const { return m_isSafe; } + void setSafe() { m_isSafe = true; } + void setUnsafe() { m_isSafe = false; } + + void setOutArgsRegionSize(const int p_size) { m_outArgsRegionSize = p_size; } + int getOutArgsRegionSize() const { return m_outArgsRegionSize; } + + void setUseFramePointer(const bool p_useFP) { m_useFP = p_useFP; } + bool getUseFramePointer() const { return m_useFP; } + + void addInstruction(wahoo::Instruction *); + void addStackAllocationInstruction(wahoo::Instruction *); + void addStackDeallocationInstruction(wahoo::Instruction *); + void addStackReferenceInstruction(wahoo::Instruction *); + void addRewriteRule(string p_rule) { m_rewrites.push_back(p_rule); } + + vector<wahoo::Instruction*> getInstructions(); + vector<wahoo::Instruction*> getStackAllocationInstructions(); + vector<wahoo::Instruction*> getStackDeallocationInstructions(); + vector<wahoo::Instruction*> getStackReferencesInstructions(); + + vector<string> getRewrites() { return m_rewrites; } + + double getInstructionCoverage(); + double getInstructionCoverage(int*, int*); + + private: + void _init(); + + int m_functionID; + string m_name; + IRDB_SDK::VirtualOffset_t m_address; + int m_size; + int m_frameSize; + bool m_isSafe; + bool m_useFP; + int m_outArgsRegionSize; + + vector<wahoo::Instruction*> m_allInstructions; + vector<wahoo::Instruction*> m_stackRefsInstructions; + vector<wahoo::Instruction*> m_stackAllocInstructions; + vector<wahoo::Instruction*> m_stackDeallocInstructions; + + vector<string> m_rewrites; // keep track of rewrite rules +}; + +} diff --git a/irdb-lib/meds2pdb/gen_hash.cpp b/irdb-lib/meds2pdb/gen_hash.cpp new file mode 100644 index 0000000000000000000000000000000000000000..358bc720969e11ff30bdc90e00b9399ac41c655b --- /dev/null +++ b/irdb-lib/meds2pdb/gen_hash.cpp @@ -0,0 +1,240 @@ +/* + * gen_hash.c - generic hash table code. + * + * Copyright (c) 2000, 2001, 2010 - University of Virginia + * + * This file is part of the Memory Error Detection System (MEDS) infrastructure. + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +/* + * gen_hash.c -- generic hashtable implmentation. + */ + + + +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include <string.h> +#include "gen_hash.h" +#include "spri_alloc.h" +#include <stdint.h> + +#define INITIAL_CAPACITY 128 + +#define HT_FREE(p,s) (spri_deallocate_type(p,s)) +#define HT_MALLOC(s) (spri_allocate_type(s)) +#define HT_CALLOC(n,s) (memset((void*)spri_allocate_type((n)*(s)),0,((n)*(s)))) + +#define TRUE 1 +#define FALSE 0 + + +Hashtable *Hashtable_create( long (*hash_func)(void* ), long (*key_compare)(void*, void*)) +{ + Hashtable *result = (Hashtable*)HT_MALLOC( sizeof(Hashtable) ); + result->table = (struct entry**)HT_CALLOC( INITIAL_CAPACITY, sizeof(struct entry*) ); + result->hash_func=hash_func; + result->key_compare=key_compare; + result->tableLength = INITIAL_CAPACITY; + + result->count = 0; + result->threshold = (long)(INITIAL_CAPACITY * 3 / 4); /* integer calcs for 3/4ths full */ + + return result; +} + +void Hashtable_destroy( Hashtable **h ) +{ +assert(0); +#if 0 + long i; + for( i = (*h)->tableLength - 1; i >= 0; i-- ) + { + struct entry *e = (*h)->table[i]; + while( e != NULL ) + { + struct entry *deleteEntry = e; + e = e->next; + HT_FREE( deleteEntry, sizeof(struct entry*) ); + } + } + HT_FREE( (*h)->table, h->tableLength*sizeof(struct entry*) ); + HT_FREE( *h, sizeof(Hashtable) ); + *h = NULL; +#endif +} + +void Hashtable_rehash( Hashtable *h ) +{ + long i; + struct entry **oldTable = h->table; + long newCapacity = h->tableLength * 2; + struct entry **newTable = (struct entry**)HT_CALLOC( newCapacity, sizeof(struct entry*) ); + + h->threshold = (long)(newCapacity * 3 / 4); /* integer calcs for 3/4ths full */ + + for( i = h->tableLength - 1; i >= 0; i-- ) + { + struct entry *old; + for( old = oldTable[i]; old != NULL; ) + { + struct entry *e = old; + long index = h->hash_func(e->key) & (newCapacity - 1) ; + old = old->next; + + e->next = newTable[index]; + newTable[index] = e; + } + } + + HT_FREE( h->table, h->tableLength*sizeof(struct entry*) ); + h->table = newTable; + h->tableLength = newCapacity; +} + +void Hashtable_put( Hashtable *h, void *key, void *value ) +{ + struct entry *e; + // long hash = (long)key; + long index = h->hash_func(key) & (h->tableLength-1); + + // make sure the key isn't already present + for( e = h->table[index]; e != NULL; e = e->next ) + { + if( h->key_compare(e->key , key )) + { + e->value = value; + return; + } + } + + if( h->count >= h->threshold ) + { + Hashtable_rehash( h ); + Hashtable_put( h, key, value ); + } + else + { + e = (struct entry *)HT_MALLOC( sizeof(struct entry) ); + e->key = key; + e->value = value; + e->next = h->table[index]; + h->table[index] = e; + h->count++; + } +} + +void *Hashtable_get( const Hashtable *h, void *key ) +{ + struct entry *e; + long index = h->hash_func(key) & (h->tableLength-1); + + for( e = h->table[index]; e != NULL; e = e->next ) + { + if( h->key_compare(e->key , key )) + return e->value; + } + return NULL; +} + +long Hashtable_size( const Hashtable *h ) +{ + return h->count; +} + + + +int Hashtable_containsKey( const Hashtable *h, void *key ) +{ + return Hashtable_get( h, key ) == NULL ? FALSE : TRUE; +} + +/* + * Initialize iterator + */ +Hashtable_iterator Hashtable_setup_iterator( Hashtable *h ) +{ + Hashtable_iterator i; + i.ht = h; + i.idx = -1; + i.current = NULL; + return i; +} + +/* +* Returns next entry in hash table +*/ +struct entry* Hashtable_get_next(Hashtable_iterator &iterator) +{ + if (!iterator.ht) + { + fprintf(stderr,"Hashtable_get_next: cannot find the hash table\n"); + return NULL; + } + else if (iterator.ht->count <= 0) + { + fprintf(stderr,"Hashtable_get_next: the hashtable count is <= 0 0x%p\n", (void*)iterator.ht); + return NULL; + } + + if (iterator.idx < 0) + { + int i=0; + // first time, find the first real entry + for (i = 0; i < iterator.ht->tableLength; ++i) + { + if (iterator.ht->table[i] != NULL) + { + iterator.idx = i; + iterator.current = iterator.ht->table[i]; + return iterator.current; + } + } + fprintf(stderr,"Hashtable_get_next: no keys found in hash table\n"); + return NULL; // empty table, no keys found + } + else + { + if (iterator.current) + { + if (iterator.current->next) + { + iterator.current = iterator.current->next; + return iterator.current; + } + else + { + int i=0; + // get the next entry + for (i = iterator.idx + 1; i < iterator.ht->tableLength; ++i) + { + if (iterator.ht->table[i] != NULL) + { + iterator.idx = i; + iterator.current = iterator.ht->table[i]; + return iterator.current; + } + } + return NULL; // we're done + } + } + return NULL; // empty table, no keys found + } +} + diff --git a/irdb-lib/meds2pdb/gen_hash.h b/irdb-lib/meds2pdb/gen_hash.h new file mode 100644 index 0000000000000000000000000000000000000000..eb8670042b50f3944ab51420117ed4cd9774011a --- /dev/null +++ b/irdb-lib/meds2pdb/gen_hash.h @@ -0,0 +1,99 @@ +/* + * gen_hash.h - generic hash table code. + * + * Copyright (c) 2000, 2001, 2010 - University of Virginia + * + * This file is part of the Memory Error Detection System (MEDS) infrastructure. + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + + +// Hashtable.h + +#ifndef HASHTABLE_H +#define HASHTABLE_H + + +// opaque structure +typedef struct gen_hashtable Hashtable; + +struct entry +{ + void *key; + void *value; + struct entry *next; +}; + +struct gen_hashtable +{ + struct entry **table; + long tableLength; + long count; + long threshold; + long (*hash_func)(void*); + long (*key_compare)(void*, void*); +}; + +struct gen_hashtable_iterator +{ + Hashtable* ht; + long idx; + struct entry* current; +}; + +typedef struct gen_hashtable_iterator Hashtable_iterator; + +/** + * Creates an empty hashtable. + */ +Hashtable *Hashtable_create(long (*hash)(void*), long (*key_compare)(void*,void*)); + +/** + * Free the hashtable memory. + */ +void Hashtable_destroy( Hashtable **h ); + +/** + * Puts the key, value pair into the hashtable. + */ +void Hashtable_put( Hashtable *h, void *key, void *value ); + +/** + * Returns the value associated with the key. + */ +void *Hashtable_get( const Hashtable *h, void *key ); + +/** + * Returns the number of values in the hashtable. + */ +long Hashtable_size( const Hashtable *h ); + + +/** + * Returns TRUE if the hashtable contains the specified key. + */ +int Hashtable_containsKey( const Hashtable *h, void *key ); + +/** + * Hash table iterator + */ + +Hashtable_iterator Hashtable_setup_iterator( Hashtable *h ); +struct entry* Hashtable_get_next(Hashtable_iterator &i); + +#endif + diff --git a/irdb-lib/meds2pdb/instrmap_hash.cpp b/irdb-lib/meds2pdb/instrmap_hash.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3a9bc6c062986d8c4278f5c3fd6cd34534c76e8b --- /dev/null +++ b/irdb-lib/meds2pdb/instrmap_hash.cpp @@ -0,0 +1,43 @@ +/* + * instrmap_hash.c - hash table for instrumentation details. + * + * Copyright (c) 2000, 2001, 2010 - University of Virginia + * + * This file is part of the Memory Error Detection System (MEDS) infrastructure. + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#include "instrmap_hash.h" + +Hashtable *instrmaps_hash=NULL; + +long instrmaps_compute_hash(void* key1) +{ + instrmap_hash_key_t * a_key=(instrmap_hash_key_t *)key1; + + return a_key->pc; +} + +long instrmaps_key_compare(void* key1, void* key2) +{ + instrmap_hash_key_t * a_key=(instrmap_hash_key_t *)key1; + instrmap_hash_key_t * b_key=(instrmap_hash_key_t *)key2; + + return a_key->pc == b_key->pc; +} + + diff --git a/irdb-lib/meds2pdb/instrmap_hash.h b/irdb-lib/meds2pdb/instrmap_hash.h new file mode 100644 index 0000000000000000000000000000000000000000..1b6239596186a4c99fb3c9a99e39f25c8b0738c0 --- /dev/null +++ b/irdb-lib/meds2pdb/instrmap_hash.h @@ -0,0 +1,49 @@ +/* + * instrmap_hash.h - hash table for instrumentation details. + * + * Copyright (c) 2000, 2001, 2010 - University of Virginia + * + * This file is part of the Memory Error Detection System (MEDS) infrastructure. + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#ifndef instrmap_hash_h +#define instrmap_hash_h + +#include "meds_all.h" + + +extern Hashtable *instrmaps_hash; +struct instrmap_hash_key +{ + int pc; +}; +typedef struct instrmap_hash_key instrmap_hash_key_t; + +struct instrmap_hash_value +{ + int func_addr; + int site_alloc; + int size; +}; +typedef struct instrmap_hash_value instrmap_hash_value_t; + +long instrmaps_compute_hash(void* key1); + +long instrmaps_key_compare(void* key1, void* key2); + +#endif diff --git a/irdb-lib/meds2pdb/instruction_descriptor.cpp b/irdb-lib/meds2pdb/instruction_descriptor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d01255f9196ab43ce70ecae5a651bb6bedece10e --- /dev/null +++ b/irdb-lib/meds2pdb/instruction_descriptor.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2014, 2015 - University of Virginia + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#include "instruction_descriptor.h" +#include "function_descriptor.h" + +using namespace IRDB_SDK; + +wahoo::Instruction::Instruction() +{ + m_address = 0; + m_size = -1; + m_function = NULL; + m_asm = ""; + + m_allocSite = false; + m_deallocSite = false; + m_stackRef = false; + m_varStackRef = false; + m_isVisited = false; + m_data = NULL; +} + +wahoo::Instruction::Instruction(VirtualOffset_t p_address, int p_size, Function* p_func) +{ + m_address = p_address; + m_size = p_size; + m_function = p_func; + m_isVisited = false; + + m_allocSite = false; + m_deallocSite = false; + m_stackRef = false; + m_data = NULL; +} + +wahoo::Instruction::~Instruction() +{ + m_function = NULL; +} + +// warning: MEDS annotation (via IDA Pro plugin) is not perfect +// and may miss fumctions +void wahoo::Instruction::markAllocSite() +{ + m_allocSite = true; + if (m_function) + m_function->addStackAllocationInstruction(this); +} + +void wahoo::Instruction::markDeallocSite() +{ + m_deallocSite = true; + if (m_function) + m_function->addStackDeallocationInstruction(this); +} + +void wahoo::Instruction::markStackRef() +{ + m_stackRef = true; + if (m_function) + m_function->addStackReferenceInstruction(this); +} + +void wahoo::Instruction::markVarStackRef() +{ + m_varStackRef = true; +} + diff --git a/irdb-lib/meds2pdb/instruction_descriptor.h b/irdb-lib/meds2pdb/instruction_descriptor.h new file mode 100644 index 0000000000000000000000000000000000000000..2cb5bfd2ec7d8dece2253460aee4e4df8f7ba761 --- /dev/null +++ b/irdb-lib/meds2pdb/instruction_descriptor.h @@ -0,0 +1,68 @@ +#ifndef _instruction_h_ +#define _instruction_h_ + +#include <string> +#include <set> +#include <irdb-core> + +#include <irdb-core> + +using namespace std; + + +namespace wahoo { + +class Function; + + +class Instruction { + public: + Instruction(); + Instruction(IRDB_SDK::VirtualOffset_t, int p_size = -1, Function* = NULL); + ~Instruction(); + + void setSize(int p_size) { m_size = p_size; } + void setFunction(Function *p_func) { m_function = p_func; } + + void markAllocSite(); + void markDeallocSite(); + void markStackRef(); + void markVarStackRef(); + + IRDB_SDK::VirtualOffset_t getAddress() const { return m_address; } + int getSize() const { return m_size; } + Function* getFunction() const { return m_function; } + string getAsm() const { return m_asm; } + void setAsm(string p_str) { m_asm = p_str; } + void setData(void *dataPtr, int len); + unsigned char* getData() const { return m_data; } + void setData(void *data) { m_data = (unsigned char*) data; } + + bool isStackRef() const { return m_stackRef; } + bool isVarStackRef() const { return m_varStackRef; } + bool isAllocSite() const { return m_allocSite; } + bool isDeallocSite() const { return m_deallocSite; } + + // keep track of whether instruction has been visited during execution + void setVisited() { m_isVisited = true; } + bool isVisited() const { return m_isVisited; } + + private: + IRDB_SDK::VirtualOffset_t m_address; + int m_size; + Function* m_function; + string m_asm; + unsigned char* m_data; + + bool m_allocSite; + bool m_deallocSite; + bool m_stackRef; + bool m_varStackRef; + + bool m_isVisited; + +}; + +} + +#endif diff --git a/irdb-lib/meds2pdb/instrument.h b/irdb-lib/meds2pdb/instrument.h new file mode 100644 index 0000000000000000000000000000000000000000..80f85f760bbcfb1a967dd9bb1e1f28b6a908e296 --- /dev/null +++ b/irdb-lib/meds2pdb/instrument.h @@ -0,0 +1,68 @@ +/* + * instrument.h -- see instrument.c + * + * Copyright (c) 2000, 2001, 2010 - University of Virginia + * + * This file is part of the Memory Error Detection System (MEDS) infrastructure. + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +/* + * instrument.h -- see instrument.c + * author - jdh8d + */ +#ifndef _instrument_h +#define _instrument_h + + +/* +no needed for SPRI +void add_smp_instrumentation(strata_fragment_t *frag, VirtualOffset_t PC, insn_t *insn); +void add_smp_postinstrumentation(strata_fragment_t *frag, VirtualOffset_t PC, insn_t *insn); +*/ + + + + + + +/* the registers are pushed onto the stack with "push eax; lahf, pusha" in this order */ +typedef struct reg_values reg_values_t; +struct reg_values +{ + int edi; + int esi; + int ebp; + int esp_dummy; + int ebx; + int edx; + int ecx; + int eax; + int eflags; +}; + + +/* +no needed for SPRI +VirtualOffset_t targ_watched_called_instrument(VirtualOffset_t next_PC, watch *w, strata_fragment_t *frag); +*/ + + +/* #define NO_ANNOT_STACK */ + +#endif + diff --git a/irdb-lib/meds2pdb/meds2pdb.cpp b/irdb-lib/meds2pdb/meds2pdb.cpp new file mode 100644 index 0000000000000000000000000000000000000000..67539ea7bb64632efcce1d1181cb76e190bc4ed7 --- /dev/null +++ b/irdb-lib/meds2pdb/meds2pdb.cpp @@ -0,0 +1,502 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <iostream> +#include <iomanip> +#include <fstream> +#include <map> +#include <time.h> +#include <string.h> +#include "rewriter.h" +#include <pqxx/pqxx> +#include <stdlib.h> +#include "MEDS_AnnotationParser.hpp" +#include "MEDS_FuncPrototypeAnnotation.hpp" +#include <irdb-core> + +using namespace std; +using namespace pqxx; +using namespace IRDB_SDK; +using namespace MEDS_Annotation; + +#include <sstream> + +string functionTable; +string addressTable; +string instructionTable; +string typesTable; +string icfsTable; +string icfsMapTable; + +static const int STRIDE = 50; + +template <class T> +inline std::string my_to_string (const T& t) +{ + std::stringstream ss; + ss << t; + return ss.str(); +} + + +int next_address_id=0; + +map<VirtualOffset_t,int> address_to_instructionid_map; +map<wahoo::Instruction*,int> instruction_to_addressid_map; + +// extract the file id from the md5 hash and the program name +int get_file_id(char *progName, char *md5hash) +{ + connection conn; + work txn(conn); + txn.exec("SET client_encoding='LATIN1';"); + + string query = "SELECT file_id FROM file_info WHERE hash="; + query += txn.quote(string(md5hash)); + query += " AND url LIKE"; + /* the plus 7 here is to drop "psprog_" from the name */ + query += txn.quote(string("%") + string(progName+7) + string("%")); + + result r = txn.exec(query); + + for (result::const_iterator row = r.begin(); row != r.end(); ++row) + { + return row["file_id"].as<int>(); + } + + return -1; // error +} + + +// insert addresses & instructions into DB +void insert_instructions(int fileID, const vector<wahoo::Instruction*> &instructions, const vector<wahoo::Function*> &functions) +{ + cerr << "Inserting instructions in the DB"<<endl; + connection conn; + work txn(conn); + // for each instruction: + // get address, insert into address table + // for each instruction: + // populate instruction table + + assert(getenv("SELF_VALIDATE")==nullptr || instructions.size() > 0 ); + + pqxx::tablewriter W_addrs(txn,addressTable); + for (auto i = 0U; i < instructions.size(); i ++ ) + { + char buf[128]; + + wahoo::Instruction *instruction = instructions[i]; + auto addr = instruction->getAddress(); + + // assign an instruction id + address_to_instructionid_map[addr]=next_address_id++; + + // assign an address id + int address_id = next_address_id++; + instruction_to_addressid_map[instruction]=address_id; + + snprintf(buf,sizeof(buf),"%lld", (long long)addr); + + + // insert into address table + vector<string> row= + { + to_string(address_id), + to_string(fileID), + string(buf), + "-1" + }; + W_addrs << row; + + } + W_addrs.complete(); + + pqxx::tablewriter W_insns(txn,instructionTable); + for (auto i = 0U; i < instructions.size(); i ++) + { + const auto instruction = instructions[i]; + const auto addr = instruction->getAddress(); + const auto instruction_id=address_to_instructionid_map[addr]; + const auto address_id=instruction_to_addressid_map[instruction]; + const auto parent_function_id = instruction->getFunction() ? instruction->getFunction()->getFunctionID() : -1 ; + const auto orig_address_id=address_id; + const auto fallthrough_address_id="-1"; + const auto target_address_id="-1"; + const auto icfs_id="-1"; + const auto ehpgm_id="-1"; + const auto ehcss_id="-1"; + + const auto data = (unsigned char*) instruction->getData(); + ostringstream hex_data; + hex_data << setfill('0') << hex;; + for (auto i = 0; i < instruction->getSize(); ++i) + hex_data << setw(2) << (int)(data[i]&0xff); + + const auto & encoded_data=hex_data.str(); + const auto callback=string(""); + const auto & comment = instruction->getAsm(); + const auto ind_target_address_id="-1"; + const auto doip_id="-1"; + + const auto row=vector<string>( + { + to_string(instruction_id), + to_string(address_id), + to_string(parent_function_id), + to_string(orig_address_id), + fallthrough_address_id, + target_address_id, + icfs_id, + ehpgm_id, + ehcss_id, + encoded_data, + callback, + comment, + ind_target_address_id, + doip_id + }) ; + W_insns << row; + + + + }; + W_insns.complete(); + + txn.commit(); + cerr << "Done inserting instructions in the DB"<<endl; +} + +void insert_functions(int fileID, const vector<wahoo::Function*> &functions ) +{ + connection conn; + work txn(conn); + txn.exec("SET client_encoding='LATIN1';"); + + assert(getenv("SELF_VALIDATE")==nullptr || functions.size() > 0 ); + + // bulk insert of function information into the DB + for (auto i = 0U; i < functions.size(); i += STRIDE) + { + string query = "INSERT INTO " + functionTable; + query += " (function_id, name, stack_frame_size, out_args_region_size, use_frame_pointer, is_safe) VALUES "; + + + for (auto j = i; j < i + STRIDE; ++j) + { + if (j >= functions.size()) break; + wahoo::Function *f = functions[j]; + string functionName = f->getName(); + int functionFrameSize = f->getFrameSize(); + + int function_id = j; + f->setFunctionID(function_id); + + int outArgsRegionSize = f->getOutArgsRegionSize(); + bool useFP = f->getUseFramePointer(); + bool isSafe = f->isSafe(); + + if (j != i) query += ","; + query += "("; + query += txn.quote(function_id) + ","; + query += txn.quote(functionName) + ","; + query += txn.quote(functionFrameSize) + ","; + query += txn.quote(outArgsRegionSize) + ","; + query += txn.quote(useFP) + ","; + query += txn.quote(isSafe) + ")"; + + } + + txn.exec(query); + } + + txn.commit(); // must commit o/w everything will be rolled back +} + +void update_functions(int fileID, const vector<wahoo::Function*> &functions ) +{ + connection conn; + work txn(conn); + txn.exec("SET client_encoding='LATIN1';"); + + assert(getenv("SELF_VALIDATE")==nullptr || functions.size() > 0 ); + + // bulk insert of function information into the DB + string query; + for (auto i = 0U; i < functions.size(); i += STRIDE ) + { + query=""; + for (auto j = i; j < i + STRIDE; ++j) + { + if (j >= functions.size()) break; + wahoo::Function *f = functions[j]; + string functionName = f->getName(); + auto functionAddress = f->getAddress(); + //int functionSize = f->getSize(); + int function_id = f->getFunctionID(); + //int outArgsRegionSize = f->getOutArgsRegionSize(); + //bool useFP = f->getUseFramePointer(); + int insnid=-1; // NOT_IN_DATABASE + + + // if a function has a valid address, but the address isn't in the table... + if(functionAddress!=0 && + address_to_instructionid_map.find(functionAddress)==address_to_instructionid_map.end()) + { +abort(); + // remove the function from the list of valid functions. + query+="delete from "+functionTable; + query+=" where function_id = " + txn.quote(my_to_string(function_id)); + query += ";"; + + } + else + { + if(functionAddress!=0) + insnid=address_to_instructionid_map[functionAddress]; + query += "update " + functionTable; + query += " set entry_point_id = " + txn.quote(my_to_string(insnid)); + query += " where function_id = " + txn.quote(my_to_string(function_id)); + query += ";"; + } + + } + txn.exec(query); + } + + txn.commit(); // must commit o/w everything will be rolled back +} + +/* + typedef enum IRDB_Type { + T_UNKNOWN = 0, T_NUMERIC = 1, T_POINTER = 2, + T_INT = 10, T_CHAR = 11, T_FLOAT = 12, T_DOUBLE = 13, + T_VARIADIC = 20, T_TYPEDEF = 21, T_SUBTYPE = 22, + T_FUNC = 100, T_AGGREGATE = 101 + } IRDB_Type; + +// MUST MATCH typedef in type.hpp in libIRDB-core!!! +*/ + +static int getNewTypeId() +{ + // start at 5000 so we don't clash with predefined type ids + static int next_type_id=5000; + return next_type_id++; +} + +void populate_predefined_types() +{ + connection conn; + work txn(conn); + string q = "SET client_encoding='LATIN1';"; + q += "INSERT into " + typesTable + " (type_id, type, name, ref_type_id, ref_type_id2) values ('0', '0','unknown','-1','-1');"; + q += "INSERT into " + typesTable + " (type_id, type, name, ref_type_id, ref_type_id2) values ('1', '1','numeric','-1','-1');"; + q += "INSERT into " + typesTable + " (type_id, type, name, ref_type_id, ref_type_id2) values ('2', '2','pointer','0','-1');"; + txn.exec(q); + txn.commit(); +} + +void update_function_prototype(const vector<wahoo::Function*> &functions, char* annotFile) +{ + populate_predefined_types(); + + MEDS_Annotations_t annotations; + + ifstream annotationif(annotFile, ifstream::in); + if (annotationif.is_open()) + { + MEDS_AnnotationParser annotationParser(annotationif); + annotations = annotationParser.getAnnotations(); + } + else + { + cerr << "warning: cannot open: " << annotFile << endl; + } + + cerr << "annotations size: " << annotations.size() << endl; + cerr << "functions size: " << functions.size() << endl; + + connection conn; + work txn(conn); + txn.exec("SET client_encoding='LATIN1';"); + + for (auto i = 0U; i < functions.size(); i += STRIDE) + { + string q = ""; + for (auto j = i; j < i + STRIDE; ++j) + { + if (j >= functions.size()) break; + wahoo::Function *f = functions[j]; + int function_id = f->getFunctionID(); + auto functionAddress = f->getAddress(); + VirtualOffset vo(functionAddress); + + //MEDS_FuncPrototypeAnnotation* fn_prototype_annot = NULL; + //MEDS_FuncPrototypeAnnotation* fn_returntotype_annot = NULL; + + std::vector<MEDS_Arg> *args = NULL; + MEDS_Arg *returnArg = NULL; + + if (annotations.count(vo) > 0) + { + std::pair<MEDS_Annotations_t::iterator,MEDS_Annotations_t::iterator> ret; + ret = annotations.equal_range(vo); + MEDS_FuncPrototypeAnnotation* p_annotation; + for ( auto it = ret.first; it != ret.second; ++it) + { + MEDS_AnnotationBase *base_type=(it->second); + p_annotation = dynamic_cast<MEDS_FuncPrototypeAnnotation*>(base_type); + if(p_annotation == NULL || !p_annotation->isValid()) + continue; + + if (p_annotation->getArgs()) + args = p_annotation->getArgs(); + + if (p_annotation->getReturnArg()) + returnArg = p_annotation->getReturnArg(); + } + } + + // we should have 2 valid annotations per function + // one for the args, one for the return type + if (args) + { + // (1) define new aggregate type + // (2) define new return type + // (3) define new function type (combo (1) + (2)) + int aggregate_type_id = getNewTypeId(); + int func_type_id = getNewTypeId(); + int basic_type_id = IRDB_SDK::itUnknown; + + for (auto i = 0U; i < args->size(); ++i) + { + if ((*args)[i].isNumericType()) + basic_type_id = itNumeric; + else if ((*args)[i].isPointerType()) + basic_type_id = itPointer; + + q += "INSERT into " + typesTable + " (type_id, type, name, ref_type_id, pos) VALUES ("; + q += txn.quote(my_to_string(aggregate_type_id)) + ","; + q += txn.quote(my_to_string(itAggregate)) + ","; + + q += txn.quote(string(f->getName()) + "_arg") + ","; + q += txn.quote(my_to_string(basic_type_id)) + ","; + q += txn.quote(my_to_string(i)) + ");"; + } + + int return_type_id = itUnknown; + if (returnArg) + { + if (returnArg->isNumericType()) + return_type_id = itNumeric; + else if (returnArg->isPointerType()) + return_type_id = itPointer; + else + return_type_id = itUnknown; + } + + // new function type id (ok to have duplicate prototypes) + // ref_type_id is the return type id + // ref_type_id2 is the type id for the aggregated type + // that describes the function arguments + q += "INSERT into " + typesTable + " (type_id, type, name, ref_type_id, ref_type_id2) VALUES ("; + + q += txn.quote(my_to_string(func_type_id)) + ","; + q += txn.quote(my_to_string(itFunc)) + ","; + q += txn.quote(string(f->getName()) + "_func") + ","; + q += txn.quote(my_to_string(return_type_id)) + ","; + q += txn.quote(my_to_string(aggregate_type_id)) + ");"; + + // update the type id in the function table + q += "UPDATE " + functionTable; + q += " SET type_id = " + txn.quote(my_to_string(func_type_id)); + q += " where function_id = " + txn.quote(my_to_string(function_id)) + "; "; + } // update function prototype + } // strided + + if (q.size() > 0) + txn.exec(q); + } // outer loop + + txn.commit(); // must commit o/w everything will be rolled back +} + +int main(int argc, char **argv) +{ + if (argc != 11) + { + cerr << "usage: " << argv[0] << " <annotations file> <info annotation file> <file id> <func tab name> <insn tab name> <addr tab name> <types tab name> <icfs table name> <icfs map table name> <elf file>" << endl; + return 1; + } + + char *annotFile = argv[1]; + char *infoAnnotFile = argv[2]; + char *fid=argv[3]; + char *myFunctionTable=argv[4]; + char *myInstructionTable=argv[5]; + char *myAddressTable=argv[6]; + char *myTypesTable=argv[7]; + char *myicfsTable=argv[8]; + char *myicfsMapTable=argv[9]; + char *elfFile=argv[10]; + + cout<<"Annotation file: "<< annotFile<<endl; + cout<<"Info annotation file: "<< infoAnnotFile<<endl; + cout<<"File ID: "<< fid<<endl; + cout<<"FTN: "<< myFunctionTable<<endl; + cout<<"ITN: "<< myInstructionTable<<endl; + cout<<"ATN: "<< myAddressTable<<endl; + cout<<"TYP: "<< myTypesTable<<endl; + cout<<"ICFSTab: "<< myicfsTable<<endl; + cout<<"ICFSMapTab: "<< myicfsMapTable<<endl; + cout<<"elfFile: "<< elfFile<<endl; + + // set global vars for importing. + functionTable=myFunctionTable; + addressTable=myAddressTable; + instructionTable=myInstructionTable; + typesTable=myTypesTable; + icfsTable=myicfsTable; + icfsMapTable=myicfsMapTable; + + Rewriter *rewriter = new Rewriter(elfFile, annotFile); + + int fileID = atoi(fid); + if(fileID<=0) + { + cerr << "Bad fileID: " << fid <<endl; + exit(1); + } + + // get functions & instructions from MEDS + vector<wahoo::Function*> functions = rewriter->getAllFunctions(); + vector<wahoo::Instruction*> instructions = rewriter->getAllInstructions(); + + cerr << "Number of functions: " << functions.size() << endl; + cerr << "Number of instructions: " << instructions.size() << endl; + insert_functions(fileID, functions); + insert_instructions(fileID, instructions, functions); + update_functions(fileID, functions); + + // add function prototype information to the IRDB + update_function_prototype(functions, infoAnnotFile); + exit(0); +} diff --git a/irdb-lib/meds2pdb/meds_all.h b/irdb-lib/meds2pdb/meds_all.h new file mode 100644 index 0000000000000000000000000000000000000000..f551ac1dc631a6bd446d07de7c1fb21b087f8454 --- /dev/null +++ b/irdb-lib/meds2pdb/meds_all.h @@ -0,0 +1,54 @@ +/* + * meds_all.h + * + * Copyright (c) 2011 - University of Virginia + * + * This file is part of the STROBE (STack Rewriting of Binary Executables) project. + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#ifndef _MEDS_ANNOT_H +#define _MEDS_ANNOT_H + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include <irdb-core> + +using namespace IRDB_SDK; + +#include "strata_defines.h" + +/* x86_32-specific headers */ +#include "instrument.h" + +#include "spri_alloc.h" +#include "bitvector.h" +#include "gen_hash.h" +#include "constant_hash.h" +#include "stackref_hash.h" +#include "framesize_hash.h" +#include "framerestore_hash.h" +#include "instrmap_hash.h" +#include "funclist_hash.h" +#include "constant_hash.h" + +#include <inttypes.h> + +#endif diff --git a/irdb-lib/meds2pdb/null_transform.cpp b/irdb-lib/meds2pdb/null_transform.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c675d20ce826ae346d1a3faa35ce524f010faec9 --- /dev/null +++ b/irdb-lib/meds2pdb/null_transform.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2014, 2015 - University of Virginia + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#include <iostream> + +#include <irdb-core> + +// #include "elfio/elfio.hpp" + +#include "null_transform.h" +#include "stackref_hash.h" + + + +using namespace wahoo; + +// +// The NullTransform produces assembly SPRI rules that +// are semantically equivalent to the original instructions. +// +// The following instructions are currently transformed: +// +// leave +// ret +// sub esp, K # when the instruction is used to allocate the stack frame +// push ebp +// pop ebp +// +// This trasformation is used primarily for testing purposes. +// + +void NullTransform::rewrite() +{ + // only transform instructions contained in well-defined functions + for (map<VirtualOffset_t, wahoo::Function*>::iterator it = m_functions.begin(); it != m_functions.end(); ++it) + { + VirtualOffset_t addr = it->first; + wahoo::Function* f = it->second; + if (!f) + { + fprintf(stderr,"nulltransform: warning: NULL function data structure at pc: 0x%8p\n", (void*)addr); + continue; + } + + for (auto j = 0U; j < f->getInstructions().size(); ++j) + { + wahoo::Instruction *instr = f->getInstructions()[j]; + char buf[1024]; + sprintf(buf, "%s", instr->getAsm().c_str()); + fprintf(getAsmSpri(), "# orig: %s\n", buf); + if (strstr(buf,"leave")) + { + fprintf(getAsmSpri(), "0x%8p -> .\n", (void*)instr->getAddress()); + fprintf(getAsmSpri(), ". ** leave\n"); + fprintf(getAsmSpri(), ". -> 0x%8p\n", (void*)(instr->getAddress() + instr->getSize())); + } + else if (strstr(buf,"ret")) + { + fprintf(getAsmSpri(), "0x%8p -> .\n", (void*)instr->getAddress()); + fprintf(getAsmSpri(), ". ** nop\n"); + fprintf(getAsmSpri(), ". ** ret\n"); + fprintf(getAsmSpri(), ". -> 0x%8p\n", (void*)(instr->getAddress() + instr->getSize())); + } + else if (instr->isAllocSite()) + { + unsigned int allocSize; + sscanf(buf,"sub esp , %x", &allocSize); + fprintf(getAsmSpri(), "# alloc site: stack frame size: %u\n", allocSize); + if (strstr(buf,"sub esp")) + { + fprintf(getAsmSpri(), "0x%8p -> .\n", (void*)instr->getAddress()); + fprintf(getAsmSpri(), ". ** nop\n"); + fprintf(getAsmSpri(), ". ** sub esp, 0x%x\n", allocSize + 283); + fprintf(getAsmSpri(), ". ** add esp, 0x%x\n", 283); + fprintf(getAsmSpri(), ". -> 0x%8p\n", (void*)(instr->getAddress() + instr->getSize())); + } + } + else if (strstr(buf,"push ebp")) + { + fprintf(getAsmSpri(), "0x%8p -> .\n", (void*)(instr->getAddress())); + fprintf(getAsmSpri(), ". ** push ebp\n"); + fprintf(getAsmSpri(), ". ** nop\n"); + fprintf(getAsmSpri(), ". ** add ebp, 1\n"); + fprintf(getAsmSpri(), ". ** sub ebp, 1\n"); + fprintf(getAsmSpri(), ". ** push ebp\n"); + fprintf(getAsmSpri(), ". ** pop ebp\n"); + fprintf(getAsmSpri(), ". -> 0x%8p\n", (void*)(instr->getAddress() + instr->getSize())); + } + else if (strstr(buf,"pop ebp")) + { + fprintf(getAsmSpri(), "0x%8p -> .\n", (void*)instr->getAddress()); + fprintf(getAsmSpri(), ". ** push ebp\n"); + fprintf(getAsmSpri(), ". ** pop ebp\n"); + fprintf(getAsmSpri(), ". ** nop\n"); + fprintf(getAsmSpri(), ". ** add ebp, 1\n"); + fprintf(getAsmSpri(), ". ** sub ebp, 1\n"); + fprintf(getAsmSpri(), ". ** pop ebp\n"); + fprintf(getAsmSpri(), ". ** nop\n"); + fprintf(getAsmSpri(), ". -> 0x%8p\n", (void*)(instr->getAddress() + instr->getSize())); + } + } + } +} diff --git a/irdb-lib/meds2pdb/null_transform.h b/irdb-lib/meds2pdb/null_transform.h new file mode 100644 index 0000000000000000000000000000000000000000..7265ea9c5a0a80183941c3c9504c1a2c28f66c27 --- /dev/null +++ b/irdb-lib/meds2pdb/null_transform.h @@ -0,0 +1,10 @@ +#include "rewriter.h" + +class NullTransform : public Rewriter +{ + public: + NullTransform(char *p_elf, char *p_annot, char *p_spri) : Rewriter(p_elf, p_annot) {} + + public: + void rewrite(); +}; diff --git a/irdb-lib/meds2pdb/read_annot_file.cpp b/irdb-lib/meds2pdb/read_annot_file.cpp new file mode 100644 index 0000000000000000000000000000000000000000..10508f2376e63d09e0886e3a9c9d18789470994a --- /dev/null +++ b/irdb-lib/meds2pdb/read_annot_file.cpp @@ -0,0 +1,691 @@ +/* + * shadow.c - see below. + * + * Copyright (c) 2000, 2001, 2010 - University of Virginia + * + * This file is part of the Memory Error Detection System (MEDS) infrastructure. + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +// First pass, we'll handle the following annotations: +// +// FUNC - function +// INSTR - instruction +// MEMORYHOLE - not allowed to write into these +// +// DATAREF STACK - allocate stack +// DEALLOC STACK - deallocate stack +// +// PTRIMMEDESP - stack references off ESP +// PTRIMMEDEBP - stack references off EBP + +// #include <stdio.h> +// #include <string.h> +#include "meds_all.h" + +template <class T> +void ignore_result(const T& v) { (void)v; } + +/* + * read_annot_file - read the annotations file provided by IDA Pro. + */ +void read_annot_file(char fn[]) +{ + FILE* fin=nullptr; + VirtualOffset_t addr=0; + union { int size, type;} size_type_u; + char type[200]; + char scope[200]; + char remainder[200000]; + /*char * objname; + int pid=0; + int var_length=0; + int bitvector_size_bits=0; + */ + int line=0; + + + constants_hash= Hashtable_create(constants_compute_hash, constants_key_compare); + stackrefs_hash= Hashtable_create(stackrefs_compute_hash, stackrefs_key_compare); + framerestores_hash= Hashtable_create(framerestores_compute_hash, framerestores_key_compare); + instrmaps_hash= Hashtable_create(instrmaps_compute_hash, instrmaps_key_compare); + funclists_hash= Hashtable_create(funclists_compute_hash, funclists_key_compare); + + if(fn[0]==0) + return; + + fin=fopen(fn, "r"); + + if(!fin) + { + fprintf(stderr,"Cannot open strata annotation file %s\n", fn); + return; + } + + + + do + { + unsigned int tmp=0; + ignore_result(fscanf(fin, "%x %d\n", &tmp, &size_type_u.size)); + addr=tmp; + + if(feof(fin)) // deal with blank lines at the EOF + break; + + ignore_result(fscanf(fin, "%s%s", type,scope)); + + int annot_type; + int is_spec_annot=FALSE; + if(size_type_u.type<-255) + { + annot_type=size_type_u.type+256; + size_type_u.type=size_type_u.type+256; + is_spec_annot=TRUE; + } + else + annot_type=size_type_u.type; + + + /* check for speculative annotations */ +// if(is_spec_annot && strata_opt_do_smp_verify_profile) + if(is_spec_annot) + { + /* skip this annotation */ + ignore_result(fgets(remainder, sizeof(remainder), fin)); + line++; + continue; + } + + /* if the size > 0, then this is a declaration of a variable */ + if(strcmp(type,"FUNC")==0) + { + char name[20000]; + /* found function declaration */ + if(strcmp(scope,"GLOBAL")==0) + { + /* remaining parameters are name {USEFP, NOFP} */ + + funclist_hash_key_t *flhk=(funclist_hash_key_t*)spri_allocate_type(sizeof(funclist_hash_key_t)); + funclist_hash_value_t *flhv=(funclist_hash_value_t*)spri_allocate_type(sizeof(funclist_hash_value_t)); + + ignore_result(fscanf(fin,"%s", name)); + flhk->name=spri_strdup(name); + flhv->pc=addr; +// STRATA_LOG("annot","Adding name=%s pc=%x to funclist hash table\n", flhk->name, flhv->pc); + printf("Adding name=%s pc=%x to funclist hash table\n", flhk->name, flhv->pc); + Hashtable_put(funclists_hash, flhk, flhv); + } + else if(strcmp(scope,"FRAMERESTORE")==0) + { + char zz[1000]; + int reg_num, reg_offset, reg_type; + int reg=0; + for( ; reg<8;reg++) + { + ignore_result(fscanf(fin, "%d %d %d", ®_num, ®_offset, ®_type)); + assert(reg_num==reg); + frame_restore_hash_add_reg_restore(addr,reg_num,reg_offset,reg_type); + } + ignore_result(fscanf(fin, "%s", zz)); + assert(strcmp("ZZ", zz)==0); + } + else if(strcmp(scope,"MMSAFENESS")==0) + { + char safeness[1000]; + ignore_result(fscanf(fin, "%s", safeness)); + if(strcmp(safeness, "SAFE")) + frame_restore_hash_set_safe_bit(addr,TRUE); + else if(strcmp(safeness, "SPECSAFE")) + frame_restore_hash_set_safe_bit(addr,TRUE); + else if(strcmp(safeness, "UNSAFE")) + frame_restore_hash_set_safe_bit(addr,FALSE); + else + fprintf(stderr,"Do not understand safeness terminoligy '%s' at line %d\n", safeness, line); + } + else + fprintf(stderr,"Do not understand type terminoligy '%s' at line %d\n", type, line); + } + else if(strcmp(type,"MEMORYHOLE")==0) + { + + char esp[1000]; + char plus[1000]; + int offset; + char name[1000]; + /* found function declaration */ + assert(strcmp(scope,"STACK")==0); + /* remaining parameters are "esp + <const> <name>" */ + ignore_result(fscanf(fin, "%s%s%d%s", esp, plus, &offset, name)); + + if(strcmp(name, "ReturnAddress")==0) + { + frame_restore_set_return_address(addr,offset); + } + + //printf("MEMORYHOLE, pc=%x offset=%d\n", addr, offset); + /* ignoring for now */ + } + else if(strcmp(type,"LOCALFRAME")==0 || strcmp(type,"INARGS")==0) + { + stackref_hash_key_t *sshk=(stackref_hash_key_t*)spri_allocate_type(sizeof(stackref_hash_key_t)); + stackref_hash_value_t *sshv=(stackref_hash_value_t*)spri_allocate_type(sizeof(stackref_hash_value_t)); + assert(strcmp(scope,"STACK")==0); + /* remaining parameters are "esp + 0 {optional LocalVars} {optional instruction}" */ + + + /* add to hashtable, a name would be nice someday */ + sshk->pc=addr; + sshv->size=size_type_u.size; + // printf("Adding pc=%x size=%d to stackref hash table\n", sshk->pc, sshv->size); + +// STRATA_LOG("annot","Adding pc=%x size=%d to stackref hash table\n", sshk->pc, sshv->size); + Hashtable_put(stackrefs_hash, sshk,sshv); + + } + else if(strcmp(type,"INSTR")==0) + { + /* optimizing annotation about not needing heavyweight metadata update */ + /* ignore for now */ + + + /* + * sudeep -- added support for flags + */ + if (strcmp(scope, "RET_SAFE") == 0) + { + } + else if (strcmp(scope, "DEADREGS") == 0) + { + // stackref_hash_key_t sshk; + // stackref_hash_value_t *sshv; + // sshk.pc = addr; + if (Hashtable_get(stackrefs_hash, &addr)) + { + // printf("STACK ALLOC INSTRUCTION CONFIRMED AT pc=0x%x size=%d\n", sshk.pc, size_type_u); + } + +#ifdef OLD_MEDS + char regname[100]; + int value = SAVE_EBP | SAVE_EDI | SAVE_ESI | SAVE_EDX | SAVE_ECX | SAVE_EBX | SAVE_EAX | SAVE_EFLAGS; + do + { + ignore_result(fscanf(fin, "%s", ®name)); + if (strcmp(regname, "EFLAGS") == 0) + value ^= SAVE_EFLAGS; + else if (strcmp(regname, "EAX") == 0) + value ^= SAVE_EAX; + else if (strcmp(regname, "EBX") == 0) + value ^= SAVE_EBX; + else if (strcmp(regname, "ECX") == 0) + value ^= SAVE_ECX; + else if (strcmp(regname, "EDX") == 0) + value ^= SAVE_EDX; + else if (strcmp(regname, "ESI") == 0) + value ^= SAVE_ESI; + else if (strcmp(regname, "EDI") == 0) + value ^= SAVE_EDI; + else if (strcmp(regname, "EBP") == 0) + value ^= SAVE_EBP; + } while (strcmp(regname, "ZZ")); + register_hash_key_t* key = spri_allocate_type(sizeof(register_hash_key_t)); + register_hash_value_t* val = spri_allocate_type(sizeof(register_hash_value_t)); + key->pc = addr; + val->value = value; + Hashtable_put(register_hash,key,val); +#endif + } + else if (strcmp(scope, "INDIRECTCALL") == 0) + { + /* ignore INSTR INDIRECTCALL annotations, profiler generated, analyzer uses only */ + } +#ifdef OLD_MEDS + else if (strcmp(scope, "FAULT") == 0) + { + int count; + ignore_result(fscanf(fin, "%d", &count)); + recordfault_add_fault(addr,count); + } + else if (strcmp(scope, "CHILDACCESS") == 0) + { + char start[100]; + char end[100]; + int istart, iend; + do + { + ignore_result(fscanf(fin, "%s", start)); + if(strcmp(start,"ZZ")==0) + break; + ignore_result(fscanf(fin, "%s", end)); + istart=atoi(start); + iend=atoi(end); + add_fgrange(addr, istart, istart+iend-1); + } + while(1); + + } +#endif + else if (strcmp(scope, "BELONGTO") == 0) + { + VirtualOffset_t func_addr; + unsigned int tmp=0; + ignore_result(fscanf(fin, "%x", &tmp)); + func_addr=tmp; + instrmap_hash_key_t* key = (instrmap_hash_key_t*)spri_allocate_type(sizeof(instrmap_hash_key_t)); + instrmap_hash_value_t* val = (instrmap_hash_value_t*)spri_allocate_type(sizeof(instrmap_hash_value_t)); + key->pc = addr; + val->func_addr = func_addr; + Hashtable_put(instrmaps_hash,key,val); + } +#ifdef OLD_MEDS + else if (strcmp(scope, "PROF_FIELD") == 0) + { + int num_elems_in_hex_rep=0; + int i=0; + int j=0; + unsigned int cur_element=0; + profiler_data_hash_value_t* pdhv=NULL; + bitvector_t * the_read_in_bitvec=NULL; + char * the_bitvector=NULL; + char temp_obj_name[1000]; + /* This case catches profiler fields information */ + + /* + Read the rest of the line (format below): + PC 0 PROF_FIELD objname pid var_length bitvector_size_bits bitvector + */ + + /* copy scope to objname */ + ignore_result(fscanf(fin, "%s", temp_obj_name)); + objname=spri_strdup(temp_obj_name); + + /* lookup in hash table */ + pdhv=get_profiler_data(addr, objname); + + + /* FIXME: if bit vector dumped as hex */ + + /* allocate memory for the bitvector */ + ignore_result(fscanf(fin, "%d%d", &pid, &var_length)); + if(var_length>0) + { + ignore_result(fscanf(fin, "%d%d", &bitvector_size_bits, &num_elems_in_hex_rep)); + + the_bitvector= spri_allocate_type(((bitvector_size_bits/8)+1)*sizeof(char) + 4); + + /* read the values in to the bit vector */ + for(i=0, j=0; i < num_elems_in_hex_rep; i++, j+=4) + { + /* read an int */ + ignore_result(fscanf(fin, "%x", &the_bitvector[j])); + + } + /* create a bitvector structure to hold the info */ + the_read_in_bitvec=spri_allocate_type(sizeof(bitvector_t)); + the_read_in_bitvec->the_bits=the_bitvector; + the_read_in_bitvec->size=bitvector_size_bits; + the_read_in_bitvec->num_bytes=(bitvector_size_bits/8)+1; + + } + + + + /* merge the bit vector with the bitvector found in the hash table, if found */ + /* if found */ + if(pdhv) + { + if(var_length>0) + { + int i=0; + for (i=0; i<bitvector_size_bits;i++) + { + /* if the bit is 1, then set it + * in the merged version + */ + if(get_bit(the_read_in_bitvec,i)) + { + set_bitvector(pdhv->data_bitvector, i); + } + + } + /* in this case, we can free the_red_in_bitvec */ + free_bitvector(the_read_in_bitvec); + } + } + else /* not found, add it to the hash table */ + { + /* add to the profiler_data_hash table */ + add_profiler_data(addr, objname, var_length, the_read_in_bitvec); + } + + + } +#endif + else + { + assert(strcmp(scope,"LOCAL")==0); + + switch(annot_type) + { + /* No Meta Data Updates */ + case -1: /* no meta data updates */ + /* remaining params: <reason> comment */ + { +#ifdef OLD_MEDS + nometa_hash_key_t *nmhk=spri_allocate_type(sizeof(nometa_hash_key_t)); + nometa_hash_value_t *nmhv + =spri_allocate_type(sizeof(nometa_hash_value_t)); + + /* add to hashtable, a name would be nice someday */ + nmhk->pc=addr; +// STRATA_LOG("annot","Adding nometa=%x to nowarn hash\n", nmhk->pc); + Hashtable_put(nometas_hash, nmhk,nmhv); + break; +#endif + } + + /* fast updates */ + case -2: /* fast meta data updates, results = always number */ + /* remaining params: <reason> reg, {reg, ...} ZZ comment */ + { +#ifdef OLD_MEDS + char n_buffer[1000], reg_buffer[1000]; + reg_buffer[0]=0; + int reg_map=0; + + ignore_result(fscanf(fin, "%s", n_buffer)); + assert(strcmp(n_buffer,"n")==0); + + while(1) // loop until we find a ZZ + { + ignore_result(fscanf(fin, "%s", reg_buffer)); + if(strcmp(reg_buffer,"EAX")==0 || strcmp(reg_buffer,"AL")==0 + || strcmp(reg_buffer,"AH")==0 || strcmp(reg_buffer,"AX")==0) + { + reg_map|=SET_EAX; + } + else if(strcmp(reg_buffer,"EBX")==0 || strcmp(reg_buffer,"BL")==0 + || strcmp(reg_buffer,"BH")==0 || strcmp(reg_buffer,"BX")==0) + { + reg_map|=SET_EBX; + } + else if(strcmp(reg_buffer,"ECX")==0 || strcmp(reg_buffer,"CL")==0 + || strcmp(reg_buffer,"CH")==0 || strcmp(reg_buffer,"CX")==0) + { + reg_map|=SET_ECX; + } + else if(strcmp(reg_buffer,"EDX")==0 || strcmp(reg_buffer,"DL")==0 + || strcmp(reg_buffer,"DH")==0 || strcmp(reg_buffer,"DX")==0) + { + reg_map|=SET_EDX; + } + else if(strcmp(reg_buffer,"EDI")==0) + { + reg_map|=SET_EDI; + } + else if(strcmp(reg_buffer,"ESI")==0) + { + reg_map|=SET_ESI; + } + else if(strcmp(reg_buffer,"EBP")==0) + { + reg_map|=SET_EBP; + } + else if(strcmp(reg_buffer,"ZZ")==0) + { + break; + } + else + assert(0); + } + fast_update_hash_key_t* key = spri_allocate_type(sizeof(fast_update_hash_key_t)); + fast_update_hash_value_t* val = spri_allocate_type(sizeof(fast_update_hash_value_t)); + key->pc = addr; + val->value = reg_map; + Hashtable_put(fast_update_hash,key,val); + + break; +#endif + } + + /* skip warning message on this instruction, promised safe */ + case -3: /* remaining params: NoWarn comment */ + { +#ifdef OLD_MEDS + nowarn_hash_key_t *nwhk=spri_allocate_type(sizeof(nowarn_hash_key_t)); + nowarn_hash_value_t *nwhv + =spri_allocate_type(sizeof(nowarn_hash_value_t)); + + /* add to hashtable, a name would be nice someday */ + nwhk->pc=addr; + STRATA_LOG("annot","Adding nowarn=%x to nowarn hash\n", nwhk->pc); + Hashtable_put(nowarns_hash, nwhk,nwhv); +#endif + break; + } + case -4 : // Introducing a new SizeOrtype id + // for safe returns + { + // Safe returns come here not + // SDT not handling them right + // now + break; + } + default: + fprintf(stderr,"Unknown optimizing annotation type %d at line %d of %s", + size_type_u.type, line, fn); + } + } + + + + } + else if(strcmp(type,"PTRIMMEDEBP")==0 || + strcmp(type,"PTRIMMEDESP")==0 || + strcmp(type,"PTRIMMEDESP2")==0 || + strcmp(type,"PTRIMMEDABSOLUTE")==0 + ) + { + int the_const; + int real_const=0; + char field[100]; + constant_hash_key_t *chk=(constant_hash_key_t*)spri_allocate_type(sizeof(constant_hash_key_t)); + constant_hash_value_t *chv=(constant_hash_value_t*)spri_allocate_type(sizeof(constant_hash_value_t)); + assert(strcmp(scope,"STACK")==0 || strcmp(scope,"GLOBAL")==0); + + /* remaining params are <const> <field> <real_const_if_global> <comment> */ + ignore_result(fscanf(fin, "%d %s", &the_const, field)); + if( strcmp(type,"PTRIMMEDESP2")==0 || + strcmp(type,"PTRIMMEDABSOLUTE")==0 + ) + ignore_result(fscanf(fin, "%x", &real_const)); + else + real_const=the_const; + + /* set the addr, and const */ + chk->pc=addr; + chk->the_const=the_const; + + /* set the field */ + if(strcmp(field,"displ")==0) chk->field=chf_DISPLACEMENT; + else if(strcmp(field,"immed")==0) chk->field=chf_IMMEDIATE; + else if(strcmp(field,"other")==0) chk->field=chf_OTHER; + else assert(0); + + /* set the type */ + if(strcmp(type,"PTRIMMEDEBP")==0 ) chv->type=cht_EBP; + else if(strcmp(type,"PTRIMMEDESP")==0 ) chv->type=cht_ESP; + else if(strcmp(type,"PTRIMMEDESP2")==0 ) chv->type=cht_ESP; + else if(strcmp(type,"PTRIMMEDABSOLUTE")==0 ) chv->type=cht_GLOBAL; + else assert(0); + + /* set the real constant */ + chv->real_const=real_const; + + /* add to hashtable */ +// STRATA_LOG("annot","Adding %x:%d type=%d to constant hash table\n", chk->pc, chk->the_const, chv->type ); + Hashtable_put(constants_hash, chk,chv); + + } + else if(strcmp(type,"DATAREF")==0) + { + char /* name[1000], */ parent_child[1000], offset_str[1000]; + int id /*, parent_id, offset, parent_offset*/; + if(size_type_u.size<=0) + { +// STRATA_LOG("warn", "Found DATAREF of size <=0 at line %d of annot file\n", line); + } + else if(strcmp(scope,"GLOBAL")==0) + { + /* remaining params id, addr, parent/child, name */ + unsigned int tmp=0; + ignore_result(fscanf(fin, "%d%x%s%s", &id, &tmp, parent_child, offset_str)); + addr=tmp; + + if(strcmp(parent_child, "PARENT")==0) + { +#ifdef OLD_MEDS + ignore_result(fscanf(fin, "%s", name)); + add_referent(spri_strdup(name),addr,size_type_u.size, 0, 0); + + if(strata_opt_do_smp_fine_grain && !STRATA_LOG_IS_ON("no_fine_grain_static")) + add_to_referent_id_map(id,find_referent(addr)); +#endif + } + else if(strcmp(parent_child, "CHILDOF")==0) + { +#ifdef OLD_MEDS + if(strata_opt_do_smp_fine_grain && !STRATA_LOG_IS_ON("no_fine_grain_static")) + { + referent_object_t* new_ref; + ignore_result(fscanf(fin, "%d%s%d", &parent_id, offset_str, parent_offset)); + assert(strcmp("OFFSET", offset_str)==0); + referent_object_t *refnt=get_referent_from_id_map(parent_id); + new_ref=add_referent_field(refnt, parent_offset, addr, size_type_u.size); + add_to_referent_id_map(id,new_ref); + } +#endif + } + else + assert(0); + + } + else if(strcmp(scope,"STACK")==0) + { + char esp[1000], plus[1000]; // , offset_str[1000]; + int esp_offset; + + /* remaining params id, addr, parent/child, name */ + ignore_result(fscanf(fin, "%d%s%s%d%s", &id, esp, plus, &esp_offset, parent_child)); + + assert(strcmp(esp, "esp")==0 && strcmp(plus,"+")==0); + + if(strcmp(parent_child, "PARENT")==0) + { + /* add to the stackref hashtable, also record the id->stackref mapping so we can + * can easily lookup the id for any fields we find. + */ + /*stackref_hash_value_t *sshv=(stackref_hash_value_t *)*/(void)add_stack_ref(addr,size_type_u.size, esp_offset); + + // printf("New stack frame at: pc=0x%x size=0x%x\n", addr, sshv->size); + +#ifdef OLD_MEDS + //if(strata_opt_do_smp_fine_grain && !STRATA_LOG_IS_ON("no_fine_grain_stack")) + // if(!STRATA_LOG_IS_ON("no_fine_grain_stack")) + // add_to_stackref_id_map(id,sshv); + + /* add to hashtable, a name would be nice someday */ + // STRATA_LOG("annot","Adding pc=%x size=%d to stackref hash table\n", addr, sshv->size); +#endif + } + else if(strcmp(parent_child, "CHILDOF")==0) + { +#ifdef OLD_MEDS + if(strata_opt_do_smp_fine_grain && !STRATA_LOG_IS_ON("no_fine_grain_stack")) + { + ignore_result(fscanf(fin, "%d%s%d", &parent_id, offset_str, &parent_offset)); + assert(strcmp("OFFSET", offset_str)==0); + stackref_hash_value_t *sshv=get_stackref_from_id_map(parent_id); + stackref_hash_value_t *new_sshv=add_stack_ref_field(sshv, addr, + size_type_u.size, parent_offset); + add_to_stackref_id_map(id,new_sshv); + } +#endif + } + else + assert(0); + } + + } + else if (strcmp(type,"DEALLOC")==0) + { + assert(strcmp(scope,"STACK")==0); + /* remaining params: comment */ + } + else if(strcmp(type,"PROFILEDNUMERIC")==0) + { +#ifdef OLD_MEDS + /* profiler generated information */ + profile_loads_add_profile_data(addr,atoll(scope),FALSE,FALSE); +#endif + } + else if(strcmp(type,"PROFILEDPOINTER")==0 ) + { +#ifdef OLD_MEDS + /* profiler generated information */ + profile_loads_add_profile_data(addr,FALSE,atoll(scope),FALSE); +#endif + } + else if(strcmp(type,"PROFILEDOTHER")==0 ) + { +#ifdef OLD_MEDS + /* profiler generated information */ + profile_loads_add_profile_data(addr,FALSE,FALSE,atoll(scope)); +#endif + } + else if(strcmp(type,"BLOCK")==0 ) + { +#ifdef OLD_MEDS + if(strcmp(scope,"PROFILECOUNT")==0) + { + /* record that we need to profile this block */ + profileblocks_add_profile_data(addr); + } + else if(strcmp(scope,"COUNT")==0) + { + /* do nothing */ + } + else + { +// strata_log("fatal", "Fatal, Unknown scope at line %d\n", line); + fprintf(stderr, "Fatal, Unknown scope at line %d\n", line); + } + + +#endif + } + else + { + // strata_log("fatal", "Fatal, Unknown type at line %d\n", line); + fprintf(stderr, "Fatal, Unknown type at line %d\n", line); + } + + ignore_result(fgets(remainder, sizeof(remainder), fin)); + line++; + } while(!feof(fin)); + fclose(fin); +} diff --git a/irdb-lib/meds2pdb/rewriter.cpp b/irdb-lib/meds2pdb/rewriter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f95a60ec44e918c040210dc63aa0e11b0bc118e2 --- /dev/null +++ b/irdb-lib/meds2pdb/rewriter.cpp @@ -0,0 +1,873 @@ +/* + * Copyright (c) 2014, 2015 - University of Virginia + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#include <iostream> +#include <fstream> +#include <string> +#include <set> +#include <stdlib.h> +#include <irdb-core> + + +#include "meds_all.h" +#include <irdb-core> +//#include "elfio/elfio.hpp" + + +#include "rewriter.h" + + +using namespace std; +using namespace IRDB_SDK; + +template <class T> +void ignore_result(T /* res */) { } + + +Rewriter::Rewriter(char *p_elfPath, char *p_annotationFilePath) +{ + m_elfReader = new ElfReader(p_elfPath); + + // parse file and build up all the data structures + readAnnotationFile(p_annotationFilePath); + readElfFile(p_elfPath); +} + +Rewriter::~Rewriter() +{ +} + +wahoo::Function* Rewriter::ensureFunctionExists(const VirtualOffset_t p_addr) +{ + if (m_functions.count(p_addr) > 0) + return m_functions[p_addr]; + + wahoo::Function *fn = new wahoo::Function(p_addr); + m_functions[p_addr] = fn; + + return fn; +} + +wahoo::Instruction* Rewriter::ensureInstructionExists(const VirtualOffset_t p_addr) +{ + if (m_instructions.count(p_addr) > 0) + return m_instructions[p_addr]; + + wahoo::Instruction *instr = new wahoo::Instruction(p_addr); + m_instructions[p_addr] = instr; + + return instr; +} + +/* +* Read MEDS annotation file and populate relevant hash table & data structures +*/ +void Rewriter::readAnnotationFile(char p_filename[]) +{ + FILE* fin=NULL; + VirtualOffset_t addr = 0, prevStackDeallocPC = 0; + union { int size, type;} size_type_u; + char type[200]; + char scope[200]; + char remainder[200000]; + + + + + int line=0; + + wahoo::Function *nullfn = new wahoo::Function("ThisIsNotAFunction", 0, 0); + m_functions[0]=nullfn; + + constants_hash= Hashtable_create(constants_compute_hash, constants_key_compare); + stackrefs_hash= Hashtable_create(stackrefs_compute_hash, stackrefs_key_compare); + framerestores_hash= Hashtable_create(framerestores_compute_hash, framerestores_key_compare); + instrmaps_hash= Hashtable_create(instrmaps_compute_hash, instrmaps_key_compare); + funclists_hash= Hashtable_create(funclists_compute_hash, funclists_key_compare); + + if(p_filename[0]==0) + return; + + fin=fopen(p_filename, "r"); + + if(!fin) + { + fprintf(stderr,"Cannot open strata annotation file %s\n", p_filename); + goto after_loop; + } + + do + { + ignore_result(fscanf(fin, "%p%d", (void**)&addr, &size_type_u.size)); + + if(feof(fin)) // deal with blank lines at the EOF + break; + + ignore_result(fscanf(fin, "%s%s", type,scope)); + + int annot_type; + if(size_type_u.type<-255) + { + annot_type=size_type_u.type+256; + size_type_u.type=size_type_u.type+256; + } + else + annot_type=size_type_u.type; + +// fprintf(stderr,"main loop: addr 0x%p scope: %s\n", addr, scope); + + /* if the size > 0, then this is a declaration of a variable */ + if(strcmp(type,"FUNC")==0) + { + prevStackDeallocPC = 0; + + char name[20000]; + /* found function declaration */ + if(strcmp(scope,"GLOBAL")==0 || strcmp(scope,"LOCAL")==0) + { +// 8048250 94 FUNC GLOBAL readString_xxx FUNC_UNSAFE USEFP RET 80482ad + /* remaining parameters are name {USEFP, NOFP} */ + + funclist_hash_key_t *flhk=(funclist_hash_key_t*)spri_allocate_type(sizeof(funclist_hash_key_t)); + funclist_hash_value_t *flhv=(funclist_hash_value_t*)spri_allocate_type(sizeof(funclist_hash_value_t)); + + ignore_result(fscanf(fin,"%s", name)); + flhk->name=spri_strdup(name); + flhv->pc=addr; +// fprintf(stderr, "Adding name=%s pc=%x to funclist hash table\n", flhk->name, flhv->pc); + Hashtable_put(funclists_hash, flhk, flhv); + + wahoo::Function *fn = ensureFunctionExists(addr); + fn->setAddress(addr); + fn->setSize(size_type_u.size); + fn->setName(name); +// wahoo::Function *fn = new wahoo::Function(name, addr, size_type_u.size); + ignore_result(fgets(remainder, sizeof(remainder), fin)); + if (strstr(remainder, "FUNC_SAFE")) + fn->setSafe(); + else + fn->setUnsafe(); + + if (strstr(remainder, "USEFP")) + fn->setUseFramePointer(true); + + m_functions[addr] = fn; + + line++; + continue; + } + else if(strcmp(scope,"FRAMERESTORE")==0) + { + char zz[1000]; + int reg_num, reg_offset, reg_type; + int reg=0; + + while(1) // loop until found ZZ + { + ignore_result(fscanf(fin, "%s", zz)); + if(strcmp("ZZ", zz)==0) + break; + + reg_num=atoi(zz); + ignore_result(fscanf(fin,"%d%d", ®_offset, ®_type)); + assert(reg_num==reg); + frame_restore_hash_add_reg_restore(addr,reg_num,reg_offset,reg_type); + reg++; + } + } + else if(strcmp(scope,"MMSAFENESS")==0) + { + char safeness[1000]; + ignore_result(fscanf(fin, "%s", safeness)); + if(strcmp(safeness, "SAFE") == 0) + { +// +// 20110315 Anh +// bug in MEDS re. FUNCTION SAFENESS, the annotation file sometimes mark a function as +// SAFE when in fact it isn't +// m_functions[addr]->setSafe(); + frame_restore_hash_set_safe_bit(addr,TRUE); + } + else if(strcmp(safeness, "SPECSAFE") == 0) + { +// m_functions[addr]->setSafe(); + frame_restore_hash_set_safe_bit(addr,TRUE); + } + else if(strcmp(safeness, "UNSAFE") == 0) + frame_restore_hash_set_safe_bit(addr,FALSE); + else + fprintf(stderr,"Do not understand safeness terminology '%s' at line %d\n", safeness, line); + } + else + fprintf(stderr,"Do not understand type terminology '%s' at line %d\n", type, line); + } + else if(strcmp(type,"MEMORYHOLE")==0) + { + char esp[1000]; + char plus[1000]; + int offset; + char name[1000]; + /* found function declaration */ + assert(strcmp(scope,"STACK")==0); + /* remaining parameters are "esp + <const> <name>" */ + ignore_result(fscanf(fin, "%s%s%d%s", esp, plus, &offset, name)); + + if(strcmp(name, "ReturnAddress")==0) + { + frame_restore_set_return_address(addr,offset); + } + +// printf("MEMORYHOLE, pc=%x offset=%d\n", addr, offset); + /* ignoring for now */ + } + else if(strcmp(type,"LOCALFRAME")==0 || strcmp(type,"INARGS")==0) + { + stackref_hash_key_t *sshk=(stackref_hash_key_t*)spri_allocate_type(sizeof(stackref_hash_key_t)); + stackref_hash_value_t *sshv=(stackref_hash_value_t*)spri_allocate_type(sizeof(stackref_hash_value_t)); + assert(strcmp(scope,"STACK")==0); + /* remaining parameters are "esp + 0 {optional LocalVars} {optional instruction}" */ + + + /* add to hashtable, a name would be nice someday */ + sshk->pc=addr; + sshv->size=size_type_u.size; +// printf("Adding pc=%x size=%d to stackref hash table\n", sshk->pc, sshv->size); + + Hashtable_put(stackrefs_hash, sshk,sshv); + + } + else if(strcmp(type,"INSTR")==0) + { +//fprintf(stderr, "INSTR: At %p, handling %s -- scope:%s\n", addr, type, scope); + + /* optimizing annotation about not needing heavyweight metadata update */ + /* ignore for now */ + + /* + * sudeep -- added support for flags + */ + if (strcmp(scope, "RET_SAFE") == 0) + { + } + else if (strcmp(scope, "DEADREGS") == 0) + { + stackref_hash_key_t sshk; + stackref_hash_value_t *sshv; + sshk.pc = addr; + ensureInstructionExists(addr); + m_instructions[addr]->setSize(size_type_u.size); + sshv = (stackref_hash_value_t*) Hashtable_get(stackrefs_hash, &sshk); + if (sshv) + { + instrmap_hash_key_t key; + key.pc = addr; + instrmap_hash_value_t* val; +// printf("STACK ALLOC INSTRUCTION CONFIRMED AT pc=0x%x size=%d\n", sshk.pc, size_type_u.size); + val = (instrmap_hash_value_t*) Hashtable_get(instrmaps_hash, &key); + if (val) + { +// printf("STACK ALLOC INSTRUCTION CONFIRMED: site alloc marked\n"); + val->site_alloc = 1; + val->size = size_type_u.size; + } + + m_instructions[addr]->markAllocSite(); + m_instructions[addr]->setSize(size_type_u.size); + } + else if (size_type_u.size == 1) + { + // keep track of 1 byte instruction + instrmap_hash_key_t* key = (instrmap_hash_key_t*)spri_allocate_type(sizeof(instrmap_hash_key_t)); + instrmap_hash_value_t* val = (instrmap_hash_value_t*)spri_allocate_type(sizeof(instrmap_hash_value_t)); + key->pc = addr; + val->site_alloc = 0; + val->size = size_type_u.size; + Hashtable_put(instrmaps_hash,key,val); + + ignore_result(fgets(remainder, sizeof(remainder), fin)); + // this is a *potential* stack deallocation instruction only + if ((strstr(remainder,"leave") && strstr(remainder,"EFLAGS")) || + (strstr(remainder,"pop" ) && strstr(remainder,"ebp" )) + ) + { + prevStackDeallocPC = addr; + } + + // b/c we ate up <remainder> we have to do this + line++; + continue; + + } + + } + else if (strcmp(scope, "INDIRECTCALL") == 0) + { + /* ignore INSTR INDIRECTCALL annotations, profiler generated, analyzer uses only */ + } + else if (strcmp(scope, "BELONGTO") == 0) + { + VirtualOffset_t func_addr; + ignore_result(fscanf(fin, "%p", (void**)&func_addr)); + instrmap_hash_key_t* key = (instrmap_hash_key_t*)spri_allocate_type(sizeof(instrmap_hash_key_t)); + instrmap_hash_value_t* val = (instrmap_hash_value_t*)spri_allocate_type(sizeof(instrmap_hash_value_t)); + key->pc = addr; + val->func_addr = func_addr; + val->site_alloc = 0; + val->size = 0; + Hashtable_put(instrmaps_hash,key,val); + + // rely on the fact that INST BELONGTO is the first INST annotation in a MEDS file (warning: but it is not required to be there) +// assert(m_functions[func_addr]); + ignore_result(ensureFunctionExists(func_addr)); + wahoo::Instruction* instr = new wahoo::Instruction(addr, -1, m_functions[func_addr]); + m_instructions[addr] = instr; + + // associate instruction with its enclosing function + m_functions[func_addr]->addInstruction(instr); +//fprintf(stderr,"0x%08x belongs to function %s\n", addr, m_functions[func_addr]->getName().c_str()); + } + else + { + + assert(strcmp(scope,"LOCAL")==0); + ensureInstructionExists(addr); + +/* + if (!m_instructions[addr]) + { + // unknown size, unknown function + wahoo::Instruction* instr = new wahoo::Instruction(addr, -1, NULL); + m_instructions[addr] = instr; + } +*/ + + switch(annot_type) + { + /* No Meta Data Updates */ + case -1: /* no meta data updates */ + /* remaining params: <reason> comment */ + { + ignore_result(fgets(remainder, sizeof(remainder), fin)); + // this is a *potential* stack deallocation instruction only + if (strstr(remainder,"add") && strstr(remainder,"esp") + && strstr(remainder,"1stSrcVia2ndSrc") + && strstr(remainder,"IMMEDNUM")) + { + prevStackDeallocPC = addr; + } + else if (strstr(remainder,"SafeFrameAlloc") + && strstr(remainder,"sub") + && strstr(remainder,"esp")) + { + m_instructions[addr]->markAllocSite(); + } + else if (strstr(remainder,"[ebp+") + && strstr(remainder,"var_")) + { +/* +MEDS doesn't mark this as a stack reference + 8048281 0 INSTR BELONGTO 8048262 + 8048281 -1 INSTR LOCAL MetadataRedundant mov eax, [ebp+var_4] +*/ + m_instructions[addr]->markStackRef(); + m_instructions[addr]->markVarStackRef(); + } + else if (strstr(remainder,"[esp+") + && (strstr(remainder,"var_") || strstr(remainder, "arg_"))) + { + m_instructions[addr]->markStackRef(); + m_instructions[addr]->markVarStackRef(); + } + + + // b/c we ate up <remainder> we have to do this + line++; + continue; + + } + + /* fast updates */ + case -2: /* fast meta data updates, results = always number */ + /* remaining params: <reason> reg, {reg, ...} ZZ comment */ + { + break; + } + + /* skip warning message on this instruction, promised safe */ + case -3: /* remaining params: NoWarn comment */ + { + break; + } + case -4 : // Introducing a new SizeOrtype id + // for safe returns + { + // Safe returns come here not + // SDT not handling them right + // now + break; + } + default: + fprintf(stderr,"Unknown optimizing annotation type %d at line %d of %s", + size_type_u.type, line, p_filename); + } + } + + + + } + else if(strcmp(type,"PTRIMMEDEBP")==0 || + strcmp(type,"PTRIMMEDESP")==0 || + strcmp(type,"PTRIMMEDESP2")==0 || + strcmp(type,"PTRIMMEDABSOLUTE")==0 + ) + { + int the_const; + int real_const=0; + char field[100]; + constant_hash_key_t *chk=(constant_hash_key_t*)spri_allocate_type(sizeof(constant_hash_key_t)); + constant_hash_value_t *chv=(constant_hash_value_t*)spri_allocate_type(sizeof(constant_hash_value_t)); + assert(strcmp(scope,"STACK")==0 || strcmp(scope,"GLOBAL")==0); + + /* remaining params are <const> <field> <real_const_if_global> <comment> */ + ignore_result(fscanf(fin, "%d%s", &the_const, field)); + if( strcmp(type,"PTRIMMEDESP2")==0 || + strcmp(type,"PTRIMMEDABSOLUTE")==0 + ) + ignore_result(fscanf(fin, "%x", &real_const)); + else + real_const=the_const; + + /* set the addr, and const */ + chk->pc=addr; + chk->the_const=the_const; + + /* set the field */ + if(strcmp(field,"displ")==0) chk->field=chf_DISPLACEMENT; + else if(strcmp(field,"immed")==0) chk->field=chf_IMMEDIATE; + else if(strcmp(field,"other")==0) chk->field=chf_OTHER; + else assert(0); + + /* set the type */ + if(strcmp(type,"PTRIMMEDEBP")==0 ) chv->type=cht_EBP; + else if(strcmp(type,"PTRIMMEDESP")==0 ) chv->type=cht_ESP; + else if(strcmp(type,"PTRIMMEDESP2")==0 ) chv->type=cht_ESP; + else if(strcmp(type,"PTRIMMEDABSOLUTE")==0 ) chv->type=cht_GLOBAL; + else assert(0); + + /* set the real constant */ + chv->real_const=real_const; + + /* add to hashtable */ + Hashtable_put(constants_hash, chk,chv); + + ensureInstructionExists(addr); +/* + if (!m_instructions[addr]) + { + // unknown size, unknown function + wahoo::Instruction* instr = new wahoo::Instruction(addr, -1, NULL); + m_instructions[addr] = instr; + } +*/ + +// fprintf(stderr,"@ 0x%x marking instruction as stack reference\n", addr); + m_instructions[addr]->markStackRef(); + m_instructions[addr]->setSize(size_type_u.size); + + // see if we can pick up access to local variables + // and access to arguments off esp + ignore_result(fgets(remainder, sizeof(remainder), fin)); + if (strstr(remainder, "var_") || + (strstr(remainder, "arg_") && strstr(remainder, "[esp"))) + { + m_instructions[addr]->markVarStackRef(); + } + + + // b/c we ate up <remainder> we have to do this + line++; + continue; + } + else if(strcmp(type,"DATAREF")==0) + { + char parent_child[1000]; + int id; + if(size_type_u.size<=0) + { + } + else if(strcmp(scope,"GLOBAL")==0) + { + /* remaining params id, addr, parent/child, name */ + ignore_result(fscanf(fin, "%d%p%s", &id, (void**)&addr, parent_child)); + + if(strcmp(parent_child, "PARENT")==0) + { + } + else if(strcmp(parent_child, "CHILDOF")==0) + { + } + else + assert(0); + + } + else if(strcmp(scope,"STACK")==0) + { + char esp[1000], plus[1000], name[1000]; + int esp_offset; + + /* remaining params id, addr, parent/child, name */ + ignore_result(fscanf(fin, "%d%s%s%d%s%s", &id, esp, plus, &esp_offset, parent_child, name)); + + assert(strcmp(esp, "esp")==0 && strcmp(plus,"+")==0); + + if(strcmp(parent_child, "PARENT")==0) + { + /* add to the stackref hashtable, also record the id->stackref mapping so we can + * can easily lookup the id for any fields we find. + */ + ignore_result(add_stack_ref(addr,size_type_u.size, esp_offset)); + + + // @todo: record frame size + // set the frame size +// 5b 64 DATAREF STACK 2 esp + 0 PARENT LocalFrame LOCALFRAME + if (strstr(name,"LocalFrame")) + { + if ( m_instructions[addr]->getFunction() ) + m_instructions[addr]->getFunction()->setFrameSize(size_type_u.size); + } + + } + else if(strcmp(parent_child, "CHILDOF")==0) + { +/* +need to pick up size of outargsregion +any esp access within this region should not be transformed +any esp access outside this region (esp + K) >= (esp + size) can be xformed + + 80482fd 28 DATAREF STACK 3123 esp + 0 CHILDOF 3122 OFFSET 0 OutArgsRegion OUTARGS + 80482fd 4 DATAREF STACK 3124 esp + 28 CHILDOF 3122 OFFSET 28 LOCALVAR var_20 + 80482fd 4 DATAREF STACK 3125 esp + 32 CHILDOF 3122 OFFSET 32 LOCALVAR var_1C + 80482fd 4 DATAREF STACK 3126 esp + 36 CHILDOF 3122 OFFSET 36 LOCALVAR var_18 +*/ + ignore_result(fgets(remainder, sizeof(remainder), fin)); + if (strstr(remainder,"OutArgsRegion")) + { +//fprintf(stderr," found OutArgsRegion @ 0x%08x\n", addr); + ensureInstructionExists(addr); + assert(m_instructions[addr]->getFunction()); + m_instructions[addr]->getFunction()->setOutArgsRegionSize(size_type_u.size); + } + line++; + continue; + + } + else + assert(0); + } + + } + else if (strcmp(type,"DEALLOC")==0) + { + assert(strcmp(scope,"STACK")==0); + /* remaining params: comment */ + + // handle the two forms of add %esp, X + // for reclaiming stack space + if (addr - prevStackDeallocPC == 3 || addr - prevStackDeallocPC == 6) + { +// fprintf(stderr, "Detected nice stack deallocation instruction at 0x%x\n", prevStackDeallocPC); +// assert(m_instructions[prevStackDeallocPC]); + ensureInstructionExists(prevStackDeallocPC); + m_instructions[prevStackDeallocPC]->markDeallocSite(); + m_instructions[prevStackDeallocPC]->setSize(addr - prevStackDeallocPC); + + } + // handle leave/ret + else if (addr - prevStackDeallocPC == 1) + { +// assert(m_instructions[prevStackDeallocPC]); + ensureInstructionExists(prevStackDeallocPC); + m_instructions[prevStackDeallocPC]->markDeallocSite(); + m_instructions[prevStackDeallocPC]->setSize(1); + } + } + else if(strcmp(type,"BLOCK")==0 ) + { + } + else + { + fprintf(stderr, "Fatal, Unknown type at line %d\n", line); + } + + ignore_result(fgets(remainder, sizeof(remainder), fin)); + line++; + } while(!feof(fin)); + fclose(fin); + +after_loop: + + // for each instruction in a function, disassemble and stash away assembly string + disassemble(); +} + + +/* +* Read MEDS annotation file and populate relevant hash table & data structures +*/ +void Rewriter::readElfFile(char p_filename[]) +{ + static char buf[64*1024]; + char* objdump=getenv("PS_OBJDUMP"); + if(!objdump) + objdump=strdup("objdump"); + sprintf(buf, "%s -d --prefix-addresses %s | grep \"^[0-9]\"", objdump, p_filename); + printf("Running objdump, like so: %s\n", buf); + FILE* pin=popen(buf, "r"); + VirtualOffset_t addr; + + assert(pin); + + + void* tmp=NULL; + ignore_result(fscanf(pin, "%p", &tmp)); + addr=(VirtualOffset_t)tmp; + ignore_result(fgets(buf,sizeof(buf),pin)); + do + { + if(m_instructions[addr]==NULL) + { + cout<<"Found instruction from objdump at "<<hex<<addr<<endl; + m_instructions[addr]=new wahoo::Instruction(addr,-1,NULL); + } + ignore_result(fscanf(pin,"%p", &tmp)); + addr=(VirtualOffset_t)tmp; + ignore_result(fgets(buf,sizeof(buf),pin)); + } while(!feof(pin)); + + pclose(pin); + + disassemble(); +} + + +/* +* for all instructions, disassemble them using the BeaEngine +*/ +void Rewriter::disassemble() +{ + getElfReader()->SetArchitecture(); + /* + if(getElfReader()->isElf64() || getElfReader()->isPe64()) + FileIR_t::SetArchitectureBitWidth(64); + else + FileIR_t::SetArchitectureBitWidth(32); + */ + + // for every instruction, grab from ELF + // disassemble + + vector<wahoo::Instruction*> instructions=getAllInstructions(); + + fprintf(stderr, "Rewriter::disassemble(): number of instructions: %" PRIuPTR "\n", (uintptr_t)instructions.size()); + + for (auto j = 0U; j < instructions.size(); ++j) + { + wahoo::Instruction *instr = instructions[j]; + + const auto instr_data=(void*)(getElfReader()->getInstructionBuffer(instr->getAddress())); + const auto p_disasm=DecodedInstruction_t::factory(instr->getAddress(), instr_data, 16); + const auto &disasm=*p_disasm; + + + /* maybe this isn't in a section so getInstructionBuffer returns 0 */ + + if(disasm.valid()) + { + const auto instr_len = disasm.length() ; //Disasm(&disasm); + instr->setAsm(disasm.getDisassembly()); + instr->setSize(instr_len); + instr->setData(instr_data); + } + else + { + cerr<<"Decided that instruction at "<<hex + <<instr->getAddress()<<dec<<" is bogus."<<endl; + /* bogus intruction, remove it */ + m_instructions[instr->getAddress()]=NULL; + + if(instr) + delete instr; + } + } +} + +void Rewriter::addSimpleRewriteRule(wahoo::Function* p_func, char *p_origInstr, int p_origSize, VirtualOffset_t p_origAddress, char *p_newInstr) +{ + char buf[1024]; + char aspri[2048]; + + aspri[0] = '\0'; + + sprintf(buf,"# orig(%d): %s\n", p_origSize, p_origInstr); + strcpy(aspri, buf); + sprintf(buf,"0x%8p -> .\n", (void*)p_origAddress); + strcat(aspri, buf); + sprintf(buf,". ** %s\n", p_newInstr); + strcat(aspri, buf); + sprintf(buf,". -> 0x%8p\n", (void*)(p_origAddress + p_origSize)); + strcat(aspri, buf); + + fprintf(stderr, "WOULD EMIT RULE: %s\n", aspri); + p_func->addRewriteRule(string(aspri)); +} + +// commit function to SPRI file +void Rewriter::commitFn2SPRI(wahoo::Function *p_func, FILE *p_fp) +{ + if (!p_func) return; + + for (auto i = 0U; i < p_func->getRewrites().size(); ++i) + { + string rewriteRule = p_func->getRewrites()[i]; + fprintf(p_fp, "%s\n", rewriteRule.c_str()); + } +} + +vector<wahoo::Function*> Rewriter::getCandidateFunctions() +{ + vector<wahoo::Function*> candidates; + for (map<VirtualOffset_t, wahoo::Function*>::iterator it = m_functions.begin(); it != m_functions.end(); ++it) + { + wahoo::Function* f = it->second; + + // null fn or fn marked as SAFE by MEDS -- we don't xform those + if (!f || f->isSafe()) continue; + + candidates.push_back(f); + } + + return candidates; +} + +vector<wahoo::Function*> Rewriter::getNonCandidateFunctions() +{ + vector<wahoo::Function*> nonCandidates; + for (map<VirtualOffset_t, wahoo::Function*>::iterator it = m_functions.begin(); it != m_functions.end(); ++it) + { + wahoo::Function* f = it->second; + + // null fn or fn marked as SAFE by MEDS -- we don't xform those + if (!f) continue; + if (f->isSafe()) + nonCandidates.push_back(f); + } + + return nonCandidates; +} + +vector<wahoo::Function*> Rewriter::getAllFunctions() +{ + vector<wahoo::Function*> allFunctions; + + for (map<VirtualOffset_t, wahoo::Function*>::iterator it = m_functions.begin(); it != m_functions.end(); ++it) + { + wahoo::Function* f = it->second; + + if (!f) continue; + + allFunctions.push_back(f); + } + + return allFunctions; +} + +vector<wahoo::Instruction*> Rewriter::getAllInstructions() +{ + vector<wahoo::Instruction*> allInstructions; + + for (map<VirtualOffset_t, wahoo::Instruction*>::iterator it = m_instructions.begin(); it != m_instructions.end(); ++it) + { + wahoo::Instruction* instr = it->second; + + if (!instr) continue; + + allInstructions.push_back(instr); + } + + return allInstructions; +} + +map<wahoo::Function*, double> Rewriter::getFunctionCoverage(char *p_instructionFile) +{ + map<wahoo::Function*, double> coverage; + + ifstream infile; + infile.open(p_instructionFile, ifstream::in); + + if(!infile.is_open()) + { + cerr << "File containing instructions visited not found:" << p_instructionFile << endl; + return coverage; + } + + set<VirtualOffset_t> visitedInstructions; + + infile.seekg(0,ios::end); + size_t size = infile.tellg(); + infile.seekg(ios::beg); + if( size == 0) + { + cerr << "File containing instructions visited is empty is empty\n"<<endl; + return coverage; + } + + while (infile.good()) + { + int address = 0; + + infile>>hex>>address; + + visitedInstructions.insert((VirtualOffset_t) address); + } + + vector<wahoo::Instruction*> allInstructions = getAllInstructions(); + + for (auto i = 0U; i < allInstructions.size(); ++i) + { + wahoo::Instruction* instr = allInstructions[i]; + if (!instr) continue; + + if (visitedInstructions.count(instr->getAddress())) + { + instr->setVisited(); + } + } + + // now all instructions have been marked as visited or not + + vector<wahoo::Function*> allFunctions = getAllFunctions(); + for (auto i = 0U; i < allFunctions.size(); ++i) + { + coverage[allFunctions[i]] = allFunctions[i]->getInstructionCoverage(); + } + + return coverage; +} diff --git a/irdb-lib/meds2pdb/rewriter.h b/irdb-lib/meds2pdb/rewriter.h new file mode 100644 index 0000000000000000000000000000000000000000..9614dbcedbd4eb3b826efca2e7056c7a2615882f --- /dev/null +++ b/irdb-lib/meds2pdb/rewriter.h @@ -0,0 +1,54 @@ +#include <map> +#include <set> +#include <irdb-core> +// #include "elfio/elfio.hpp" +//#include "elfio/elfio_dump.hpp" + +#include "elfreader.h" +#include "function_descriptor.h" + + +using namespace std; + +class Rewriter +{ + public: + Rewriter(char *p_elf, char *p_annotationFile); + ~Rewriter(); + + virtual vector<wahoo::Function*> getAllFunctions(); + virtual vector<wahoo::Function*> getCandidateFunctions(); + virtual vector<wahoo::Function*> getNonCandidateFunctions(); + + virtual vector<wahoo::Instruction*> getAllInstructions(); + + map<wahoo::Function*, double> getFunctionCoverage(char *p_instFile); + + protected: + void readAnnotationFile(char []); + void readElfFile(char []); + ElfReader *getElfReader() const { return m_elfReader; } + FILE* getAsmSpri() { return m_spri; }; + void setAsmSpri(FILE *p_spri) { m_spri = p_spri; }; + + // disassemble all functions + void disassemble(); + + // one instruction modification + void addSimpleRewriteRule(wahoo::Function* p_func, char *p_origInstr, int p_origSize, IRDB_SDK::VirtualOffset_t p_origAddress, char *p_newInstr); + + // commit function to AsmSPRI file + void commitFn2SPRI(wahoo::Function* p_func, FILE *p_file); + + protected: + map<IRDB_SDK::VirtualOffset_t, wahoo::Function*> m_functions; + map<IRDB_SDK::VirtualOffset_t, wahoo::Instruction*> m_instructions; + + private: + wahoo::Function* ensureFunctionExists(const IRDB_SDK::VirtualOffset_t); + wahoo::Instruction* ensureInstructionExists(const IRDB_SDK::VirtualOffset_t); + + private: + ElfReader* m_elfReader; + FILE* m_spri; +}; diff --git a/irdb-lib/meds2pdb/spri_alloc.cpp b/irdb-lib/meds2pdb/spri_alloc.cpp new file mode 100644 index 0000000000000000000000000000000000000000..57a4b77e05af5467d25d9601a4226be22b05e81a --- /dev/null +++ b/irdb-lib/meds2pdb/spri_alloc.cpp @@ -0,0 +1,50 @@ +/* + * spri_alloc.c - allocation routines, see below. + * + * Copyright (c) 2011 - Zephyr Software + * + * This file is part of the Strata dynamic code modification infrastructure. + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <stdlib.h> +#include <string.h> +#include "spri_alloc.h" + +// +// Wrap memory management routines +// +// This will make it easier to integrate back within the Strata library +// as we could simply call strata_allocate_type and strata_deallocate_type +// instead of malloc/free +// + +void* spri_allocate_type(int p_size) +{ + return malloc(p_size); +} + +void* spri_deallocate_type(void *p_ptr, int p_size) +{ + free(p_ptr); + return NULL; +} + +char* spri_strdup(const char *p_ptr) +{ + return strdup(p_ptr); +} diff --git a/irdb-lib/meds2pdb/spri_alloc.h b/irdb-lib/meds2pdb/spri_alloc.h new file mode 100644 index 0000000000000000000000000000000000000000..880db71a059609c9417894dd0f07638e4bc992b8 --- /dev/null +++ b/irdb-lib/meds2pdb/spri_alloc.h @@ -0,0 +1,35 @@ +/* + * spri_alloc.h - allocation routines, see below. + * + * Copyright (c) 2011 - Zephyr Software + * + * This file is part of the Strata dynamic code modification infrastructure. + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef _SPRI_ALLOC_ +#define _SPRI_ALLOC_ + +/* + * Memory allocation/deallocation wrapper + */ + +void* spri_allocate_type(int); +void* spri_deallocate_type(void *, int); +char* spri_strdup(const char *); + +#endif diff --git a/irdb-lib/meds2pdb/stackref_hash.cpp b/irdb-lib/meds2pdb/stackref_hash.cpp new file mode 100644 index 0000000000000000000000000000000000000000..baba2498166443b3f7780e44300f271f3e0f7d18 --- /dev/null +++ b/irdb-lib/meds2pdb/stackref_hash.cpp @@ -0,0 +1,84 @@ +/* + * stackref_hash.c - see below. + * + * Copyright (c) 2000, 2001, 2010 - University of Virginia + * + * This file is part of the Memory Error Detection System (MEDS) infrastructure. + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#include "meds_all.h" +#include "stackref_hash.h" + +/* + * hashtable of data for stack referents + */ + +Hashtable *stackrefs_hash=NULL; + +long stackrefs_compute_hash(void* key1) +{ + stackref_hash_key_t * a_key=(stackref_hash_key_t *)key1; + + return a_key->pc; +} + +long stackrefs_key_compare(void* key1, void* key2) +{ + stackref_hash_key_t * a_key=(stackref_hash_key_t *)key1; + stackref_hash_key_t * b_key=(stackref_hash_key_t *)key2; + + return a_key->pc == b_key->pc; +} + + +/* add something to the stackrefs_hash hashtable */ +stackref_hash_value_t *add_stack_ref(VirtualOffset_t pc,int size, int offset) +{ + stackref_hash_key_t *sshk=(stackref_hash_key_t*)spri_allocate_type(sizeof(stackref_hash_key_t )); + stackref_hash_value_t *sshv=(stackref_hash_value_t*)spri_allocate_type(sizeof(stackref_hash_value_t )); + + sshk->pc=pc; + sshv->esp_offset=offset; + sshv->size=size; + sshv->parent_stackref=NULL; + sshv->child_stackref=NULL; + sshv->sibling_stackref=NULL; + + Hashtable_put(stackrefs_hash, sshk, sshv); + + return sshv; +} + +stackref_hash_value_t *add_stack_ref_field(stackref_hash_value_t* parent, VirtualOffset_t pc, int size, int offset) +{ + stackref_hash_key_t *sshk=(stackref_hash_key_t*)spri_allocate_type(sizeof(stackref_hash_key_t )); + stackref_hash_value_t *sshv=(stackref_hash_value_t*)spri_allocate_type(sizeof(stackref_hash_value_t )); + + sshk->pc=pc; + sshv->esp_offset=offset; + sshv->size=size; + sshv->parent_stackref=parent; + sshv->child_stackref=NULL; + + /* link into the parent's child list */ + sshv->sibling_stackref=parent->child_stackref; + parent->child_stackref=sshv; + + return sshv; +} + diff --git a/irdb-lib/meds2pdb/stackref_hash.h b/irdb-lib/meds2pdb/stackref_hash.h new file mode 100644 index 0000000000000000000000000000000000000000..b5f526aa3e01c5083edb4e6a6c0651224a78ea05 --- /dev/null +++ b/irdb-lib/meds2pdb/stackref_hash.h @@ -0,0 +1,59 @@ +/* + * stackref_hash.h - see below. + * + * Copyright (c) 2000, 2001, 2010 - University of Virginia + * + * This file is part of the Memory Error Detection System (MEDS) infrastructure. + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from the University + * of Virginia. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: University of Virginia + * e-mail: jwd@virginia.com + * URL : http://www.cs.virginia.edu/ + * + */ + +#ifndef stackref_hash_h +#define stackref_hash_h + +#include "meds_all.h" + + +/* + * necessary code for creating a hashtable of stack reference data + */ + +extern Hashtable *stackrefs_hash; +typedef struct stackref_hash_key stackref_hash_key_t; +struct stackref_hash_key +{ + VirtualOffset_t pc; +}; + +typedef struct stackref_hash_value stackref_hash_value_t; +struct stackref_hash_value +{ + int esp_offset; + int size; + stackref_hash_value_t *parent_stackref; + stackref_hash_value_t *child_stackref; + stackref_hash_value_t *sibling_stackref; +}; + +long stackrefs_compute_hash(void* key1); + +long stackrefs_key_compare(void* key1, void* key2); + +stackref_hash_value_t *add_stack_ref(VirtualOffset_t pc,int size, int offset); +stackref_hash_value_t *add_stack_ref_field(stackref_hash_value_t *parent, VirtualOffset_t pc,int size, int offset); + +#endif + diff --git a/irdb-lib/meds2pdb/strata_defines.h b/irdb-lib/meds2pdb/strata_defines.h new file mode 100644 index 0000000000000000000000000000000000000000..6b50f8adf5bf9801796af06326d5f4f96f10119d --- /dev/null +++ b/irdb-lib/meds2pdb/strata_defines.h @@ -0,0 +1,31 @@ +/* + * strata_defines.h - Declarations for the Strata option package + * + * Copyright (c) 2000, 2001, 2010 - Zephyr Software + * + * This file is part of the Strata dynamic code modification infrastructure. + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + +#define TRUE (1==1) +#define FALSE (1==0) + +#define TOSTRING(x) STRINGIFY(x) +#define STRINGIFY(x) #x + + diff --git a/irdb-lib/pebliss/trunk/Makefile b/irdb-lib/pebliss/trunk/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..775475eed83139bab31eb74d5b7d90bdbd14b860 --- /dev/null +++ b/irdb-lib/pebliss/trunk/Makefile @@ -0,0 +1,24 @@ +TARGETS = pe_bliss samples_pack tests_pack +TARGETS_CLEAN = pe_clean samples_clean tests_clean + +all: $(TARGETS) + +clean: $(TARGETS_CLEAN) + +pe_bliss: + $(MAKE) PE_DEBUG=$(PE_DEBUG) -C ./pe_lib + +samples_pack: pe_bliss + $(MAKE) PE_DEBUG=$(PE_DEBUG) -C ./samples + +pe_clean: + $(MAKE) -C ./pe_lib clean + +samples_clean: + $(MAKE) -C ./samples clean + +tests_pack: pe_bliss + $(MAKE) PE_DEBUG=$(PE_DEBUG) -C ./tests + +tests_clean: + $(MAKE) -C ./tests clean diff --git a/irdb-lib/pebliss/trunk/pe_bliss_tests_vc10.sln b/irdb-lib/pebliss/trunk/pe_bliss_tests_vc10.sln new file mode 100644 index 0000000000000000000000000000000000000000..61765d88a46debcd1ef1d052b778135f3372d64b --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_bliss_tests_vc10.sln @@ -0,0 +1,272 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_checksum", "tests\test_checksum\test_checksum.vcxproj", "{7B7AEAB2-7755-409D-A6C9-D5FFB7D1A95A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_entropy", "tests\test_entropy\test_entropy.vcxproj", "{853CFFF4-1FAB-48EB-81A9-CC35F9FB3F80}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_rich_data", "tests\test_rich_data\test_rich_data.vcxproj", "{114AC59B-BC28-40DB-8380-67C422D0C81B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests_basic", "tests\tests_basic\tests_basic.vcxproj", "{7870A9AC-92BB-423B-BC03-FBF7B46CD338}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests_utils", "tests\tests_utils\tests_utils.vcxproj", "{50212477-1614-49C9-9791-4AC72025DC76}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_runner", "tests\test_runner\test_runner.vcxproj", "{132DFCC9-13EF-4178-9772-1C467FB296D6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_imports", "tests\test_imports\test_imports.vcxproj", "{CE1D0620-BC75-456F-914B-3BEBF5444B4C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_relocations", "tests\test_relocations\test_relocations.vcxproj", "{709B0E41-9792-4A0A-B28B-CBD06CE441B9}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_load_config", "tests\test_load_config\test_load_config.vcxproj", "{FAD361E1-1FD7-4993-BD20-7450026E51CC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_exception_directory", "tests\test_exception_directory\test_exception_directory.vcxproj", "{B6A37BAA-484D-4175-BEA2-62892A12E8F5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_tls", "tests\test_tls\test_tls.vcxproj", "{CFC22F11-2C5F-46F3-9C51-ED8C3E5EFA89}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_resources", "tests\test_resources\test_resources.vcxproj", "{8ECEF4F9-1461-4FCB-87D9-C871C71B01B7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_dotnet", "tests\test_dotnet\test_dotnet.vcxproj", "{F8A9C956-AA19-4AEF-B1B7-E7C392E437FE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_debug", "tests\test_debug\test_debug.vcxproj", "{B82FC407-B927-49D1-9DEB-0DFC3DC12A9C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_exports", "tests\test_exports\test_exports.vcxproj", "{82EAF17E-9618-4BD7-AE50-0C325591B585}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_bound_import", "tests\test_bound_import\test_bound_import.vcxproj", "{DA8A8F03-E719-45EF-A376-766A18772FA5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_resource_viewer", "tests\test_resource_viewer\test_resource_viewer.vcxproj", "{1FC3537C-EC13-4877-A06C-42DD8B81CBF3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_resource_manager", "tests\test_resource_manager\test_resource_manager.vcxproj", "{415A9FD5-59F6-4B1B-8EB8-EBD87E37EEA4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_resource_bitmap", "tests\test_resource_bitmap\test_resource_bitmap.vcxproj", "{F401B9A2-B8CB-477A-A515-F029D0AA5553}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_resource_icon_cursor", "tests\test_resource_icon_cursor\test_resource_icon_cursor.vcxproj", "{D9AC6F2E-3FE9-4D64-BEAA-C7104A0397B2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{6712270F-F056-4512-883A-1756A25D90E1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_resource_string_table", "tests\test_resource_string_table\test_resource_string_table.vcxproj", "{5E32A144-2F2D-4BB1-BBEF-13BE94414E99}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_resource_message_table", "tests\test_resource_message_table\test_resource_message_table.vcxproj", "{6CBACE55-8DDC-4EAE-A23A-DF412265D30C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_resource_version_info", "tests\test_resource_version_info\test_resource_version_info.vcxproj", "{5C2B081E-5414-437B-86EB-B2695AEDF3F0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7B7AEAB2-7755-409D-A6C9-D5FFB7D1A95A}.Debug|Win32.ActiveCfg = Debug|Win32 + {7B7AEAB2-7755-409D-A6C9-D5FFB7D1A95A}.Debug|Win32.Build.0 = Debug|Win32 + {7B7AEAB2-7755-409D-A6C9-D5FFB7D1A95A}.Debug|x64.ActiveCfg = Debug|x64 + {7B7AEAB2-7755-409D-A6C9-D5FFB7D1A95A}.Debug|x64.Build.0 = Debug|x64 + {7B7AEAB2-7755-409D-A6C9-D5FFB7D1A95A}.Release|Win32.ActiveCfg = Release|Win32 + {7B7AEAB2-7755-409D-A6C9-D5FFB7D1A95A}.Release|Win32.Build.0 = Release|Win32 + {7B7AEAB2-7755-409D-A6C9-D5FFB7D1A95A}.Release|x64.ActiveCfg = Release|x64 + {7B7AEAB2-7755-409D-A6C9-D5FFB7D1A95A}.Release|x64.Build.0 = Release|x64 + {853CFFF4-1FAB-48EB-81A9-CC35F9FB3F80}.Debug|Win32.ActiveCfg = Debug|Win32 + {853CFFF4-1FAB-48EB-81A9-CC35F9FB3F80}.Debug|Win32.Build.0 = Debug|Win32 + {853CFFF4-1FAB-48EB-81A9-CC35F9FB3F80}.Debug|x64.ActiveCfg = Debug|x64 + {853CFFF4-1FAB-48EB-81A9-CC35F9FB3F80}.Debug|x64.Build.0 = Debug|x64 + {853CFFF4-1FAB-48EB-81A9-CC35F9FB3F80}.Release|Win32.ActiveCfg = Release|Win32 + {853CFFF4-1FAB-48EB-81A9-CC35F9FB3F80}.Release|Win32.Build.0 = Release|Win32 + {853CFFF4-1FAB-48EB-81A9-CC35F9FB3F80}.Release|x64.ActiveCfg = Release|x64 + {853CFFF4-1FAB-48EB-81A9-CC35F9FB3F80}.Release|x64.Build.0 = Release|x64 + {114AC59B-BC28-40DB-8380-67C422D0C81B}.Debug|Win32.ActiveCfg = Debug|Win32 + {114AC59B-BC28-40DB-8380-67C422D0C81B}.Debug|Win32.Build.0 = Debug|Win32 + {114AC59B-BC28-40DB-8380-67C422D0C81B}.Debug|x64.ActiveCfg = Debug|x64 + {114AC59B-BC28-40DB-8380-67C422D0C81B}.Debug|x64.Build.0 = Debug|x64 + {114AC59B-BC28-40DB-8380-67C422D0C81B}.Release|Win32.ActiveCfg = Release|Win32 + {114AC59B-BC28-40DB-8380-67C422D0C81B}.Release|Win32.Build.0 = Release|Win32 + {114AC59B-BC28-40DB-8380-67C422D0C81B}.Release|x64.ActiveCfg = Release|x64 + {114AC59B-BC28-40DB-8380-67C422D0C81B}.Release|x64.Build.0 = Release|x64 + {7870A9AC-92BB-423B-BC03-FBF7B46CD338}.Debug|Win32.ActiveCfg = Debug|Win32 + {7870A9AC-92BB-423B-BC03-FBF7B46CD338}.Debug|Win32.Build.0 = Debug|Win32 + {7870A9AC-92BB-423B-BC03-FBF7B46CD338}.Debug|x64.ActiveCfg = Debug|x64 + {7870A9AC-92BB-423B-BC03-FBF7B46CD338}.Debug|x64.Build.0 = Debug|x64 + {7870A9AC-92BB-423B-BC03-FBF7B46CD338}.Release|Win32.ActiveCfg = Release|Win32 + {7870A9AC-92BB-423B-BC03-FBF7B46CD338}.Release|Win32.Build.0 = Release|Win32 + {7870A9AC-92BB-423B-BC03-FBF7B46CD338}.Release|x64.ActiveCfg = Release|x64 + {7870A9AC-92BB-423B-BC03-FBF7B46CD338}.Release|x64.Build.0 = Release|x64 + {50212477-1614-49C9-9791-4AC72025DC76}.Debug|Win32.ActiveCfg = Debug|Win32 + {50212477-1614-49C9-9791-4AC72025DC76}.Debug|Win32.Build.0 = Debug|Win32 + {50212477-1614-49C9-9791-4AC72025DC76}.Debug|x64.ActiveCfg = Debug|x64 + {50212477-1614-49C9-9791-4AC72025DC76}.Debug|x64.Build.0 = Debug|x64 + {50212477-1614-49C9-9791-4AC72025DC76}.Release|Win32.ActiveCfg = Release|Win32 + {50212477-1614-49C9-9791-4AC72025DC76}.Release|Win32.Build.0 = Release|Win32 + {50212477-1614-49C9-9791-4AC72025DC76}.Release|x64.ActiveCfg = Release|x64 + {50212477-1614-49C9-9791-4AC72025DC76}.Release|x64.Build.0 = Release|x64 + {132DFCC9-13EF-4178-9772-1C467FB296D6}.Debug|Win32.ActiveCfg = Debug|Win32 + {132DFCC9-13EF-4178-9772-1C467FB296D6}.Debug|Win32.Build.0 = Debug|Win32 + {132DFCC9-13EF-4178-9772-1C467FB296D6}.Debug|x64.ActiveCfg = Debug|x64 + {132DFCC9-13EF-4178-9772-1C467FB296D6}.Debug|x64.Build.0 = Debug|x64 + {132DFCC9-13EF-4178-9772-1C467FB296D6}.Release|Win32.ActiveCfg = Release|Win32 + {132DFCC9-13EF-4178-9772-1C467FB296D6}.Release|Win32.Build.0 = Release|Win32 + {132DFCC9-13EF-4178-9772-1C467FB296D6}.Release|x64.ActiveCfg = Release|x64 + {132DFCC9-13EF-4178-9772-1C467FB296D6}.Release|x64.Build.0 = Release|x64 + {CE1D0620-BC75-456F-914B-3BEBF5444B4C}.Debug|Win32.ActiveCfg = Debug|Win32 + {CE1D0620-BC75-456F-914B-3BEBF5444B4C}.Debug|Win32.Build.0 = Debug|Win32 + {CE1D0620-BC75-456F-914B-3BEBF5444B4C}.Debug|x64.ActiveCfg = Debug|x64 + {CE1D0620-BC75-456F-914B-3BEBF5444B4C}.Debug|x64.Build.0 = Debug|x64 + {CE1D0620-BC75-456F-914B-3BEBF5444B4C}.Release|Win32.ActiveCfg = Release|Win32 + {CE1D0620-BC75-456F-914B-3BEBF5444B4C}.Release|Win32.Build.0 = Release|Win32 + {CE1D0620-BC75-456F-914B-3BEBF5444B4C}.Release|x64.ActiveCfg = Release|x64 + {CE1D0620-BC75-456F-914B-3BEBF5444B4C}.Release|x64.Build.0 = Release|x64 + {709B0E41-9792-4A0A-B28B-CBD06CE441B9}.Debug|Win32.ActiveCfg = Debug|Win32 + {709B0E41-9792-4A0A-B28B-CBD06CE441B9}.Debug|Win32.Build.0 = Debug|Win32 + {709B0E41-9792-4A0A-B28B-CBD06CE441B9}.Debug|x64.ActiveCfg = Debug|x64 + {709B0E41-9792-4A0A-B28B-CBD06CE441B9}.Debug|x64.Build.0 = Debug|x64 + {709B0E41-9792-4A0A-B28B-CBD06CE441B9}.Release|Win32.ActiveCfg = Release|Win32 + {709B0E41-9792-4A0A-B28B-CBD06CE441B9}.Release|Win32.Build.0 = Release|Win32 + {709B0E41-9792-4A0A-B28B-CBD06CE441B9}.Release|x64.ActiveCfg = Release|x64 + {709B0E41-9792-4A0A-B28B-CBD06CE441B9}.Release|x64.Build.0 = Release|x64 + {FAD361E1-1FD7-4993-BD20-7450026E51CC}.Debug|Win32.ActiveCfg = Debug|Win32 + {FAD361E1-1FD7-4993-BD20-7450026E51CC}.Debug|Win32.Build.0 = Debug|Win32 + {FAD361E1-1FD7-4993-BD20-7450026E51CC}.Debug|x64.ActiveCfg = Debug|x64 + {FAD361E1-1FD7-4993-BD20-7450026E51CC}.Debug|x64.Build.0 = Debug|x64 + {FAD361E1-1FD7-4993-BD20-7450026E51CC}.Release|Win32.ActiveCfg = Release|Win32 + {FAD361E1-1FD7-4993-BD20-7450026E51CC}.Release|Win32.Build.0 = Release|Win32 + {FAD361E1-1FD7-4993-BD20-7450026E51CC}.Release|x64.ActiveCfg = Release|x64 + {FAD361E1-1FD7-4993-BD20-7450026E51CC}.Release|x64.Build.0 = Release|x64 + {B6A37BAA-484D-4175-BEA2-62892A12E8F5}.Debug|Win32.ActiveCfg = Debug|Win32 + {B6A37BAA-484D-4175-BEA2-62892A12E8F5}.Debug|Win32.Build.0 = Debug|Win32 + {B6A37BAA-484D-4175-BEA2-62892A12E8F5}.Debug|x64.ActiveCfg = Debug|x64 + {B6A37BAA-484D-4175-BEA2-62892A12E8F5}.Debug|x64.Build.0 = Debug|x64 + {B6A37BAA-484D-4175-BEA2-62892A12E8F5}.Release|Win32.ActiveCfg = Release|Win32 + {B6A37BAA-484D-4175-BEA2-62892A12E8F5}.Release|Win32.Build.0 = Release|Win32 + {B6A37BAA-484D-4175-BEA2-62892A12E8F5}.Release|x64.ActiveCfg = Release|x64 + {B6A37BAA-484D-4175-BEA2-62892A12E8F5}.Release|x64.Build.0 = Release|x64 + {CFC22F11-2C5F-46F3-9C51-ED8C3E5EFA89}.Debug|Win32.ActiveCfg = Debug|Win32 + {CFC22F11-2C5F-46F3-9C51-ED8C3E5EFA89}.Debug|Win32.Build.0 = Debug|Win32 + {CFC22F11-2C5F-46F3-9C51-ED8C3E5EFA89}.Debug|x64.ActiveCfg = Debug|x64 + {CFC22F11-2C5F-46F3-9C51-ED8C3E5EFA89}.Debug|x64.Build.0 = Debug|x64 + {CFC22F11-2C5F-46F3-9C51-ED8C3E5EFA89}.Release|Win32.ActiveCfg = Release|Win32 + {CFC22F11-2C5F-46F3-9C51-ED8C3E5EFA89}.Release|Win32.Build.0 = Release|Win32 + {CFC22F11-2C5F-46F3-9C51-ED8C3E5EFA89}.Release|x64.ActiveCfg = Release|x64 + {CFC22F11-2C5F-46F3-9C51-ED8C3E5EFA89}.Release|x64.Build.0 = Release|x64 + {8ECEF4F9-1461-4FCB-87D9-C871C71B01B7}.Debug|Win32.ActiveCfg = Debug|Win32 + {8ECEF4F9-1461-4FCB-87D9-C871C71B01B7}.Debug|Win32.Build.0 = Debug|Win32 + {8ECEF4F9-1461-4FCB-87D9-C871C71B01B7}.Debug|x64.ActiveCfg = Debug|x64 + {8ECEF4F9-1461-4FCB-87D9-C871C71B01B7}.Debug|x64.Build.0 = Debug|x64 + {8ECEF4F9-1461-4FCB-87D9-C871C71B01B7}.Release|Win32.ActiveCfg = Release|Win32 + {8ECEF4F9-1461-4FCB-87D9-C871C71B01B7}.Release|Win32.Build.0 = Release|Win32 + {8ECEF4F9-1461-4FCB-87D9-C871C71B01B7}.Release|x64.ActiveCfg = Release|x64 + {8ECEF4F9-1461-4FCB-87D9-C871C71B01B7}.Release|x64.Build.0 = Release|x64 + {F8A9C956-AA19-4AEF-B1B7-E7C392E437FE}.Debug|Win32.ActiveCfg = Debug|Win32 + {F8A9C956-AA19-4AEF-B1B7-E7C392E437FE}.Debug|Win32.Build.0 = Debug|Win32 + {F8A9C956-AA19-4AEF-B1B7-E7C392E437FE}.Debug|x64.ActiveCfg = Debug|x64 + {F8A9C956-AA19-4AEF-B1B7-E7C392E437FE}.Debug|x64.Build.0 = Debug|x64 + {F8A9C956-AA19-4AEF-B1B7-E7C392E437FE}.Release|Win32.ActiveCfg = Release|Win32 + {F8A9C956-AA19-4AEF-B1B7-E7C392E437FE}.Release|Win32.Build.0 = Release|Win32 + {F8A9C956-AA19-4AEF-B1B7-E7C392E437FE}.Release|x64.ActiveCfg = Release|x64 + {F8A9C956-AA19-4AEF-B1B7-E7C392E437FE}.Release|x64.Build.0 = Release|x64 + {B82FC407-B927-49D1-9DEB-0DFC3DC12A9C}.Debug|Win32.ActiveCfg = Debug|Win32 + {B82FC407-B927-49D1-9DEB-0DFC3DC12A9C}.Debug|Win32.Build.0 = Debug|Win32 + {B82FC407-B927-49D1-9DEB-0DFC3DC12A9C}.Debug|x64.ActiveCfg = Debug|x64 + {B82FC407-B927-49D1-9DEB-0DFC3DC12A9C}.Debug|x64.Build.0 = Debug|x64 + {B82FC407-B927-49D1-9DEB-0DFC3DC12A9C}.Release|Win32.ActiveCfg = Release|Win32 + {B82FC407-B927-49D1-9DEB-0DFC3DC12A9C}.Release|Win32.Build.0 = Release|Win32 + {B82FC407-B927-49D1-9DEB-0DFC3DC12A9C}.Release|x64.ActiveCfg = Release|x64 + {B82FC407-B927-49D1-9DEB-0DFC3DC12A9C}.Release|x64.Build.0 = Release|x64 + {82EAF17E-9618-4BD7-AE50-0C325591B585}.Debug|Win32.ActiveCfg = Debug|Win32 + {82EAF17E-9618-4BD7-AE50-0C325591B585}.Debug|Win32.Build.0 = Debug|Win32 + {82EAF17E-9618-4BD7-AE50-0C325591B585}.Debug|x64.ActiveCfg = Debug|x64 + {82EAF17E-9618-4BD7-AE50-0C325591B585}.Debug|x64.Build.0 = Debug|x64 + {82EAF17E-9618-4BD7-AE50-0C325591B585}.Release|Win32.ActiveCfg = Release|Win32 + {82EAF17E-9618-4BD7-AE50-0C325591B585}.Release|Win32.Build.0 = Release|Win32 + {82EAF17E-9618-4BD7-AE50-0C325591B585}.Release|x64.ActiveCfg = Release|x64 + {82EAF17E-9618-4BD7-AE50-0C325591B585}.Release|x64.Build.0 = Release|x64 + {DA8A8F03-E719-45EF-A376-766A18772FA5}.Debug|Win32.ActiveCfg = Debug|Win32 + {DA8A8F03-E719-45EF-A376-766A18772FA5}.Debug|Win32.Build.0 = Debug|Win32 + {DA8A8F03-E719-45EF-A376-766A18772FA5}.Debug|x64.ActiveCfg = Debug|x64 + {DA8A8F03-E719-45EF-A376-766A18772FA5}.Debug|x64.Build.0 = Debug|x64 + {DA8A8F03-E719-45EF-A376-766A18772FA5}.Release|Win32.ActiveCfg = Release|Win32 + {DA8A8F03-E719-45EF-A376-766A18772FA5}.Release|Win32.Build.0 = Release|Win32 + {DA8A8F03-E719-45EF-A376-766A18772FA5}.Release|x64.ActiveCfg = Release|x64 + {DA8A8F03-E719-45EF-A376-766A18772FA5}.Release|x64.Build.0 = Release|x64 + {1FC3537C-EC13-4877-A06C-42DD8B81CBF3}.Debug|Win32.ActiveCfg = Debug|Win32 + {1FC3537C-EC13-4877-A06C-42DD8B81CBF3}.Debug|Win32.Build.0 = Debug|Win32 + {1FC3537C-EC13-4877-A06C-42DD8B81CBF3}.Debug|x64.ActiveCfg = Debug|x64 + {1FC3537C-EC13-4877-A06C-42DD8B81CBF3}.Debug|x64.Build.0 = Debug|x64 + {1FC3537C-EC13-4877-A06C-42DD8B81CBF3}.Release|Win32.ActiveCfg = Release|Win32 + {1FC3537C-EC13-4877-A06C-42DD8B81CBF3}.Release|Win32.Build.0 = Release|Win32 + {1FC3537C-EC13-4877-A06C-42DD8B81CBF3}.Release|x64.ActiveCfg = Release|x64 + {1FC3537C-EC13-4877-A06C-42DD8B81CBF3}.Release|x64.Build.0 = Release|x64 + {415A9FD5-59F6-4B1B-8EB8-EBD87E37EEA4}.Debug|Win32.ActiveCfg = Debug|Win32 + {415A9FD5-59F6-4B1B-8EB8-EBD87E37EEA4}.Debug|Win32.Build.0 = Debug|Win32 + {415A9FD5-59F6-4B1B-8EB8-EBD87E37EEA4}.Debug|x64.ActiveCfg = Debug|x64 + {415A9FD5-59F6-4B1B-8EB8-EBD87E37EEA4}.Debug|x64.Build.0 = Debug|x64 + {415A9FD5-59F6-4B1B-8EB8-EBD87E37EEA4}.Release|Win32.ActiveCfg = Release|Win32 + {415A9FD5-59F6-4B1B-8EB8-EBD87E37EEA4}.Release|Win32.Build.0 = Release|Win32 + {415A9FD5-59F6-4B1B-8EB8-EBD87E37EEA4}.Release|x64.ActiveCfg = Release|x64 + {415A9FD5-59F6-4B1B-8EB8-EBD87E37EEA4}.Release|x64.Build.0 = Release|x64 + {F401B9A2-B8CB-477A-A515-F029D0AA5553}.Debug|Win32.ActiveCfg = Debug|Win32 + {F401B9A2-B8CB-477A-A515-F029D0AA5553}.Debug|Win32.Build.0 = Debug|Win32 + {F401B9A2-B8CB-477A-A515-F029D0AA5553}.Debug|x64.ActiveCfg = Debug|x64 + {F401B9A2-B8CB-477A-A515-F029D0AA5553}.Debug|x64.Build.0 = Debug|x64 + {F401B9A2-B8CB-477A-A515-F029D0AA5553}.Release|Win32.ActiveCfg = Release|Win32 + {F401B9A2-B8CB-477A-A515-F029D0AA5553}.Release|Win32.Build.0 = Release|Win32 + {F401B9A2-B8CB-477A-A515-F029D0AA5553}.Release|x64.ActiveCfg = Release|x64 + {F401B9A2-B8CB-477A-A515-F029D0AA5553}.Release|x64.Build.0 = Release|x64 + {D9AC6F2E-3FE9-4D64-BEAA-C7104A0397B2}.Debug|Win32.ActiveCfg = Debug|Win32 + {D9AC6F2E-3FE9-4D64-BEAA-C7104A0397B2}.Debug|Win32.Build.0 = Debug|Win32 + {D9AC6F2E-3FE9-4D64-BEAA-C7104A0397B2}.Debug|x64.ActiveCfg = Debug|x64 + {D9AC6F2E-3FE9-4D64-BEAA-C7104A0397B2}.Debug|x64.Build.0 = Debug|x64 + {D9AC6F2E-3FE9-4D64-BEAA-C7104A0397B2}.Release|Win32.ActiveCfg = Release|Win32 + {D9AC6F2E-3FE9-4D64-BEAA-C7104A0397B2}.Release|Win32.Build.0 = Release|Win32 + {D9AC6F2E-3FE9-4D64-BEAA-C7104A0397B2}.Release|x64.ActiveCfg = Release|x64 + {D9AC6F2E-3FE9-4D64-BEAA-C7104A0397B2}.Release|x64.Build.0 = Release|x64 + {5E32A144-2F2D-4BB1-BBEF-13BE94414E99}.Debug|Win32.ActiveCfg = Debug|Win32 + {5E32A144-2F2D-4BB1-BBEF-13BE94414E99}.Debug|Win32.Build.0 = Debug|Win32 + {5E32A144-2F2D-4BB1-BBEF-13BE94414E99}.Debug|x64.ActiveCfg = Debug|x64 + {5E32A144-2F2D-4BB1-BBEF-13BE94414E99}.Debug|x64.Build.0 = Debug|x64 + {5E32A144-2F2D-4BB1-BBEF-13BE94414E99}.Release|Win32.ActiveCfg = Release|Win32 + {5E32A144-2F2D-4BB1-BBEF-13BE94414E99}.Release|Win32.Build.0 = Release|Win32 + {5E32A144-2F2D-4BB1-BBEF-13BE94414E99}.Release|x64.ActiveCfg = Release|x64 + {5E32A144-2F2D-4BB1-BBEF-13BE94414E99}.Release|x64.Build.0 = Release|x64 + {6CBACE55-8DDC-4EAE-A23A-DF412265D30C}.Debug|Win32.ActiveCfg = Debug|Win32 + {6CBACE55-8DDC-4EAE-A23A-DF412265D30C}.Debug|Win32.Build.0 = Debug|Win32 + {6CBACE55-8DDC-4EAE-A23A-DF412265D30C}.Debug|x64.ActiveCfg = Debug|x64 + {6CBACE55-8DDC-4EAE-A23A-DF412265D30C}.Debug|x64.Build.0 = Debug|x64 + {6CBACE55-8DDC-4EAE-A23A-DF412265D30C}.Release|Win32.ActiveCfg = Release|Win32 + {6CBACE55-8DDC-4EAE-A23A-DF412265D30C}.Release|Win32.Build.0 = Release|Win32 + {6CBACE55-8DDC-4EAE-A23A-DF412265D30C}.Release|x64.ActiveCfg = Release|x64 + {6CBACE55-8DDC-4EAE-A23A-DF412265D30C}.Release|x64.Build.0 = Release|x64 + {5C2B081E-5414-437B-86EB-B2695AEDF3F0}.Debug|Win32.ActiveCfg = Debug|Win32 + {5C2B081E-5414-437B-86EB-B2695AEDF3F0}.Debug|Win32.Build.0 = Debug|Win32 + {5C2B081E-5414-437B-86EB-B2695AEDF3F0}.Debug|x64.ActiveCfg = Debug|x64 + {5C2B081E-5414-437B-86EB-B2695AEDF3F0}.Debug|x64.Build.0 = Debug|x64 + {5C2B081E-5414-437B-86EB-B2695AEDF3F0}.Release|Win32.ActiveCfg = Release|Win32 + {5C2B081E-5414-437B-86EB-B2695AEDF3F0}.Release|Win32.Build.0 = Release|Win32 + {5C2B081E-5414-437B-86EB-B2695AEDF3F0}.Release|x64.ActiveCfg = Release|x64 + {5C2B081E-5414-437B-86EB-B2695AEDF3F0}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {853CFFF4-1FAB-48EB-81A9-CC35F9FB3F80} = {6712270F-F056-4512-883A-1756A25D90E1} + {114AC59B-BC28-40DB-8380-67C422D0C81B} = {6712270F-F056-4512-883A-1756A25D90E1} + {7870A9AC-92BB-423B-BC03-FBF7B46CD338} = {6712270F-F056-4512-883A-1756A25D90E1} + {50212477-1614-49C9-9791-4AC72025DC76} = {6712270F-F056-4512-883A-1756A25D90E1} + {CE1D0620-BC75-456F-914B-3BEBF5444B4C} = {6712270F-F056-4512-883A-1756A25D90E1} + {709B0E41-9792-4A0A-B28B-CBD06CE441B9} = {6712270F-F056-4512-883A-1756A25D90E1} + {FAD361E1-1FD7-4993-BD20-7450026E51CC} = {6712270F-F056-4512-883A-1756A25D90E1} + {B6A37BAA-484D-4175-BEA2-62892A12E8F5} = {6712270F-F056-4512-883A-1756A25D90E1} + {CFC22F11-2C5F-46F3-9C51-ED8C3E5EFA89} = {6712270F-F056-4512-883A-1756A25D90E1} + {8ECEF4F9-1461-4FCB-87D9-C871C71B01B7} = {6712270F-F056-4512-883A-1756A25D90E1} + {F8A9C956-AA19-4AEF-B1B7-E7C392E437FE} = {6712270F-F056-4512-883A-1756A25D90E1} + {B82FC407-B927-49D1-9DEB-0DFC3DC12A9C} = {6712270F-F056-4512-883A-1756A25D90E1} + {82EAF17E-9618-4BD7-AE50-0C325591B585} = {6712270F-F056-4512-883A-1756A25D90E1} + {DA8A8F03-E719-45EF-A376-766A18772FA5} = {6712270F-F056-4512-883A-1756A25D90E1} + {1FC3537C-EC13-4877-A06C-42DD8B81CBF3} = {6712270F-F056-4512-883A-1756A25D90E1} + {415A9FD5-59F6-4B1B-8EB8-EBD87E37EEA4} = {6712270F-F056-4512-883A-1756A25D90E1} + {F401B9A2-B8CB-477A-A515-F029D0AA5553} = {6712270F-F056-4512-883A-1756A25D90E1} + {D9AC6F2E-3FE9-4D64-BEAA-C7104A0397B2} = {6712270F-F056-4512-883A-1756A25D90E1} + {7B7AEAB2-7755-409D-A6C9-D5FFB7D1A95A} = {6712270F-F056-4512-883A-1756A25D90E1} + {5E32A144-2F2D-4BB1-BBEF-13BE94414E99} = {6712270F-F056-4512-883A-1756A25D90E1} + {6CBACE55-8DDC-4EAE-A23A-DF412265D30C} = {6712270F-F056-4512-883A-1756A25D90E1} + {5C2B081E-5414-437B-86EB-B2695AEDF3F0} = {6712270F-F056-4512-883A-1756A25D90E1} + EndGlobalSection +EndGlobal diff --git a/irdb-lib/pebliss/trunk/pe_bliss_tests_vc9.sln b/irdb-lib/pebliss/trunk/pe_bliss_tests_vc9.sln new file mode 100644 index 0000000000000000000000000000000000000000..11ccb577a69e14fe599bc9cc344aa3e21a42d26e --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_bliss_tests_vc9.sln @@ -0,0 +1,272 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_runner", "tests\test_runner\test_runner.vcproj", "{31843E48-DC9A-4887-BD97-328079D78C88}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{FB42AFF5-C8AA-495F-A397-E073D1A03BDE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_bound_import", "tests\test_bound_import\test_bound_import.vcproj", "{6EBEAFA6-7489-4026-83D1-CAF67D243119}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_checksum", "tests\test_checksum\test_checksum.vcproj", "{7F95DC75-2CFA-4D0D-BD43-1BF6749F16EE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_dotnet", "tests\test_dotnet\test_dotnet.vcproj", "{094A7331-54E1-4034-BD1E-BE2F974B0142}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_debug", "tests\test_debug\test_debug.vcproj", "{42AC1521-0800-4D81-9363-6EF9362F7A4A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_entropy", "tests\test_entropy\test_entropy.vcproj", "{D3FAD2A8-FF48-4E59-A347-C54AD9DB6AC4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_exception_directory", "tests\test_exception_directory\test_exception_directory.vcproj", "{1C36ED94-CBE5-4107-83B6-9C37F3A4041C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_exports", "tests\test_exports\test_exports.vcproj", "{E126644C-38FF-41EF-9EAF-ED8C9FCF62EF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_imports", "tests\test_imports\test_imports.vcproj", "{BD969F96-E5A5-47B2-B5EF-B7999A441CE5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_load_config", "tests\test_load_config\test_load_config.vcproj", "{089E9482-33DD-4C64-84A1-C9B5F10F802A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_relocations", "tests\test_relocations\test_relocations.vcproj", "{997A89F0-372D-4306-AE4D-7438D93273C3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_resource_bitmap", "tests\test_resource_bitmap\test_resource_bitmap.vcproj", "{1B337DC2-628E-4DA4-8C0F-A6880289C6E2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_resource_icon_cursor", "tests\test_resource_icon_cursor\test_resource_icon_cursor.vcproj", "{1E59538C-2C78-4D35-8639-568890543A4A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_resource_manager", "tests\test_resource_manager\test_resource_manager.vcproj", "{39E1826B-5436-47D3-9B95-D3C667691461}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_resource_message_table", "tests\test_resource_message_table\test_resource_message_table.vcproj", "{57EFEFC9-E2D9-418E-9F05-3FD0D9921251}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_resource_string_table", "tests\test_resource_string_table\test_resource_string_table.vcproj", "{C68A466D-0C1B-40BC-9AB1-49B582958524}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_resource_version_info", "tests\test_resource_version_info\test_resource_version_info.vcproj", "{C30B270A-4C93-44A3-AABE-633713D0F1D7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_resource_viewer", "tests\test_resource_viewer\test_resource_viewer.vcproj", "{DD6C58C3-6DD5-43B2-A9ED-760E5F5830AA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_resources", "tests\test_resources\test_resources.vcproj", "{7E3867A9-59BC-4441-A74E-F4ABFFEE231C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_rich_data", "tests\test_rich_data\test_rich_data.vcproj", "{1F877026-3D94-41BF-B392-06DFAF67AE34}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_tls", "tests\test_tls\test_tls.vcproj", "{63D80BC8-EB14-4698-A391-4A41AC15E8D1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests_basic", "tests\tests_basic\tests_basic.vcproj", "{3451AE03-3363-445B-8DA8-94B197563D59}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests_utils", "tests\tests_utils\tests_utils.vcproj", "{B0478C25-73AD-4085-BA1A-DDF66431EB6E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {31843E48-DC9A-4887-BD97-328079D78C88}.Debug|Win32.ActiveCfg = Debug|Win32 + {31843E48-DC9A-4887-BD97-328079D78C88}.Debug|Win32.Build.0 = Debug|Win32 + {31843E48-DC9A-4887-BD97-328079D78C88}.Debug|x64.ActiveCfg = Debug|x64 + {31843E48-DC9A-4887-BD97-328079D78C88}.Debug|x64.Build.0 = Debug|x64 + {31843E48-DC9A-4887-BD97-328079D78C88}.Release|Win32.ActiveCfg = Release|Win32 + {31843E48-DC9A-4887-BD97-328079D78C88}.Release|Win32.Build.0 = Release|Win32 + {31843E48-DC9A-4887-BD97-328079D78C88}.Release|x64.ActiveCfg = Release|x64 + {31843E48-DC9A-4887-BD97-328079D78C88}.Release|x64.Build.0 = Release|x64 + {6EBEAFA6-7489-4026-83D1-CAF67D243119}.Debug|Win32.ActiveCfg = Debug|Win32 + {6EBEAFA6-7489-4026-83D1-CAF67D243119}.Debug|Win32.Build.0 = Debug|Win32 + {6EBEAFA6-7489-4026-83D1-CAF67D243119}.Debug|x64.ActiveCfg = Debug|x64 + {6EBEAFA6-7489-4026-83D1-CAF67D243119}.Debug|x64.Build.0 = Debug|x64 + {6EBEAFA6-7489-4026-83D1-CAF67D243119}.Release|Win32.ActiveCfg = Release|Win32 + {6EBEAFA6-7489-4026-83D1-CAF67D243119}.Release|Win32.Build.0 = Release|Win32 + {6EBEAFA6-7489-4026-83D1-CAF67D243119}.Release|x64.ActiveCfg = Release|x64 + {6EBEAFA6-7489-4026-83D1-CAF67D243119}.Release|x64.Build.0 = Release|x64 + {7F95DC75-2CFA-4D0D-BD43-1BF6749F16EE}.Debug|Win32.ActiveCfg = Debug|Win32 + {7F95DC75-2CFA-4D0D-BD43-1BF6749F16EE}.Debug|Win32.Build.0 = Debug|Win32 + {7F95DC75-2CFA-4D0D-BD43-1BF6749F16EE}.Debug|x64.ActiveCfg = Debug|x64 + {7F95DC75-2CFA-4D0D-BD43-1BF6749F16EE}.Debug|x64.Build.0 = Debug|x64 + {7F95DC75-2CFA-4D0D-BD43-1BF6749F16EE}.Release|Win32.ActiveCfg = Release|Win32 + {7F95DC75-2CFA-4D0D-BD43-1BF6749F16EE}.Release|Win32.Build.0 = Release|Win32 + {7F95DC75-2CFA-4D0D-BD43-1BF6749F16EE}.Release|x64.ActiveCfg = Release|x64 + {7F95DC75-2CFA-4D0D-BD43-1BF6749F16EE}.Release|x64.Build.0 = Release|x64 + {094A7331-54E1-4034-BD1E-BE2F974B0142}.Debug|Win32.ActiveCfg = Debug|Win32 + {094A7331-54E1-4034-BD1E-BE2F974B0142}.Debug|Win32.Build.0 = Debug|Win32 + {094A7331-54E1-4034-BD1E-BE2F974B0142}.Debug|x64.ActiveCfg = Debug|x64 + {094A7331-54E1-4034-BD1E-BE2F974B0142}.Debug|x64.Build.0 = Debug|x64 + {094A7331-54E1-4034-BD1E-BE2F974B0142}.Release|Win32.ActiveCfg = Release|Win32 + {094A7331-54E1-4034-BD1E-BE2F974B0142}.Release|Win32.Build.0 = Release|Win32 + {094A7331-54E1-4034-BD1E-BE2F974B0142}.Release|x64.ActiveCfg = Release|x64 + {094A7331-54E1-4034-BD1E-BE2F974B0142}.Release|x64.Build.0 = Release|x64 + {42AC1521-0800-4D81-9363-6EF9362F7A4A}.Debug|Win32.ActiveCfg = Debug|Win32 + {42AC1521-0800-4D81-9363-6EF9362F7A4A}.Debug|Win32.Build.0 = Debug|Win32 + {42AC1521-0800-4D81-9363-6EF9362F7A4A}.Debug|x64.ActiveCfg = Debug|x64 + {42AC1521-0800-4D81-9363-6EF9362F7A4A}.Debug|x64.Build.0 = Debug|x64 + {42AC1521-0800-4D81-9363-6EF9362F7A4A}.Release|Win32.ActiveCfg = Release|Win32 + {42AC1521-0800-4D81-9363-6EF9362F7A4A}.Release|Win32.Build.0 = Release|Win32 + {42AC1521-0800-4D81-9363-6EF9362F7A4A}.Release|x64.ActiveCfg = Release|x64 + {42AC1521-0800-4D81-9363-6EF9362F7A4A}.Release|x64.Build.0 = Release|x64 + {D3FAD2A8-FF48-4E59-A347-C54AD9DB6AC4}.Debug|Win32.ActiveCfg = Debug|Win32 + {D3FAD2A8-FF48-4E59-A347-C54AD9DB6AC4}.Debug|Win32.Build.0 = Debug|Win32 + {D3FAD2A8-FF48-4E59-A347-C54AD9DB6AC4}.Debug|x64.ActiveCfg = Debug|x64 + {D3FAD2A8-FF48-4E59-A347-C54AD9DB6AC4}.Debug|x64.Build.0 = Debug|x64 + {D3FAD2A8-FF48-4E59-A347-C54AD9DB6AC4}.Release|Win32.ActiveCfg = Release|Win32 + {D3FAD2A8-FF48-4E59-A347-C54AD9DB6AC4}.Release|Win32.Build.0 = Release|Win32 + {D3FAD2A8-FF48-4E59-A347-C54AD9DB6AC4}.Release|x64.ActiveCfg = Release|x64 + {D3FAD2A8-FF48-4E59-A347-C54AD9DB6AC4}.Release|x64.Build.0 = Release|x64 + {1C36ED94-CBE5-4107-83B6-9C37F3A4041C}.Debug|Win32.ActiveCfg = Debug|Win32 + {1C36ED94-CBE5-4107-83B6-9C37F3A4041C}.Debug|Win32.Build.0 = Debug|Win32 + {1C36ED94-CBE5-4107-83B6-9C37F3A4041C}.Debug|x64.ActiveCfg = Debug|x64 + {1C36ED94-CBE5-4107-83B6-9C37F3A4041C}.Debug|x64.Build.0 = Debug|x64 + {1C36ED94-CBE5-4107-83B6-9C37F3A4041C}.Release|Win32.ActiveCfg = Release|Win32 + {1C36ED94-CBE5-4107-83B6-9C37F3A4041C}.Release|Win32.Build.0 = Release|Win32 + {1C36ED94-CBE5-4107-83B6-9C37F3A4041C}.Release|x64.ActiveCfg = Release|x64 + {1C36ED94-CBE5-4107-83B6-9C37F3A4041C}.Release|x64.Build.0 = Release|x64 + {E126644C-38FF-41EF-9EAF-ED8C9FCF62EF}.Debug|Win32.ActiveCfg = Debug|Win32 + {E126644C-38FF-41EF-9EAF-ED8C9FCF62EF}.Debug|Win32.Build.0 = Debug|Win32 + {E126644C-38FF-41EF-9EAF-ED8C9FCF62EF}.Debug|x64.ActiveCfg = Debug|x64 + {E126644C-38FF-41EF-9EAF-ED8C9FCF62EF}.Debug|x64.Build.0 = Debug|x64 + {E126644C-38FF-41EF-9EAF-ED8C9FCF62EF}.Release|Win32.ActiveCfg = Release|Win32 + {E126644C-38FF-41EF-9EAF-ED8C9FCF62EF}.Release|Win32.Build.0 = Release|Win32 + {E126644C-38FF-41EF-9EAF-ED8C9FCF62EF}.Release|x64.ActiveCfg = Release|x64 + {E126644C-38FF-41EF-9EAF-ED8C9FCF62EF}.Release|x64.Build.0 = Release|x64 + {BD969F96-E5A5-47B2-B5EF-B7999A441CE5}.Debug|Win32.ActiveCfg = Debug|Win32 + {BD969F96-E5A5-47B2-B5EF-B7999A441CE5}.Debug|Win32.Build.0 = Debug|Win32 + {BD969F96-E5A5-47B2-B5EF-B7999A441CE5}.Debug|x64.ActiveCfg = Debug|x64 + {BD969F96-E5A5-47B2-B5EF-B7999A441CE5}.Debug|x64.Build.0 = Debug|x64 + {BD969F96-E5A5-47B2-B5EF-B7999A441CE5}.Release|Win32.ActiveCfg = Release|Win32 + {BD969F96-E5A5-47B2-B5EF-B7999A441CE5}.Release|Win32.Build.0 = Release|Win32 + {BD969F96-E5A5-47B2-B5EF-B7999A441CE5}.Release|x64.ActiveCfg = Release|x64 + {BD969F96-E5A5-47B2-B5EF-B7999A441CE5}.Release|x64.Build.0 = Release|x64 + {089E9482-33DD-4C64-84A1-C9B5F10F802A}.Debug|Win32.ActiveCfg = Debug|Win32 + {089E9482-33DD-4C64-84A1-C9B5F10F802A}.Debug|Win32.Build.0 = Debug|Win32 + {089E9482-33DD-4C64-84A1-C9B5F10F802A}.Debug|x64.ActiveCfg = Debug|x64 + {089E9482-33DD-4C64-84A1-C9B5F10F802A}.Debug|x64.Build.0 = Debug|x64 + {089E9482-33DD-4C64-84A1-C9B5F10F802A}.Release|Win32.ActiveCfg = Release|Win32 + {089E9482-33DD-4C64-84A1-C9B5F10F802A}.Release|Win32.Build.0 = Release|Win32 + {089E9482-33DD-4C64-84A1-C9B5F10F802A}.Release|x64.ActiveCfg = Release|x64 + {089E9482-33DD-4C64-84A1-C9B5F10F802A}.Release|x64.Build.0 = Release|x64 + {997A89F0-372D-4306-AE4D-7438D93273C3}.Debug|Win32.ActiveCfg = Debug|Win32 + {997A89F0-372D-4306-AE4D-7438D93273C3}.Debug|Win32.Build.0 = Debug|Win32 + {997A89F0-372D-4306-AE4D-7438D93273C3}.Debug|x64.ActiveCfg = Debug|x64 + {997A89F0-372D-4306-AE4D-7438D93273C3}.Debug|x64.Build.0 = Debug|x64 + {997A89F0-372D-4306-AE4D-7438D93273C3}.Release|Win32.ActiveCfg = Release|Win32 + {997A89F0-372D-4306-AE4D-7438D93273C3}.Release|Win32.Build.0 = Release|Win32 + {997A89F0-372D-4306-AE4D-7438D93273C3}.Release|x64.ActiveCfg = Release|x64 + {997A89F0-372D-4306-AE4D-7438D93273C3}.Release|x64.Build.0 = Release|x64 + {1B337DC2-628E-4DA4-8C0F-A6880289C6E2}.Debug|Win32.ActiveCfg = Debug|Win32 + {1B337DC2-628E-4DA4-8C0F-A6880289C6E2}.Debug|Win32.Build.0 = Debug|Win32 + {1B337DC2-628E-4DA4-8C0F-A6880289C6E2}.Debug|x64.ActiveCfg = Debug|x64 + {1B337DC2-628E-4DA4-8C0F-A6880289C6E2}.Debug|x64.Build.0 = Debug|x64 + {1B337DC2-628E-4DA4-8C0F-A6880289C6E2}.Release|Win32.ActiveCfg = Release|Win32 + {1B337DC2-628E-4DA4-8C0F-A6880289C6E2}.Release|Win32.Build.0 = Release|Win32 + {1B337DC2-628E-4DA4-8C0F-A6880289C6E2}.Release|x64.ActiveCfg = Release|x64 + {1B337DC2-628E-4DA4-8C0F-A6880289C6E2}.Release|x64.Build.0 = Release|x64 + {1E59538C-2C78-4D35-8639-568890543A4A}.Debug|Win32.ActiveCfg = Debug|Win32 + {1E59538C-2C78-4D35-8639-568890543A4A}.Debug|Win32.Build.0 = Debug|Win32 + {1E59538C-2C78-4D35-8639-568890543A4A}.Debug|x64.ActiveCfg = Debug|x64 + {1E59538C-2C78-4D35-8639-568890543A4A}.Debug|x64.Build.0 = Debug|x64 + {1E59538C-2C78-4D35-8639-568890543A4A}.Release|Win32.ActiveCfg = Release|Win32 + {1E59538C-2C78-4D35-8639-568890543A4A}.Release|Win32.Build.0 = Release|Win32 + {1E59538C-2C78-4D35-8639-568890543A4A}.Release|x64.ActiveCfg = Release|x64 + {1E59538C-2C78-4D35-8639-568890543A4A}.Release|x64.Build.0 = Release|x64 + {39E1826B-5436-47D3-9B95-D3C667691461}.Debug|Win32.ActiveCfg = Debug|Win32 + {39E1826B-5436-47D3-9B95-D3C667691461}.Debug|Win32.Build.0 = Debug|Win32 + {39E1826B-5436-47D3-9B95-D3C667691461}.Debug|x64.ActiveCfg = Debug|x64 + {39E1826B-5436-47D3-9B95-D3C667691461}.Debug|x64.Build.0 = Debug|x64 + {39E1826B-5436-47D3-9B95-D3C667691461}.Release|Win32.ActiveCfg = Release|Win32 + {39E1826B-5436-47D3-9B95-D3C667691461}.Release|Win32.Build.0 = Release|Win32 + {39E1826B-5436-47D3-9B95-D3C667691461}.Release|x64.ActiveCfg = Release|x64 + {39E1826B-5436-47D3-9B95-D3C667691461}.Release|x64.Build.0 = Release|x64 + {57EFEFC9-E2D9-418E-9F05-3FD0D9921251}.Debug|Win32.ActiveCfg = Debug|Win32 + {57EFEFC9-E2D9-418E-9F05-3FD0D9921251}.Debug|Win32.Build.0 = Debug|Win32 + {57EFEFC9-E2D9-418E-9F05-3FD0D9921251}.Debug|x64.ActiveCfg = Debug|x64 + {57EFEFC9-E2D9-418E-9F05-3FD0D9921251}.Debug|x64.Build.0 = Debug|x64 + {57EFEFC9-E2D9-418E-9F05-3FD0D9921251}.Release|Win32.ActiveCfg = Release|Win32 + {57EFEFC9-E2D9-418E-9F05-3FD0D9921251}.Release|Win32.Build.0 = Release|Win32 + {57EFEFC9-E2D9-418E-9F05-3FD0D9921251}.Release|x64.ActiveCfg = Release|x64 + {57EFEFC9-E2D9-418E-9F05-3FD0D9921251}.Release|x64.Build.0 = Release|x64 + {C68A466D-0C1B-40BC-9AB1-49B582958524}.Debug|Win32.ActiveCfg = Debug|Win32 + {C68A466D-0C1B-40BC-9AB1-49B582958524}.Debug|Win32.Build.0 = Debug|Win32 + {C68A466D-0C1B-40BC-9AB1-49B582958524}.Debug|x64.ActiveCfg = Debug|x64 + {C68A466D-0C1B-40BC-9AB1-49B582958524}.Debug|x64.Build.0 = Debug|x64 + {C68A466D-0C1B-40BC-9AB1-49B582958524}.Release|Win32.ActiveCfg = Release|Win32 + {C68A466D-0C1B-40BC-9AB1-49B582958524}.Release|Win32.Build.0 = Release|Win32 + {C68A466D-0C1B-40BC-9AB1-49B582958524}.Release|x64.ActiveCfg = Release|x64 + {C68A466D-0C1B-40BC-9AB1-49B582958524}.Release|x64.Build.0 = Release|x64 + {C30B270A-4C93-44A3-AABE-633713D0F1D7}.Debug|Win32.ActiveCfg = Debug|Win32 + {C30B270A-4C93-44A3-AABE-633713D0F1D7}.Debug|Win32.Build.0 = Debug|Win32 + {C30B270A-4C93-44A3-AABE-633713D0F1D7}.Debug|x64.ActiveCfg = Debug|x64 + {C30B270A-4C93-44A3-AABE-633713D0F1D7}.Debug|x64.Build.0 = Debug|x64 + {C30B270A-4C93-44A3-AABE-633713D0F1D7}.Release|Win32.ActiveCfg = Release|Win32 + {C30B270A-4C93-44A3-AABE-633713D0F1D7}.Release|Win32.Build.0 = Release|Win32 + {C30B270A-4C93-44A3-AABE-633713D0F1D7}.Release|x64.ActiveCfg = Release|x64 + {C30B270A-4C93-44A3-AABE-633713D0F1D7}.Release|x64.Build.0 = Release|x64 + {DD6C58C3-6DD5-43B2-A9ED-760E5F5830AA}.Debug|Win32.ActiveCfg = Debug|Win32 + {DD6C58C3-6DD5-43B2-A9ED-760E5F5830AA}.Debug|Win32.Build.0 = Debug|Win32 + {DD6C58C3-6DD5-43B2-A9ED-760E5F5830AA}.Debug|x64.ActiveCfg = Debug|x64 + {DD6C58C3-6DD5-43B2-A9ED-760E5F5830AA}.Debug|x64.Build.0 = Debug|x64 + {DD6C58C3-6DD5-43B2-A9ED-760E5F5830AA}.Release|Win32.ActiveCfg = Release|Win32 + {DD6C58C3-6DD5-43B2-A9ED-760E5F5830AA}.Release|Win32.Build.0 = Release|Win32 + {DD6C58C3-6DD5-43B2-A9ED-760E5F5830AA}.Release|x64.ActiveCfg = Release|x64 + {DD6C58C3-6DD5-43B2-A9ED-760E5F5830AA}.Release|x64.Build.0 = Release|x64 + {7E3867A9-59BC-4441-A74E-F4ABFFEE231C}.Debug|Win32.ActiveCfg = Debug|Win32 + {7E3867A9-59BC-4441-A74E-F4ABFFEE231C}.Debug|Win32.Build.0 = Debug|Win32 + {7E3867A9-59BC-4441-A74E-F4ABFFEE231C}.Debug|x64.ActiveCfg = Debug|x64 + {7E3867A9-59BC-4441-A74E-F4ABFFEE231C}.Debug|x64.Build.0 = Debug|x64 + {7E3867A9-59BC-4441-A74E-F4ABFFEE231C}.Release|Win32.ActiveCfg = Release|Win32 + {7E3867A9-59BC-4441-A74E-F4ABFFEE231C}.Release|Win32.Build.0 = Release|Win32 + {7E3867A9-59BC-4441-A74E-F4ABFFEE231C}.Release|x64.ActiveCfg = Release|x64 + {7E3867A9-59BC-4441-A74E-F4ABFFEE231C}.Release|x64.Build.0 = Release|x64 + {1F877026-3D94-41BF-B392-06DFAF67AE34}.Debug|Win32.ActiveCfg = Debug|Win32 + {1F877026-3D94-41BF-B392-06DFAF67AE34}.Debug|Win32.Build.0 = Debug|Win32 + {1F877026-3D94-41BF-B392-06DFAF67AE34}.Debug|x64.ActiveCfg = Debug|x64 + {1F877026-3D94-41BF-B392-06DFAF67AE34}.Debug|x64.Build.0 = Debug|x64 + {1F877026-3D94-41BF-B392-06DFAF67AE34}.Release|Win32.ActiveCfg = Release|Win32 + {1F877026-3D94-41BF-B392-06DFAF67AE34}.Release|Win32.Build.0 = Release|Win32 + {1F877026-3D94-41BF-B392-06DFAF67AE34}.Release|x64.ActiveCfg = Release|x64 + {1F877026-3D94-41BF-B392-06DFAF67AE34}.Release|x64.Build.0 = Release|x64 + {63D80BC8-EB14-4698-A391-4A41AC15E8D1}.Debug|Win32.ActiveCfg = Debug|Win32 + {63D80BC8-EB14-4698-A391-4A41AC15E8D1}.Debug|Win32.Build.0 = Debug|Win32 + {63D80BC8-EB14-4698-A391-4A41AC15E8D1}.Debug|x64.ActiveCfg = Debug|x64 + {63D80BC8-EB14-4698-A391-4A41AC15E8D1}.Debug|x64.Build.0 = Debug|x64 + {63D80BC8-EB14-4698-A391-4A41AC15E8D1}.Release|Win32.ActiveCfg = Release|Win32 + {63D80BC8-EB14-4698-A391-4A41AC15E8D1}.Release|Win32.Build.0 = Release|Win32 + {63D80BC8-EB14-4698-A391-4A41AC15E8D1}.Release|x64.ActiveCfg = Release|x64 + {63D80BC8-EB14-4698-A391-4A41AC15E8D1}.Release|x64.Build.0 = Release|x64 + {3451AE03-3363-445B-8DA8-94B197563D59}.Debug|Win32.ActiveCfg = Debug|Win32 + {3451AE03-3363-445B-8DA8-94B197563D59}.Debug|Win32.Build.0 = Debug|Win32 + {3451AE03-3363-445B-8DA8-94B197563D59}.Debug|x64.ActiveCfg = Debug|x64 + {3451AE03-3363-445B-8DA8-94B197563D59}.Debug|x64.Build.0 = Debug|x64 + {3451AE03-3363-445B-8DA8-94B197563D59}.Release|Win32.ActiveCfg = Release|Win32 + {3451AE03-3363-445B-8DA8-94B197563D59}.Release|Win32.Build.0 = Release|Win32 + {3451AE03-3363-445B-8DA8-94B197563D59}.Release|x64.ActiveCfg = Release|x64 + {3451AE03-3363-445B-8DA8-94B197563D59}.Release|x64.Build.0 = Release|x64 + {B0478C25-73AD-4085-BA1A-DDF66431EB6E}.Debug|Win32.ActiveCfg = Debug|Win32 + {B0478C25-73AD-4085-BA1A-DDF66431EB6E}.Debug|Win32.Build.0 = Debug|Win32 + {B0478C25-73AD-4085-BA1A-DDF66431EB6E}.Debug|x64.ActiveCfg = Debug|x64 + {B0478C25-73AD-4085-BA1A-DDF66431EB6E}.Debug|x64.Build.0 = Debug|x64 + {B0478C25-73AD-4085-BA1A-DDF66431EB6E}.Release|Win32.ActiveCfg = Release|Win32 + {B0478C25-73AD-4085-BA1A-DDF66431EB6E}.Release|Win32.Build.0 = Release|Win32 + {B0478C25-73AD-4085-BA1A-DDF66431EB6E}.Release|x64.ActiveCfg = Release|x64 + {B0478C25-73AD-4085-BA1A-DDF66431EB6E}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {6EBEAFA6-7489-4026-83D1-CAF67D243119} = {FB42AFF5-C8AA-495F-A397-E073D1A03BDE} + {7F95DC75-2CFA-4D0D-BD43-1BF6749F16EE} = {FB42AFF5-C8AA-495F-A397-E073D1A03BDE} + {094A7331-54E1-4034-BD1E-BE2F974B0142} = {FB42AFF5-C8AA-495F-A397-E073D1A03BDE} + {42AC1521-0800-4D81-9363-6EF9362F7A4A} = {FB42AFF5-C8AA-495F-A397-E073D1A03BDE} + {D3FAD2A8-FF48-4E59-A347-C54AD9DB6AC4} = {FB42AFF5-C8AA-495F-A397-E073D1A03BDE} + {1C36ED94-CBE5-4107-83B6-9C37F3A4041C} = {FB42AFF5-C8AA-495F-A397-E073D1A03BDE} + {E126644C-38FF-41EF-9EAF-ED8C9FCF62EF} = {FB42AFF5-C8AA-495F-A397-E073D1A03BDE} + {BD969F96-E5A5-47B2-B5EF-B7999A441CE5} = {FB42AFF5-C8AA-495F-A397-E073D1A03BDE} + {089E9482-33DD-4C64-84A1-C9B5F10F802A} = {FB42AFF5-C8AA-495F-A397-E073D1A03BDE} + {997A89F0-372D-4306-AE4D-7438D93273C3} = {FB42AFF5-C8AA-495F-A397-E073D1A03BDE} + {1B337DC2-628E-4DA4-8C0F-A6880289C6E2} = {FB42AFF5-C8AA-495F-A397-E073D1A03BDE} + {1E59538C-2C78-4D35-8639-568890543A4A} = {FB42AFF5-C8AA-495F-A397-E073D1A03BDE} + {39E1826B-5436-47D3-9B95-D3C667691461} = {FB42AFF5-C8AA-495F-A397-E073D1A03BDE} + {57EFEFC9-E2D9-418E-9F05-3FD0D9921251} = {FB42AFF5-C8AA-495F-A397-E073D1A03BDE} + {C68A466D-0C1B-40BC-9AB1-49B582958524} = {FB42AFF5-C8AA-495F-A397-E073D1A03BDE} + {C30B270A-4C93-44A3-AABE-633713D0F1D7} = {FB42AFF5-C8AA-495F-A397-E073D1A03BDE} + {DD6C58C3-6DD5-43B2-A9ED-760E5F5830AA} = {FB42AFF5-C8AA-495F-A397-E073D1A03BDE} + {7E3867A9-59BC-4441-A74E-F4ABFFEE231C} = {FB42AFF5-C8AA-495F-A397-E073D1A03BDE} + {1F877026-3D94-41BF-B392-06DFAF67AE34} = {FB42AFF5-C8AA-495F-A397-E073D1A03BDE} + {63D80BC8-EB14-4698-A391-4A41AC15E8D1} = {FB42AFF5-C8AA-495F-A397-E073D1A03BDE} + {3451AE03-3363-445B-8DA8-94B197563D59} = {FB42AFF5-C8AA-495F-A397-E073D1A03BDE} + {B0478C25-73AD-4085-BA1A-DDF66431EB6E} = {FB42AFF5-C8AA-495F-A397-E073D1A03BDE} + EndGlobalSection +EndGlobal diff --git a/irdb-lib/pebliss/trunk/pe_bliss_vc10.sln b/irdb-lib/pebliss/trunk/pe_bliss_vc10.sln new file mode 100644 index 0000000000000000000000000000000000000000..587aa18c4d31ae985090a5bc34263d5dbf6153a3 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_bliss_vc10.sln @@ -0,0 +1,417 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pe_bliss", "pe_lib\pe_lib.vcxproj", "{1461F543-D1FA-4E4C-B6D7-0F879F566035}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "View PE information", "View PE information", "{49B3F007-A569-40AE-8FB4-A2AE0347F479}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PE Library", "PE Library", "{9554CAF4-678B-4E42-B886-0F9771FD2B61}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Edit PE files", "Edit PE files", "{53A03406-AEFB-4ABA-8DD1-5AE9B8DFB036}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "address_convertions", "samples\address_convertions\address_convertions.vcxproj", "{2754B0D6-4A8B-49F4-AB9E-E7306D0DAB32}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic_info_viewer", "samples\basic_info_viewer\basic_info_viewer.vcxproj", "{71707667-1A10-4B53-AC02-E4AD898AC6E7}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bound_import_reader", "samples\bound_import_reader\bound_import_reader.vcxproj", "{EFC31F33-D5E4-4356-A892-18CADABCFCCF}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "debug_info_reader", "samples\debug_info_reader\debug_info_reader.vcxproj", "{332A1418-E89B-4658-9F7F-8D219ED776EA}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "entropy_calculator", "samples\entropy_calculator\entropy_calculator.vcxproj", "{48879460-0DF8-491E-BD1D-A489C8D92746}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "exception_dir_reader", "samples\exception_dir_reader\exception_dir_reader.vcxproj", "{EFAF41AB-C77D-4819-996E-4F6C305553A5}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "exports_reader", "samples\exports_reader\exports_reader.vcxproj", "{32ABD41F-7BCE-43E0-853E-21E16260EDB7}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "imports_reader", "samples\imports_reader\imports_reader.vcxproj", "{752670B7-53AA-46CF-B3C5-D3FABBDC027D}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pe_config_reader", "samples\pe_config_reader\pe_config_reader.vcxproj", "{4F642892-D07F-4A96-82E4-36E2966D222D}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pe_sections_reader", "samples\pe_sections_reader\pe_sections_reader.vcxproj", "{F154B72B-22DD-493A-B5D5-CDCD8914DA28}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "relocations_reader", "samples\relocations_reader\relocations_reader.vcxproj", "{A188C743-EA65-4D18-8964-18EAE61ACAC2}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "resource_viewer", "samples\resource_viewer\resource_viewer.vcxproj", "{BC2D8697-73C1-46B9-AC1C-7777D1A71609}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rich_overlay_stub_reader", "samples\rich_overlay_stub_reader\rich_overlay_stub_reader.vcxproj", "{3FDDF315-4CD6-4A21-91CE-F5AFF5BB9667}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sections_and_addresses", "samples\sections_and_addresses\sections_and_addresses.vcxproj", "{99F41F8F-44DB-410E-9883-A6A16E903DF8}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tls_reader", "samples\tls_reader\tls_reader.vcxproj", "{CFB9A225-E2E5-43BC-898A-6D52357E7F92}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic_dotnet_viewer", "samples\basic_dotnet_viewer\basic_dotnet_viewer.vcxproj", "{5E2C4403-4C8B-4773-89A6-61547756ABDC}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "section_adder", "samples\section_adder\section_adder.vcxproj", "{93ABC577-1018-48C2-95C6-39B0B26DD3B0}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pe_rebaser", "samples\pe_rebaser\pe_rebaser.vcxproj", "{46FD39E7-B16C-4F73-B2F0-F1B570464C6E}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pe_stripper", "samples\pe_stripper\pe_stripper.vcxproj", "{B32991F6-CD2C-48FE-A2AE-BDE8A4AC847D}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pe_realigner", "samples\pe_realigner\pe_realigner.vcxproj", "{F40CE9C6-5E3F-445A-8EA4-ED819E608024}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "import_adder", "samples\import_adder\import_adder.vcxproj", "{EE56AFB0-A1C4-4F6D-8F90-0DB5A17C5C59}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "export_adder", "samples\export_adder\export_adder.vcxproj", "{17C01A93-C7F0-49EB-A9A0-81F5E06779C3}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "relocation_adder", "samples\relocation_adder\relocation_adder.vcxproj", "{7375047B-90D7-4564-BA84-7E5C638C7CCE}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tls_editor", "samples\tls_editor\tls_editor.vcxproj", "{ABA9C7BF-D145-4066-8E0D-41C190BB5C0A}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "resource_editor", "samples\resource_editor\resource_editor.vcxproj", "{B88455A6-C93A-4F17-93A5-FC84B70F9CFE}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "image_config_editor", "samples\image_config_editor\image_config_editor.vcxproj", "{48B99169-44E6-41E5-A681-78243B885E86}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "full_pe_rebuilder", "samples\full_pe_rebuilder\full_pe_rebuilder.vcxproj", "{D7F6EE93-F88A-4B66-8761-87EC844E20C5}" + ProjectSection(ProjectDependencies) = postProject + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {1461F543-D1FA-4E4C-B6D7-0F879F566035} + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{65326322-DFB0-46BF-80A6-84B8A7C9628D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1461F543-D1FA-4E4C-B6D7-0F879F566035}.Debug|Win32.ActiveCfg = Debug|Win32 + {1461F543-D1FA-4E4C-B6D7-0F879F566035}.Debug|Win32.Build.0 = Debug|Win32 + {1461F543-D1FA-4E4C-B6D7-0F879F566035}.Debug|x64.ActiveCfg = Debug|x64 + {1461F543-D1FA-4E4C-B6D7-0F879F566035}.Debug|x64.Build.0 = Debug|x64 + {1461F543-D1FA-4E4C-B6D7-0F879F566035}.Release|Win32.ActiveCfg = Release|Win32 + {1461F543-D1FA-4E4C-B6D7-0F879F566035}.Release|Win32.Build.0 = Release|Win32 + {1461F543-D1FA-4E4C-B6D7-0F879F566035}.Release|x64.ActiveCfg = Release|x64 + {1461F543-D1FA-4E4C-B6D7-0F879F566035}.Release|x64.Build.0 = Release|x64 + {2754B0D6-4A8B-49F4-AB9E-E7306D0DAB32}.Debug|Win32.ActiveCfg = Debug|Win32 + {2754B0D6-4A8B-49F4-AB9E-E7306D0DAB32}.Debug|Win32.Build.0 = Debug|Win32 + {2754B0D6-4A8B-49F4-AB9E-E7306D0DAB32}.Debug|x64.ActiveCfg = Debug|x64 + {2754B0D6-4A8B-49F4-AB9E-E7306D0DAB32}.Debug|x64.Build.0 = Debug|x64 + {2754B0D6-4A8B-49F4-AB9E-E7306D0DAB32}.Release|Win32.ActiveCfg = Release|Win32 + {2754B0D6-4A8B-49F4-AB9E-E7306D0DAB32}.Release|Win32.Build.0 = Release|Win32 + {2754B0D6-4A8B-49F4-AB9E-E7306D0DAB32}.Release|x64.ActiveCfg = Release|x64 + {2754B0D6-4A8B-49F4-AB9E-E7306D0DAB32}.Release|x64.Build.0 = Release|x64 + {71707667-1A10-4B53-AC02-E4AD898AC6E7}.Debug|Win32.ActiveCfg = Debug|Win32 + {71707667-1A10-4B53-AC02-E4AD898AC6E7}.Debug|Win32.Build.0 = Debug|Win32 + {71707667-1A10-4B53-AC02-E4AD898AC6E7}.Debug|x64.ActiveCfg = Debug|x64 + {71707667-1A10-4B53-AC02-E4AD898AC6E7}.Debug|x64.Build.0 = Debug|x64 + {71707667-1A10-4B53-AC02-E4AD898AC6E7}.Release|Win32.ActiveCfg = Release|Win32 + {71707667-1A10-4B53-AC02-E4AD898AC6E7}.Release|Win32.Build.0 = Release|Win32 + {71707667-1A10-4B53-AC02-E4AD898AC6E7}.Release|x64.ActiveCfg = Release|x64 + {71707667-1A10-4B53-AC02-E4AD898AC6E7}.Release|x64.Build.0 = Release|x64 + {EFC31F33-D5E4-4356-A892-18CADABCFCCF}.Debug|Win32.ActiveCfg = Debug|Win32 + {EFC31F33-D5E4-4356-A892-18CADABCFCCF}.Debug|Win32.Build.0 = Debug|Win32 + {EFC31F33-D5E4-4356-A892-18CADABCFCCF}.Debug|x64.ActiveCfg = Debug|x64 + {EFC31F33-D5E4-4356-A892-18CADABCFCCF}.Debug|x64.Build.0 = Debug|x64 + {EFC31F33-D5E4-4356-A892-18CADABCFCCF}.Release|Win32.ActiveCfg = Release|Win32 + {EFC31F33-D5E4-4356-A892-18CADABCFCCF}.Release|Win32.Build.0 = Release|Win32 + {EFC31F33-D5E4-4356-A892-18CADABCFCCF}.Release|x64.ActiveCfg = Release|x64 + {EFC31F33-D5E4-4356-A892-18CADABCFCCF}.Release|x64.Build.0 = Release|x64 + {332A1418-E89B-4658-9F7F-8D219ED776EA}.Debug|Win32.ActiveCfg = Debug|Win32 + {332A1418-E89B-4658-9F7F-8D219ED776EA}.Debug|Win32.Build.0 = Debug|Win32 + {332A1418-E89B-4658-9F7F-8D219ED776EA}.Debug|x64.ActiveCfg = Debug|x64 + {332A1418-E89B-4658-9F7F-8D219ED776EA}.Debug|x64.Build.0 = Debug|x64 + {332A1418-E89B-4658-9F7F-8D219ED776EA}.Release|Win32.ActiveCfg = Release|Win32 + {332A1418-E89B-4658-9F7F-8D219ED776EA}.Release|Win32.Build.0 = Release|Win32 + {332A1418-E89B-4658-9F7F-8D219ED776EA}.Release|x64.ActiveCfg = Release|x64 + {332A1418-E89B-4658-9F7F-8D219ED776EA}.Release|x64.Build.0 = Release|x64 + {48879460-0DF8-491E-BD1D-A489C8D92746}.Debug|Win32.ActiveCfg = Debug|Win32 + {48879460-0DF8-491E-BD1D-A489C8D92746}.Debug|Win32.Build.0 = Debug|Win32 + {48879460-0DF8-491E-BD1D-A489C8D92746}.Debug|x64.ActiveCfg = Debug|x64 + {48879460-0DF8-491E-BD1D-A489C8D92746}.Debug|x64.Build.0 = Debug|x64 + {48879460-0DF8-491E-BD1D-A489C8D92746}.Release|Win32.ActiveCfg = Release|Win32 + {48879460-0DF8-491E-BD1D-A489C8D92746}.Release|Win32.Build.0 = Release|Win32 + {48879460-0DF8-491E-BD1D-A489C8D92746}.Release|x64.ActiveCfg = Release|x64 + {48879460-0DF8-491E-BD1D-A489C8D92746}.Release|x64.Build.0 = Release|x64 + {EFAF41AB-C77D-4819-996E-4F6C305553A5}.Debug|Win32.ActiveCfg = Debug|Win32 + {EFAF41AB-C77D-4819-996E-4F6C305553A5}.Debug|Win32.Build.0 = Debug|Win32 + {EFAF41AB-C77D-4819-996E-4F6C305553A5}.Debug|x64.ActiveCfg = Debug|x64 + {EFAF41AB-C77D-4819-996E-4F6C305553A5}.Debug|x64.Build.0 = Debug|x64 + {EFAF41AB-C77D-4819-996E-4F6C305553A5}.Release|Win32.ActiveCfg = Release|Win32 + {EFAF41AB-C77D-4819-996E-4F6C305553A5}.Release|Win32.Build.0 = Release|Win32 + {EFAF41AB-C77D-4819-996E-4F6C305553A5}.Release|x64.ActiveCfg = Release|x64 + {EFAF41AB-C77D-4819-996E-4F6C305553A5}.Release|x64.Build.0 = Release|x64 + {32ABD41F-7BCE-43E0-853E-21E16260EDB7}.Debug|Win32.ActiveCfg = Debug|Win32 + {32ABD41F-7BCE-43E0-853E-21E16260EDB7}.Debug|Win32.Build.0 = Debug|Win32 + {32ABD41F-7BCE-43E0-853E-21E16260EDB7}.Debug|x64.ActiveCfg = Debug|x64 + {32ABD41F-7BCE-43E0-853E-21E16260EDB7}.Debug|x64.Build.0 = Debug|x64 + {32ABD41F-7BCE-43E0-853E-21E16260EDB7}.Release|Win32.ActiveCfg = Release|Win32 + {32ABD41F-7BCE-43E0-853E-21E16260EDB7}.Release|Win32.Build.0 = Release|Win32 + {32ABD41F-7BCE-43E0-853E-21E16260EDB7}.Release|x64.ActiveCfg = Release|x64 + {32ABD41F-7BCE-43E0-853E-21E16260EDB7}.Release|x64.Build.0 = Release|x64 + {752670B7-53AA-46CF-B3C5-D3FABBDC027D}.Debug|Win32.ActiveCfg = Debug|Win32 + {752670B7-53AA-46CF-B3C5-D3FABBDC027D}.Debug|Win32.Build.0 = Debug|Win32 + {752670B7-53AA-46CF-B3C5-D3FABBDC027D}.Debug|x64.ActiveCfg = Debug|x64 + {752670B7-53AA-46CF-B3C5-D3FABBDC027D}.Debug|x64.Build.0 = Debug|x64 + {752670B7-53AA-46CF-B3C5-D3FABBDC027D}.Release|Win32.ActiveCfg = Release|Win32 + {752670B7-53AA-46CF-B3C5-D3FABBDC027D}.Release|Win32.Build.0 = Release|Win32 + {752670B7-53AA-46CF-B3C5-D3FABBDC027D}.Release|x64.ActiveCfg = Release|x64 + {752670B7-53AA-46CF-B3C5-D3FABBDC027D}.Release|x64.Build.0 = Release|x64 + {4F642892-D07F-4A96-82E4-36E2966D222D}.Debug|Win32.ActiveCfg = Debug|Win32 + {4F642892-D07F-4A96-82E4-36E2966D222D}.Debug|Win32.Build.0 = Debug|Win32 + {4F642892-D07F-4A96-82E4-36E2966D222D}.Debug|x64.ActiveCfg = Debug|x64 + {4F642892-D07F-4A96-82E4-36E2966D222D}.Debug|x64.Build.0 = Debug|x64 + {4F642892-D07F-4A96-82E4-36E2966D222D}.Release|Win32.ActiveCfg = Release|Win32 + {4F642892-D07F-4A96-82E4-36E2966D222D}.Release|Win32.Build.0 = Release|Win32 + {4F642892-D07F-4A96-82E4-36E2966D222D}.Release|x64.ActiveCfg = Release|x64 + {4F642892-D07F-4A96-82E4-36E2966D222D}.Release|x64.Build.0 = Release|x64 + {F154B72B-22DD-493A-B5D5-CDCD8914DA28}.Debug|Win32.ActiveCfg = Debug|Win32 + {F154B72B-22DD-493A-B5D5-CDCD8914DA28}.Debug|Win32.Build.0 = Debug|Win32 + {F154B72B-22DD-493A-B5D5-CDCD8914DA28}.Debug|x64.ActiveCfg = Debug|x64 + {F154B72B-22DD-493A-B5D5-CDCD8914DA28}.Debug|x64.Build.0 = Debug|x64 + {F154B72B-22DD-493A-B5D5-CDCD8914DA28}.Release|Win32.ActiveCfg = Release|Win32 + {F154B72B-22DD-493A-B5D5-CDCD8914DA28}.Release|Win32.Build.0 = Release|Win32 + {F154B72B-22DD-493A-B5D5-CDCD8914DA28}.Release|x64.ActiveCfg = Release|x64 + {F154B72B-22DD-493A-B5D5-CDCD8914DA28}.Release|x64.Build.0 = Release|x64 + {A188C743-EA65-4D18-8964-18EAE61ACAC2}.Debug|Win32.ActiveCfg = Debug|Win32 + {A188C743-EA65-4D18-8964-18EAE61ACAC2}.Debug|Win32.Build.0 = Debug|Win32 + {A188C743-EA65-4D18-8964-18EAE61ACAC2}.Debug|x64.ActiveCfg = Debug|x64 + {A188C743-EA65-4D18-8964-18EAE61ACAC2}.Debug|x64.Build.0 = Debug|x64 + {A188C743-EA65-4D18-8964-18EAE61ACAC2}.Release|Win32.ActiveCfg = Release|Win32 + {A188C743-EA65-4D18-8964-18EAE61ACAC2}.Release|Win32.Build.0 = Release|Win32 + {A188C743-EA65-4D18-8964-18EAE61ACAC2}.Release|x64.ActiveCfg = Release|x64 + {A188C743-EA65-4D18-8964-18EAE61ACAC2}.Release|x64.Build.0 = Release|x64 + {BC2D8697-73C1-46B9-AC1C-7777D1A71609}.Debug|Win32.ActiveCfg = Debug|Win32 + {BC2D8697-73C1-46B9-AC1C-7777D1A71609}.Debug|Win32.Build.0 = Debug|Win32 + {BC2D8697-73C1-46B9-AC1C-7777D1A71609}.Debug|x64.ActiveCfg = Debug|x64 + {BC2D8697-73C1-46B9-AC1C-7777D1A71609}.Debug|x64.Build.0 = Debug|x64 + {BC2D8697-73C1-46B9-AC1C-7777D1A71609}.Release|Win32.ActiveCfg = Release|Win32 + {BC2D8697-73C1-46B9-AC1C-7777D1A71609}.Release|Win32.Build.0 = Release|Win32 + {BC2D8697-73C1-46B9-AC1C-7777D1A71609}.Release|x64.ActiveCfg = Release|x64 + {BC2D8697-73C1-46B9-AC1C-7777D1A71609}.Release|x64.Build.0 = Release|x64 + {3FDDF315-4CD6-4A21-91CE-F5AFF5BB9667}.Debug|Win32.ActiveCfg = Debug|Win32 + {3FDDF315-4CD6-4A21-91CE-F5AFF5BB9667}.Debug|Win32.Build.0 = Debug|Win32 + {3FDDF315-4CD6-4A21-91CE-F5AFF5BB9667}.Debug|x64.ActiveCfg = Debug|x64 + {3FDDF315-4CD6-4A21-91CE-F5AFF5BB9667}.Debug|x64.Build.0 = Debug|x64 + {3FDDF315-4CD6-4A21-91CE-F5AFF5BB9667}.Release|Win32.ActiveCfg = Release|Win32 + {3FDDF315-4CD6-4A21-91CE-F5AFF5BB9667}.Release|Win32.Build.0 = Release|Win32 + {3FDDF315-4CD6-4A21-91CE-F5AFF5BB9667}.Release|x64.ActiveCfg = Release|x64 + {3FDDF315-4CD6-4A21-91CE-F5AFF5BB9667}.Release|x64.Build.0 = Release|x64 + {99F41F8F-44DB-410E-9883-A6A16E903DF8}.Debug|Win32.ActiveCfg = Debug|Win32 + {99F41F8F-44DB-410E-9883-A6A16E903DF8}.Debug|Win32.Build.0 = Debug|Win32 + {99F41F8F-44DB-410E-9883-A6A16E903DF8}.Debug|x64.ActiveCfg = Debug|x64 + {99F41F8F-44DB-410E-9883-A6A16E903DF8}.Debug|x64.Build.0 = Debug|x64 + {99F41F8F-44DB-410E-9883-A6A16E903DF8}.Release|Win32.ActiveCfg = Release|Win32 + {99F41F8F-44DB-410E-9883-A6A16E903DF8}.Release|Win32.Build.0 = Release|Win32 + {99F41F8F-44DB-410E-9883-A6A16E903DF8}.Release|x64.ActiveCfg = Release|x64 + {99F41F8F-44DB-410E-9883-A6A16E903DF8}.Release|x64.Build.0 = Release|x64 + {CFB9A225-E2E5-43BC-898A-6D52357E7F92}.Debug|Win32.ActiveCfg = Debug|Win32 + {CFB9A225-E2E5-43BC-898A-6D52357E7F92}.Debug|Win32.Build.0 = Debug|Win32 + {CFB9A225-E2E5-43BC-898A-6D52357E7F92}.Debug|x64.ActiveCfg = Debug|x64 + {CFB9A225-E2E5-43BC-898A-6D52357E7F92}.Debug|x64.Build.0 = Debug|x64 + {CFB9A225-E2E5-43BC-898A-6D52357E7F92}.Release|Win32.ActiveCfg = Release|Win32 + {CFB9A225-E2E5-43BC-898A-6D52357E7F92}.Release|Win32.Build.0 = Release|Win32 + {CFB9A225-E2E5-43BC-898A-6D52357E7F92}.Release|x64.ActiveCfg = Release|x64 + {CFB9A225-E2E5-43BC-898A-6D52357E7F92}.Release|x64.Build.0 = Release|x64 + {5E2C4403-4C8B-4773-89A6-61547756ABDC}.Debug|Win32.ActiveCfg = Debug|Win32 + {5E2C4403-4C8B-4773-89A6-61547756ABDC}.Debug|Win32.Build.0 = Debug|Win32 + {5E2C4403-4C8B-4773-89A6-61547756ABDC}.Debug|x64.ActiveCfg = Debug|x64 + {5E2C4403-4C8B-4773-89A6-61547756ABDC}.Debug|x64.Build.0 = Debug|x64 + {5E2C4403-4C8B-4773-89A6-61547756ABDC}.Release|Win32.ActiveCfg = Release|Win32 + {5E2C4403-4C8B-4773-89A6-61547756ABDC}.Release|Win32.Build.0 = Release|Win32 + {5E2C4403-4C8B-4773-89A6-61547756ABDC}.Release|x64.ActiveCfg = Release|x64 + {5E2C4403-4C8B-4773-89A6-61547756ABDC}.Release|x64.Build.0 = Release|x64 + {93ABC577-1018-48C2-95C6-39B0B26DD3B0}.Debug|Win32.ActiveCfg = Debug|Win32 + {93ABC577-1018-48C2-95C6-39B0B26DD3B0}.Debug|Win32.Build.0 = Debug|Win32 + {93ABC577-1018-48C2-95C6-39B0B26DD3B0}.Debug|x64.ActiveCfg = Debug|x64 + {93ABC577-1018-48C2-95C6-39B0B26DD3B0}.Debug|x64.Build.0 = Debug|x64 + {93ABC577-1018-48C2-95C6-39B0B26DD3B0}.Release|Win32.ActiveCfg = Release|Win32 + {93ABC577-1018-48C2-95C6-39B0B26DD3B0}.Release|Win32.Build.0 = Release|Win32 + {93ABC577-1018-48C2-95C6-39B0B26DD3B0}.Release|x64.ActiveCfg = Release|x64 + {93ABC577-1018-48C2-95C6-39B0B26DD3B0}.Release|x64.Build.0 = Release|x64 + {46FD39E7-B16C-4F73-B2F0-F1B570464C6E}.Debug|Win32.ActiveCfg = Debug|Win32 + {46FD39E7-B16C-4F73-B2F0-F1B570464C6E}.Debug|Win32.Build.0 = Debug|Win32 + {46FD39E7-B16C-4F73-B2F0-F1B570464C6E}.Debug|x64.ActiveCfg = Debug|x64 + {46FD39E7-B16C-4F73-B2F0-F1B570464C6E}.Debug|x64.Build.0 = Debug|x64 + {46FD39E7-B16C-4F73-B2F0-F1B570464C6E}.Release|Win32.ActiveCfg = Release|Win32 + {46FD39E7-B16C-4F73-B2F0-F1B570464C6E}.Release|Win32.Build.0 = Release|Win32 + {46FD39E7-B16C-4F73-B2F0-F1B570464C6E}.Release|x64.ActiveCfg = Release|x64 + {46FD39E7-B16C-4F73-B2F0-F1B570464C6E}.Release|x64.Build.0 = Release|x64 + {B32991F6-CD2C-48FE-A2AE-BDE8A4AC847D}.Debug|Win32.ActiveCfg = Debug|Win32 + {B32991F6-CD2C-48FE-A2AE-BDE8A4AC847D}.Debug|Win32.Build.0 = Debug|Win32 + {B32991F6-CD2C-48FE-A2AE-BDE8A4AC847D}.Debug|x64.ActiveCfg = Debug|x64 + {B32991F6-CD2C-48FE-A2AE-BDE8A4AC847D}.Debug|x64.Build.0 = Debug|x64 + {B32991F6-CD2C-48FE-A2AE-BDE8A4AC847D}.Release|Win32.ActiveCfg = Release|Win32 + {B32991F6-CD2C-48FE-A2AE-BDE8A4AC847D}.Release|Win32.Build.0 = Release|Win32 + {B32991F6-CD2C-48FE-A2AE-BDE8A4AC847D}.Release|x64.ActiveCfg = Release|x64 + {B32991F6-CD2C-48FE-A2AE-BDE8A4AC847D}.Release|x64.Build.0 = Release|x64 + {F40CE9C6-5E3F-445A-8EA4-ED819E608024}.Debug|Win32.ActiveCfg = Debug|Win32 + {F40CE9C6-5E3F-445A-8EA4-ED819E608024}.Debug|Win32.Build.0 = Debug|Win32 + {F40CE9C6-5E3F-445A-8EA4-ED819E608024}.Debug|x64.ActiveCfg = Debug|x64 + {F40CE9C6-5E3F-445A-8EA4-ED819E608024}.Debug|x64.Build.0 = Debug|x64 + {F40CE9C6-5E3F-445A-8EA4-ED819E608024}.Release|Win32.ActiveCfg = Release|Win32 + {F40CE9C6-5E3F-445A-8EA4-ED819E608024}.Release|Win32.Build.0 = Release|Win32 + {F40CE9C6-5E3F-445A-8EA4-ED819E608024}.Release|x64.ActiveCfg = Release|x64 + {F40CE9C6-5E3F-445A-8EA4-ED819E608024}.Release|x64.Build.0 = Release|x64 + {EE56AFB0-A1C4-4F6D-8F90-0DB5A17C5C59}.Debug|Win32.ActiveCfg = Debug|Win32 + {EE56AFB0-A1C4-4F6D-8F90-0DB5A17C5C59}.Debug|Win32.Build.0 = Debug|Win32 + {EE56AFB0-A1C4-4F6D-8F90-0DB5A17C5C59}.Debug|x64.ActiveCfg = Debug|x64 + {EE56AFB0-A1C4-4F6D-8F90-0DB5A17C5C59}.Debug|x64.Build.0 = Debug|x64 + {EE56AFB0-A1C4-4F6D-8F90-0DB5A17C5C59}.Release|Win32.ActiveCfg = Release|Win32 + {EE56AFB0-A1C4-4F6D-8F90-0DB5A17C5C59}.Release|Win32.Build.0 = Release|Win32 + {EE56AFB0-A1C4-4F6D-8F90-0DB5A17C5C59}.Release|x64.ActiveCfg = Release|x64 + {EE56AFB0-A1C4-4F6D-8F90-0DB5A17C5C59}.Release|x64.Build.0 = Release|x64 + {17C01A93-C7F0-49EB-A9A0-81F5E06779C3}.Debug|Win32.ActiveCfg = Debug|Win32 + {17C01A93-C7F0-49EB-A9A0-81F5E06779C3}.Debug|Win32.Build.0 = Debug|Win32 + {17C01A93-C7F0-49EB-A9A0-81F5E06779C3}.Debug|x64.ActiveCfg = Debug|x64 + {17C01A93-C7F0-49EB-A9A0-81F5E06779C3}.Debug|x64.Build.0 = Debug|x64 + {17C01A93-C7F0-49EB-A9A0-81F5E06779C3}.Release|Win32.ActiveCfg = Release|Win32 + {17C01A93-C7F0-49EB-A9A0-81F5E06779C3}.Release|Win32.Build.0 = Release|Win32 + {17C01A93-C7F0-49EB-A9A0-81F5E06779C3}.Release|x64.ActiveCfg = Release|x64 + {17C01A93-C7F0-49EB-A9A0-81F5E06779C3}.Release|x64.Build.0 = Release|x64 + {7375047B-90D7-4564-BA84-7E5C638C7CCE}.Debug|Win32.ActiveCfg = Debug|Win32 + {7375047B-90D7-4564-BA84-7E5C638C7CCE}.Debug|Win32.Build.0 = Debug|Win32 + {7375047B-90D7-4564-BA84-7E5C638C7CCE}.Debug|x64.ActiveCfg = Debug|x64 + {7375047B-90D7-4564-BA84-7E5C638C7CCE}.Debug|x64.Build.0 = Debug|x64 + {7375047B-90D7-4564-BA84-7E5C638C7CCE}.Release|Win32.ActiveCfg = Release|Win32 + {7375047B-90D7-4564-BA84-7E5C638C7CCE}.Release|Win32.Build.0 = Release|Win32 + {7375047B-90D7-4564-BA84-7E5C638C7CCE}.Release|x64.ActiveCfg = Release|x64 + {7375047B-90D7-4564-BA84-7E5C638C7CCE}.Release|x64.Build.0 = Release|x64 + {ABA9C7BF-D145-4066-8E0D-41C190BB5C0A}.Debug|Win32.ActiveCfg = Debug|Win32 + {ABA9C7BF-D145-4066-8E0D-41C190BB5C0A}.Debug|Win32.Build.0 = Debug|Win32 + {ABA9C7BF-D145-4066-8E0D-41C190BB5C0A}.Debug|x64.ActiveCfg = Debug|x64 + {ABA9C7BF-D145-4066-8E0D-41C190BB5C0A}.Debug|x64.Build.0 = Debug|x64 + {ABA9C7BF-D145-4066-8E0D-41C190BB5C0A}.Release|Win32.ActiveCfg = Release|Win32 + {ABA9C7BF-D145-4066-8E0D-41C190BB5C0A}.Release|Win32.Build.0 = Release|Win32 + {ABA9C7BF-D145-4066-8E0D-41C190BB5C0A}.Release|x64.ActiveCfg = Release|x64 + {ABA9C7BF-D145-4066-8E0D-41C190BB5C0A}.Release|x64.Build.0 = Release|x64 + {B88455A6-C93A-4F17-93A5-FC84B70F9CFE}.Debug|Win32.ActiveCfg = Debug|Win32 + {B88455A6-C93A-4F17-93A5-FC84B70F9CFE}.Debug|Win32.Build.0 = Debug|Win32 + {B88455A6-C93A-4F17-93A5-FC84B70F9CFE}.Debug|x64.ActiveCfg = Debug|x64 + {B88455A6-C93A-4F17-93A5-FC84B70F9CFE}.Debug|x64.Build.0 = Debug|x64 + {B88455A6-C93A-4F17-93A5-FC84B70F9CFE}.Release|Win32.ActiveCfg = Release|Win32 + {B88455A6-C93A-4F17-93A5-FC84B70F9CFE}.Release|Win32.Build.0 = Release|Win32 + {B88455A6-C93A-4F17-93A5-FC84B70F9CFE}.Release|x64.ActiveCfg = Release|x64 + {B88455A6-C93A-4F17-93A5-FC84B70F9CFE}.Release|x64.Build.0 = Release|x64 + {48B99169-44E6-41E5-A681-78243B885E86}.Debug|Win32.ActiveCfg = Debug|Win32 + {48B99169-44E6-41E5-A681-78243B885E86}.Debug|Win32.Build.0 = Debug|Win32 + {48B99169-44E6-41E5-A681-78243B885E86}.Debug|x64.ActiveCfg = Debug|x64 + {48B99169-44E6-41E5-A681-78243B885E86}.Debug|x64.Build.0 = Debug|x64 + {48B99169-44E6-41E5-A681-78243B885E86}.Release|Win32.ActiveCfg = Release|Win32 + {48B99169-44E6-41E5-A681-78243B885E86}.Release|Win32.Build.0 = Release|Win32 + {48B99169-44E6-41E5-A681-78243B885E86}.Release|x64.ActiveCfg = Release|x64 + {48B99169-44E6-41E5-A681-78243B885E86}.Release|x64.Build.0 = Release|x64 + {D7F6EE93-F88A-4B66-8761-87EC844E20C5}.Debug|Win32.ActiveCfg = Debug|Win32 + {D7F6EE93-F88A-4B66-8761-87EC844E20C5}.Debug|Win32.Build.0 = Debug|Win32 + {D7F6EE93-F88A-4B66-8761-87EC844E20C5}.Debug|x64.ActiveCfg = Debug|x64 + {D7F6EE93-F88A-4B66-8761-87EC844E20C5}.Debug|x64.Build.0 = Debug|x64 + {D7F6EE93-F88A-4B66-8761-87EC844E20C5}.Release|Win32.ActiveCfg = Release|Win32 + {D7F6EE93-F88A-4B66-8761-87EC844E20C5}.Release|Win32.Build.0 = Release|Win32 + {D7F6EE93-F88A-4B66-8761-87EC844E20C5}.Release|x64.ActiveCfg = Release|x64 + {D7F6EE93-F88A-4B66-8761-87EC844E20C5}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {1461F543-D1FA-4E4C-B6D7-0F879F566035} = {9554CAF4-678B-4E42-B886-0F9771FD2B61} + {2754B0D6-4A8B-49F4-AB9E-E7306D0DAB32} = {49B3F007-A569-40AE-8FB4-A2AE0347F479} + {71707667-1A10-4B53-AC02-E4AD898AC6E7} = {49B3F007-A569-40AE-8FB4-A2AE0347F479} + {EFC31F33-D5E4-4356-A892-18CADABCFCCF} = {49B3F007-A569-40AE-8FB4-A2AE0347F479} + {332A1418-E89B-4658-9F7F-8D219ED776EA} = {49B3F007-A569-40AE-8FB4-A2AE0347F479} + {48879460-0DF8-491E-BD1D-A489C8D92746} = {49B3F007-A569-40AE-8FB4-A2AE0347F479} + {EFAF41AB-C77D-4819-996E-4F6C305553A5} = {49B3F007-A569-40AE-8FB4-A2AE0347F479} + {32ABD41F-7BCE-43E0-853E-21E16260EDB7} = {49B3F007-A569-40AE-8FB4-A2AE0347F479} + {752670B7-53AA-46CF-B3C5-D3FABBDC027D} = {49B3F007-A569-40AE-8FB4-A2AE0347F479} + {4F642892-D07F-4A96-82E4-36E2966D222D} = {49B3F007-A569-40AE-8FB4-A2AE0347F479} + {F154B72B-22DD-493A-B5D5-CDCD8914DA28} = {49B3F007-A569-40AE-8FB4-A2AE0347F479} + {A188C743-EA65-4D18-8964-18EAE61ACAC2} = {49B3F007-A569-40AE-8FB4-A2AE0347F479} + {BC2D8697-73C1-46B9-AC1C-7777D1A71609} = {49B3F007-A569-40AE-8FB4-A2AE0347F479} + {3FDDF315-4CD6-4A21-91CE-F5AFF5BB9667} = {49B3F007-A569-40AE-8FB4-A2AE0347F479} + {99F41F8F-44DB-410E-9883-A6A16E903DF8} = {49B3F007-A569-40AE-8FB4-A2AE0347F479} + {CFB9A225-E2E5-43BC-898A-6D52357E7F92} = {49B3F007-A569-40AE-8FB4-A2AE0347F479} + {5E2C4403-4C8B-4773-89A6-61547756ABDC} = {49B3F007-A569-40AE-8FB4-A2AE0347F479} + {93ABC577-1018-48C2-95C6-39B0B26DD3B0} = {53A03406-AEFB-4ABA-8DD1-5AE9B8DFB036} + {46FD39E7-B16C-4F73-B2F0-F1B570464C6E} = {53A03406-AEFB-4ABA-8DD1-5AE9B8DFB036} + {B32991F6-CD2C-48FE-A2AE-BDE8A4AC847D} = {53A03406-AEFB-4ABA-8DD1-5AE9B8DFB036} + {F40CE9C6-5E3F-445A-8EA4-ED819E608024} = {53A03406-AEFB-4ABA-8DD1-5AE9B8DFB036} + {EE56AFB0-A1C4-4F6D-8F90-0DB5A17C5C59} = {53A03406-AEFB-4ABA-8DD1-5AE9B8DFB036} + {17C01A93-C7F0-49EB-A9A0-81F5E06779C3} = {53A03406-AEFB-4ABA-8DD1-5AE9B8DFB036} + {7375047B-90D7-4564-BA84-7E5C638C7CCE} = {53A03406-AEFB-4ABA-8DD1-5AE9B8DFB036} + {ABA9C7BF-D145-4066-8E0D-41C190BB5C0A} = {53A03406-AEFB-4ABA-8DD1-5AE9B8DFB036} + {B88455A6-C93A-4F17-93A5-FC84B70F9CFE} = {53A03406-AEFB-4ABA-8DD1-5AE9B8DFB036} + {48B99169-44E6-41E5-A681-78243B885E86} = {53A03406-AEFB-4ABA-8DD1-5AE9B8DFB036} + {D7F6EE93-F88A-4B66-8761-87EC844E20C5} = {53A03406-AEFB-4ABA-8DD1-5AE9B8DFB036} + {53A03406-AEFB-4ABA-8DD1-5AE9B8DFB036} = {65326322-DFB0-46BF-80A6-84B8A7C9628D} + {49B3F007-A569-40AE-8FB4-A2AE0347F479} = {65326322-DFB0-46BF-80A6-84B8A7C9628D} + EndGlobalSection +EndGlobal diff --git a/irdb-lib/pebliss/trunk/pe_bliss_vc9.sln b/irdb-lib/pebliss/trunk/pe_bliss_vc9.sln new file mode 100644 index 0000000000000000000000000000000000000000..d6c04b4569ff8fcf11d36c2162daa39cdee8e1ea --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_bliss_vc9.sln @@ -0,0 +1,417 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pe_lib", "pe_lib\pe_lib.vcproj", "{4B658F8F-1722-4EEA-880C-A4A64DCA9F2C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PE Library", "PE Library", "{20B98358-3862-4D16-985F-ECE9DE5D9FEB}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "View PE information", "View PE information", "{25A7C026-702D-48A4-A1EC-81DE78F0664E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Edit PE files", "Edit PE files", "{0CF51D6D-1F80-4D2C-95BE-566641BD1F71}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "address_convertions", "samples\address_convertions\address_convertions.vcproj", "{642392B3-C763-44C8-91F4-EA90C3651608}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic_dotnet_viewer", "samples\basic_dotnet_viewer\basic_dotnet_viewer.vcproj", "{DE053D44-F9BD-4C1A-B44B-3157BE27AD02}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic_info_viewer", "samples\basic_info_viewer\basic_info_viewer.vcproj", "{7AF45D7B-8341-42CF-B382-B67E1399D8B1}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bound_import_reader", "samples\bound_import_reader\bound_import_reader.vcproj", "{65229ACC-5C9B-429C-B9DA-4710697637EB}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "debug_info_reader", "samples\debug_info_reader\debug_info_reader.vcproj", "{218033A7-A6D0-45B4-88F6-F4FF5DD25207}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "entropy_calculator", "samples\entropy_calculator\entropy_calculator.vcproj", "{111344DB-1F0B-460E-91DD-9DD36D2238A4}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "exception_dir_reader", "samples\exception_dir_reader\exception_dir_reader.vcproj", "{D8E2714A-11A7-478D-A966-EF6968FFB766}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "export_adder", "samples\export_adder\export_adder.vcproj", "{4459EB9F-0332-46C4-BF60-6CECA73C7D17}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "exports_reader", "samples\exports_reader\exports_reader.vcproj", "{AC7C3A84-2F81-4B22-B27E-50A9D4C750E2}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "import_adder", "samples\import_adder\import_adder.vcproj", "{5303D6F1-D667-4E92-A501-8B396252156F}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "imports_reader", "samples\imports_reader\imports_reader.vcproj", "{15AFEB1D-4EF8-4AF0-88C8-9FCA879F8AE2}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pe_config_reader", "samples\pe_config_reader\pe_config_reader.vcproj", "{1F7B06CA-5529-4A3D-89CE-15161D4A01D9}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pe_realigner", "samples\pe_realigner\pe_realigner.vcproj", "{36EB9E03-E155-4487-AB1B-0B1B862B0155}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pe_rebaser", "samples\pe_rebaser\pe_rebaser.vcproj", "{0F52C42C-EEDA-4031-B0A0-F6CD53C81465}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pe_sections_reader", "samples\pe_sections_reader\pe_sections_reader.vcproj", "{0A06D231-FC40-4EC9-B0FC-F0D08270384E}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pe_stripper", "samples\pe_stripper\pe_stripper.vcproj", "{9E09B1EB-D3F3-4C38-B87F-AE642F509D04}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "relocation_adder", "samples\relocation_adder\relocation_adder.vcproj", "{9E7C038E-470E-4DF8-A887-3E1B8A02B78C}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "relocations_reader", "samples\relocations_reader\relocations_reader.vcproj", "{3EDCB092-C785-41EB-8A83-C5B37A2FF310}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "resource_editor", "samples\resource_editor\resource_editor.vcproj", "{B0D287DB-451D-4005-9CE3-185D7602F0B7}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "resource_viewer", "samples\resource_viewer\resource_viewer.vcproj", "{D10B61A9-09FD-4E87-8C66-BE07AE5CC8E9}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rich_overlay_stub_reader", "samples\rich_overlay_stub_reader\rich_overlay_stub_reader.vcproj", "{33FF435B-A3CF-441E-964E-A7DA8735E7B1}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "section_adder", "samples\section_adder\section_adder.vcproj", "{C3B58F69-FA5D-4E9E-8E21-F6C5EBAC22ED}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sections_and_addresses", "samples\sections_and_addresses\sections_and_addresses.vcproj", "{660117AA-6B9E-4C7D-B0BE-DE6BD17DBA1E}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tls_editor", "samples\tls_editor\tls_editor.vcproj", "{781B56DF-15CE-4CBA-A008-0403029E558A}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tls_reader", "samples\tls_reader\tls_reader.vcproj", "{BA36739B-F101-4C91-928D-678AB9521A22}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "image_config_editor", "samples\image_config_editor\image_config_editor.vcproj", "{22788F46-AB6B-4278-B1C0-ED220AE85F4A}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "full_pe_rebuilder", "samples\full_pe_rebuilder\full_pe_rebuilder.vcproj", "{F61AB18A-8E8B-43D1-91B2-D6A2A297FDD6}" + ProjectSection(ProjectDependencies) = postProject + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{9191A7C3-3B0A-45A5-99A2-72D1903AA7B7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C}.Debug|Win32.ActiveCfg = Debug|Win32 + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C}.Debug|Win32.Build.0 = Debug|Win32 + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C}.Debug|x64.ActiveCfg = Debug|x64 + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C}.Debug|x64.Build.0 = Debug|x64 + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C}.Release|Win32.ActiveCfg = Release|Win32 + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C}.Release|Win32.Build.0 = Release|Win32 + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C}.Release|x64.ActiveCfg = Release|x64 + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C}.Release|x64.Build.0 = Release|x64 + {642392B3-C763-44C8-91F4-EA90C3651608}.Debug|Win32.ActiveCfg = Debug|Win32 + {642392B3-C763-44C8-91F4-EA90C3651608}.Debug|Win32.Build.0 = Debug|Win32 + {642392B3-C763-44C8-91F4-EA90C3651608}.Debug|x64.ActiveCfg = Debug|x64 + {642392B3-C763-44C8-91F4-EA90C3651608}.Debug|x64.Build.0 = Debug|x64 + {642392B3-C763-44C8-91F4-EA90C3651608}.Release|Win32.ActiveCfg = Release|Win32 + {642392B3-C763-44C8-91F4-EA90C3651608}.Release|Win32.Build.0 = Release|Win32 + {642392B3-C763-44C8-91F4-EA90C3651608}.Release|x64.ActiveCfg = Release|x64 + {642392B3-C763-44C8-91F4-EA90C3651608}.Release|x64.Build.0 = Release|x64 + {DE053D44-F9BD-4C1A-B44B-3157BE27AD02}.Debug|Win32.ActiveCfg = Debug|Win32 + {DE053D44-F9BD-4C1A-B44B-3157BE27AD02}.Debug|Win32.Build.0 = Debug|Win32 + {DE053D44-F9BD-4C1A-B44B-3157BE27AD02}.Debug|x64.ActiveCfg = Debug|x64 + {DE053D44-F9BD-4C1A-B44B-3157BE27AD02}.Debug|x64.Build.0 = Debug|x64 + {DE053D44-F9BD-4C1A-B44B-3157BE27AD02}.Release|Win32.ActiveCfg = Release|Win32 + {DE053D44-F9BD-4C1A-B44B-3157BE27AD02}.Release|Win32.Build.0 = Release|Win32 + {DE053D44-F9BD-4C1A-B44B-3157BE27AD02}.Release|x64.ActiveCfg = Release|x64 + {DE053D44-F9BD-4C1A-B44B-3157BE27AD02}.Release|x64.Build.0 = Release|x64 + {7AF45D7B-8341-42CF-B382-B67E1399D8B1}.Debug|Win32.ActiveCfg = Debug|Win32 + {7AF45D7B-8341-42CF-B382-B67E1399D8B1}.Debug|Win32.Build.0 = Debug|Win32 + {7AF45D7B-8341-42CF-B382-B67E1399D8B1}.Debug|x64.ActiveCfg = Debug|x64 + {7AF45D7B-8341-42CF-B382-B67E1399D8B1}.Debug|x64.Build.0 = Debug|x64 + {7AF45D7B-8341-42CF-B382-B67E1399D8B1}.Release|Win32.ActiveCfg = Release|Win32 + {7AF45D7B-8341-42CF-B382-B67E1399D8B1}.Release|Win32.Build.0 = Release|Win32 + {7AF45D7B-8341-42CF-B382-B67E1399D8B1}.Release|x64.ActiveCfg = Release|x64 + {7AF45D7B-8341-42CF-B382-B67E1399D8B1}.Release|x64.Build.0 = Release|x64 + {65229ACC-5C9B-429C-B9DA-4710697637EB}.Debug|Win32.ActiveCfg = Debug|Win32 + {65229ACC-5C9B-429C-B9DA-4710697637EB}.Debug|Win32.Build.0 = Debug|Win32 + {65229ACC-5C9B-429C-B9DA-4710697637EB}.Debug|x64.ActiveCfg = Debug|x64 + {65229ACC-5C9B-429C-B9DA-4710697637EB}.Debug|x64.Build.0 = Debug|x64 + {65229ACC-5C9B-429C-B9DA-4710697637EB}.Release|Win32.ActiveCfg = Release|Win32 + {65229ACC-5C9B-429C-B9DA-4710697637EB}.Release|Win32.Build.0 = Release|Win32 + {65229ACC-5C9B-429C-B9DA-4710697637EB}.Release|x64.ActiveCfg = Release|x64 + {65229ACC-5C9B-429C-B9DA-4710697637EB}.Release|x64.Build.0 = Release|x64 + {218033A7-A6D0-45B4-88F6-F4FF5DD25207}.Debug|Win32.ActiveCfg = Debug|Win32 + {218033A7-A6D0-45B4-88F6-F4FF5DD25207}.Debug|Win32.Build.0 = Debug|Win32 + {218033A7-A6D0-45B4-88F6-F4FF5DD25207}.Debug|x64.ActiveCfg = Debug|x64 + {218033A7-A6D0-45B4-88F6-F4FF5DD25207}.Debug|x64.Build.0 = Debug|x64 + {218033A7-A6D0-45B4-88F6-F4FF5DD25207}.Release|Win32.ActiveCfg = Release|Win32 + {218033A7-A6D0-45B4-88F6-F4FF5DD25207}.Release|Win32.Build.0 = Release|Win32 + {218033A7-A6D0-45B4-88F6-F4FF5DD25207}.Release|x64.ActiveCfg = Release|x64 + {218033A7-A6D0-45B4-88F6-F4FF5DD25207}.Release|x64.Build.0 = Release|x64 + {111344DB-1F0B-460E-91DD-9DD36D2238A4}.Debug|Win32.ActiveCfg = Debug|Win32 + {111344DB-1F0B-460E-91DD-9DD36D2238A4}.Debug|Win32.Build.0 = Debug|Win32 + {111344DB-1F0B-460E-91DD-9DD36D2238A4}.Debug|x64.ActiveCfg = Debug|x64 + {111344DB-1F0B-460E-91DD-9DD36D2238A4}.Debug|x64.Build.0 = Debug|x64 + {111344DB-1F0B-460E-91DD-9DD36D2238A4}.Release|Win32.ActiveCfg = Release|Win32 + {111344DB-1F0B-460E-91DD-9DD36D2238A4}.Release|Win32.Build.0 = Release|Win32 + {111344DB-1F0B-460E-91DD-9DD36D2238A4}.Release|x64.ActiveCfg = Release|x64 + {111344DB-1F0B-460E-91DD-9DD36D2238A4}.Release|x64.Build.0 = Release|x64 + {D8E2714A-11A7-478D-A966-EF6968FFB766}.Debug|Win32.ActiveCfg = Debug|Win32 + {D8E2714A-11A7-478D-A966-EF6968FFB766}.Debug|Win32.Build.0 = Debug|Win32 + {D8E2714A-11A7-478D-A966-EF6968FFB766}.Debug|x64.ActiveCfg = Debug|x64 + {D8E2714A-11A7-478D-A966-EF6968FFB766}.Debug|x64.Build.0 = Debug|x64 + {D8E2714A-11A7-478D-A966-EF6968FFB766}.Release|Win32.ActiveCfg = Release|Win32 + {D8E2714A-11A7-478D-A966-EF6968FFB766}.Release|Win32.Build.0 = Release|Win32 + {D8E2714A-11A7-478D-A966-EF6968FFB766}.Release|x64.ActiveCfg = Release|x64 + {D8E2714A-11A7-478D-A966-EF6968FFB766}.Release|x64.Build.0 = Release|x64 + {4459EB9F-0332-46C4-BF60-6CECA73C7D17}.Debug|Win32.ActiveCfg = Debug|Win32 + {4459EB9F-0332-46C4-BF60-6CECA73C7D17}.Debug|Win32.Build.0 = Debug|Win32 + {4459EB9F-0332-46C4-BF60-6CECA73C7D17}.Debug|x64.ActiveCfg = Debug|x64 + {4459EB9F-0332-46C4-BF60-6CECA73C7D17}.Debug|x64.Build.0 = Debug|x64 + {4459EB9F-0332-46C4-BF60-6CECA73C7D17}.Release|Win32.ActiveCfg = Release|Win32 + {4459EB9F-0332-46C4-BF60-6CECA73C7D17}.Release|Win32.Build.0 = Release|Win32 + {4459EB9F-0332-46C4-BF60-6CECA73C7D17}.Release|x64.ActiveCfg = Release|x64 + {4459EB9F-0332-46C4-BF60-6CECA73C7D17}.Release|x64.Build.0 = Release|x64 + {AC7C3A84-2F81-4B22-B27E-50A9D4C750E2}.Debug|Win32.ActiveCfg = Debug|Win32 + {AC7C3A84-2F81-4B22-B27E-50A9D4C750E2}.Debug|Win32.Build.0 = Debug|Win32 + {AC7C3A84-2F81-4B22-B27E-50A9D4C750E2}.Debug|x64.ActiveCfg = Debug|x64 + {AC7C3A84-2F81-4B22-B27E-50A9D4C750E2}.Debug|x64.Build.0 = Debug|x64 + {AC7C3A84-2F81-4B22-B27E-50A9D4C750E2}.Release|Win32.ActiveCfg = Release|Win32 + {AC7C3A84-2F81-4B22-B27E-50A9D4C750E2}.Release|Win32.Build.0 = Release|Win32 + {AC7C3A84-2F81-4B22-B27E-50A9D4C750E2}.Release|x64.ActiveCfg = Release|x64 + {AC7C3A84-2F81-4B22-B27E-50A9D4C750E2}.Release|x64.Build.0 = Release|x64 + {5303D6F1-D667-4E92-A501-8B396252156F}.Debug|Win32.ActiveCfg = Debug|Win32 + {5303D6F1-D667-4E92-A501-8B396252156F}.Debug|Win32.Build.0 = Debug|Win32 + {5303D6F1-D667-4E92-A501-8B396252156F}.Debug|x64.ActiveCfg = Debug|x64 + {5303D6F1-D667-4E92-A501-8B396252156F}.Debug|x64.Build.0 = Debug|x64 + {5303D6F1-D667-4E92-A501-8B396252156F}.Release|Win32.ActiveCfg = Release|Win32 + {5303D6F1-D667-4E92-A501-8B396252156F}.Release|Win32.Build.0 = Release|Win32 + {5303D6F1-D667-4E92-A501-8B396252156F}.Release|x64.ActiveCfg = Release|x64 + {5303D6F1-D667-4E92-A501-8B396252156F}.Release|x64.Build.0 = Release|x64 + {15AFEB1D-4EF8-4AF0-88C8-9FCA879F8AE2}.Debug|Win32.ActiveCfg = Debug|Win32 + {15AFEB1D-4EF8-4AF0-88C8-9FCA879F8AE2}.Debug|Win32.Build.0 = Debug|Win32 + {15AFEB1D-4EF8-4AF0-88C8-9FCA879F8AE2}.Debug|x64.ActiveCfg = Debug|x64 + {15AFEB1D-4EF8-4AF0-88C8-9FCA879F8AE2}.Debug|x64.Build.0 = Debug|x64 + {15AFEB1D-4EF8-4AF0-88C8-9FCA879F8AE2}.Release|Win32.ActiveCfg = Release|Win32 + {15AFEB1D-4EF8-4AF0-88C8-9FCA879F8AE2}.Release|Win32.Build.0 = Release|Win32 + {15AFEB1D-4EF8-4AF0-88C8-9FCA879F8AE2}.Release|x64.ActiveCfg = Release|x64 + {15AFEB1D-4EF8-4AF0-88C8-9FCA879F8AE2}.Release|x64.Build.0 = Release|x64 + {1F7B06CA-5529-4A3D-89CE-15161D4A01D9}.Debug|Win32.ActiveCfg = Debug|Win32 + {1F7B06CA-5529-4A3D-89CE-15161D4A01D9}.Debug|Win32.Build.0 = Debug|Win32 + {1F7B06CA-5529-4A3D-89CE-15161D4A01D9}.Debug|x64.ActiveCfg = Debug|x64 + {1F7B06CA-5529-4A3D-89CE-15161D4A01D9}.Debug|x64.Build.0 = Debug|x64 + {1F7B06CA-5529-4A3D-89CE-15161D4A01D9}.Release|Win32.ActiveCfg = Release|Win32 + {1F7B06CA-5529-4A3D-89CE-15161D4A01D9}.Release|Win32.Build.0 = Release|Win32 + {1F7B06CA-5529-4A3D-89CE-15161D4A01D9}.Release|x64.ActiveCfg = Release|x64 + {1F7B06CA-5529-4A3D-89CE-15161D4A01D9}.Release|x64.Build.0 = Release|x64 + {36EB9E03-E155-4487-AB1B-0B1B862B0155}.Debug|Win32.ActiveCfg = Debug|Win32 + {36EB9E03-E155-4487-AB1B-0B1B862B0155}.Debug|Win32.Build.0 = Debug|Win32 + {36EB9E03-E155-4487-AB1B-0B1B862B0155}.Debug|x64.ActiveCfg = Debug|x64 + {36EB9E03-E155-4487-AB1B-0B1B862B0155}.Debug|x64.Build.0 = Debug|x64 + {36EB9E03-E155-4487-AB1B-0B1B862B0155}.Release|Win32.ActiveCfg = Release|Win32 + {36EB9E03-E155-4487-AB1B-0B1B862B0155}.Release|Win32.Build.0 = Release|Win32 + {36EB9E03-E155-4487-AB1B-0B1B862B0155}.Release|x64.ActiveCfg = Release|x64 + {36EB9E03-E155-4487-AB1B-0B1B862B0155}.Release|x64.Build.0 = Release|x64 + {0F52C42C-EEDA-4031-B0A0-F6CD53C81465}.Debug|Win32.ActiveCfg = Debug|Win32 + {0F52C42C-EEDA-4031-B0A0-F6CD53C81465}.Debug|Win32.Build.0 = Debug|Win32 + {0F52C42C-EEDA-4031-B0A0-F6CD53C81465}.Debug|x64.ActiveCfg = Debug|x64 + {0F52C42C-EEDA-4031-B0A0-F6CD53C81465}.Debug|x64.Build.0 = Debug|x64 + {0F52C42C-EEDA-4031-B0A0-F6CD53C81465}.Release|Win32.ActiveCfg = Release|Win32 + {0F52C42C-EEDA-4031-B0A0-F6CD53C81465}.Release|Win32.Build.0 = Release|Win32 + {0F52C42C-EEDA-4031-B0A0-F6CD53C81465}.Release|x64.ActiveCfg = Release|x64 + {0F52C42C-EEDA-4031-B0A0-F6CD53C81465}.Release|x64.Build.0 = Release|x64 + {0A06D231-FC40-4EC9-B0FC-F0D08270384E}.Debug|Win32.ActiveCfg = Debug|Win32 + {0A06D231-FC40-4EC9-B0FC-F0D08270384E}.Debug|Win32.Build.0 = Debug|Win32 + {0A06D231-FC40-4EC9-B0FC-F0D08270384E}.Debug|x64.ActiveCfg = Debug|x64 + {0A06D231-FC40-4EC9-B0FC-F0D08270384E}.Debug|x64.Build.0 = Debug|x64 + {0A06D231-FC40-4EC9-B0FC-F0D08270384E}.Release|Win32.ActiveCfg = Release|Win32 + {0A06D231-FC40-4EC9-B0FC-F0D08270384E}.Release|Win32.Build.0 = Release|Win32 + {0A06D231-FC40-4EC9-B0FC-F0D08270384E}.Release|x64.ActiveCfg = Release|x64 + {0A06D231-FC40-4EC9-B0FC-F0D08270384E}.Release|x64.Build.0 = Release|x64 + {9E09B1EB-D3F3-4C38-B87F-AE642F509D04}.Debug|Win32.ActiveCfg = Debug|Win32 + {9E09B1EB-D3F3-4C38-B87F-AE642F509D04}.Debug|Win32.Build.0 = Debug|Win32 + {9E09B1EB-D3F3-4C38-B87F-AE642F509D04}.Debug|x64.ActiveCfg = Debug|x64 + {9E09B1EB-D3F3-4C38-B87F-AE642F509D04}.Debug|x64.Build.0 = Debug|x64 + {9E09B1EB-D3F3-4C38-B87F-AE642F509D04}.Release|Win32.ActiveCfg = Release|Win32 + {9E09B1EB-D3F3-4C38-B87F-AE642F509D04}.Release|Win32.Build.0 = Release|Win32 + {9E09B1EB-D3F3-4C38-B87F-AE642F509D04}.Release|x64.ActiveCfg = Release|x64 + {9E09B1EB-D3F3-4C38-B87F-AE642F509D04}.Release|x64.Build.0 = Release|x64 + {9E7C038E-470E-4DF8-A887-3E1B8A02B78C}.Debug|Win32.ActiveCfg = Debug|Win32 + {9E7C038E-470E-4DF8-A887-3E1B8A02B78C}.Debug|Win32.Build.0 = Debug|Win32 + {9E7C038E-470E-4DF8-A887-3E1B8A02B78C}.Debug|x64.ActiveCfg = Debug|x64 + {9E7C038E-470E-4DF8-A887-3E1B8A02B78C}.Debug|x64.Build.0 = Debug|x64 + {9E7C038E-470E-4DF8-A887-3E1B8A02B78C}.Release|Win32.ActiveCfg = Release|Win32 + {9E7C038E-470E-4DF8-A887-3E1B8A02B78C}.Release|Win32.Build.0 = Release|Win32 + {9E7C038E-470E-4DF8-A887-3E1B8A02B78C}.Release|x64.ActiveCfg = Release|x64 + {9E7C038E-470E-4DF8-A887-3E1B8A02B78C}.Release|x64.Build.0 = Release|x64 + {3EDCB092-C785-41EB-8A83-C5B37A2FF310}.Debug|Win32.ActiveCfg = Debug|Win32 + {3EDCB092-C785-41EB-8A83-C5B37A2FF310}.Debug|Win32.Build.0 = Debug|Win32 + {3EDCB092-C785-41EB-8A83-C5B37A2FF310}.Debug|x64.ActiveCfg = Debug|x64 + {3EDCB092-C785-41EB-8A83-C5B37A2FF310}.Debug|x64.Build.0 = Debug|x64 + {3EDCB092-C785-41EB-8A83-C5B37A2FF310}.Release|Win32.ActiveCfg = Release|Win32 + {3EDCB092-C785-41EB-8A83-C5B37A2FF310}.Release|Win32.Build.0 = Release|Win32 + {3EDCB092-C785-41EB-8A83-C5B37A2FF310}.Release|x64.ActiveCfg = Release|x64 + {3EDCB092-C785-41EB-8A83-C5B37A2FF310}.Release|x64.Build.0 = Release|x64 + {B0D287DB-451D-4005-9CE3-185D7602F0B7}.Debug|Win32.ActiveCfg = Debug|Win32 + {B0D287DB-451D-4005-9CE3-185D7602F0B7}.Debug|Win32.Build.0 = Debug|Win32 + {B0D287DB-451D-4005-9CE3-185D7602F0B7}.Debug|x64.ActiveCfg = Debug|x64 + {B0D287DB-451D-4005-9CE3-185D7602F0B7}.Debug|x64.Build.0 = Debug|x64 + {B0D287DB-451D-4005-9CE3-185D7602F0B7}.Release|Win32.ActiveCfg = Release|Win32 + {B0D287DB-451D-4005-9CE3-185D7602F0B7}.Release|Win32.Build.0 = Release|Win32 + {B0D287DB-451D-4005-9CE3-185D7602F0B7}.Release|x64.ActiveCfg = Release|x64 + {B0D287DB-451D-4005-9CE3-185D7602F0B7}.Release|x64.Build.0 = Release|x64 + {D10B61A9-09FD-4E87-8C66-BE07AE5CC8E9}.Debug|Win32.ActiveCfg = Debug|Win32 + {D10B61A9-09FD-4E87-8C66-BE07AE5CC8E9}.Debug|Win32.Build.0 = Debug|Win32 + {D10B61A9-09FD-4E87-8C66-BE07AE5CC8E9}.Debug|x64.ActiveCfg = Debug|x64 + {D10B61A9-09FD-4E87-8C66-BE07AE5CC8E9}.Debug|x64.Build.0 = Debug|x64 + {D10B61A9-09FD-4E87-8C66-BE07AE5CC8E9}.Release|Win32.ActiveCfg = Release|Win32 + {D10B61A9-09FD-4E87-8C66-BE07AE5CC8E9}.Release|Win32.Build.0 = Release|Win32 + {D10B61A9-09FD-4E87-8C66-BE07AE5CC8E9}.Release|x64.ActiveCfg = Release|x64 + {D10B61A9-09FD-4E87-8C66-BE07AE5CC8E9}.Release|x64.Build.0 = Release|x64 + {33FF435B-A3CF-441E-964E-A7DA8735E7B1}.Debug|Win32.ActiveCfg = Debug|Win32 + {33FF435B-A3CF-441E-964E-A7DA8735E7B1}.Debug|Win32.Build.0 = Debug|Win32 + {33FF435B-A3CF-441E-964E-A7DA8735E7B1}.Debug|x64.ActiveCfg = Debug|x64 + {33FF435B-A3CF-441E-964E-A7DA8735E7B1}.Debug|x64.Build.0 = Debug|x64 + {33FF435B-A3CF-441E-964E-A7DA8735E7B1}.Release|Win32.ActiveCfg = Release|Win32 + {33FF435B-A3CF-441E-964E-A7DA8735E7B1}.Release|Win32.Build.0 = Release|Win32 + {33FF435B-A3CF-441E-964E-A7DA8735E7B1}.Release|x64.ActiveCfg = Release|x64 + {33FF435B-A3CF-441E-964E-A7DA8735E7B1}.Release|x64.Build.0 = Release|x64 + {C3B58F69-FA5D-4E9E-8E21-F6C5EBAC22ED}.Debug|Win32.ActiveCfg = Debug|Win32 + {C3B58F69-FA5D-4E9E-8E21-F6C5EBAC22ED}.Debug|Win32.Build.0 = Debug|Win32 + {C3B58F69-FA5D-4E9E-8E21-F6C5EBAC22ED}.Debug|x64.ActiveCfg = Debug|x64 + {C3B58F69-FA5D-4E9E-8E21-F6C5EBAC22ED}.Debug|x64.Build.0 = Debug|x64 + {C3B58F69-FA5D-4E9E-8E21-F6C5EBAC22ED}.Release|Win32.ActiveCfg = Release|Win32 + {C3B58F69-FA5D-4E9E-8E21-F6C5EBAC22ED}.Release|Win32.Build.0 = Release|Win32 + {C3B58F69-FA5D-4E9E-8E21-F6C5EBAC22ED}.Release|x64.ActiveCfg = Release|x64 + {C3B58F69-FA5D-4E9E-8E21-F6C5EBAC22ED}.Release|x64.Build.0 = Release|x64 + {660117AA-6B9E-4C7D-B0BE-DE6BD17DBA1E}.Debug|Win32.ActiveCfg = Debug|Win32 + {660117AA-6B9E-4C7D-B0BE-DE6BD17DBA1E}.Debug|Win32.Build.0 = Debug|Win32 + {660117AA-6B9E-4C7D-B0BE-DE6BD17DBA1E}.Debug|x64.ActiveCfg = Debug|x64 + {660117AA-6B9E-4C7D-B0BE-DE6BD17DBA1E}.Debug|x64.Build.0 = Debug|x64 + {660117AA-6B9E-4C7D-B0BE-DE6BD17DBA1E}.Release|Win32.ActiveCfg = Release|Win32 + {660117AA-6B9E-4C7D-B0BE-DE6BD17DBA1E}.Release|Win32.Build.0 = Release|Win32 + {660117AA-6B9E-4C7D-B0BE-DE6BD17DBA1E}.Release|x64.ActiveCfg = Release|x64 + {660117AA-6B9E-4C7D-B0BE-DE6BD17DBA1E}.Release|x64.Build.0 = Release|x64 + {781B56DF-15CE-4CBA-A008-0403029E558A}.Debug|Win32.ActiveCfg = Debug|Win32 + {781B56DF-15CE-4CBA-A008-0403029E558A}.Debug|Win32.Build.0 = Debug|Win32 + {781B56DF-15CE-4CBA-A008-0403029E558A}.Debug|x64.ActiveCfg = Debug|x64 + {781B56DF-15CE-4CBA-A008-0403029E558A}.Debug|x64.Build.0 = Debug|x64 + {781B56DF-15CE-4CBA-A008-0403029E558A}.Release|Win32.ActiveCfg = Release|Win32 + {781B56DF-15CE-4CBA-A008-0403029E558A}.Release|Win32.Build.0 = Release|Win32 + {781B56DF-15CE-4CBA-A008-0403029E558A}.Release|x64.ActiveCfg = Release|x64 + {781B56DF-15CE-4CBA-A008-0403029E558A}.Release|x64.Build.0 = Release|x64 + {BA36739B-F101-4C91-928D-678AB9521A22}.Debug|Win32.ActiveCfg = Debug|Win32 + {BA36739B-F101-4C91-928D-678AB9521A22}.Debug|Win32.Build.0 = Debug|Win32 + {BA36739B-F101-4C91-928D-678AB9521A22}.Debug|x64.ActiveCfg = Debug|x64 + {BA36739B-F101-4C91-928D-678AB9521A22}.Debug|x64.Build.0 = Debug|x64 + {BA36739B-F101-4C91-928D-678AB9521A22}.Release|Win32.ActiveCfg = Release|Win32 + {BA36739B-F101-4C91-928D-678AB9521A22}.Release|Win32.Build.0 = Release|Win32 + {BA36739B-F101-4C91-928D-678AB9521A22}.Release|x64.ActiveCfg = Release|x64 + {BA36739B-F101-4C91-928D-678AB9521A22}.Release|x64.Build.0 = Release|x64 + {22788F46-AB6B-4278-B1C0-ED220AE85F4A}.Debug|Win32.ActiveCfg = Debug|Win32 + {22788F46-AB6B-4278-B1C0-ED220AE85F4A}.Debug|Win32.Build.0 = Debug|Win32 + {22788F46-AB6B-4278-B1C0-ED220AE85F4A}.Debug|x64.ActiveCfg = Debug|x64 + {22788F46-AB6B-4278-B1C0-ED220AE85F4A}.Debug|x64.Build.0 = Debug|x64 + {22788F46-AB6B-4278-B1C0-ED220AE85F4A}.Release|Win32.ActiveCfg = Release|Win32 + {22788F46-AB6B-4278-B1C0-ED220AE85F4A}.Release|Win32.Build.0 = Release|Win32 + {22788F46-AB6B-4278-B1C0-ED220AE85F4A}.Release|x64.ActiveCfg = Release|x64 + {22788F46-AB6B-4278-B1C0-ED220AE85F4A}.Release|x64.Build.0 = Release|x64 + {F61AB18A-8E8B-43D1-91B2-D6A2A297FDD6}.Debug|Win32.ActiveCfg = Debug|Win32 + {F61AB18A-8E8B-43D1-91B2-D6A2A297FDD6}.Debug|Win32.Build.0 = Debug|Win32 + {F61AB18A-8E8B-43D1-91B2-D6A2A297FDD6}.Debug|x64.ActiveCfg = Debug|x64 + {F61AB18A-8E8B-43D1-91B2-D6A2A297FDD6}.Debug|x64.Build.0 = Debug|x64 + {F61AB18A-8E8B-43D1-91B2-D6A2A297FDD6}.Release|Win32.ActiveCfg = Release|Win32 + {F61AB18A-8E8B-43D1-91B2-D6A2A297FDD6}.Release|Win32.Build.0 = Release|Win32 + {F61AB18A-8E8B-43D1-91B2-D6A2A297FDD6}.Release|x64.ActiveCfg = Release|x64 + {F61AB18A-8E8B-43D1-91B2-D6A2A297FDD6}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {4B658F8F-1722-4EEA-880C-A4A64DCA9F2C} = {20B98358-3862-4D16-985F-ECE9DE5D9FEB} + {642392B3-C763-44C8-91F4-EA90C3651608} = {25A7C026-702D-48A4-A1EC-81DE78F0664E} + {DE053D44-F9BD-4C1A-B44B-3157BE27AD02} = {25A7C026-702D-48A4-A1EC-81DE78F0664E} + {7AF45D7B-8341-42CF-B382-B67E1399D8B1} = {25A7C026-702D-48A4-A1EC-81DE78F0664E} + {65229ACC-5C9B-429C-B9DA-4710697637EB} = {25A7C026-702D-48A4-A1EC-81DE78F0664E} + {218033A7-A6D0-45B4-88F6-F4FF5DD25207} = {25A7C026-702D-48A4-A1EC-81DE78F0664E} + {111344DB-1F0B-460E-91DD-9DD36D2238A4} = {25A7C026-702D-48A4-A1EC-81DE78F0664E} + {D8E2714A-11A7-478D-A966-EF6968FFB766} = {25A7C026-702D-48A4-A1EC-81DE78F0664E} + {AC7C3A84-2F81-4B22-B27E-50A9D4C750E2} = {25A7C026-702D-48A4-A1EC-81DE78F0664E} + {15AFEB1D-4EF8-4AF0-88C8-9FCA879F8AE2} = {25A7C026-702D-48A4-A1EC-81DE78F0664E} + {1F7B06CA-5529-4A3D-89CE-15161D4A01D9} = {25A7C026-702D-48A4-A1EC-81DE78F0664E} + {0A06D231-FC40-4EC9-B0FC-F0D08270384E} = {25A7C026-702D-48A4-A1EC-81DE78F0664E} + {3EDCB092-C785-41EB-8A83-C5B37A2FF310} = {25A7C026-702D-48A4-A1EC-81DE78F0664E} + {D10B61A9-09FD-4E87-8C66-BE07AE5CC8E9} = {25A7C026-702D-48A4-A1EC-81DE78F0664E} + {33FF435B-A3CF-441E-964E-A7DA8735E7B1} = {25A7C026-702D-48A4-A1EC-81DE78F0664E} + {660117AA-6B9E-4C7D-B0BE-DE6BD17DBA1E} = {25A7C026-702D-48A4-A1EC-81DE78F0664E} + {BA36739B-F101-4C91-928D-678AB9521A22} = {25A7C026-702D-48A4-A1EC-81DE78F0664E} + {4459EB9F-0332-46C4-BF60-6CECA73C7D17} = {0CF51D6D-1F80-4D2C-95BE-566641BD1F71} + {5303D6F1-D667-4E92-A501-8B396252156F} = {0CF51D6D-1F80-4D2C-95BE-566641BD1F71} + {36EB9E03-E155-4487-AB1B-0B1B862B0155} = {0CF51D6D-1F80-4D2C-95BE-566641BD1F71} + {0F52C42C-EEDA-4031-B0A0-F6CD53C81465} = {0CF51D6D-1F80-4D2C-95BE-566641BD1F71} + {9E09B1EB-D3F3-4C38-B87F-AE642F509D04} = {0CF51D6D-1F80-4D2C-95BE-566641BD1F71} + {9E7C038E-470E-4DF8-A887-3E1B8A02B78C} = {0CF51D6D-1F80-4D2C-95BE-566641BD1F71} + {B0D287DB-451D-4005-9CE3-185D7602F0B7} = {0CF51D6D-1F80-4D2C-95BE-566641BD1F71} + {C3B58F69-FA5D-4E9E-8E21-F6C5EBAC22ED} = {0CF51D6D-1F80-4D2C-95BE-566641BD1F71} + {781B56DF-15CE-4CBA-A008-0403029E558A} = {0CF51D6D-1F80-4D2C-95BE-566641BD1F71} + {22788F46-AB6B-4278-B1C0-ED220AE85F4A} = {0CF51D6D-1F80-4D2C-95BE-566641BD1F71} + {F61AB18A-8E8B-43D1-91B2-D6A2A297FDD6} = {0CF51D6D-1F80-4D2C-95BE-566641BD1F71} + {0CF51D6D-1F80-4D2C-95BE-566641BD1F71} = {9191A7C3-3B0A-45A5-99A2-72D1903AA7B7} + {25A7C026-702D-48A4-A1EC-81DE78F0664E} = {9191A7C3-3B0A-45A5-99A2-72D1903AA7B7} + EndGlobalSection +EndGlobal diff --git a/irdb-lib/pebliss/trunk/pe_lib/Makefile b/irdb-lib/pebliss/trunk/pe_lib/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..6105f28c22f8d2ff1ea5ad5dff479f0e207d907d --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/Makefile @@ -0,0 +1,24 @@ +OBJS = entropy.o file_version_info.o message_table.o pe_base.o pe_bound_import.o pe_checksum.o pe_debug.o pe_directory.o pe_dotnet.o pe_exception_directory.o pe_exports.o pe_imports.o pe_load_config.o pe_properties.o pe_properties_generic.o pe_relocations.o pe_factory.o pe_resources.o pe_resource_manager.o pe_resource_viewer.o pe_rich_data.o pe_section.o pe_tls.o utils.o version_info_editor.o version_info_viewer.o pe_exception.o resource_message_list_reader.o resource_string_table_reader.o resource_version_info_reader.o resource_version_info_writer.o resource_cursor_icon_reader.o resource_cursor_icon_writer.o resource_bitmap_writer.o resource_bitmap_reader.o resource_data_info.o pe_rebuilder.o +LIBNAME = pebliss +LIBPATH = ../lib +CXXFLAGS = -O2 -Wall -fPIC -DPIC -I. + +ifdef PE_DEBUG +CXXFLAGS += -g -O0 +endif + +all: $(LIBPATH)/lib$(LIBNAME).a + +clean: + rm -f $(OBJS) lib$(LIBNAME).a + rm -rf ../lib + +lib$(LIBNAME).a: $(OBJS) + ar -cvr lib$(LIBNAME).a $(OBJS) + ranlib lib$(LIBNAME).a + +$(LIBPATH): + mkdir -p ../lib + +$(LIBPATH)/lib$(LIBNAME).a: lib$(LIBNAME).a $(LIBPATH) + cp -d lib$(LIBNAME).a ../lib diff --git a/irdb-lib/pebliss/trunk/pe_lib/SConscript b/irdb-lib/pebliss/trunk/pe_lib/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..e5270eac2201cf4659e32e3f137e403b1187e567 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/SConscript @@ -0,0 +1,59 @@ +import os + +Import('env') +myenv=env +myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) + + +libname="pebliss" +files= ''' + entropy.cpp + file_version_info.cpp + message_table.cpp + pe_base.cpp + pe_bound_import.cpp + pe_checksum.cpp + pe_debug.cpp + pe_directory.cpp + pe_dotnet.cpp + pe_exception.cpp + pe_exception_directory.cpp + pe_exports.cpp + pe_factory.cpp + pe_imports.cpp + pe_load_config.cpp + pe_properties.cpp + pe_properties_generic.cpp + pe_rebuilder.cpp + pe_relocations.cpp + pe_resource_manager.cpp + pe_resource_viewer.cpp + pe_resources.cpp + pe_rich_data.cpp + pe_section.cpp + pe_tls.cpp + resource_bitmap_reader.cpp + resource_bitmap_writer.cpp + resource_cursor_icon_reader.cpp + resource_cursor_icon_writer.cpp + resource_data_info.cpp + resource_message_list_reader.cpp + resource_string_table_reader.cpp + resource_version_info_reader.cpp + resource_version_info_writer.cpp + utils.cpp + version_info_editor.cpp + version_info_viewer.cpp + ''' + +cpppath=''' + $SECURITY_TRANSFORMS_HOME/pebliss/trunk/pe_lib + ''' + +myenv=myenv.Clone(CPPPATH=Split(cpppath)) +myenv.Append(CCFLAGS=" -w ") +lib=myenv.SharedLibrary(libname, Split(files)) + +install=myenv.Install("$SECURITY_TRANSFORMS_HOME/lib/", lib) +Default(install) + diff --git a/irdb-lib/pebliss/trunk/pe_lib/SConstruct b/irdb-lib/pebliss/trunk/pe_lib/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..c0dd68a00d406b0148a93709cf916ad6d05f282c --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/SConstruct @@ -0,0 +1,6 @@ + + + +env=Environment() +Export('env') +SConscript("SConscript") diff --git a/irdb-lib/pebliss/trunk/pe_lib/entropy.cpp b/irdb-lib/pebliss/trunk/pe_lib/entropy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cdd8efb8a95a94ab734402b5725e4415148f4310 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/entropy.cpp @@ -0,0 +1,90 @@ +#include <cmath> +#include "entropy.h" +#include "utils.h" + +namespace pe_bliss +{ +//Calculates entropy for PE image section +double entropy_calculator::calculate_entropy(const section& s) +{ + if(s.get_raw_data().empty()) //Don't count entropy for empty sections + throw pe_exception("Section is empty", pe_exception::section_is_empty); + + return calculate_entropy(s.get_raw_data().data(), s.get_raw_data().length()); +} + +//Calculates entropy for istream (from current position of stream) +double entropy_calculator::calculate_entropy(std::istream& file) +{ + uint32_t byte_count[256] = {0}; //Byte count for each of 255 bytes + + if(file.bad()) + throw pe_exception("Stream is bad", pe_exception::stream_is_bad); + + std::streamoff pos = file.tellg(); + + std::streamoff length = pe_utils::get_file_size(file); + length -= file.tellg(); + + if(!length) //Don't calculate entropy for empty buffers + throw pe_exception("Data length is zero", pe_exception::data_is_empty); + + //Count bytes + for(std::streamoff i = 0; i != length; ++i) + ++byte_count[static_cast<unsigned char>(file.get())]; + + file.seekg(pos); + + return calculate_entropy(byte_count, length); +} + +//Calculates entropy for data block +double entropy_calculator::calculate_entropy(const char* data, size_t length) +{ + uint32_t byte_count[256] = {0}; //Byte count for each of 255 bytes + + if(!length) //Don't calculate entropy for empty buffers + throw pe_exception("Data length is zero", pe_exception::data_is_empty); + + //Count bytes + for(size_t i = 0; i != length; ++i) + ++byte_count[static_cast<unsigned char>(data[i])]; + + return calculate_entropy(byte_count, length); +} + +//Calculates entropy for this PE file (only section data) +double entropy_calculator::calculate_entropy(const pe_base& pe) +{ + uint32_t byte_count[256] = {0}; //Byte count for each of 255 bytes + + size_t total_data_length = 0; + + //Count bytes for each section + for(section_list::const_iterator it = pe.get_image_sections().begin(); it != pe.get_image_sections().end(); ++it) + { + const std::string& data = (*it).get_raw_data(); + size_t length = data.length(); + total_data_length += length; + for(size_t i = 0; i != length; ++i) + ++byte_count[static_cast<unsigned char>(data[i])]; + } + + return calculate_entropy(byte_count, total_data_length); +} + +//Calculates entropy from bytes count +double entropy_calculator::calculate_entropy(const uint32_t byte_count[256], std::streamoff total_length) +{ + double entropy = 0.; //Entropy result value + //Calculate entropy + for(uint32_t i = 0; i < 256; ++i) + { + double temp = static_cast<double>(byte_count[i]) / total_length; + if(temp > 0.) + entropy += std::abs(temp * (std::log(temp) * pe_utils::log_2)); + } + + return entropy; +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/entropy.h b/irdb-lib/pebliss/trunk/pe_lib/entropy.h new file mode 100644 index 0000000000000000000000000000000000000000..749ad4c588f23e1a869dca74af71eff6bd805f20 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/entropy.h @@ -0,0 +1,34 @@ +#ifndef pebliss_entropy_h +#define pebliss_entropy_h +#pragma once + +#include <istream> +#include "pe_base.h" + +namespace pe_bliss +{ +class entropy_calculator +{ +public: + //Calculates entropy for PE image section + static double calculate_entropy(const section& s); + + //Calculates entropy for istream (from current position of stream) + static double calculate_entropy(std::istream& file); + + //Calculates entropy for data block + static double calculate_entropy(const char* data, size_t length); + + //Calculates entropy for this PE file (only section data) + static double calculate_entropy(const pe_base& pe); + +private: + entropy_calculator(); + entropy_calculator(const entropy_calculator&); + entropy_calculator& operator=(const entropy_calculator&); + + //Calculates entropy from bytes count + static double calculate_entropy(const uint32_t byte_count[256], std::streamoff total_length); +}; +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/file_version_info.cpp b/irdb-lib/pebliss/trunk/pe_lib/file_version_info.cpp new file mode 100644 index 0000000000000000000000000000000000000000..50a02f89087e84b00dd8fbeb52ea7a3a85fd679c --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/file_version_info.cpp @@ -0,0 +1,419 @@ +#include "file_version_info.h" +#include "pe_structures.h" + +namespace pe_bliss +{ +using namespace pe_win; + +//Default constructor +file_version_info::file_version_info() + :file_version_ms_(0), file_version_ls_(0), + product_version_ms_(0), product_version_ls_(0), + file_flags_(0), + file_os_(0), + file_type_(0), file_subtype_(0), + file_date_ms_(0), file_date_ls_(0) +{} + +//Constructor from Windows fixed version info structure +file_version_info::file_version_info(const vs_fixedfileinfo& info) + :file_version_ms_(info.dwFileVersionMS), file_version_ls_(info.dwFileVersionLS), + product_version_ms_(info.dwProductVersionMS), product_version_ls_(info.dwProductVersionLS), + file_flags_(info.dwFileFlags), + file_os_(info.dwFileOS), + file_type_(info.dwFileType), file_subtype_(info.dwFileSubtype), + file_date_ms_(info.dwFileDateMS), file_date_ls_(info.dwFileDateLS) +{} + +//Returns true if file is debug-built +bool file_version_info::is_debug() const +{ + return file_flags_ & vs_ff_debug ? true : false; +} + +//Returns true if file is release-built +bool file_version_info::is_prerelease() const +{ + return file_flags_ & vs_ff_prerelease ? true : false; +} + +//Returns true if file is patched +bool file_version_info::is_patched() const +{ + return file_flags_ & vs_ff_patched ? true : false; +} + +//Returns true if private build +bool file_version_info::is_private_build() const +{ + return file_flags_ & vs_ff_privatebuild ? true : false; +} + +//Returns true if special build +bool file_version_info::is_special_build() const +{ + return file_flags_ & vs_ff_specialbuild ? true : false; +} + +//Returns true if info inferred +bool file_version_info::is_info_inferred() const +{ + return file_flags_ & vs_ff_infoinferred ? true : false; +} + +//Retuens file flags (raw DWORD) +uint32_t file_version_info::get_file_flags() const +{ + return file_flags_; +} + +//Returns file version most significant DWORD +uint32_t file_version_info::get_file_version_ms() const +{ + return file_version_ms_; +} + +//Returns file version least significant DWORD +uint32_t file_version_info::get_file_version_ls() const +{ + return file_version_ls_; +} + +//Returns product version most significant DWORD +uint32_t file_version_info::get_product_version_ms() const +{ + return product_version_ms_; +} + +//Returns product version least significant DWORD +uint32_t file_version_info::get_product_version_ls() const +{ + return product_version_ls_; +} + +//Returns file OS type (raw DWORD) +uint32_t file_version_info::get_file_os_raw() const +{ + return file_os_; +} + +//Returns file OS type +file_version_info::file_os_type file_version_info::get_file_os() const +{ + //Determine file operation system type + switch(file_os_) + { + case vos_dos: + return file_os_dos; + + case vos_os216: + return file_os_os216; + + case vos_os232: + return file_os_os232; + + case vos_nt: + return file_os_nt; + + case vos_wince: + return file_os_wince; + + case vos__windows16: + return file_os_win16; + + case vos__pm16: + return file_os_pm16; + + case vos__pm32: + return file_os_pm32; + + case vos__windows32: + return file_os_win32; + + case vos_dos_windows16: + return file_os_dos_win16; + + case vos_dos_windows32: + return file_os_dos_win32; + + case vos_os216_pm16: + return file_os_os216_pm16; + + case vos_os232_pm32: + return file_os_os232_pm32; + + case vos_nt_windows32: + return file_os_nt_win32; + } + + return file_os_unknown; +} + +//Returns file type (raw DWORD) +uint32_t file_version_info::get_file_type_raw() const +{ + return file_type_; +} + +//Returns file type +file_version_info::file_type file_version_info::get_file_type() const +{ + //Determine file type + switch(file_type_) + { + case vft_app: + return file_type_application; + + case vft_dll: + return file_type_dll; + + case vft_drv: + return file_type_driver; + + case vft_font: + return file_type_font; + + case vft_vxd: + return file_type_vxd; + + case vft_static_lib: + return file_type_static_lib; + } + + return file_type_unknown; +} + +//Returns file subtype (usually non-zero for drivers and fonts) +uint32_t file_version_info::get_file_subtype() const +{ + return file_subtype_; +} + +//Returns file date most significant DWORD +uint32_t file_version_info::get_file_date_ms() const +{ + return file_date_ms_; +} + +//Returns file date least significant DWORD +uint32_t file_version_info::get_file_date_ls() const +{ + return file_date_ls_; +} + +//Helper to set file flag +void file_version_info::set_file_flag(uint32_t flag) +{ + file_flags_ |= flag; +} + +//Helper to clear file flag +void file_version_info::clear_file_flag(uint32_t flag) +{ + file_flags_ &= ~flag; +} + +//Helper to set or clear file flag +void file_version_info::set_file_flag(uint32_t flag, bool set_flag) +{ + set_flag ? set_file_flag(flag) : clear_file_flag(flag); +} + +//Sets if file is debug-built +void file_version_info::set_debug(bool debug) +{ + set_file_flag(vs_ff_debug, debug); +} + +//Sets if file is prerelease +void file_version_info::set_prerelease(bool prerelease) +{ + set_file_flag(vs_ff_prerelease, prerelease); +} + +//Sets if file is patched +void file_version_info::set_patched(bool patched) +{ + set_file_flag(vs_ff_patched, patched); +} + +//Sets if private build +void file_version_info::set_private_build(bool private_build) +{ + set_file_flag(vs_ff_privatebuild, private_build); +} + +//Sets if special build +void file_version_info::set_special_build(bool special_build) +{ + set_file_flag(vs_ff_specialbuild, special_build); +} + +//Sets if info inferred +void file_version_info::set_info_inferred(bool info_inferred) +{ + set_file_flag(vs_ff_infoinferred, info_inferred); +} + +//Sets flags (raw DWORD) +void file_version_info::set_file_flags(uint32_t file_flags) +{ + file_flags_ = file_flags; +} + +//Sets file version most significant DWORD +void file_version_info::set_file_version_ms(uint32_t file_version_ms) +{ + file_version_ms_ = file_version_ms; +} + +//Sets file version least significant DWORD +void file_version_info::set_file_version_ls(uint32_t file_version_ls) +{ + file_version_ls_ = file_version_ls; +} + +//Sets product version most significant DWORD +void file_version_info::set_product_version_ms(uint32_t product_version_ms) +{ + product_version_ms_ = product_version_ms; +} + +//Sets product version least significant DWORD +void file_version_info::set_product_version_ls(uint32_t product_version_ls) +{ + product_version_ls_ = product_version_ls; +} + +//Sets file OS type (raw DWORD) +void file_version_info::set_file_os_raw(uint32_t file_os) +{ + file_os_ = file_os; +} + +//Sets file OS type +void file_version_info::set_file_os(file_os_type file_os) +{ + //Determine file operation system type + switch(file_os) + { + case file_os_dos: + file_os_ = vos_dos; + return; + + case file_os_os216: + file_os_ = vos_os216; + return; + + case file_os_os232: + file_os_ = vos_os232; + return; + + case file_os_nt: + file_os_ = vos_nt; + return; + + case file_os_wince: + file_os_ = vos_wince; + return; + + case file_os_win16: + file_os_ = vos__windows16; + return; + + case file_os_pm16: + file_os_ = vos__pm16; + return; + + case file_os_pm32: + file_os_ = vos__pm32; + return; + + case file_os_win32: + file_os_ = vos__windows32; + return; + + case file_os_dos_win16: + file_os_ = vos_dos_windows16; + return; + + case file_os_dos_win32: + file_os_ = vos_dos_windows32; + return; + + case file_os_os216_pm16: + file_os_ = vos_os216_pm16; + return; + + case file_os_os232_pm32: + file_os_ = vos_os232_pm32; + return; + + case file_os_nt_win32: + file_os_ = vos_nt_windows32; + return; + + default: + return; + } +} + +//Sets file type (raw DWORD) +void file_version_info::set_file_type_raw(uint32_t file_type) +{ + file_type_ = file_type; +} + +//Sets file type +void file_version_info::set_file_type(file_type file_type) +{ + //Determine file type + switch(file_type) + { + case file_type_application: + file_type_ = vft_app; + return; + + case file_type_dll: + file_type_ = vft_dll; + return; + + case file_type_driver: + file_type_ = vft_drv; + return; + + case file_type_font: + file_type_ = vft_font; + return; + + case file_type_vxd: + file_type_ = vft_vxd; + return; + + case file_type_static_lib: + file_type_ = vft_static_lib; + return; + + default: + return; + } +} + +//Sets file subtype (usually non-zero for drivers and fonts) +void file_version_info::set_file_subtype(uint32_t file_subtype) +{ + file_subtype_ = file_subtype; +} + +//Sets file date most significant DWORD +void file_version_info::set_file_date_ms(uint32_t file_date_ms) +{ + file_date_ms_ = file_date_ms; +} + +//Sets file date least significant DWORD +void file_version_info::set_file_date_ls(uint32_t file_date_ls) +{ + file_date_ls_ = file_date_ls; +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/file_version_info.h b/irdb-lib/pebliss/trunk/pe_lib/file_version_info.h new file mode 100644 index 0000000000000000000000000000000000000000..34fc2de03f7afdbf7c3fe045d7f159203ba05aea --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/file_version_info.h @@ -0,0 +1,181 @@ +#ifndef pebliss_file_version_info_h +#define pebliss_file_version_info_h +#pragma once +#include <string> +#include <map> +#include "stdint_defs.h" +#include "pe_structures.h" + +namespace pe_bliss +{ +//Structure representing fixed file version info +class file_version_info +{ +public: + //Enumeration of file operating system types + enum file_os_type + { + file_os_unknown, + file_os_dos, + file_os_os216, + file_os_os232, + file_os_nt, + file_os_wince, + file_os_win16, + file_os_pm16, + file_os_pm32, + file_os_win32, + file_os_dos_win16, + file_os_dos_win32, + file_os_os216_pm16, + file_os_os232_pm32, + file_os_nt_win32 + }; + + //Enumeration of file types + enum file_type + { + file_type_unknown, + file_type_application, + file_type_dll, + file_type_driver, + file_type_font, + file_type_vxd, + file_type_static_lib + }; + +public: + //Default constructor + file_version_info(); + //Constructor from Windows fixed version info structure + explicit file_version_info(const pe_win::vs_fixedfileinfo& info); + +public: //Getters + //Returns true if file is debug-built + bool is_debug() const; + //Returns true if file is prerelease + bool is_prerelease() const; + //Returns true if file is patched + bool is_patched() const; + //Returns true if private build + bool is_private_build() const; + //Returns true if special build + bool is_special_build() const; + //Returns true if info inferred + bool is_info_inferred() const; + //Retuens file flags (raw DWORD) + uint32_t get_file_flags() const; + + //Returns file version most significant DWORD + uint32_t get_file_version_ms() const; + //Returns file version least significant DWORD + uint32_t get_file_version_ls() const; + //Returns product version most significant DWORD + uint32_t get_product_version_ms() const; + //Returns product version least significant DWORD + uint32_t get_product_version_ls() const; + + //Returns file OS type (raw DWORD) + uint32_t get_file_os_raw() const; + //Returns file OS type + file_os_type get_file_os() const; + + //Returns file type (raw DWORD) + uint32_t get_file_type_raw() const; + //Returns file type + file_type get_file_type() const; + + //Returns file subtype (usually non-zero for drivers and fonts) + uint32_t get_file_subtype() const; + + //Returns file date most significant DWORD + uint32_t get_file_date_ms() const; + //Returns file date least significant DWORD + uint32_t get_file_date_ls() const; + + //Returns file version string + template<typename T> + const std::basic_string<T> get_file_version_string() const + { + return get_version_string<T>(file_version_ms_, file_version_ls_); + } + + //Returns product version string + template<typename T> + const std::basic_string<T> get_product_version_string() const + { + return get_version_string<T>(product_version_ms_, product_version_ls_); + } + +public: //Setters + //Sets if file is debug-built + void set_debug(bool debug); + //Sets if file is prerelease + void set_prerelease(bool prerelease); + //Sets if file is patched + void set_patched(bool patched); + //Sets if private build + void set_private_build(bool private_build); + //Sets if special build + void set_special_build(bool special_build); + //Sets if info inferred + void set_info_inferred(bool info_inferred); + //Sets flags (raw DWORD) + void set_file_flags(uint32_t file_flags); + + //Sets file version most significant DWORD + void set_file_version_ms(uint32_t file_version_ms); + //Sets file version least significant DWORD + void set_file_version_ls(uint32_t file_version_ls); + //Sets product version most significant DWORD + void set_product_version_ms(uint32_t product_version_ms); + //Sets product version least significant DWORD + void set_product_version_ls(uint32_t product_version_ls); + + //Sets file OS type (raw DWORD) + void set_file_os_raw(uint32_t file_os); + //Sets file OS type + void set_file_os(file_os_type file_os); + + //Sets file type (raw DWORD) + void set_file_type_raw(uint32_t file_type); + //Sets file type + void set_file_type(file_type file_type); + + //Sets file subtype (usually non-zero for drivers and fonts) + void set_file_subtype(uint32_t file_subtype); + + //Sets file date most significant DWORD + void set_file_date_ms(uint32_t file_date_ms); + //Sets file date least significant DWORD + void set_file_date_ls(uint32_t file_date_ls); + +private: + //Helper to convert version DWORDs to string + template<typename T> + static const std::basic_string<T> get_version_string(uint32_t ms, uint32_t ls) + { + std::basic_stringstream<T> ss; + ss << (ms >> 16) << static_cast<T>(L'.') + << (ms & 0xFFFF) << static_cast<T>(L'.') + << (ls >> 16) << static_cast<T>(L'.') + << (ls & 0xFFFF); + return ss.str(); + } + + //Helper to set file flag + void set_file_flag(uint32_t flag); + //Helper to clear file flag + void clear_file_flag(uint32_t flag); + //Helper to set or clear file flag + void set_file_flag(uint32_t flag, bool set_flag); + + uint32_t file_version_ms_, file_version_ls_, + product_version_ms_, product_version_ls_; + uint32_t file_flags_; + uint32_t file_os_; + uint32_t file_type_, file_subtype_; + uint32_t file_date_ms_, file_date_ls_; +}; +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/message_table.cpp b/irdb-lib/pebliss/trunk/pe_lib/message_table.cpp new file mode 100644 index 0000000000000000000000000000000000000000..940387dd281c1aa146fe52bdc0e74704972e81d5 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/message_table.cpp @@ -0,0 +1,60 @@ +#include "message_table.h" +#include "utils.h" + +namespace pe_bliss +{ +//Default constructor +message_table_item::message_table_item() + :unicode_(false) +{} + +//Constructor from ANSI string +message_table_item::message_table_item(const std::string& str) + :unicode_(false), ansi_str_(str) +{ + pe_utils::strip_nullbytes(ansi_str_); +} + +//Constructor from UNICODE string +message_table_item::message_table_item(const std::wstring& str) + :unicode_(true), unicode_str_(str) +{ + pe_utils::strip_nullbytes(unicode_str_); +} + +//Returns true if contained string is unicode +bool message_table_item::is_unicode() const +{ + return unicode_; +} + +//Returns ANSI string +const std::string& message_table_item::get_ansi_string() const +{ + return ansi_str_; +} + +//Returns UNICODE string +const std::wstring& message_table_item::get_unicode_string() const +{ + return unicode_str_; +} + +//Sets ANSI string (clears UNICODE one) +void message_table_item::set_string(const std::string& str) +{ + ansi_str_ = str; + pe_utils::strip_nullbytes(ansi_str_); + unicode_str_.clear(); + unicode_ = false; +} + +//Sets UNICODE string (clears ANSI one) +void message_table_item::set_string(const std::wstring& str) +{ + unicode_str_ = str; + pe_utils::strip_nullbytes(unicode_str_); + ansi_str_.clear(); + unicode_ = true; +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/message_table.h b/irdb-lib/pebliss/trunk/pe_lib/message_table.h new file mode 100644 index 0000000000000000000000000000000000000000..91f7d11daf2a0cae770b01cb191ebf1077de093d --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/message_table.h @@ -0,0 +1,42 @@ +#ifndef pebliss_message_table_h +#define pebliss_message_table_h +#pragma once +#ifndef pe_bliss_message_table_h +#define pe_bliss_message_table_h + +#include <string> +#include <map> +#include "stdint_defs.h" + +namespace pe_bliss +{ +//Structure representing message table string +class message_table_item +{ +public: + //Default constructor + message_table_item(); + //Constructors from ANSI and UNICODE strings + explicit message_table_item(const std::string& str); + explicit message_table_item(const std::wstring& str); + + //Returns true if string is UNICODE + bool is_unicode() const; + //Returns ANSI string + const std::string& get_ansi_string() const; + //Returns UNICODE string + const std::wstring& get_unicode_string() const; + +public: + //Sets ANSI or UNICODE string + void set_string(const std::string& str); + void set_string(const std::wstring& str); + +private: + bool unicode_; + std::string ansi_str_; + std::wstring unicode_str_; +}; +} +#endif +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_base.cpp b/irdb-lib/pebliss/trunk/pe_lib/pe_base.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e3ba9aaf34f874cb5c3a0d802385d2dc041dcc2a --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_base.cpp @@ -0,0 +1,1659 @@ +#include <string> +#include <vector> +#include <istream> +#include <ostream> +#include <algorithm> +#include <cmath> +#include <set> +#include <string.h> +#include "pe_exception.h" +#include "pe_base.h" + +namespace pe_bliss +{ +using namespace pe_win; + +//Constructor +pe_base::pe_base(std::istream& file, const pe_properties& props, bool read_debug_raw_data) +{ + props_ = props.duplicate().release(); + + //Save istream state + std::ios_base::iostate state = file.exceptions(); + std::streamoff old_offset = file.tellg(); + + try + { + file.exceptions(std::ios::goodbit); + //Read DOS header, PE headers and section data + read_dos_header(file); + read_pe(file, read_debug_raw_data); + } + catch(const std::exception&) + { + //If something went wrong, restore istream state + file.seekg(old_offset); + file.exceptions(state); + file.clear(); + //Rethrow + throw; + } + + //Restore istream state + file.seekg(old_offset); + file.exceptions(state); + file.clear(); +} + +pe_base::pe_base(const pe_properties& props, uint32_t section_alignment, bool dll, uint16_t subsystem) +{ + props_ = props.duplicate().release(); + props_->create_pe(section_alignment, subsystem); + + has_overlay_ = false; + memset(&dos_header_, 0, sizeof(dos_header_)); + + dos_header_.e_magic = 0x5A4D; //"MZ" + //Magic numbers from MSVC++ build + dos_header_.e_maxalloc = 0xFFFF; + dos_header_.e_cblp = 0x90; + dos_header_.e_cp = 3; + dos_header_.e_cparhdr = 4; + dos_header_.e_sp = 0xB8; + dos_header_.e_lfarlc = 64; + + set_characteristics(image_file_executable_image | image_file_relocs_stripped); + + if(get_pe_type() == pe_type_32) + set_characteristics_flags(image_file_32bit_machine); + + if(dll) + set_characteristics_flags(image_file_dll); + + set_subsystem_version(5, 1); //WinXP + set_os_version(5, 1); //WinXP +} + +pe_base::pe_base(const pe_base& pe) + :dos_header_(pe.dos_header_), + rich_overlay_(pe.rich_overlay_), + sections_(pe.sections_), + has_overlay_(pe.has_overlay_), + full_headers_data_(pe.full_headers_data_), + debug_data_(pe.debug_data_), + props_(0) +{ + props_ = pe.props_->duplicate().release(); +} + +pe_base& pe_base::operator=(const pe_base& pe) +{ + dos_header_ = pe.dos_header_; + rich_overlay_ = pe.rich_overlay_; + sections_ = pe.sections_; + has_overlay_ = pe.has_overlay_; + full_headers_data_ = pe.full_headers_data_; + debug_data_ = pe.debug_data_; + delete props_; + props_ = 0; + props_ = pe.props_->duplicate().release(); + + return *this; +} + +pe_base::~pe_base() +{ + delete props_; +} + +//Returns dos header +const image_dos_header& pe_base::get_dos_header() const +{ + return dos_header_; +} + +//Returns dos header +image_dos_header& pe_base::get_dos_header() +{ + return dos_header_; +} + +//Returns PE headers start position (e_lfanew) +int32_t pe_base::get_pe_header_start() const +{ + return dos_header_.e_lfanew; +} + +//Strips MSVC stub overlay +void pe_base::strip_stub_overlay() +{ + rich_overlay_.clear(); +} + +//Fills MSVC stub overlay with character c +void pe_base::fill_stub_overlay(char c) +{ + if(rich_overlay_.length()) + rich_overlay_.assign(rich_overlay_.length(), c); +} + +//Sets stub MSVS overlay +void pe_base::set_stub_overlay(const std::string& data) +{ + rich_overlay_ = data; +} + +//Returns stub overlay +const std::string& pe_base::get_stub_overlay() const +{ + return rich_overlay_; +} + +//Realigns all sections +void pe_base::realign_all_sections() +{ + for(unsigned int i = 0; i < sections_.size(); i++) + realign_section(i); +} + +//Returns number of sections from PE header +uint16_t pe_base::get_number_of_sections() const +{ + return props_->get_number_of_sections(); +} + +//Updates number of sections in PE header +uint16_t pe_base::update_number_of_sections() +{ + uint16_t new_number = static_cast<uint16_t>(sections_.size()); + props_->set_number_of_sections(new_number); + return new_number; +} + +//Returns section alignment +uint32_t pe_base::get_section_alignment() const +{ + return props_->get_section_alignment(); +} + +//Returns image sections list +section_list& pe_base::get_image_sections() +{ + return sections_; +} + +//Returns image sections list +const section_list& pe_base::get_image_sections() const +{ + return sections_; +} + +//Realigns section by index +void pe_base::realign_section(uint32_t index) +{ + //Check index + if(sections_.size() <= index) + throw pe_exception("Section not found", pe_exception::section_not_found); + + //Get section iterator + section_list::iterator it = sections_.begin() + index; + section& s = *it; + + //Calculate, how many null bytes we have in the end of raw section data + std::size_t strip = 0; + for(std::size_t i = (*it).get_raw_data().length(); i >= 1; --i) + { + if(s.get_raw_data()[i - 1] == 0) + strip++; + else + break; + } + + if(it == sections_.end() - 1) //If we're realigning the last section + { + //We can strip ending null bytes + s.set_size_of_raw_data(static_cast<uint32_t>(s.get_raw_data().length() - strip)); + s.get_raw_data().resize(s.get_raw_data().length() - strip, 0); + } + else + { + //Else just set size of raw data + uint32_t raw_size_aligned = s.get_aligned_raw_size(get_file_alignment()); + s.set_size_of_raw_data(raw_size_aligned); + s.get_raw_data().resize(raw_size_aligned, 0); + } +} + +//Returns file alignment +uint32_t pe_base::get_file_alignment() const +{ + return props_->get_file_alignment(); +} + +//Sets file alignment +void pe_base::set_file_alignment(uint32_t alignment) +{ + //Check alignment + if(alignment < minimum_file_alignment) + throw pe_exception("File alignment can't be less than 512", pe_exception::incorrect_file_alignment); + + if(!pe_utils::is_power_of_2(alignment)) + throw pe_exception("File alignment must be a power of 2", pe_exception::incorrect_file_alignment); + + if(alignment > get_section_alignment()) + throw pe_exception("File alignment must be <= section alignment", pe_exception::incorrect_file_alignment); + + //Set file alignment without any additional checks + set_file_alignment_unchecked(alignment); +} + +//Returns size of image +uint32_t pe_base::get_size_of_image() const +{ + return props_->get_size_of_image(); +} + +//Returns image entry point +uint32_t pe_base::get_ep() const +{ + return props_->get_ep(); +} + +//Sets image entry point (just a value of PE header) +void pe_base::set_ep(uint32_t new_ep) +{ + props_->set_ep(new_ep); +} + +//Returns number of RVA and sizes (number of DATA_DIRECTORY entries) +uint32_t pe_base::get_number_of_rvas_and_sizes() const +{ + return props_->get_number_of_rvas_and_sizes(); +} + +//Sets number of RVA and sizes (number of DATA_DIRECTORY entries) +void pe_base::set_number_of_rvas_and_sizes(uint32_t number) +{ + props_->set_number_of_rvas_and_sizes(number); +} + +//Returns PE characteristics +uint16_t pe_base::get_characteristics() const +{ + return props_->get_characteristics(); +} + +//Sets PE characteristics (a value inside header) +void pe_base::set_characteristics(uint16_t ch) +{ + props_->set_characteristics(ch); +} + +//Returns section from RVA +section& pe_base::section_from_rva(uint32_t rva) +{ + //Search for section + for(section_list::iterator i = sections_.begin(); i != sections_.end(); ++i) + { + section& s = *i; + //Return section if found + if(rva >= s.get_virtual_address() && rva < s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment())) + return s; + } + + throw pe_exception("No section found by presented address", pe_exception::no_section_found); +} + +//Returns section from RVA +const section& pe_base::section_from_rva(uint32_t rva) const +{ + //Search for section + for(section_list::const_iterator i = sections_.begin(); i != sections_.end(); ++i) + { + const section& s = *i; + //Return section if found + if(rva >= s.get_virtual_address() && rva < s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment())) + return s; + } + + throw pe_exception("No section found by presented address", pe_exception::no_section_found); +} + +//Returns section from directory ID +section& pe_base::section_from_directory(uint32_t directory_id) +{ + return section_from_rva(get_directory_rva(directory_id)); +} + +//Returns section from directory ID +const section& pe_base::section_from_directory(uint32_t directory_id) const +{ + return section_from_rva(get_directory_rva(directory_id)); +} + +//Sets section virtual size (actual for the last one of this PE or for unbound section) +void pe_base::set_section_virtual_size(section& s, uint32_t vsize) +{ + //Check if we're changing virtual size of the last section + //Of course, we can change virtual size of section that's not bound to this PE file + if(sections_.empty() || std::find_if(sections_.begin(), sections_.end() - 1, section_ptr_finder(s)) != sections_.end() - 1) + throw pe_exception("Can't change virtual size of any section, except last one", pe_exception::error_changing_section_virtual_size); + + //If we're setting virtual size to zero + if(vsize == 0) + { + //Check if section is empty + if(s.empty()) + throw pe_exception("Cannot set virtual size of empty section to zero", pe_exception::error_changing_section_virtual_size); + + //Set virtual size equal to aligned size of raw data + s.set_virtual_size(s.get_size_of_raw_data()); + } + else + { + s.set_virtual_size(vsize); + } + + //Update image size if we're changing virtual size for the last section of this PE + if(!sections_.empty() || &s == &(*(sections_.end() - 1))) + update_image_size(); +} + +//Expands section raw or virtual size to hold data from specified RVA with specified size +//Section must be free (not bound to any image) +//or the last section of this image +bool pe_base::expand_section(section& s, uint32_t needed_rva, uint32_t needed_size, section_expand_type expand) +{ + //Check if we're changing the last section + //Of course, we can change the section that's not bound to this PE file + if(sections_.empty() || std::find_if(sections_.begin(), sections_.end() - 1, section_ptr_finder(s)) != sections_.end() - 1) + throw pe_exception("Can't expand any section, except last one", pe_exception::error_expanding_section); + + //Check if we should expand our section + if(expand == expand_section_raw && section_data_length_from_rva(s, needed_rva, section_data_raw) < needed_size) + { + //Expand section raw data + s.get_raw_data().resize(needed_rva - s.get_virtual_address() + needed_size); + recalculate_section_sizes(s, false); + return true; + } + else if(expand == expand_section_virtual && section_data_length_from_rva(s, needed_rva, section_data_virtual) < needed_size) + { + //Expand section virtual data + set_section_virtual_size(s, needed_rva - s.get_virtual_address() + needed_size); + return true; + } + + return false; +} + +//Updates image virtual size +void pe_base::update_image_size() +{ + //Write virtual size of image to headers + if(!sections_.empty()) + set_size_of_image(sections_.back().get_virtual_address() + sections_.back().get_aligned_virtual_size(get_section_alignment())); + else + set_size_of_image(get_size_of_headers()); +} + +//Returns checksum of PE file from header +uint32_t pe_base::get_checksum() const +{ + return props_->get_checksum(); +} + +//Sets checksum of PE file +void pe_base::set_checksum(uint32_t checksum) +{ + props_->set_checksum(checksum); +} + +//Returns timestamp of PE file from header +uint32_t pe_base::get_time_date_stamp() const +{ + return props_->get_time_date_stamp(); +} + +//Sets timestamp of PE file +void pe_base::set_time_date_stamp(uint32_t timestamp) +{ + props_->set_time_date_stamp(timestamp); +} + +//Returns Machine field value of PE file from header +uint16_t pe_base::get_machine() const +{ + return props_->get_machine(); +} + +//Sets Machine field value of PE file +void pe_base::set_machine(uint16_t machine) +{ + props_->set_machine(machine); +} + +//Prepares section before attaching it +void pe_base::prepare_section(section& s) +{ + //Calculate its size of raw data + s.set_size_of_raw_data(static_cast<uint32_t>(pe_utils::align_up(s.get_raw_data().length(), get_file_alignment()))); + + //Check section virtual and raw size + if(!s.get_size_of_raw_data() && !s.get_virtual_size()) + throw pe_exception("Virtual and Physical sizes of section can't be 0 at the same time", pe_exception::zero_section_sizes); + + //If section virtual size is zero + if(!s.get_virtual_size()) + { + s.set_virtual_size(s.get_size_of_raw_data()); + } + else + { + //Else calculate its virtual size + s.set_virtual_size( + std::max<uint32_t>(pe_utils::align_up(s.get_size_of_raw_data(), get_file_alignment()), + pe_utils::align_up(s.get_virtual_size(), get_section_alignment()))); + } +} + +//Adds section to image +section& pe_base::add_section(section s) +{ + if(sections_.size() >= maximum_number_of_sections) + throw pe_exception("Maximum number of sections has been reached", pe_exception::no_more_sections_can_be_added); + + //Prepare section before adding it + prepare_section(s); + + //Calculate section virtual address + if(!sections_.empty()) + { + s.set_virtual_address(pe_utils::align_up(sections_.back().get_virtual_address() + sections_.back().get_aligned_virtual_size(get_section_alignment()), get_section_alignment())); + + //We should align last section raw size, if it wasn't aligned + section& last = sections_.back(); + last.set_size_of_raw_data(static_cast<uint32_t>(pe_utils::align_up(last.get_raw_data().length(), get_file_alignment()))); + } + else + { + s.set_virtual_address( + s.get_virtual_address() == 0 + ? pe_utils::align_up(get_size_of_headers(), get_section_alignment()) + : pe_utils::align_up(s.get_virtual_address(), get_section_alignment())); + } + + //Add section to the end of section list + sections_.push_back(s); + //Set number of sections in PE header + set_number_of_sections(static_cast<uint16_t>(sections_.size())); + //Recalculate virtual size of image + set_size_of_image(get_size_of_image() + s.get_aligned_virtual_size(get_section_alignment())); + //rETurn last section + return sections_.back(); +} + +//Returns true if sectios "s" is already attached to this PE file +bool pe_base::section_attached(const section& s) const +{ + return sections_.end() != std::find_if(sections_.begin(), sections_.end(), section_ptr_finder(s)); +} + +//Returns true if directory exists +bool pe_base::directory_exists(uint32_t id) const +{ + return props_->directory_exists(id); +} + +//Removes directory +void pe_base::remove_directory(uint32_t id) +{ + props_->remove_directory(id); +} + +//Returns directory RVA +uint32_t pe_base::get_directory_rva(uint32_t id) const +{ + return props_->get_directory_rva(id); +} + +//Returns directory size +uint32_t pe_base::get_directory_size(uint32_t id) const +{ + return props_->get_directory_size(id); +} + +//Sets directory RVA (just a value of PE header, no moving occurs) +void pe_base::set_directory_rva(uint32_t id, uint32_t rva) +{ + return props_->set_directory_rva(id, rva); +} + +//Sets directory size (just a value of PE header, no moving occurs) +void pe_base::set_directory_size(uint32_t id, uint32_t size) +{ + return props_->set_directory_size(id, size); +} + +//Strips only zero DATA_DIRECTORY entries to count = min_count +//Returns resulting number of data directories +//strip_iat_directory - if true, even not empty IAT directory will be stripped +uint32_t pe_base::strip_data_directories(uint32_t min_count, bool strip_iat_directory) +{ + return props_->strip_data_directories(min_count, strip_iat_directory); +} + +//Returns true if image has import directory +bool pe_base::has_imports() const +{ + return directory_exists(image_directory_entry_import); +} + +//Returns true if image has export directory +bool pe_base::has_exports() const +{ + return directory_exists(image_directory_entry_export); +} + +//Returns true if image has resource directory +bool pe_base::has_resources() const +{ + return directory_exists(image_directory_entry_resource); +} + +//Returns true if image has security directory +bool pe_base::has_security() const +{ + return directory_exists(image_directory_entry_security); +} + +//Returns true if image has relocations +bool pe_base::has_reloc() const +{ + return directory_exists(image_directory_entry_basereloc) && !(get_characteristics() & image_file_relocs_stripped); +} + +//Returns true if image has TLS directory +bool pe_base::has_tls() const +{ + return directory_exists(image_directory_entry_tls); +} + +//Returns true if image has config directory +bool pe_base::has_config() const +{ + return directory_exists(image_directory_entry_load_config); +} + +//Returns true if image has bound import directory +bool pe_base::has_bound_import() const +{ + return directory_exists(image_directory_entry_bound_import); +} + +//Returns true if image has delay import directory +bool pe_base::has_delay_import() const +{ + return directory_exists(image_directory_entry_delay_import); +} + +//Returns true if image has COM directory +bool pe_base::is_dotnet() const +{ + return directory_exists(image_directory_entry_com_descriptor); +} + +//Returns true if image has exception directory +bool pe_base::has_exception_directory() const +{ + return directory_exists(image_directory_entry_exception); +} + +//Returns true if image has debug directory +bool pe_base::has_debug() const +{ + return directory_exists(image_directory_entry_debug); +} + +//Returns corresponding section data pointer from RVA inside section "s" (checks bounds) +char* pe_base::section_data_from_rva(section& s, uint32_t rva) +{ + //Check if RVA is inside section "s" + if(rva >= s.get_virtual_address() && rva < s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment())) + { + if(s.get_raw_data().empty()) + throw pe_exception("Section raw data is empty and cannot be changed", pe_exception::section_is_empty); + + return &s.get_raw_data()[rva - s.get_virtual_address()]; + } + + throw pe_exception("RVA not found inside section", pe_exception::rva_not_exists); +} + +//Returns corresponding section data pointer from RVA inside section "s" (checks bounds) +const char* pe_base::section_data_from_rva(const section& s, uint32_t rva, section_data_type datatype) const +{ + //Check if RVA is inside section "s" + if(rva >= s.get_virtual_address() && rva < s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment())) + return (datatype == section_data_raw ? s.get_raw_data().data() : s.get_virtual_data(get_section_alignment()).c_str()) + rva - s.get_virtual_address(); + + throw pe_exception("RVA not found inside section", pe_exception::rva_not_exists); +} + +//Returns section TOTAL RAW/VIRTUAL data length from RVA inside section +uint32_t pe_base::section_data_length_from_rva(uint32_t rva, section_data_type datatype, bool include_headers) const +{ + //if RVA is inside of headers and we're searching them too... + if(include_headers && rva < full_headers_data_.length()) + return static_cast<unsigned long>(full_headers_data_.length()); + + const section& s = section_from_rva(rva); + return static_cast<unsigned long>(datatype == section_data_raw ? s.get_raw_data().length() /* instead of SizeOfRawData */ : s.get_aligned_virtual_size(get_section_alignment())); +} + +//Returns section TOTAL RAW/VIRTUAL data length from VA inside section for PE32 +uint32_t pe_base::section_data_length_from_va(uint32_t va, section_data_type datatype, bool include_headers) const +{ + return section_data_length_from_rva(va_to_rva(va), datatype, include_headers); +} + +//Returns section TOTAL RAW/VIRTUAL data length from VA inside section for PE32/PE64 +uint32_t pe_base::section_data_length_from_va(uint64_t va, section_data_type datatype, bool include_headers) const +{ + return section_data_length_from_rva(va_to_rva(va), datatype, include_headers); +} + +//Returns section remaining RAW/VIRTUAL data length from RVA "rva_inside" to the end of section containing RVA "rva" +uint32_t pe_base::section_data_length_from_rva(uint32_t rva, uint32_t rva_inside, section_data_type datatype, bool include_headers) const +{ + //if RVAs are inside of headers and we're searching them too... + if(include_headers && rva < full_headers_data_.length() && rva_inside < full_headers_data_.length()) + return static_cast<unsigned long>(full_headers_data_.length() - rva_inside); + + const section& s = section_from_rva(rva); + if(rva_inside < s.get_virtual_address()) + throw pe_exception("RVA not found inside section", pe_exception::rva_not_exists); + + //Calculate remaining length of section data from "rva" address + long length = static_cast<long>(datatype == section_data_raw ? s.get_raw_data().length() /* instead of SizeOfRawData */ : s.get_aligned_virtual_size(get_section_alignment())) + + s.get_virtual_address() - rva_inside; + + if(length < 0) + return 0; + + return static_cast<unsigned long>(length); +} + +//Returns section remaining RAW/VIRTUAL data length from VA "va_inside" to the end of section containing VA "va" for PE32 +uint32_t pe_base::section_data_length_from_va(uint32_t va, uint32_t va_inside, section_data_type datatype, bool include_headers) const +{ + return section_data_length_from_rva(va_to_rva(va), va_to_rva(va_inside), datatype, include_headers); +} + +//Returns section remaining RAW/VIRTUAL data length from VA "va_inside" to the end of section containing VA "va" for PE32/PE64 +uint32_t pe_base::section_data_length_from_va(uint64_t va, uint64_t va_inside, section_data_type datatype, bool include_headers) const +{ + return section_data_length_from_rva(va_to_rva(va), va_to_rva(va_inside), datatype, include_headers); +} + +//Returns section remaining RAW/VIRTUAL data length from RVA to the end of section "s" (checks bounds) +uint32_t pe_base::section_data_length_from_rva(const section& s, uint32_t rva_inside, section_data_type datatype) const +{ + //Check rva_inside + if(rva_inside >= s.get_virtual_address() && rva_inside < s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment())) + { + //Calculate remaining length of section data from "rva" address + int32_t length = static_cast<int32_t>(datatype == section_data_raw ? s.get_raw_data().length() /* instead of SizeOfRawData */ : s.get_aligned_virtual_size(get_section_alignment())) + + s.get_virtual_address() - rva_inside; + + if(length < 0) + return 0; + + return static_cast<uint32_t>(length); + } + + throw pe_exception("RVA not found inside section", pe_exception::rva_not_exists); +} + +//Returns section remaining RAW/VIRTUAL data length from VA to the end of section "s" for PE32 (checks bounds) +uint32_t pe_base::section_data_length_from_va(const section& s, uint32_t va_inside, section_data_type datatype) const +{ + return section_data_length_from_rva(s, va_to_rva(va_inside), datatype); +} + +//Returns section remaining RAW/VIRTUAL data length from VA to the end of section "s" for PE32/PE64 (checks bounds) +uint32_t pe_base::section_data_length_from_va(const section& s, uint64_t va_inside, section_data_type datatype) const +{ + return section_data_length_from_rva(s, va_to_rva(va_inside), datatype); +} + +//Returns corresponding section data pointer from RVA inside section +char* pe_base::section_data_from_rva(uint32_t rva, bool include_headers) +{ + //if RVA is inside of headers and we're searching them too... + if(include_headers && rva < full_headers_data_.length()) + return &full_headers_data_[rva]; + + section& s = section_from_rva(rva); + + if(s.get_raw_data().empty()) + throw pe_exception("Section raw data is empty and cannot be changed", pe_exception::section_is_empty); + + return &s.get_raw_data()[rva - s.get_virtual_address()]; +} + +//Returns corresponding section data pointer from RVA inside section +const char* pe_base::section_data_from_rva(uint32_t rva, section_data_type datatype, bool include_headers) const +{ + //if RVA is inside of headers and we're searching them too... + if(include_headers && rva < full_headers_data_.length()) + return &full_headers_data_[rva]; + + const section& s = section_from_rva(rva); + return (datatype == section_data_raw ? s.get_raw_data().data() : s.get_virtual_data(get_section_alignment()).c_str()) + rva - s.get_virtual_address(); +} + +//Reads DOS headers from istream +void pe_base::read_dos_header(std::istream& file, image_dos_header& header) +{ + //Check istream flags + if(file.bad() || file.eof()) + throw pe_exception("PE file stream is bad or closed.", pe_exception::bad_pe_file); + + //Read DOS header and check istream + file.read(reinterpret_cast<char*>(&header), sizeof(image_dos_header)); + if(file.bad() || file.eof()) + throw pe_exception("Unable to read IMAGE_DOS_HEADER", pe_exception::bad_dos_header); + + //Check DOS header magic + if(header.e_magic != 0x5a4d) //"MZ" + throw pe_exception("IMAGE_DOS_HEADER signature is incorrect", pe_exception::bad_dos_header); +} + +//Reads DOS headers from istream +void pe_base::read_dos_header(std::istream& file) +{ + read_dos_header(file, dos_header_); +} + +//Reads PE image from istream +void pe_base::read_pe(std::istream& file, bool read_debug_raw_data) +{ + //Get istream size + std::streamoff filesize = pe_utils::get_file_size(file); + + //Check if PE header is DWORD-aligned + if((dos_header_.e_lfanew % sizeof(uint32_t)) != 0) + throw pe_exception("PE header is not DWORD-aligned", pe_exception::bad_dos_header); + + //Seek to NT headers + file.seekg(dos_header_.e_lfanew); + if(file.bad() || file.fail()) + throw pe_exception("Cannot reach IMAGE_NT_HEADERS", pe_exception::image_nt_headers_not_found); + + //Read NT headers + file.read(get_nt_headers_ptr(), get_sizeof_nt_header() - sizeof(image_data_directory) * image_numberof_directory_entries); + if(file.bad() || file.eof()) + throw pe_exception("Error reading IMAGE_NT_HEADERS", pe_exception::error_reading_image_nt_headers); + + //Check PE signature + if(get_pe_signature() != 0x4550) //"PE" + throw pe_exception("Incorrect PE signature", pe_exception::pe_signature_incorrect); + + //Check number of directories + if(get_number_of_rvas_and_sizes() > image_numberof_directory_entries) + set_number_of_rvas_and_sizes(image_numberof_directory_entries); + + if(get_number_of_rvas_and_sizes() > 0) + { + //Read data directory headers, if any + file.read(get_nt_headers_ptr() + (get_sizeof_nt_header() - sizeof(image_data_directory) * image_numberof_directory_entries), sizeof(image_data_directory) * get_number_of_rvas_and_sizes()); + if(file.bad() || file.eof()) + throw pe_exception("Error reading DATA_DIRECTORY headers", pe_exception::error_reading_data_directories); + } + + //Check section number + //Images with zero section number accepted + if(get_number_of_sections() > maximum_number_of_sections) + throw pe_exception("Incorrect number of sections", pe_exception::section_number_incorrect); + + //Check PE magic + if(get_magic() != get_needed_magic()) + throw pe_exception("Incorrect PE signature", pe_exception::pe_signature_incorrect); + + //Check section alignment + if(!pe_utils::is_power_of_2(get_section_alignment())) + throw pe_exception("Incorrect section alignment", pe_exception::incorrect_section_alignment); + + //Check file alignment + if(!pe_utils::is_power_of_2(get_file_alignment())) + throw pe_exception("Incorrect file alignment", pe_exception::incorrect_file_alignment); + + if(get_file_alignment() != get_section_alignment() && (get_file_alignment() < minimum_file_alignment || get_file_alignment() > get_section_alignment())) + throw pe_exception("Incorrect file alignment", pe_exception::incorrect_file_alignment); + + //Check size of image + if(pe_utils::align_up(get_size_of_image(), get_section_alignment()) == 0) + throw pe_exception("Incorrect size of image", pe_exception::incorrect_size_of_image); + + //Read rich data overlay / DOS stub (if any) + if(static_cast<uint32_t>(dos_header_.e_lfanew) > sizeof(image_dos_header)) + { + rich_overlay_.resize(dos_header_.e_lfanew - sizeof(image_dos_header)); + file.seekg(sizeof(image_dos_header)); + file.read(&rich_overlay_[0], dos_header_.e_lfanew - sizeof(image_dos_header)); + if(file.bad() || file.eof()) + throw pe_exception("Error reading 'Rich' & 'DOS stub' overlay", pe_exception::error_reading_overlay); + } + + //Calculate first section raw position + //Sum is safe here + uint32_t first_section = dos_header_.e_lfanew + get_size_of_optional_header() + sizeof(image_file_header) + sizeof(uint32_t) /* Signature */; + + if(get_number_of_sections() > 0) + { + //Go to first section + file.seekg(first_section); + if(file.bad() || file.fail()) + throw pe_exception("Cannot reach section headers", pe_exception::image_section_headers_not_found); + } + + uint32_t last_raw_size = 0; + + //Read all sections + for(int i = 0; i < get_number_of_sections(); i++) + { + section s; + //Read section header + file.read(reinterpret_cast<char*>(&s.get_raw_header()), sizeof(image_section_header)); + if(file.bad() || file.eof()) + throw pe_exception("Error reading section header", pe_exception::error_reading_section_header); + + //Save next section header position + std::streamoff next_sect = file.tellg(); + + //Check section virtual and raw sizes + if(!s.get_size_of_raw_data() && !s.get_virtual_size()) + throw pe_exception("Virtual and Physical sizes of section can't be 0 at the same time", pe_exception::zero_section_sizes); + + //Check for adequate values of section fields + if(!pe_utils::is_sum_safe(s.get_virtual_address(), s.get_virtual_size()) || s.get_virtual_size() > pe_utils::two_gb + || !pe_utils::is_sum_safe(s.get_pointer_to_raw_data(), s.get_size_of_raw_data()) || s.get_size_of_raw_data() > pe_utils::two_gb) + throw pe_exception("Incorrect section address or size", pe_exception::section_incorrect_addr_or_size); + + if(s.get_size_of_raw_data() != 0) + { + //If section has raw data + + //If section raw data size is greater than virtual, fix it + last_raw_size = s.get_size_of_raw_data(); + if(pe_utils::align_up(s.get_size_of_raw_data(), get_file_alignment()) > pe_utils::align_up(s.get_virtual_size(), get_section_alignment())) + s.set_size_of_raw_data(s.get_virtual_size()); + + //Check virtual and raw section sizes and addresses + if(s.get_virtual_address() + pe_utils::align_up(s.get_virtual_size(), get_section_alignment()) > pe_utils::align_up(get_size_of_image(), get_section_alignment()) + || + pe_utils::align_down(s.get_pointer_to_raw_data(), get_file_alignment()) + s.get_size_of_raw_data() > static_cast<uint32_t>(filesize)) + throw pe_exception("Incorrect section address or size", pe_exception::section_incorrect_addr_or_size); + + //Seek to section raw data + file.seekg(pe_utils::align_down(s.get_pointer_to_raw_data(), get_file_alignment())); + if(file.bad() || file.fail()) + throw pe_exception("Cannot reach section data", pe_exception::image_section_data_not_found); + + //Read section raw data + s.get_raw_data().resize(s.get_size_of_raw_data()); + file.read(&s.get_raw_data()[0], s.get_size_of_raw_data()); + if(file.bad() || file.fail()) + throw pe_exception("Error reading section data", pe_exception::image_section_data_not_found); + } + + //Check virtual address and size of section + if(s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment()) > pe_utils::align_up(get_size_of_image(), get_section_alignment())) + throw pe_exception("Incorrect section address or size", pe_exception::section_incorrect_addr_or_size); + + //Save section + sections_.push_back(s); + + //Seek to the next section header + file.seekg(next_sect); + } + + //Check size of headers: SizeOfHeaders can't be larger than first section VA + if(!sections_.empty() && get_size_of_headers() > sections_.front().get_virtual_address()) + throw pe_exception("Incorrect size of headers", pe_exception::incorrect_size_of_headers); + + //If image has more than two sections + if(sections_.size() >= 2) + { + //Check sections virtual sizes + for(section_list::const_iterator i = sections_.begin() + 1; i != sections_.end(); ++i) + { + if((*i).get_virtual_address() != (*(i - 1)).get_virtual_address() + (*(i - 1)).get_aligned_virtual_size(get_section_alignment())) + throw pe_exception("Section table is incorrect", pe_exception::image_section_table_incorrect); + } + } + + //Check if image has overlay in the end of file + has_overlay_ = !sections_.empty() && filesize > static_cast<std::streamoff>(sections_.back().get_pointer_to_raw_data() + last_raw_size); + + { + //Additionally, read data from the beginning of istream to size of headers + file.seekg(0); + uint32_t size_of_headers = std::min<uint32_t>(get_size_of_headers(), static_cast<uint32_t>(filesize)); + + if(!sections_.empty()) + { + for(section_list::const_iterator i = sections_.begin(); i != sections_.end(); ++i) + { + if(!(*i).empty()) + { + size_of_headers = std::min<uint32_t>(get_size_of_headers(), (*i).get_pointer_to_raw_data()); + break; + } + } + } + + full_headers_data_.resize(size_of_headers); + file.read(&full_headers_data_[0], size_of_headers); + if(file.bad() || file.eof()) + throw pe_exception("Error reading file", pe_exception::error_reading_file); + } + + //Moreover, if there's debug directory, read its raw data for some debug info types + while(read_debug_raw_data && has_debug()) + { + try + { + //Check the length in bytes of the section containing debug directory + if(section_data_length_from_rva(get_directory_rva(image_directory_entry_debug), get_directory_rva(image_directory_entry_debug), section_data_virtual, true) < sizeof(image_debug_directory)) + break; + + unsigned long current_pos = get_directory_rva(image_directory_entry_debug); + + //First IMAGE_DEBUG_DIRECTORY table + image_debug_directory directory = section_data_from_rva<image_debug_directory>(current_pos, section_data_virtual, true); + + //Iterate over all IMAGE_DEBUG_DIRECTORY directories + while(directory.PointerToRawData + && current_pos < get_directory_rva(image_directory_entry_debug) + get_directory_size(image_directory_entry_debug)) + { + //If we have something to read + if((directory.Type == image_debug_type_codeview + || directory.Type == image_debug_type_misc + || directory.Type == image_debug_type_coff) + && directory.SizeOfData) + { + std::string data; + data.resize(directory.SizeOfData); + file.seekg(directory.PointerToRawData); + file.read(&data[0], directory.SizeOfData); + if(file.bad() || file.eof()) + throw pe_exception("Error reading file", pe_exception::error_reading_file); + + debug_data_.insert(std::make_pair(directory.PointerToRawData, data)); + } + + //Go to next debug entry + current_pos += sizeof(image_debug_directory); + directory = section_data_from_rva<image_debug_directory>(current_pos, section_data_virtual, true); + } + + break; + } + catch(const pe_exception&) + { + //Don't throw any exception here, if debug info is corrupted or incorrect + break; + } + catch(const std::bad_alloc&) + { + //Don't throw any exception here, if debug info is corrupted or incorrect + break; + } + } +} + +//Returns PE type of this image +pe_type pe_base::get_pe_type() const +{ + return props_->get_pe_type(); +} + +//Returns PE type (PE or PE+) from pe_type enumeration (minimal correctness checks) +pe_type pe_base::get_pe_type(std::istream& file) +{ + //Save state of the istream + std::ios_base::iostate state = file.exceptions(); + std::streamoff old_offset = file.tellg(); + image_nt_headers32 nt_headers; + image_dos_header header; + + try + { + //Read dos header + file.exceptions(std::ios::goodbit); + read_dos_header(file, header); + + //Seek to the NT headers start + file.seekg(header.e_lfanew); + if(file.bad() || file.fail()) + throw pe_exception("Cannot reach IMAGE_NT_HEADERS", pe_exception::image_nt_headers_not_found); + + //Read NT headers (we're using 32-bit version, because there's no significant differencies between 32 and 64 bit version structures) + file.read(reinterpret_cast<char*>(&nt_headers), sizeof(image_nt_headers32) - sizeof(image_data_directory) * image_numberof_directory_entries); + if(file.bad() || file.eof()) + throw pe_exception("Error reading IMAGE_NT_HEADERS", pe_exception::error_reading_image_nt_headers); + + //Check NT headers signature + if(nt_headers.Signature != 0x4550) //"PE" + throw pe_exception("Incorrect PE signature", pe_exception::pe_signature_incorrect); + + //Check NT headers magic + if(nt_headers.OptionalHeader.Magic != image_nt_optional_hdr32_magic && nt_headers.OptionalHeader.Magic != image_nt_optional_hdr64_magic) + throw pe_exception("Incorrect PE signature", pe_exception::pe_signature_incorrect); + } + catch(const std::exception&) + { + //If something went wrong, restore istream state + file.exceptions(state); + file.seekg(old_offset); + file.clear(); + //Retrhow exception + throw; + } + + //Restore stream state + file.exceptions(state); + file.seekg(old_offset); + file.clear(); + + //Determine PE type and return it + return nt_headers.OptionalHeader.Magic == image_nt_optional_hdr64_magic ? pe_type_64 : pe_type_32; +} + +//Returns true if image has overlay data at the end of file +bool pe_base::has_overlay() const +{ + return has_overlay_; +} + +//Clears PE characteristics flag +void pe_base::clear_characteristics_flags(uint16_t flags) +{ + set_characteristics(get_characteristics() & ~flags); +} + +//Sets PE characteristics flag +void pe_base::set_characteristics_flags(uint16_t flags) +{ + set_characteristics(get_characteristics() | flags); +} + +//Returns true if PE characteristics flag set +bool pe_base::check_characteristics_flag(uint16_t flag) const +{ + return (get_characteristics() & flag) ? true : false; +} + +//Returns subsystem value +uint16_t pe_base::get_subsystem() const +{ + return props_->get_subsystem(); +} + +//Sets subsystem value +void pe_base::set_subsystem(uint16_t subsystem) +{ + props_->set_subsystem(subsystem); +} + +//Returns true if image has console subsystem +bool pe_base::is_console() const +{ + return get_subsystem() == image_subsystem_windows_cui; +} + +//Returns true if image has Windows GUI subsystem +bool pe_base::is_gui() const +{ + return get_subsystem() == image_subsystem_windows_gui; +} + +//Sets required operation system version +void pe_base::set_os_version(uint16_t major, uint16_t minor) +{ + props_->set_os_version(major, minor); +} + +//Returns required operation system version (minor word) +uint16_t pe_base::get_minor_os_version() const +{ + return props_->get_minor_os_version(); +} + +//Returns required operation system version (major word) +uint16_t pe_base::get_major_os_version() const +{ + return props_->get_major_os_version(); +} + +//Sets required subsystem version +void pe_base::set_subsystem_version(uint16_t major, uint16_t minor) +{ + props_->set_subsystem_version(major, minor); +} + +//Returns required subsystem version (minor word) +uint16_t pe_base::get_minor_subsystem_version() const +{ + return props_->get_minor_subsystem_version(); +} + +//Returns required subsystem version (major word) +uint16_t pe_base::get_major_subsystem_version() const +{ + return props_->get_major_subsystem_version(); +} + +//Returns corresponding section data pointer from VA inside section "s" for PE32 (checks bounds) +char* pe_base::section_data_from_va(section& s, uint32_t va) //Always returns raw data +{ + return section_data_from_rva(s, va_to_rva(va)); +} + +//Returns corresponding section data pointer from VA inside section "s" for PE32 (checks bounds) +const char* pe_base::section_data_from_va(const section& s, uint32_t va, section_data_type datatype) const +{ + return section_data_from_rva(s, va_to_rva(va), datatype); +} + +//Returns corresponding section data pointer from VA inside section for PE32 +char* pe_base::section_data_from_va(uint32_t va, bool include_headers) //Always returns raw data +{ + return section_data_from_rva(va_to_rva(va), include_headers); +} + +//Returns corresponding section data pointer from VA inside section for PE32 +const char* pe_base::section_data_from_va(uint32_t va, section_data_type datatype, bool include_headers) const +{ + return section_data_from_rva(va_to_rva(va), datatype, include_headers); +} + +//Returns corresponding section data pointer from VA inside section "s" for PE32/PE64 (checks bounds) +char* pe_base::section_data_from_va(section& s, uint64_t va) //Always returns raw data +{ + return section_data_from_rva(s, va_to_rva(va)); +} + +//Returns corresponding section data pointer from VA inside section "s" for PE32/PE64 (checks bounds) +const char* pe_base::section_data_from_va(const section& s, uint64_t va, section_data_type datatype) const +{ + return section_data_from_rva(s, va_to_rva(va), datatype); +} + +//Returns corresponding section data pointer from VA inside section for PE32/PE64 +char* pe_base::section_data_from_va(uint64_t va, bool include_headers) //Always returns raw data +{ + return section_data_from_rva(va_to_rva(va), include_headers); +} + +//Returns corresponding section data pointer from VA inside section for PE32/PE64 +const char* pe_base::section_data_from_va(uint64_t va, section_data_type datatype, bool include_headers) const +{ + return section_data_from_rva(va_to_rva(va), datatype, include_headers); +} + +//Returns section from VA inside it for PE32 +section& pe_base::section_from_va(uint32_t va) +{ + return section_from_rva(va_to_rva(va)); +} + +//Returns section from VA inside it for PE32/PE64 +section& pe_base::section_from_va(uint64_t va) +{ + return section_from_rva(va_to_rva(va)); +} + +//Returns section from RVA inside it for PE32 +const section& pe_base::section_from_va(uint32_t va) const +{ + return section_from_rva(va_to_rva(va)); +} + +//Returns section from RVA inside it for PE32/PE64 +const section& pe_base::section_from_va(uint64_t va) const +{ + return section_from_rva(va_to_rva(va)); +} + +uint32_t pe_base::va_to_rva(uint32_t va, bool bound_check) const +{ + return props_->va_to_rva(va, bound_check); +} + +uint32_t pe_base::va_to_rva(uint64_t va, bool bound_check) const +{ + return props_->va_to_rva(va, bound_check); +} + +uint32_t pe_base::rva_to_va_32(uint32_t rva) const +{ + return props_->rva_to_va_32(rva); +} + +uint64_t pe_base::rva_to_va_64(uint32_t rva) const +{ + return props_->rva_to_va_64(rva); +} + +//Relative Virtual Address (RVA) to Virtual Address (VA) convertion for PE32 +void pe_base::rva_to_va(uint32_t rva, uint32_t& va) const +{ + va = rva_to_va_32(rva); +} + +//Relative Virtual Address (RVA) to Virtual Address (VA) convertions for PE32/PE64 +void pe_base::rva_to_va(uint32_t rva, uint64_t& va) const +{ + va = rva_to_va_64(rva); +} + +//Returns section from file offset (4gb max) +section& pe_base::section_from_file_offset(uint32_t offset) +{ + return *file_offset_to_section(offset); +} + +//Returns section from file offset (4gb max) +const section& pe_base::section_from_file_offset(uint32_t offset) const +{ + return *file_offset_to_section(offset); +} + +//Returns section and offset (raw data only) from its start from RVA +const std::pair<uint32_t, const section*> pe_base::section_and_offset_from_rva(uint32_t rva) const +{ + const section& s = section_from_rva(rva); + return std::make_pair(rva - s.get_virtual_address(), &s); +} + +//Returns DLL Characteristics +uint16_t pe_base::get_dll_characteristics() const +{ + return props_->get_dll_characteristics(); +} + +//Sets DLL Characteristics +void pe_base::set_dll_characteristics(uint16_t characteristics) +{ + props_->set_dll_characteristics(characteristics); +} + +//Returns size of headers +uint32_t pe_base::get_size_of_headers() const +{ + return props_->get_size_of_headers(); +} + +//Returns size of optional header +uint16_t pe_base::get_size_of_optional_header() const +{ + return props_->get_size_of_optional_header(); +} + +//Returns PE signature +uint32_t pe_base::get_pe_signature() const +{ + return props_->get_pe_signature(); +} + +//Returns magic value +uint32_t pe_base::get_magic() const +{ + return props_->get_magic(); +} + +//Returns image base for PE32 +void pe_base::get_image_base(uint32_t& base) const +{ + base = get_image_base_32(); +} + +//Returns image base for PE32 and PE64 respectively +uint32_t pe_base::get_image_base_32() const +{ + return props_->get_image_base_32(); +} + +//Sets image base for PE32 and PE64 respectively +uint64_t pe_base::get_image_base_64() const +{ + return props_->get_image_base_64(); +} + +//RVA to RAW file offset convertion (4gb max) +uint32_t pe_base::rva_to_file_offset(uint32_t rva) const +{ + //Maybe, RVA is inside PE headers + if(rva < get_size_of_headers()) + return rva; + + const section& s = section_from_rva(rva); + return s.get_pointer_to_raw_data() + rva - s.get_virtual_address(); +} + +//RAW file offset to RVA convertion (4gb max) +uint32_t pe_base::file_offset_to_rva(uint32_t offset) const +{ + //Maybe, offset is inside PE headers + if(offset < get_size_of_headers()) + return offset; + + const section_list::const_iterator it = file_offset_to_section(offset); + return offset - (*it).get_pointer_to_raw_data() + (*it).get_virtual_address(); +} + +//RAW file offset to section convertion helper (4gb max) +section_list::const_iterator pe_base::file_offset_to_section(uint32_t offset) const +{ + section_list::const_iterator it = std::find_if(sections_.begin(), sections_.end(), section_by_raw_offset(offset)); + if(it == sections_.end()) + throw pe_exception("No section found by presented file offset", pe_exception::no_section_found); + + return it; +} + +//RAW file offset to section convertion helper (4gb max) +section_list::iterator pe_base::file_offset_to_section(uint32_t offset) +{ + section_list::iterator it = std::find_if(sections_.begin(), sections_.end(), section_by_raw_offset(offset)); + if(it == sections_.end()) + throw pe_exception("No section found by presented file offset", pe_exception::no_section_found); + + return it; +} + +//RVA from section raw data offset +uint32_t pe_base::rva_from_section_offset(const section& s, uint32_t raw_offset_from_section_start) +{ + return s.get_virtual_address() + raw_offset_from_section_start; +} + +//Returns image base for PE32/PE64 +void pe_base::get_image_base(uint64_t& base) const +{ + base = get_image_base_64(); +} + +//Sets new image base +void pe_base::set_image_base(uint32_t base) +{ + props_->set_image_base(base); +} + +void pe_base::set_image_base_64(uint64_t base) +{ + props_->set_image_base_64(base); +} + +//Sets heap size commit for PE32 and PE64 respectively +void pe_base::set_heap_size_commit(uint32_t size) +{ + props_->set_heap_size_commit(size); +} + +void pe_base::set_heap_size_commit(uint64_t size) +{ + props_->set_heap_size_commit(size); +} + +//Sets heap size reserve for PE32 and PE64 respectively +void pe_base::set_heap_size_reserve(uint32_t size) +{ + props_->set_heap_size_reserve(size); +} + +void pe_base::set_heap_size_reserve(uint64_t size) +{ + props_->set_heap_size_reserve(size); +} + +//Sets stack size commit for PE32 and PE64 respectively +void pe_base::set_stack_size_commit(uint32_t size) +{ + props_->set_stack_size_commit(size); +} + +void pe_base::set_stack_size_commit(uint64_t size) +{ + props_->set_stack_size_commit(size); +} + +//Sets stack size reserve for PE32 and PE64 respectively +void pe_base::set_stack_size_reserve(uint32_t size) +{ + props_->set_stack_size_reserve(size); +} + +void pe_base::set_stack_size_reserve(uint64_t size) +{ + props_->set_stack_size_reserve(size); +} + +//Returns heap size commit for PE32 and PE64 respectively +uint32_t pe_base::get_heap_size_commit_32() const +{ + return props_->get_heap_size_commit_32(); +} + +uint64_t pe_base::get_heap_size_commit_64() const +{ + return props_->get_heap_size_commit_64(); +} + +//Returns heap size reserve for PE32 and PE64 respectively +uint32_t pe_base::get_heap_size_reserve_32() const +{ + return props_->get_heap_size_reserve_32(); +} + +uint64_t pe_base::get_heap_size_reserve_64() const +{ + return props_->get_heap_size_reserve_64(); +} + +//Returns stack size commit for PE32 and PE64 respectively +uint32_t pe_base::get_stack_size_commit_32() const +{ + return props_->get_stack_size_commit_32(); +} + +uint64_t pe_base::get_stack_size_commit_64() const +{ + return props_->get_stack_size_commit_64(); +} + +//Returns stack size reserve for PE32 and PE64 respectively +uint32_t pe_base::get_stack_size_reserve_32() const +{ + return props_->get_stack_size_reserve_32(); +} + +uint64_t pe_base::get_stack_size_reserve_64() const +{ + return props_->get_stack_size_reserve_64(); +} + +//Returns heap size commit for PE32 +void pe_base::get_heap_size_commit(uint32_t& size) const +{ + size = get_heap_size_commit_32(); +} + +//Returns heap size commit for PE32/PE64 +void pe_base::get_heap_size_commit(uint64_t& size) const +{ + size = get_heap_size_commit_64(); +} + +//Returns heap size reserve for PE32 +void pe_base::get_heap_size_reserve(uint32_t& size) const +{ + size = get_heap_size_reserve_32(); +} + +//Returns heap size reserve for PE32/PE64 +void pe_base::get_heap_size_reserve(uint64_t& size) const +{ + size = get_heap_size_reserve_64(); +} + +//Returns stack size commit for PE32 +void pe_base::get_stack_size_commit(uint32_t& size) const +{ + size = get_stack_size_commit_32(); +} + +//Returns stack size commit for PE32/PE64 +void pe_base::get_stack_size_commit(uint64_t& size) const +{ + size = get_stack_size_commit_64(); +} + +//Returns stack size reserve for PE32 +void pe_base::get_stack_size_reserve(uint32_t& size) const +{ + size = get_stack_size_reserve_32(); +} + +//Returns stack size reserve for PE32/PE64 +void pe_base::get_stack_size_reserve(uint64_t& size) const +{ + size = get_stack_size_reserve_64(); +} + +//Realigns file (changes file alignment) +void pe_base::realign_file(uint32_t new_file_alignment) +{ + //Checks alignment for correctness + set_file_alignment(new_file_alignment); + realign_all_sections(); +} + +//Helper function to recalculate RAW and virtual section sizes and strip it, if necessary +void pe_base::recalculate_section_sizes(section& s, bool auto_strip) +{ + prepare_section(s); //Recalculate section raw addresses + + //Strip RAW size of section, if it is the last one + //For all others it must be file-aligned and calculated by prepare_section() call + if(auto_strip && !(sections_.empty() || &s == &*(sections_.end() - 1))) + { + //Strip ending raw data nullbytes to optimize size + std::string& raw_data = s.get_raw_data(); + if(!raw_data.empty()) + { + std::string::size_type i = raw_data.length(); + for(; i != 1; --i) + { + if(raw_data[i - 1] != 0) + break; + } + + raw_data.resize(i); + } + + s.set_size_of_raw_data(static_cast<uint32_t>(raw_data.length())); + } + + //Can occur only for last section + if(pe_utils::align_up(s.get_virtual_size(), get_section_alignment()) < pe_utils::align_up(s.get_size_of_raw_data(), get_file_alignment())) + set_section_virtual_size(s, pe_utils::align_up(s.get_size_of_raw_data(), get_section_alignment())); //Recalculate section virtual size +} + +//Returns data from the beginning of image +//Size = SizeOfHeaders +const std::string& pe_base::get_full_headers_data() const +{ + return full_headers_data_; +} + +const pe_base::debug_data_list& pe_base::get_raw_debug_data_list() const +{ + return debug_data_; +} + +//Sets number of sections +void pe_base::set_number_of_sections(uint16_t number) +{ + props_->set_number_of_sections(number); +} + +//Sets size of image +void pe_base::set_size_of_image(uint32_t size) +{ + props_->set_size_of_image(size); +} + +//Sets size of headers +void pe_base::set_size_of_headers(uint32_t size) +{ + props_->set_size_of_headers(size); +} + +//Sets size of optional headers +void pe_base::set_size_of_optional_header(uint16_t size) +{ + props_->set_size_of_optional_header(size); +} + +//Returns nt headers data pointer +char* pe_base::get_nt_headers_ptr() +{ + return props_->get_nt_headers_ptr(); +} + +//Returns nt headers data pointer +const char* pe_base::get_nt_headers_ptr() const +{ + return props_->get_nt_headers_ptr(); +} + +//Returns sizeof() nt headers +uint32_t pe_base::get_sizeof_nt_header() const +{ + return props_->get_sizeof_nt_header(); +} + +//Returns sizeof() optional headers +uint32_t pe_base::get_sizeof_opt_headers() const +{ + return props_->get_sizeof_opt_headers(); +} + +//Sets file alignment (no checks) +void pe_base::set_file_alignment_unchecked(uint32_t alignment) +{ + props_->set_file_alignment_unchecked(alignment); +} + +//Sets base of code +void pe_base::set_base_of_code(uint32_t base) +{ + props_->set_base_of_code(base); +} + +//Returns base of code +uint32_t pe_base::get_base_of_code() const +{ + return props_->get_base_of_code(); +} + +//Returns needed magic of image +uint32_t pe_base::get_needed_magic() const +{ + return props_->get_needed_magic(); +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_base.h b/irdb-lib/pebliss/trunk/pe_lib/pe_base.h new file mode 100644 index 0000000000000000000000000000000000000000..334914e662989d219728b8a0bd4d241381cc75ef --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_base.h @@ -0,0 +1,530 @@ +#ifndef pebliss_pe_base_h +#define pebliss_pe_base_h +#pragma once +#ifndef pebliss_pebase_h +#define pebliss_pebase_h + +#include <string> +#include <vector> +#include <istream> +#include <ostream> +#include <map> +#include "pe_exception.h" +#include "pe_structures.h" +#include "utils.h" +#include "pe_section.h" +#include "pe_properties.h" + +//Please don't remove this information from header +//PEBliss 1.0.0 +//(c) DX 2011 - 2012, http://kaimi.ru +//Free to use for commertial and non-commertial purposes, modification and distribution + +// == more important == +//TODO: compact import rebuilder +//TODO: remove sections in the middle +//== less important == +//TODO: relocations that take more than one element (seems to be not possible in Windows PE, but anyway) +//TODO: delay import directory +//TODO: write message tables +//TODO: write string tables +//TODO: read security information +//TODO: read full .NET information + +namespace pe_bliss +{ +//Portable executable class +class pe_base +{ +public: //CONSTRUCTORS + //Constructor from stream + pe_base(std::istream& file, const pe_properties& props, bool read_debug_raw_data = true); + + //Constructor of empty PE-file + explicit pe_base(const pe_properties& props, uint32_t section_alignment = 0x1000, bool dll = false, uint16_t subsystem = pe_win::image_subsystem_windows_gui); + + pe_base(const pe_base& pe); + pe_base& operator=(const pe_base& pe); + +public: + ~pe_base(); + +public: //STUB + //Strips stub MSVS overlay, if any + void strip_stub_overlay(); + //Fills stub MSVS overlay with specified byte + void fill_stub_overlay(char c); + //Sets stub MSVS overlay + void set_stub_overlay(const std::string& data); + //Returns stub overlay contents + const std::string& get_stub_overlay() const; + + +public: //DIRECTORIES + //Returns true if directory exists + bool directory_exists(uint32_t id) const; + //Removes directory + void remove_directory(uint32_t id); + + //Returns directory RVA + uint32_t get_directory_rva(uint32_t id) const; + //Returns directory size + uint32_t get_directory_size(uint32_t id) const; + + //Sets directory RVA (just a value of PE header, no moving occurs) + void set_directory_rva(uint32_t id, uint32_t rva); + //Sets directory size (just a value of PE header, no moving occurs) + void set_directory_size(uint32_t id, uint32_t size); + + //Strips only zero DATA_DIRECTORY entries to count = min_count + //Returns resulting number of data directories + //strip_iat_directory - if true, even not empty IAT directory will be stripped + uint32_t strip_data_directories(uint32_t min_count = 1, bool strip_iat_directory = true); + + //Returns true if image has import directory + bool has_imports() const; + //Returns true if image has export directory + bool has_exports() const; + //Returns true if image has resource directory + bool has_resources() const; + //Returns true if image has security directory + bool has_security() const; + //Returns true if image has relocations + bool has_reloc() const; + //Returns true if image has TLS directory + bool has_tls() const; + //Returns true if image has config directory + bool has_config() const; + //Returns true if image has bound import directory + bool has_bound_import() const; + //Returns true if image has delay import directory + bool has_delay_import() const; + //Returns true if image has COM directory + bool is_dotnet() const; + //Returns true if image has exception directory + bool has_exception_directory() const; + //Returns true if image has debug directory + bool has_debug() const; + + //Returns subsystem value + uint16_t get_subsystem() const; + //Sets subsystem value + void set_subsystem(uint16_t subsystem); + //Returns true if image has console subsystem + bool is_console() const; + //Returns true if image has Windows GUI subsystem + bool is_gui() const; + + //Sets required operation system version + void set_os_version(uint16_t major, uint16_t minor); + //Returns required operation system version (minor word) + uint16_t get_minor_os_version() const; + //Returns required operation system version (major word) + uint16_t get_major_os_version() const; + + //Sets required subsystem version + void set_subsystem_version(uint16_t major, uint16_t minor); + //Returns required subsystem version (minor word) + uint16_t get_minor_subsystem_version() const; + //Returns required subsystem version (major word) + uint16_t get_major_subsystem_version() const; + +public: //PE HEADER + //Returns DOS header + const pe_win::image_dos_header& get_dos_header() const; + pe_win::image_dos_header& get_dos_header(); + + //Returns PE header start (e_lfanew) + int32_t get_pe_header_start() const; + + //Returns file alignment + uint32_t get_file_alignment() const; + //Sets file alignment, checking the correctness of its value + void set_file_alignment(uint32_t alignment); + + //Returns size of image + uint32_t get_size_of_image() const; + + //Returns image entry point + uint32_t get_ep() const; + //Sets image entry point (just a value of PE header) + void set_ep(uint32_t new_ep); + + //Returns number of RVA and sizes (number of DATA_DIRECTORY entries) + uint32_t get_number_of_rvas_and_sizes() const; + //Sets number of RVA and sizes (number of DATA_DIRECTORY entries) + void set_number_of_rvas_and_sizes(uint32_t number); + + //Returns PE characteristics + uint16_t get_characteristics() const; + //Sets PE characteristics (a value inside header) + void set_characteristics(uint16_t ch); + //Clears PE characteristics flag + void clear_characteristics_flags(uint16_t flags); + //Sets PE characteristics flag + void set_characteristics_flags(uint16_t flags); + //Returns true if PE characteristics flag set + bool check_characteristics_flag(uint16_t flag) const; + + //Returns DLL Characteristics + uint16_t get_dll_characteristics() const; + //Sets DLL Characteristics + void set_dll_characteristics(uint16_t characteristics); + + //Returns size of headers + uint32_t get_size_of_headers() const; + //Returns size of optional header + uint16_t get_size_of_optional_header() const; + + //Returns PE signature + uint32_t get_pe_signature() const; + + //Returns magic value + uint32_t get_magic() const; + + //Returns image base for PE32 and PE64 respectively + uint32_t get_image_base_32() const; + void get_image_base(uint32_t& base) const; + //Sets image base for PE32 and PE64 respectively + uint64_t get_image_base_64() const; + void get_image_base(uint64_t& base) const; + + //Sets new image base + void set_image_base(uint32_t base); + void set_image_base_64(uint64_t base); + + //Sets heap size commit for PE32 and PE64 respectively + void set_heap_size_commit(uint32_t size); + void set_heap_size_commit(uint64_t size); + //Sets heap size reserve for PE32 and PE64 respectively + void set_heap_size_reserve(uint32_t size); + void set_heap_size_reserve(uint64_t size); + //Sets stack size commit for PE32 and PE64 respectively + void set_stack_size_commit(uint32_t size); + void set_stack_size_commit(uint64_t size); + //Sets stack size reserve for PE32 and PE64 respectively + void set_stack_size_reserve(uint32_t size); + void set_stack_size_reserve(uint64_t size); + + //Returns heap size commit for PE32 and PE64 respectively + uint32_t get_heap_size_commit_32() const; + void get_heap_size_commit(uint32_t& size) const; + uint64_t get_heap_size_commit_64() const; + void get_heap_size_commit(uint64_t& size) const; + //Returns heap size reserve for PE32 and PE64 respectively + uint32_t get_heap_size_reserve_32() const; + void get_heap_size_reserve(uint32_t& size) const; + uint64_t get_heap_size_reserve_64() const; + void get_heap_size_reserve(uint64_t& size) const; + //Returns stack size commit for PE32 and PE64 respectively + uint32_t get_stack_size_commit_32() const; + void get_stack_size_commit(uint32_t& size) const; + uint64_t get_stack_size_commit_64() const; + void get_stack_size_commit(uint64_t& size) const; + //Returns stack size reserve for PE32 and PE64 respectively + uint32_t get_stack_size_reserve_32() const; + void get_stack_size_reserve(uint32_t& size) const; + uint64_t get_stack_size_reserve_64() const; + void get_stack_size_reserve(uint64_t& size) const; + + //Updates virtual size of image corresponding to section virtual sizes + void update_image_size(); + + //Returns checksum of PE file from header + uint32_t get_checksum() const; + //Sets checksum of PE file + void set_checksum(uint32_t checksum); + + //Returns timestamp of PE file from header + uint32_t get_time_date_stamp() const; + //Sets timestamp of PE file + void set_time_date_stamp(uint32_t timestamp); + + //Returns Machine field value of PE file from header + uint16_t get_machine() const; + //Sets Machine field value of PE file + void set_machine(uint16_t machine); + + //Returns data from the beginning of image + //Size = SizeOfHeaders + const std::string& get_full_headers_data() const; + + typedef std::multimap<uint32_t, std::string> debug_data_list; + //Returns raw list of debug data + const debug_data_list& get_raw_debug_data_list() const; + + //Reads and checks DOS header + static void read_dos_header(std::istream& file, pe_win::image_dos_header& header); + + //Returns sizeof() nt headers + uint32_t get_sizeof_nt_header() const; + //Returns sizeof() optional headers + uint32_t get_sizeof_opt_headers() const; + //Returns raw nt headers data pointer + const char* get_nt_headers_ptr() const; + + //Sets size of headers (to NT headers) + void set_size_of_headers(uint32_t size); + //Sets size of optional headers (to NT headers) + void set_size_of_optional_header(uint16_t size); + + //Sets base of code + void set_base_of_code(uint32_t base); + //Returns base of code + uint32_t get_base_of_code() const; + +public: //ADDRESS CONVERTIONS + //Virtual Address (VA) to Relative Virtual Address (RVA) convertions + //for PE32 and PE64 respectively + //bound_check checks integer overflow + uint32_t va_to_rva(uint32_t va, bool bound_check = true) const; + uint32_t va_to_rva(uint64_t va, bool bound_check = true) const; + + //Relative Virtual Address (RVA) to Virtual Address (VA) convertions + //for PE32 and PE64 respectively + uint32_t rva_to_va_32(uint32_t rva) const; + void rva_to_va(uint32_t rva, uint32_t& va) const; + uint64_t rva_to_va_64(uint32_t rva) const; + void rva_to_va(uint32_t rva, uint64_t& va) const; + + //RVA to RAW file offset convertion (4gb max) + uint32_t rva_to_file_offset(uint32_t rva) const; + //RAW file offset to RVA convertion (4gb max) + uint32_t file_offset_to_rva(uint32_t offset) const; + + //RVA from section raw data offset + static uint32_t rva_from_section_offset(const section& s, uint32_t raw_offset_from_section_start); + +public: //IMAGE SECTIONS + //Returns number of sections from PE header + uint16_t get_number_of_sections() const; + + //Updates number of sections in PE header + uint16_t update_number_of_sections(); + + //Returns section alignment + uint32_t get_section_alignment() const; + + //Returns section list + section_list& get_image_sections(); + const section_list& get_image_sections() const; + + //Realigns all sections, if you made any changes to sections or alignments + void realign_all_sections(); + //Resligns section with specified index + void realign_section(uint32_t index); + + //Returns section from RVA inside it + section& section_from_rva(uint32_t rva); + const section& section_from_rva(uint32_t rva) const; + //Returns section from directory ID + section& section_from_directory(uint32_t directory_id); + const section& section_from_directory(uint32_t directory_id) const; + //Returns section from VA inside it for PE32 and PE64 respectively + section& section_from_va(uint32_t va); + const section& section_from_va(uint32_t va) const; + section& section_from_va(uint64_t va); + const section& section_from_va(uint64_t va) const; + //Returns section from file offset (4gb max) + section& section_from_file_offset(uint32_t offset); + const section& section_from_file_offset(uint32_t offset) const; + + //Returns section TOTAL RAW/VIRTUAL data length from RVA inside section + //If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too + uint32_t section_data_length_from_rva(uint32_t rva, section_data_type datatype = section_data_raw, bool include_headers = false) const; + //Returns section TOTAL RAW/VIRTUAL data length from VA inside section for PE32 and PE64 respectively + //If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too + uint32_t section_data_length_from_va(uint32_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const; + uint32_t section_data_length_from_va(uint64_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const; + + //Returns section remaining RAW/VIRTUAL data length from RVA to the end of section "s" (checks bounds) + uint32_t section_data_length_from_rva(const section& s, uint32_t rva_inside, section_data_type datatype = section_data_raw) const; + //Returns section remaining RAW/VIRTUAL data length from VA to the end of section "s" for PE32 and PE64 respectively (checks bounds) + uint32_t section_data_length_from_va(const section& s, uint64_t va_inside, section_data_type datatype = section_data_raw) const; + uint32_t section_data_length_from_va(const section& s, uint32_t va_inside, section_data_type datatype = section_data_raw) const; + + //Returns section remaining RAW/VIRTUAL data length from RVA "rva_inside" to the end of section containing RVA "rva" + //If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too + uint32_t section_data_length_from_rva(uint32_t rva, uint32_t rva_inside, section_data_type datatype = section_data_raw, bool include_headers = false) const; + //Returns section remaining RAW/VIRTUAL data length from VA "va_inside" to the end of section containing VA "va" for PE32 and PE64 respectively + //If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too + uint32_t section_data_length_from_va(uint32_t va, uint32_t va_inside, section_data_type datatype = section_data_raw, bool include_headers = false) const; + uint32_t section_data_length_from_va(uint64_t va, uint64_t va_inside, section_data_type datatype = section_data_raw, bool include_headers = false) const; + + //If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too + //Returns corresponding section data pointer from RVA inside section + char* section_data_from_rva(uint32_t rva, bool include_headers = false); + const char* section_data_from_rva(uint32_t rva, section_data_type datatype = section_data_raw, bool include_headers = false) const; + //Returns corresponding section data pointer from VA inside section for PE32 and PE64 respectively + char* section_data_from_va(uint32_t va, bool include_headers = false); + const char* section_data_from_va(uint32_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const; + char* section_data_from_va(uint64_t va, bool include_headers = false); + const char* section_data_from_va(uint64_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const; + + //Returns corresponding section data pointer from RVA inside section "s" (checks bounds) + char* section_data_from_rva(section& s, uint32_t rva); + const char* section_data_from_rva(const section& s, uint32_t rva, section_data_type datatype = section_data_raw) const; + //Returns corresponding section data pointer from VA inside section "s" for PE32 and PE64 respectively (checks bounds) + char* section_data_from_va(section& s, uint32_t va); //Always returns raw data + const char* section_data_from_va(const section& s, uint32_t va, section_data_type datatype = section_data_raw) const; + char* section_data_from_va(section& s, uint64_t va); //Always returns raw data + const char* section_data_from_va(const section& s, uint64_t va, section_data_type datatype = section_data_raw) const; + + //Returns corresponding section data pointer from RVA inside section "s" (checks bounds, checks sizes, the most safe function) + template<typename T> + T section_data_from_rva(const section& s, uint32_t rva, section_data_type datatype = section_data_raw) const + { + if(rva >= s.get_virtual_address() && rva < s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment()) && pe_utils::is_sum_safe(rva, sizeof(T))) + { + const std::string& data = datatype == section_data_raw ? s.get_raw_data() : s.get_virtual_data(get_section_alignment()); + //Don't check for underflow here, comparsion is unsigned + if(data.size() < rva - s.get_virtual_address() + sizeof(T)) + throw pe_exception("RVA and requested data size does not exist inside section", pe_exception::rva_not_exists); + + return *reinterpret_cast<const T*>(data.data() + rva - s.get_virtual_address()); + } + + throw pe_exception("RVA not found inside section", pe_exception::rva_not_exists); + } + + //Returns corresponding section data pointer from RVA inside section (checks rva, checks sizes, the most safe function) + //If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too + template<typename T> + T section_data_from_rva(uint32_t rva, section_data_type datatype = section_data_raw, bool include_headers = false) const + { + //if RVA is inside of headers and we're searching them too... + if(include_headers && pe_utils::is_sum_safe(rva, sizeof(T)) && (rva + sizeof(T) < full_headers_data_.length())) + return *reinterpret_cast<const T*>(&full_headers_data_[rva]); + + const section& s = section_from_rva(rva); + const std::string& data = datatype == section_data_raw ? s.get_raw_data() : s.get_virtual_data(get_section_alignment()); + //Don't check for underflow here, comparsion is unsigned + if(data.size() < rva - s.get_virtual_address() + sizeof(T)) + throw pe_exception("RVA and requested data size does not exist inside section", pe_exception::rva_not_exists); + + return *reinterpret_cast<const T*>(data.data() + rva - s.get_virtual_address()); + } + + //Returns corresponding section data pointer from VA inside section "s" (checks bounds, checks sizes, the most safe function) + template<typename T> + T section_data_from_va(const section& s, uint32_t va, section_data_type datatype = section_data_raw) const + { + return section_data_from_rva<T>(s, va_to_rva(va), datatype); + } + + template<typename T> + T section_data_from_va(const section& s, uint64_t va, section_data_type datatype = section_data_raw) const + { + return section_data_from_rva<T>(s, va_to_rva(va), datatype); + } + + //Returns corresponding section data pointer from VA inside section (checks rva, checks sizes, the most safe function) + //If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too + template<typename T> + T section_data_from_va(uint32_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const + { + return section_data_from_rva<T>(va_to_rva(va), datatype, include_headers); + } + + template<typename T> + T section_data_from_va(uint64_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const + { + return section_data_from_rva<T>(va_to_rva(va), datatype, include_headers); + } + + //Returns section and offset (raw data only) from its start from RVA + const std::pair<uint32_t, const section*> section_and_offset_from_rva(uint32_t rva) const; + + //Sets virtual size of section "s" + //Section must be free (not bound to any image) + //or the last section of this image + //Function calls update_image_size automatically in second case + void set_section_virtual_size(section& s, uint32_t vsize); + + //Represents section expand type for expand_section function + enum section_expand_type + { + expand_section_raw, //Section raw data size will be expanded + expand_section_virtual //Section virtual data size will be expanded + }; + + //Expands section raw or virtual size to hold data from specified RVA with specified size + //Section must be free (not bound to any image) + //or the last section of this image + //Returns true if section was expanded + bool expand_section(section& s, uint32_t needed_rva, uint32_t needed_size, section_expand_type expand); + + //Adds section to image + //Returns last section + section& add_section(section s); + //Prepares section to later add it to image (checks and recalculates virtual and raw section size) + //Section must be prepared by this function before calling add_section + void prepare_section(section& s); + + //Returns true if sectios "s" is already attached to this PE file + bool section_attached(const section& s) const; + + +public: //IMAGE + //Returns PE type (PE or PE+) from pe_type enumeration (minimal correctness checks) + static pe_type get_pe_type(std::istream& file); + //Returns PE type of this image + pe_type get_pe_type() const; + + //Returns true if image has overlay data at the end of file + bool has_overlay() const; + + //Realigns file (changes file alignment) + void realign_file(uint32_t new_file_alignment); + + //Helper function to recalculate RAW and virtual section sizes and strip it, if necessary + //auto_strip = strip section, if necessary + void recalculate_section_sizes(section& s, bool auto_strip); + + // ========== END OF PUBLIC MEMBERS AND STRUCTURES ========== // +private: + //Image DOS header + pe_win::image_dos_header dos_header_; + //Rich (stub) overlay data (for MSVS) + std::string rich_overlay_; + //List of image sections + section_list sections_; + //True if image has overlay + bool has_overlay_; + //Raw SizeOfHeaders-sized data from the beginning of image + std::string full_headers_data_; + //Raw debug data for all directories + //PointerToRawData; Data + debug_data_list debug_data_; + //PE or PE+ related properties + pe_properties* props_; + + //Reads and checks DOS header + void read_dos_header(std::istream& file); + + //Reads and checks PE headers and section headers, data + void read_pe(std::istream& file, bool read_debug_raw_data); + + //Sets number of sections + void set_number_of_sections(uint16_t number); + //Sets size of image + void set_size_of_image(uint32_t size); + //Sets file alignment (no checks) + void set_file_alignment_unchecked(uint32_t alignment); + //Returns needed magic of image + uint32_t get_needed_magic() const; + //Returns nt headers data pointer + char* get_nt_headers_ptr(); + +private: + static const uint16_t maximum_number_of_sections = 0x60; + static const uint32_t minimum_file_alignment = 512; + +private: + //RAW file offset to section convertion helpers (4gb max) + section_list::const_iterator file_offset_to_section(uint32_t offset) const; + section_list::iterator file_offset_to_section(uint32_t offset); +}; +} +#endif +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_bliss.h b/irdb-lib/pebliss/trunk/pe_lib/pe_bliss.h new file mode 100644 index 0000000000000000000000000000000000000000..f5a8bbbb6382bc79202288e9858ea74fb372bd0d --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_bliss.h @@ -0,0 +1,21 @@ +#ifndef pebliss_pe_bliss_h +#define pebliss_pe_bliss_h +#pragma once +#include "pe_base.h" +#include "pe_rebuilder.h" +#include "pe_factory.h" +#include "pe_bound_import.h" +#include "pe_debug.h" +#include "pe_dotnet.h" +#include "pe_exception_directory.h" +#include "pe_exports.h" +#include "pe_imports.h" +#include "pe_load_config.h" +#include "pe_relocations.h" +#include "pe_resources.h" +#include "pe_rich_data.h" +#include "pe_tls.h" +#include "pe_properties_generic.h" +#include "pe_checksum.h" +#include "entropy.h" +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_bliss_resources.h b/irdb-lib/pebliss/trunk/pe_lib/pe_bliss_resources.h new file mode 100644 index 0000000000000000000000000000000000000000..cb6515f25a98575a75e8824d1971db0bdc0f80ee --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_bliss_resources.h @@ -0,0 +1,18 @@ +#ifndef pebliss_pe_bliss_resources_h +#define pebliss_pe_bliss_resources_h +#pragma once +#include "file_version_info.h" +#include "message_table.h" +#include "pe_resource_manager.h" +#include "pe_resource_viewer.h" +#include "version_info_editor.h" +#include "version_info_viewer.h" +#include "resource_bitmap_reader.h" +#include "resource_bitmap_writer.h" +#include "resource_cursor_icon_reader.h" +#include "resource_cursor_icon_writer.h" +#include "resource_version_info_reader.h" +#include "resource_version_info_writer.h" +#include "resource_string_table_reader.h" +#include "resource_message_list_reader.h" +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_bound_import.cpp b/irdb-lib/pebliss/trunk/pe_lib/pe_bound_import.cpp new file mode 100644 index 0000000000000000000000000000000000000000..605cf229b42bb66b88d8c754bf09ac6e95276300 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_bound_import.cpp @@ -0,0 +1,290 @@ +#include <string.h> +#include "pe_bound_import.h" +#include "utils.h" + +namespace pe_bliss +{ +using namespace pe_win; + +//BOUND IMPORT +//Default constructor +bound_import_ref::bound_import_ref() + :timestamp_(0) +{} + +//Constructor from data +bound_import_ref::bound_import_ref(const std::string& module_name, uint32_t timestamp) + :module_name_(module_name), timestamp_(timestamp) +{} + +//Returns imported module name +const std::string& bound_import_ref::get_module_name() const +{ + return module_name_; +} + +//Returns bound import date and time stamp +uint32_t bound_import_ref::get_timestamp() const +{ + return timestamp_; +} + +//Sets module name +void bound_import_ref::set_module_name(const std::string& module_name) +{ + module_name_ = module_name; +} + +//Sets timestamp +void bound_import_ref::set_timestamp(uint32_t timestamp) +{ + timestamp_ = timestamp; +} + +//Default constructor +bound_import::bound_import() + :timestamp_(0) +{} + +//Constructor from data +bound_import::bound_import(const std::string& module_name, uint32_t timestamp) + :module_name_(module_name), timestamp_(timestamp) +{} + +//Returns imported module name +const std::string& bound_import::get_module_name() const +{ + return module_name_; +} + +//Returns bound import date and time stamp +uint32_t bound_import::get_timestamp() const +{ + return timestamp_; +} + +//Returns bound references cound +size_t bound_import::get_module_ref_count() const +{ + return refs_.size(); +} + +//Returns module references +const bound_import::ref_list& bound_import::get_module_ref_list() const +{ + return refs_; +} + +//Adds module reference +void bound_import::add_module_ref(const bound_import_ref& ref) +{ + refs_.push_back(ref); +} + +//Clears module references list +void bound_import::clear_module_refs() +{ + refs_.clear(); +} + +//Returns module references +bound_import::ref_list& bound_import::get_module_ref_list() +{ + return refs_; +} + +//Sets module name +void bound_import::set_module_name(const std::string& module_name) +{ + module_name_ = module_name; +} + +//Sets timestamp +void bound_import::set_timestamp(uint32_t timestamp) +{ + timestamp_ = timestamp; +} + +const bound_import_module_list get_bound_import_module_list(const pe_base& pe) +{ + //Returned bound import modules list + bound_import_module_list ret; + + //If image has no bound imports + if(!pe.has_bound_import()) + return ret; + + uint32_t bound_import_data_len = + pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_bound_import), pe.get_directory_rva(image_directory_entry_bound_import), section_data_raw, true); + + if(bound_import_data_len < pe.get_directory_size(image_directory_entry_bound_import)) + throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory); + + const char* bound_import_data = pe.section_data_from_rva(pe.get_directory_rva(image_directory_entry_bound_import), section_data_raw, true); + + //Check read in "read_pe" function raw bound import data size + if(bound_import_data_len < sizeof(image_bound_import_descriptor)) + throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory); + + //current bound_import_data_ in-string position + unsigned long current_pos = 0; + //first bound import descriptor + //so, we're working with raw data here, no section helpers available + const image_bound_import_descriptor* descriptor = reinterpret_cast<const image_bound_import_descriptor*>(&bound_import_data[current_pos]); + + //Enumerate until zero + while(descriptor->OffsetModuleName) + { + //Check module name offset + if(descriptor->OffsetModuleName >= bound_import_data_len) + throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory); + + //Check module name for null-termination + if(!pe_utils::is_null_terminated(&bound_import_data[descriptor->OffsetModuleName], bound_import_data_len - descriptor->OffsetModuleName)) + throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory); + + //Create bound import descriptor structure + bound_import elem(&bound_import_data[descriptor->OffsetModuleName], descriptor->TimeDateStamp); + + //Check DWORDs + if(descriptor->NumberOfModuleForwarderRefs >= pe_utils::max_dword / sizeof(image_bound_forwarder_ref) + || !pe_utils::is_sum_safe(current_pos, 2 /* this descriptor and the next one */ * sizeof(image_bound_import_descriptor) + descriptor->NumberOfModuleForwarderRefs * sizeof(image_bound_forwarder_ref))) + throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory); + + //Move after current descriptor + current_pos += sizeof(image_bound_import_descriptor); + + //Enumerate referenced bound import descriptors + for(unsigned long i = 0; i != descriptor->NumberOfModuleForwarderRefs; ++i) + { + //They're just after parent descriptor + //Check size of structure + if(current_pos + sizeof(image_bound_forwarder_ref) > bound_import_data_len) + throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory); + + //Get IMAGE_BOUND_FORWARDER_REF pointer + const image_bound_forwarder_ref* ref_descriptor = reinterpret_cast<const image_bound_forwarder_ref*>(&bound_import_data[current_pos]); + + //Check referenced module name + if(ref_descriptor->OffsetModuleName >= bound_import_data_len) + throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory); + + //And its null-termination + if(!pe_utils::is_null_terminated(&bound_import_data[ref_descriptor->OffsetModuleName], bound_import_data_len - ref_descriptor->OffsetModuleName)) + throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory); + + //Add referenced module to current bound import structure + elem.add_module_ref(bound_import_ref(&bound_import_data[ref_descriptor->OffsetModuleName], ref_descriptor->TimeDateStamp)); + + //Move after referenced bound import descriptor + current_pos += sizeof(image_bound_forwarder_ref); + } + + //Check structure size + if(current_pos + sizeof(image_bound_import_descriptor) > bound_import_data_len) + throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory); + + //Move to next bound import descriptor + descriptor = reinterpret_cast<const image_bound_import_descriptor*>(&bound_import_data[current_pos]); + + //Save created descriptor structure and references + ret.push_back(elem); + } + + //Return result + return ret; +} + +//imports - bound imported modules list +//imports_section - section where export directory will be placed (must be attached to PE image) +//offset_from_section_start - offset from imports_section raw data start +//save_to_pe_headers - if true, new bound import directory information will be saved to PE image headers +//auto_strip_last_section - if true and bound imports are placed in the last section, it will be automatically stripped +const image_directory rebuild_bound_imports(pe_base& pe, const bound_import_module_list& imports, section& imports_section, uint32_t offset_from_section_start, bool save_to_pe_header, bool auto_strip_last_section) +{ + //Check that exports_section is attached to this PE image + if(!pe.section_attached(imports_section)) + throw pe_exception("Bound import section must be attached to PE file", pe_exception::section_is_not_attached); + + uint32_t directory_pos = pe_utils::align_up(offset_from_section_start, sizeof(uint32_t)); + uint32_t needed_size = sizeof(image_bound_import_descriptor) /* Ending null descriptor */; + uint32_t needed_size_for_strings = 0; + + //Calculate needed size for bound import data + for(bound_import_module_list::const_iterator it = imports.begin(); it != imports.end(); ++it) + { + const bound_import& import = *it; + needed_size += sizeof(image_bound_import_descriptor); + needed_size_for_strings += static_cast<uint32_t>((*it).get_module_name().length()) + 1 /* nullbyte */; + + const bound_import::ref_list& refs = import.get_module_ref_list(); + for(bound_import::ref_list::const_iterator ref_it = refs.begin(); ref_it != refs.end(); ++ref_it) + { + needed_size_for_strings += static_cast<uint32_t>((*ref_it).get_module_name().length()) + 1 /* nullbyte */; + needed_size += sizeof(image_bound_forwarder_ref); + } + } + + needed_size += needed_size_for_strings; + + //Check if imports_section is last one. If it's not, check if there's enough place for bound import data + if(&imports_section != &*(pe.get_image_sections().end() - 1) && + (imports_section.empty() || pe_utils::align_up(imports_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + directory_pos)) + throw pe_exception("Insufficient space for bound import directory", pe_exception::insufficient_space); + + std::string& raw_data = imports_section.get_raw_data(); + + //This will be done only if imports_section is the last section of image or for section with unaligned raw length of data + if(raw_data.length() < needed_size + directory_pos) + raw_data.resize(needed_size + directory_pos); //Expand section raw data + + uint32_t current_pos_for_structures = directory_pos; + uint32_t current_pos_for_strings = current_pos_for_structures + needed_size - needed_size_for_strings; + + for(bound_import_module_list::const_iterator it = imports.begin(); it != imports.end(); ++it) + { + const bound_import& import = *it; + image_bound_import_descriptor descriptor; + descriptor.NumberOfModuleForwarderRefs = static_cast<uint16_t>(import.get_module_ref_list().size()); + descriptor.OffsetModuleName = static_cast<uint16_t>(current_pos_for_strings - directory_pos); + descriptor.TimeDateStamp = import.get_timestamp(); + + memcpy(&raw_data[current_pos_for_structures], &descriptor, sizeof(descriptor)); + current_pos_for_structures += sizeof(descriptor); + + size_t length = import.get_module_name().length() + 1 /* nullbyte */; + memcpy(&raw_data[current_pos_for_strings], import.get_module_name().c_str(), length); + current_pos_for_strings += static_cast<uint32_t>(length); + + const bound_import::ref_list& refs = import.get_module_ref_list(); + for(bound_import::ref_list::const_iterator ref_it = refs.begin(); ref_it != refs.end(); ++ref_it) + { + const bound_import_ref& ref = *ref_it; + image_bound_forwarder_ref ref_descriptor = {0}; + ref_descriptor.OffsetModuleName = static_cast<uint16_t>(current_pos_for_strings - directory_pos); + ref_descriptor.TimeDateStamp = ref.get_timestamp(); + + memcpy(&raw_data[current_pos_for_structures], &ref_descriptor, sizeof(ref_descriptor)); + current_pos_for_structures += sizeof(ref_descriptor); + + length = ref.get_module_name().length() + 1 /* nullbyte */; + memcpy(&raw_data[current_pos_for_strings], ref.get_module_name().c_str(), length); + current_pos_for_strings += static_cast<uint32_t>(length); + } + } + + //Adjust section raw and virtual sizes + pe.recalculate_section_sizes(imports_section, auto_strip_last_section); + + image_directory ret(pe.rva_from_section_offset(imports_section, directory_pos), needed_size); + + //If auto-rewrite of PE headers is required + if(save_to_pe_header) + { + pe.set_directory_rva(image_directory_entry_bound_import, ret.get_rva()); + pe.set_directory_size(image_directory_entry_bound_import, ret.get_size()); + } + + return ret; +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_bound_import.h b/irdb-lib/pebliss/trunk/pe_lib/pe_bound_import.h new file mode 100644 index 0000000000000000000000000000000000000000..1bc70caa8de035dc09d614729d734c1fec6713cf --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_bound_import.h @@ -0,0 +1,90 @@ +#ifndef pebliss_pe_bound_import_h +#define pebliss_pe_bound_import_h +#pragma once +#include <vector> +#include <string> +#include "pe_structures.h" +#include "pe_base.h" +#include "pe_directory.h" + +namespace pe_bliss +{ +//Class representing bound import reference +class bound_import_ref +{ +public: + //Default constructor + bound_import_ref(); + //Constructor from data + bound_import_ref(const std::string& module_name, uint32_t timestamp); + + //Returns imported module name + const std::string& get_module_name() const; + //Returns bound import date and time stamp + uint32_t get_timestamp() const; + +public: //Setters + //Sets module name + void set_module_name(const std::string& module_name); + //Sets timestamp + void set_timestamp(uint32_t timestamp); + +private: + std::string module_name_; //Imported module name + uint32_t timestamp_; //Bound import timestamp +}; + +//Class representing image bound import information +class bound_import +{ +public: + typedef std::vector<bound_import_ref> ref_list; + +public: + //Default constructor + bound_import(); + //Constructor from data + bound_import(const std::string& module_name, uint32_t timestamp); + + //Returns imported module name + const std::string& get_module_name() const; + //Returns bound import date and time stamp + uint32_t get_timestamp() const; + + //Returns bound references cound + size_t get_module_ref_count() const; + //Returns module references + const ref_list& get_module_ref_list() const; + +public: //Setters + //Sets module name + void set_module_name(const std::string& module_name); + //Sets timestamp + void set_timestamp(uint32_t timestamp); + + //Adds module reference + void add_module_ref(const bound_import_ref& ref); + //Clears module references list + void clear_module_refs(); + //Returns module references + ref_list& get_module_ref_list(); + +private: + std::string module_name_; //Imported module name + uint32_t timestamp_; //Bound import timestamp + ref_list refs_; //Module references list +}; + +typedef std::vector<bound_import> bound_import_module_list; + +//Returns bound import information +const bound_import_module_list get_bound_import_module_list(const pe_base& pe);//Export directory rebuilder + +//imports - bound imported modules list +//imports_section - section where export directory will be placed (must be attached to PE image) +//offset_from_section_start - offset from imports_section raw data start +//save_to_pe_headers - if true, new bound import directory information will be saved to PE image headers +//auto_strip_last_section - if true and bound imports are placed in the last section, it will be automatically stripped +const image_directory rebuild_bound_imports(pe_base& pe, const bound_import_module_list& imports, section& imports_section, uint32_t offset_from_section_start = 0, bool save_to_pe_header = true, bool auto_strip_last_section = true); +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_checksum.cpp b/irdb-lib/pebliss/trunk/pe_lib/pe_checksum.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fe3aa81b9e0ee7bbf06df48d44cfd50c15a17043 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_checksum.cpp @@ -0,0 +1,82 @@ +#include "pe_checksum.h" +#include "pe_structures.h" +#include "pe_base.h" + +namespace pe_bliss +{ +using namespace pe_win; + +//Calculate checksum of image +uint32_t calculate_checksum(std::istream& file) +{ + //Save istream state + std::ios_base::iostate state = file.exceptions(); + std::streamoff old_offset = file.tellg(); + + //Checksum value + unsigned long long checksum = 0; + + try + { + image_dos_header header; + + file.exceptions(std::ios::goodbit); + + //Read DOS header + pe_base::read_dos_header(file, header); + + //Calculate PE checksum + file.seekg(0); + unsigned long long top = 0xFFFFFFFF; + top++; + + //"CheckSum" field position in optional PE headers - it's always 64 for PE and PE+ + static const unsigned long checksum_pos_in_optional_headers = 64; + //Calculate real PE headers "CheckSum" field position + //Sum is safe here + unsigned long pe_checksum_pos = header.e_lfanew + sizeof(image_file_header) + sizeof(uint32_t) + checksum_pos_in_optional_headers; + + //Calculate checksum for each byte of file + std::streamoff filesize = pe_utils::get_file_size(file); + for(unsigned long long i = 0; i < (unsigned long long) filesize; i += 4) + { + unsigned long dw = 0; + + //Read DWORD from file + file.read(reinterpret_cast<char*>(&dw), sizeof(unsigned long)); + //Skip "CheckSum" DWORD + if(i == pe_checksum_pos) + continue; + + //Calculate checksum + checksum = (checksum & 0xffffffff) + dw + (checksum >> 32); + if(checksum > top) + checksum = (checksum & 0xffffffff) + (checksum >> 32); + } + + //Finish checksum + checksum = (checksum & 0xffff) + (checksum >> 16); + checksum = (checksum) + (checksum >> 16); + checksum = checksum & 0xffff; + + checksum += static_cast<unsigned long>(filesize); + } + catch(const std::exception&) + { + //If something went wrong, restore istream state + file.exceptions(state); + file.seekg(old_offset); + file.clear(); + //Rethrow + throw; + } + + //Restore istream state + file.exceptions(state); + file.seekg(old_offset); + file.clear(); + + //Return checksum + return static_cast<uint32_t>(checksum); +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_checksum.h b/irdb-lib/pebliss/trunk/pe_lib/pe_checksum.h new file mode 100644 index 0000000000000000000000000000000000000000..5be9fe94b4d726888b4474e9cd7f7174ddabcc52 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_checksum.h @@ -0,0 +1,12 @@ +#ifndef pebliss_pe_checksum_h +#define pebliss_pe_checksum_h +#pragma once +#include <istream> +#include "stdint_defs.h" + +namespace pe_bliss +{ +//Calculate checksum of image (performs no checks on PE structures) +uint32_t calculate_checksum(std::istream& file); +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_debug.cpp b/irdb-lib/pebliss/trunk/pe_lib/pe_debug.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f077f29fb852e9021dec723846bb90493a41ed5c --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_debug.cpp @@ -0,0 +1,844 @@ +#include <string.h> +#include "pe_debug.h" +#include "utils.h" + +namespace pe_bliss +{ +using namespace pe_win; +//DEBUG +//Default constructor +debug_info::debug_info() + :characteristics_(0), + time_stamp_(0), + major_version_(0), minor_version_(0), + type_(0), + size_of_data_(0), + address_of_raw_data_(0), + pointer_to_raw_data_(0), + advanced_info_type_(advanced_info_none) +{} + +//Constructor from data +debug_info::debug_info(const image_debug_directory& debug) + :characteristics_(debug.Characteristics), + time_stamp_(debug.TimeDateStamp), + major_version_(debug.MajorVersion), minor_version_(debug.MinorVersion), + type_(debug.Type), + size_of_data_(debug.SizeOfData), + address_of_raw_data_(debug.AddressOfRawData), + pointer_to_raw_data_(debug.PointerToRawData), + advanced_info_type_(advanced_info_none) +{} + +//Returns debug characteristics +uint32_t debug_info::get_characteristics() const +{ + return characteristics_; +} + +//Returns debug datetimestamp +uint32_t debug_info::get_time_stamp() const +{ + return time_stamp_; +} + +//Returns major version +uint32_t debug_info::get_major_version() const +{ + return major_version_; +} + +//Returns minor version +uint32_t debug_info::get_minor_version() const +{ + return minor_version_; +} + +//Returns type of debug info (unchecked) +uint32_t debug_info::get_type_raw() const +{ + return type_; +} + +//Returns type of debug info from debug_info_type enumeration +debug_info::debug_info_type debug_info::get_type() const +{ + //Determine debug type + switch(type_) + { + case image_debug_type_coff: + return debug_type_coff; + + case image_debug_type_codeview: + return debug_type_codeview; + + case image_debug_type_fpo: + return debug_type_fpo; + + case image_debug_type_misc: + return debug_type_misc; + + case image_debug_type_exception: + return debug_type_exception; + + case image_debug_type_fixup: + return debug_type_fixup; + + case image_debug_type_omap_to_src: + return debug_type_omap_to_src; + + case image_debug_type_omap_from_src: + return debug_type_omap_from_src; + + case image_debug_type_borland: + return debug_type_borland; + + case image_debug_type_clsid: + return debug_type_clsid; + + case image_debug_type_reserved10: + return debug_type_reserved10; + } + + return debug_type_unknown; +} + +//Returns size of debug data (internal, .pdb or other file doesn't count) +uint32_t debug_info::get_size_of_data() const +{ + return size_of_data_; +} + +//Returns RVA of debug info when mapped to memory or zero, if info is not mapped +uint32_t debug_info::get_rva_of_raw_data() const +{ + return address_of_raw_data_; +} + +//Returns raw file pointer to raw data +uint32_t debug_info::get_pointer_to_raw_data() const +{ + return pointer_to_raw_data_; +} + +//Copy constructor +debug_info::debug_info(const debug_info& info) + :characteristics_(info.characteristics_), + time_stamp_(info.time_stamp_), + major_version_(info.major_version_), minor_version_(info.minor_version_), + type_(info.type_), + size_of_data_(info.size_of_data_), + address_of_raw_data_(info.address_of_raw_data_), + pointer_to_raw_data_(info.pointer_to_raw_data_), + advanced_info_type_(info.advanced_info_type_) +{ + copy_advanced_info(info); +} + +//Copy assignment operator +debug_info& debug_info::operator=(const debug_info& info) +{ + copy_advanced_info(info); + + characteristics_ = info.characteristics_; + time_stamp_ = info.time_stamp_; + major_version_ = info.major_version_; + minor_version_ = info.minor_version_; + type_ = info.type_; + size_of_data_ = info.size_of_data_; + address_of_raw_data_ = info.address_of_raw_data_; + pointer_to_raw_data_ = info.pointer_to_raw_data_; + advanced_info_type_ = info.advanced_info_type_; + + return *this; +} + +//Default constructor +debug_info::advanced_info::advanced_info() + :adv_pdb_7_0_info(0) //Zero pointer to advanced data +{} + +//Returns true if advanced debug info is present +bool debug_info::advanced_info::is_present() const +{ + return adv_pdb_7_0_info != 0; +} + +//Helper for advanced debug information copying +void debug_info::copy_advanced_info(const debug_info& info) +{ + free_present_advanced_info(); + + switch(info.advanced_info_type_) + { + case advanced_info_pdb_7_0: + advanced_debug_info_.adv_pdb_7_0_info = new pdb_7_0_info(*info.advanced_debug_info_.adv_pdb_7_0_info); + break; + case advanced_info_pdb_2_0: + advanced_debug_info_.adv_pdb_2_0_info = new pdb_2_0_info(*info.advanced_debug_info_.adv_pdb_2_0_info); + break; + case advanced_info_misc: + advanced_debug_info_.adv_misc_info = new misc_debug_info(*info.advanced_debug_info_.adv_misc_info); + break; + case advanced_info_coff: + advanced_debug_info_.adv_coff_info = new coff_debug_info(*info.advanced_debug_info_.adv_coff_info); + break; + default: + break; + } + + advanced_info_type_ = info.advanced_info_type_; +} + +//Helper for clearing any present advanced debug information +void debug_info::free_present_advanced_info() +{ + switch(advanced_info_type_) + { + case advanced_info_pdb_7_0: + delete advanced_debug_info_.adv_pdb_7_0_info; + break; + case advanced_info_pdb_2_0: + delete advanced_debug_info_.adv_pdb_2_0_info; + break; + case advanced_info_misc: + delete advanced_debug_info_.adv_misc_info; + break; + case advanced_info_coff: + delete advanced_debug_info_.adv_coff_info; + break; + default: + break; + } + + advanced_debug_info_.adv_pdb_7_0_info = 0; + advanced_info_type_ = advanced_info_none; +} + +//Destructor +debug_info::~debug_info() +{ + free_present_advanced_info(); +} + +//Sets advanced debug information +void debug_info::set_advanced_debug_info(const pdb_7_0_info& info) +{ + free_present_advanced_info(); + advanced_debug_info_.adv_pdb_7_0_info = new pdb_7_0_info(info); + advanced_info_type_ = advanced_info_pdb_7_0; +} + +void debug_info::set_advanced_debug_info(const pdb_2_0_info& info) +{ + free_present_advanced_info(); + advanced_debug_info_.adv_pdb_2_0_info = new pdb_2_0_info(info); + advanced_info_type_ = advanced_info_pdb_2_0; +} + +void debug_info::set_advanced_debug_info(const misc_debug_info& info) +{ + free_present_advanced_info(); + advanced_debug_info_.adv_misc_info = new misc_debug_info(info); + advanced_info_type_ = advanced_info_misc; +} + +void debug_info::set_advanced_debug_info(const coff_debug_info& info) +{ + free_present_advanced_info(); + advanced_debug_info_.adv_coff_info = new coff_debug_info(info); + advanced_info_type_ = advanced_info_coff; +} + +//Returns advanced debug information type +debug_info::advanced_info_type debug_info::get_advanced_info_type() const +{ + return advanced_info_type_; +} + +//Returns advanced debug information or throws an exception, +//if requested information type is not contained by structure +template<> +const pdb_7_0_info debug_info::get_advanced_debug_info<pdb_7_0_info>() const +{ + if(advanced_info_type_ != advanced_info_pdb_7_0) + throw pe_exception("Debug info structure does not contain PDB 7.0 data", pe_exception::advanced_debug_information_request_error); + + return *advanced_debug_info_.adv_pdb_7_0_info; +} + +template<> +const pdb_2_0_info debug_info::get_advanced_debug_info<pdb_2_0_info>() const +{ + if(advanced_info_type_ != advanced_info_pdb_2_0) + throw pe_exception("Debug info structure does not contain PDB 2.0 data", pe_exception::advanced_debug_information_request_error); + + return *advanced_debug_info_.adv_pdb_2_0_info; +} + +template<> +const misc_debug_info debug_info::get_advanced_debug_info<misc_debug_info>() const +{ + if(advanced_info_type_ != advanced_info_misc) + throw pe_exception("Debug info structure does not contain MISC data", pe_exception::advanced_debug_information_request_error); + + return *advanced_debug_info_.adv_misc_info; +} + +template<> +const coff_debug_info debug_info::get_advanced_debug_info<coff_debug_info>() const +{ + if(advanced_info_type_ != advanced_info_coff) + throw pe_exception("Debug info structure does not contain COFF data", pe_exception::advanced_debug_information_request_error); + + return *advanced_debug_info_.adv_coff_info; +} + +//Sets advanced debug information type, if no advanced info structure available +void debug_info::set_advanced_info_type(advanced_info_type type) +{ + free_present_advanced_info(); + if(advanced_info_type_ >= advanced_info_codeview_4_0) //Don't set info type for those types, which have advanced info structures + advanced_info_type_ = type; +} + +//Default constructor +pdb_7_0_info::pdb_7_0_info() + :age_(0) +{ + memset(&guid_, 0, sizeof(guid_)); +} + +//Constructor from data +pdb_7_0_info::pdb_7_0_info(const CV_INFO_PDB70* info) + :age_(info->Age), guid_(info->Signature), + pdb_file_name_(reinterpret_cast<const char*>(info->PdbFileName)) //Must be checked before for null-termination +{} + +//Returns debug PDB 7.0 structure GUID +const guid pdb_7_0_info::get_guid() const +{ + return guid_; +} + +//Returns age of build +uint32_t pdb_7_0_info::get_age() const +{ + return age_; +} + +//Returns PDB file name / path +const std::string& pdb_7_0_info::get_pdb_file_name() const +{ + return pdb_file_name_; +} + +//Default constructor +pdb_2_0_info::pdb_2_0_info() + :age_(0), signature_(0) +{} + +//Constructor from data +pdb_2_0_info::pdb_2_0_info(const CV_INFO_PDB20* info) + :age_(info->Age), signature_(info->Signature), + pdb_file_name_(reinterpret_cast<const char*>(info->PdbFileName)) //Must be checked before for null-termination +{} + +//Returns debug PDB 2.0 structure signature +uint32_t pdb_2_0_info::get_signature() const +{ + return signature_; +} + +//Returns age of build +uint32_t pdb_2_0_info::get_age() const +{ + return age_; +} + +//Returns PDB file name / path +const std::string& pdb_2_0_info::get_pdb_file_name() const +{ + return pdb_file_name_; +} + +//Default constructor +misc_debug_info::misc_debug_info() + :data_type_(0), unicode_(false) +{} + +//Constructor from data +misc_debug_info::misc_debug_info(const image_debug_misc* info) + :data_type_(info->DataType), unicode_(info->Unicode ? true : false) +{ + //IMAGE_DEBUG_MISC::Data must be checked before! + if(info->Unicode) + { +#ifdef PE_BLISS_WINDOWS + debug_data_unicode_ = std::wstring(reinterpret_cast<const wchar_t*>(info->Data), (info->Length - sizeof(image_debug_misc) + 1 /* BYTE[1] in the end of structure */) / 2); +#else + debug_data_unicode_ = pe_utils::from_ucs2(u16string(reinterpret_cast<const unicode16_t*>(info->Data), (info->Length - sizeof(image_debug_misc) + 1 /* BYTE[1] in the end of structure */) / 2)); +#endif + + pe_utils::strip_nullbytes(debug_data_unicode_); //Strip nullbytes in the end of string + } + else + { + debug_data_ansi_ = std::string(reinterpret_cast<const char*>(info->Data), info->Length - sizeof(image_debug_misc) + 1 /* BYTE[1] in the end of structure */); + pe_utils::strip_nullbytes(debug_data_ansi_); //Strip nullbytes in the end of string + } +} + +//Returns debug data type +uint32_t misc_debug_info::get_data_type() const +{ + return data_type_; +} + +//Returns true if data type is exe name +bool misc_debug_info::is_exe_name() const +{ + return data_type_ == image_debug_misc_exename; +} + +//Returns true if debug data is UNICODE +bool misc_debug_info::is_unicode() const +{ + return unicode_; +} + +//Returns debug data (ANSI) +const std::string& misc_debug_info::get_data_ansi() const +{ + return debug_data_ansi_; +} + +//Returns debug data (UNICODE) +const std::wstring& misc_debug_info::get_data_unicode() const +{ + return debug_data_unicode_; +} + +//Default constructor +coff_debug_info::coff_debug_info() + :number_of_symbols_(0), + lva_to_first_symbol_(0), + number_of_line_numbers_(0), + lva_to_first_line_number_(0), + rva_to_first_byte_of_code_(0), + rva_to_last_byte_of_code_(0), + rva_to_first_byte_of_data_(0), + rva_to_last_byte_of_data_(0) +{} + +//Constructor from data +coff_debug_info::coff_debug_info(const image_coff_symbols_header* info) + :number_of_symbols_(info->NumberOfSymbols), + lva_to_first_symbol_(info->LvaToFirstSymbol), + number_of_line_numbers_(info->NumberOfLinenumbers), + lva_to_first_line_number_(info->LvaToFirstLinenumber), + rva_to_first_byte_of_code_(info->RvaToFirstByteOfCode), + rva_to_last_byte_of_code_(info->RvaToLastByteOfCode), + rva_to_first_byte_of_data_(info->RvaToFirstByteOfData), + rva_to_last_byte_of_data_(info->RvaToLastByteOfData) +{} + +//Returns number of symbols +uint32_t coff_debug_info::get_number_of_symbols() const +{ + return number_of_symbols_; +} + +//Returns virtual address of the first symbol +uint32_t coff_debug_info::get_lva_to_first_symbol() const +{ + return lva_to_first_symbol_; +} + +//Returns number of line-number entries +uint32_t coff_debug_info::get_number_of_line_numbers() const +{ + return number_of_line_numbers_; +} + +//Returns virtual address of the first line-number entry +uint32_t coff_debug_info::get_lva_to_first_line_number() const +{ + return lva_to_first_line_number_; +} + +//Returns relative virtual address of the first byte of code +uint32_t coff_debug_info::get_rva_to_first_byte_of_code() const +{ + return rva_to_first_byte_of_code_; +} + +//Returns relative virtual address of the last byte of code +uint32_t coff_debug_info::get_rva_to_last_byte_of_code() const +{ + return rva_to_last_byte_of_code_; +} + +//Returns relative virtual address of the first byte of data +uint32_t coff_debug_info::get_rva_to_first_byte_of_data() const +{ + return rva_to_first_byte_of_data_; +} + +//Returns relative virtual address of the last byte of data +uint32_t coff_debug_info::get_rva_to_last_byte_of_data() const +{ + return rva_to_last_byte_of_data_; +} + +//Returns COFF symbols list +const coff_debug_info::coff_symbols_list& coff_debug_info::get_symbols() const +{ + return symbols_; +} + +//Adds COFF symbol +void coff_debug_info::add_symbol(const coff_symbol& sym) +{ + symbols_.push_back(sym); +} + +//Default constructor +coff_debug_info::coff_symbol::coff_symbol() + :storage_class_(0), + index_(0), + section_number_(0), rva_(0), + type_(0), + is_filename_(false) +{} + +//Returns storage class +uint32_t coff_debug_info::coff_symbol::get_storage_class() const +{ + return storage_class_; +} + +//Returns symbol index +uint32_t coff_debug_info::coff_symbol::get_index() const +{ + return index_; +} + +//Returns section number +uint32_t coff_debug_info::coff_symbol::get_section_number() const +{ + return section_number_; +} + +//Returns RVA +uint32_t coff_debug_info::coff_symbol::get_rva() const +{ + return rva_; +} + +//Returns true if structure contains file name +bool coff_debug_info::coff_symbol::is_file() const +{ + return is_filename_; +} + +//Returns text data (symbol or file name) +const std::string& coff_debug_info::coff_symbol::get_symbol() const +{ + return name_; +} + +//Sets storage class +void coff_debug_info::coff_symbol::set_storage_class(uint32_t storage_class) +{ + storage_class_ = storage_class; +} + +//Sets symbol index +void coff_debug_info::coff_symbol::set_index(uint32_t index) +{ + index_ = index; +} + +//Sets section number +void coff_debug_info::coff_symbol::set_section_number(uint32_t section_number) +{ + section_number_ = section_number; +} + +//Sets RVA +void coff_debug_info::coff_symbol::set_rva(uint32_t rva) +{ + rva_ = rva; +} + +//Sets file name +void coff_debug_info::coff_symbol::set_file_name(const std::string& file_name) +{ + name_ = file_name; + is_filename_ = true; +} + +//Sets symbol name +void coff_debug_info::coff_symbol::set_symbol_name(const std::string& symbol_name) +{ + name_ = symbol_name; + is_filename_ = false; +} + +//Returns type +uint16_t coff_debug_info::coff_symbol::get_type() const +{ + return type_; +} + +//Sets type +void coff_debug_info::coff_symbol::set_type(uint16_t type) +{ + type_ = type; +} + +//Returns debug information list +const debug_info_list get_debug_information(const pe_base& pe) +{ + debug_info_list ret; + + //If there's no debug directory, return empty list + if(!pe.has_debug()) + return ret; + + //Check the length in bytes of the section containing debug directory + if(pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_debug), pe.get_directory_rva(image_directory_entry_debug), section_data_virtual, true) + < sizeof(image_debug_directory)) + throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); + + unsigned long current_pos = pe.get_directory_rva(image_directory_entry_debug); + + //First IMAGE_DEBUG_DIRECTORY table + image_debug_directory directory = pe.section_data_from_rva<image_debug_directory>(current_pos, section_data_virtual, true); + + if(!pe_utils::is_sum_safe(pe.get_directory_rva(image_directory_entry_debug), pe.get_directory_size(image_directory_entry_debug))) + throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); + + //Iterate over all IMAGE_DEBUG_DIRECTORY directories + while(directory.PointerToRawData + && current_pos < pe.get_directory_rva(image_directory_entry_debug) + pe.get_directory_size(image_directory_entry_debug)) + { + //Create debug information structure + debug_info info(directory); + + //Find raw debug data + const pe_base::debug_data_list& debug_datas = pe.get_raw_debug_data_list(); + pe_base::debug_data_list::const_iterator it = debug_datas.find(directory.PointerToRawData); + if(it != debug_datas.end()) //If it exists, we'll do some detailed debug info research + { + const std::string& debug_data = (*it).second; + switch(directory.Type) + { + case image_debug_type_coff: + { + //Check data length + if(debug_data.length() < sizeof(image_coff_symbols_header)) + throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); + + //Get coff header structure pointer + const image_coff_symbols_header* coff = reinterpret_cast<const image_coff_symbols_header*>(debug_data.data()); + + //Check possible overflows + if(coff->NumberOfSymbols >= pe_utils::max_dword / sizeof(image_symbol) + || !pe_utils::is_sum_safe(coff->NumberOfSymbols * sizeof(image_symbol), coff->LvaToFirstSymbol)) + throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); + + //Check data length again + if(debug_data.length() < coff->NumberOfSymbols * sizeof(image_symbol) + coff->LvaToFirstSymbol) + throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); + + //Create COFF debug info structure + coff_debug_info coff_info(coff); + + //Enumerate debug symbols data + for(uint32_t i = 0; i < coff->NumberOfSymbols; ++i) + { + //Safe sum (checked above) + const image_symbol* sym = reinterpret_cast<const image_symbol*>(debug_data.data() + i * sizeof(image_symbol) + coff->LvaToFirstSymbol); + + coff_debug_info::coff_symbol symbol; + symbol.set_index(i); //Save symbol index + symbol.set_storage_class(sym->StorageClass); //Save storage class + symbol.set_type(sym->Type); //Save storage class + + //Check data length again + if(!pe_utils::is_sum_safe(i, sym->NumberOfAuxSymbols) + || (i + sym->NumberOfAuxSymbols) > coff->NumberOfSymbols + || debug_data.length() < (i + 1) * sizeof(image_symbol) + coff->LvaToFirstSymbol + sym->NumberOfAuxSymbols * sizeof(image_symbol)) + throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); + + //If symbol is filename + if(sym->StorageClass == image_sym_class_file) + { + //Save file name, it is situated just after this IMAGE_SYMBOL structure + std::string file_name(reinterpret_cast<const char*>(debug_data.data() + (i + 1) * sizeof(image_symbol)), sym->NumberOfAuxSymbols * sizeof(image_symbol)); + pe_utils::strip_nullbytes(file_name); + symbol.set_file_name(file_name); + + //Save symbol info + coff_info.add_symbol(symbol); + + //Move to next symbol + i += sym->NumberOfAuxSymbols; + continue; + } + + //Dump some other symbols + if(((sym->StorageClass == image_sym_class_static) + && (sym->NumberOfAuxSymbols == 0) + && (sym->SectionNumber == 1)) + || + ((sym->StorageClass == image_sym_class_external) + && ISFCN(sym->Type) + && (sym->SectionNumber > 0)) + ) + { + //Save RVA and section number + symbol.set_section_number(sym->SectionNumber); + symbol.set_rva(sym->Value); + + //If symbol has short name + if(sym->N.Name.Short) + { + //Copy and save symbol name + char name_buff[9]; + memcpy(name_buff, sym->N.ShortName, 8); + name_buff[8] = '\0'; + symbol.set_symbol_name(name_buff); + } + else + { + //Symbol has long name + + //Check possible overflows + if(!pe_utils::is_sum_safe(coff->LvaToFirstSymbol + coff->NumberOfSymbols * sizeof(image_symbol), sym->N.Name.Long)) + throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); + + //Here we have an offset to the string table + uint32_t symbol_offset = coff->LvaToFirstSymbol + coff->NumberOfSymbols * sizeof(image_symbol) + sym->N.Name.Long; + + //Check data length + if(debug_data.length() < symbol_offset) + throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); + + //Check symbol name for null-termination + if(!pe_utils::is_null_terminated(debug_data.data() + symbol_offset, debug_data.length() - symbol_offset)) + throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); + + //Save symbol name + symbol.set_symbol_name(debug_data.data() + symbol_offset); + } + + //Save symbol info + coff_info.add_symbol(symbol); + + //Move to next symbol + i += sym->NumberOfAuxSymbols; + continue; + } + } + + info.set_advanced_debug_info(coff_info); + } + break; + + case image_debug_type_codeview: + { + //Check data length + if(debug_data.length() < sizeof(OMFSignature*)) + throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); + + //Get POMFSignature structure pointer from the very beginning of debug data + const OMFSignature* sig = reinterpret_cast<const OMFSignature*>(debug_data.data()); + if(!memcmp(sig->Signature, "RSDS", 4)) + { + //Signature is "RSDS" - PDB 7.0 + + //Check data length + if(debug_data.length() < sizeof(CV_INFO_PDB70)) + throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); + + const CV_INFO_PDB70* pdb_data = reinterpret_cast<const CV_INFO_PDB70*>(debug_data.data()); + + //Check PDB file name null-termination + if(!pe_utils::is_null_terminated(pdb_data->PdbFileName, debug_data.length() - (sizeof(CV_INFO_PDB70) - 1 /* BYTE of filename in structure */))) + throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); + + info.set_advanced_debug_info(pdb_7_0_info(pdb_data)); + } + else if(!memcmp(sig->Signature, "NB10", 4)) + { + //Signature is "NB10" - PDB 2.0 + + //Check data length + if(debug_data.length() < sizeof(CV_INFO_PDB20)) + throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); + + const CV_INFO_PDB20* pdb_data = reinterpret_cast<const CV_INFO_PDB20*>(debug_data.data()); + + //Check PDB file name null-termination + if(!pe_utils::is_null_terminated(pdb_data->PdbFileName, debug_data.length() - (sizeof(CV_INFO_PDB20) - 1 /* BYTE of filename in structure */))) + throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); + + info.set_advanced_debug_info(pdb_2_0_info(pdb_data)); + } + else if(!memcmp(sig->Signature, "NB09", 4)) + { + //CodeView 4.0, no structures available + info.set_advanced_info_type(debug_info::advanced_info_codeview_4_0); + } + else if(!memcmp(sig->Signature, "NB11", 4)) + { + //CodeView 5.0, no structures available + info.set_advanced_info_type(debug_info::advanced_info_codeview_5_0); + } + else if(!memcmp(sig->Signature, "NB05", 4)) + { + //Other CodeView, no structures available + info.set_advanced_info_type(debug_info::advanced_info_codeview); + } + } + + break; + + case image_debug_type_misc: + { + //Check data length + if(debug_data.length() < sizeof(image_debug_misc)) + throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); + + //Get misc structure pointer + const image_debug_misc* misc_data = reinterpret_cast<const image_debug_misc*>(debug_data.data()); + + //Check misc data length + if(debug_data.length() < misc_data->Length /* Total length of record */) + throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); + + //Save advanced information + info.set_advanced_debug_info(misc_debug_info(misc_data)); + } + break; + } + } + + //Save debug information structure + ret.push_back(info); + + //Check possible overflow + if(!pe_utils::is_sum_safe(current_pos, sizeof(image_debug_directory))) + throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory); + + //Go to next debug entry + current_pos += sizeof(image_debug_directory); + directory = pe.section_data_from_rva<image_debug_directory>(current_pos, section_data_virtual, true); + } + + return ret; +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_debug.h b/irdb-lib/pebliss/trunk/pe_lib/pe_debug.h new file mode 100644 index 0000000000000000000000000000000000000000..2b0bf9d2a74dabd7e54fb08fce0b80ad571c52ed --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_debug.h @@ -0,0 +1,306 @@ +#ifndef pebliss_pe_debug_h +#define pebliss_pe_debug_h +#pragma once +#include <vector> +#include "pe_structures.h" +#include "pe_base.h" + +namespace pe_bliss +{ +//Class representing advanced RSDS (PDB 7.0) information +class pdb_7_0_info +{ +public: + //Default constructor + pdb_7_0_info(); + //Constructor from data + explicit pdb_7_0_info(const pe_win::CV_INFO_PDB70* info); + + //Returns debug PDB 7.0 structure GUID + const pe_win::guid get_guid() const; + //Returns age of build + uint32_t get_age() const; + //Returns PDB file name / path + const std::string& get_pdb_file_name() const; + +private: + uint32_t age_; + pe_win::guid guid_; + std::string pdb_file_name_; +}; + +//Class representing advanced NB10 (PDB 2.0) information +class pdb_2_0_info +{ +public: + //Default constructor + pdb_2_0_info(); + //Constructor from data + explicit pdb_2_0_info(const pe_win::CV_INFO_PDB20* info); + + //Returns debug PDB 2.0 structure signature + uint32_t get_signature() const; + //Returns age of build + uint32_t get_age() const; + //Returns PDB file name / path + const std::string& get_pdb_file_name() const; + +private: + uint32_t age_; + uint32_t signature_; + std::string pdb_file_name_; +}; + +//Class representing advanced misc (IMAGE_DEBUG_TYPE_MISC) info +class misc_debug_info +{ +public: + //Default constructor + misc_debug_info(); + //Constructor from data + explicit misc_debug_info(const pe_win::image_debug_misc* info); + + //Returns debug data type + uint32_t get_data_type() const; + //Returns true if data type is exe name + bool is_exe_name() const; + + //Returns true if debug data is UNICODE + bool is_unicode() const; + //Returns debug data (ANSI or UNICODE) + const std::string& get_data_ansi() const; + const std::wstring& get_data_unicode() const; + +private: + uint32_t data_type_; + bool unicode_; + std::string debug_data_ansi_; + std::wstring debug_data_unicode_; +}; + +//Class representing COFF (IMAGE_DEBUG_TYPE_COFF) debug info +class coff_debug_info +{ +public: + //Structure representing COFF symbol + struct coff_symbol + { + public: + //Default constructor + coff_symbol(); + + //Returns storage class + uint32_t get_storage_class() const; + //Returns symbol index + uint32_t get_index() const; + //Returns section number + uint32_t get_section_number() const; + //Returns RVA + uint32_t get_rva() const; + //Returns type + uint16_t get_type() const; + + //Returns true if structure contains file name + bool is_file() const; + //Returns text data (symbol or file name) + const std::string& get_symbol() const; + + public: //These functions do not change everything inside image, they are used by PE class + //Sets storage class + void set_storage_class(uint32_t storage_class); + //Sets symbol index + void set_index(uint32_t index); + //Sets section number + void set_section_number(uint32_t section_number); + //Sets RVA + void set_rva(uint32_t rva); + //Sets type + void set_type(uint16_t type); + + //Sets file name + void set_file_name(const std::string& file_name); + //Sets symbol name + void set_symbol_name(const std::string& symbol_name); + + private: + uint32_t storage_class_; + uint32_t index_; + uint32_t section_number_, rva_; + uint16_t type_; + bool is_filename_; + std::string name_; + }; + +public: + typedef std::vector<coff_symbol> coff_symbols_list; + +public: + //Default constructor + coff_debug_info(); + //Constructor from data + explicit coff_debug_info(const pe_win::image_coff_symbols_header* info); + + //Returns number of symbols + uint32_t get_number_of_symbols() const; + //Returns virtual address of the first symbol + uint32_t get_lva_to_first_symbol() const; + //Returns number of line-number entries + uint32_t get_number_of_line_numbers() const; + //Returns virtual address of the first line-number entry + uint32_t get_lva_to_first_line_number() const; + //Returns relative virtual address of the first byte of code + uint32_t get_rva_to_first_byte_of_code() const; + //Returns relative virtual address of the last byte of code + uint32_t get_rva_to_last_byte_of_code() const; + //Returns relative virtual address of the first byte of data + uint32_t get_rva_to_first_byte_of_data() const; + //Returns relative virtual address of the last byte of data + uint32_t get_rva_to_last_byte_of_data() const; + + //Returns COFF symbols list + const coff_symbols_list& get_symbols() const; + +public: //These functions do not change everything inside image, they are used by PE class + //Adds COFF symbol + void add_symbol(const coff_symbol& sym); + +private: + uint32_t number_of_symbols_; + uint32_t lva_to_first_symbol_; + uint32_t number_of_line_numbers_; + uint32_t lva_to_first_line_number_; + uint32_t rva_to_first_byte_of_code_; + uint32_t rva_to_last_byte_of_code_; + uint32_t rva_to_first_byte_of_data_; + uint32_t rva_to_last_byte_of_data_; + +private: + coff_symbols_list symbols_; +}; + +//Class representing debug information +class debug_info +{ +public: + //Enumeration of debug information types + enum debug_info_type + { + debug_type_unknown, + debug_type_coff, + debug_type_codeview, + debug_type_fpo, + debug_type_misc, + debug_type_exception, + debug_type_fixup, + debug_type_omap_to_src, + debug_type_omap_from_src, + debug_type_borland, + debug_type_reserved10, + debug_type_clsid + }; + +public: + //Enumeration of advanced debug information types + enum advanced_info_type + { + advanced_info_none, //No advanced info + advanced_info_pdb_7_0, //PDB 7.0 + advanced_info_pdb_2_0, //PDB 2.0 + advanced_info_misc, //MISC debug info + advanced_info_coff, //COFF debug info + //No advanced info structures available for types below + advanced_info_codeview_4_0, //CodeView 4.0 + advanced_info_codeview_5_0, //CodeView 5.0 + advanced_info_codeview //CodeView + }; + +public: + //Default constructor + debug_info(); + //Constructor from data + explicit debug_info(const pe_win::image_debug_directory& debug); + //Copy constructor + debug_info(const debug_info& info); + //Copy assignment operator + debug_info& operator=(const debug_info& info); + //Destructor + ~debug_info(); + + //Returns debug characteristics + uint32_t get_characteristics() const; + //Returns debug datetimestamp + uint32_t get_time_stamp() const; + //Returns major version + uint32_t get_major_version() const; + //Returns minor version + uint32_t get_minor_version() const; + //Returns type of debug info (unchecked) + uint32_t get_type_raw() const; + //Returns type of debug info from debug_info_type enumeration + debug_info_type get_type() const; + //Returns size of debug data (internal, .pdb or other file doesn't count) + uint32_t get_size_of_data() const; + //Returns RVA of debug info when mapped to memory or zero, if info is not mapped + uint32_t get_rva_of_raw_data() const; + //Returns raw file pointer to raw data + uint32_t get_pointer_to_raw_data() const; + + //Returns advanced debug information type + advanced_info_type get_advanced_info_type() const; + //Returns advanced debug information or throws an exception, + //if requested information type is not contained by structure + template<typename AdvancedInfo> + const AdvancedInfo get_advanced_debug_info() const; + +public: //These functions do not change everything inside image, they are used by PE class + //Sets advanced debug information + void set_advanced_debug_info(const pdb_7_0_info& info); + void set_advanced_debug_info(const pdb_2_0_info& info); + void set_advanced_debug_info(const misc_debug_info& info); + void set_advanced_debug_info(const coff_debug_info& info); + + //Sets advanced debug information type, if no advanced info structure available + void set_advanced_info_type(advanced_info_type type); + +private: + uint32_t characteristics_; + uint32_t time_stamp_; + uint32_t major_version_, minor_version_; + uint32_t type_; + uint32_t size_of_data_; + uint32_t address_of_raw_data_; //RVA when mapped or 0 + uint32_t pointer_to_raw_data_; //RAW file offset + + //Union containing advanced debug information pointer + union advanced_info + { + public: + //Default constructor + advanced_info(); + + //Returns true if advanced debug info is present + bool is_present() const; + + public: + pdb_7_0_info* adv_pdb_7_0_info; + pdb_2_0_info* adv_pdb_2_0_info; + misc_debug_info* adv_misc_info; + coff_debug_info* adv_coff_info; + }; + + //Helper for advanced debug information copying + void copy_advanced_info(const debug_info& info); + //Helper for clearing any present advanced debug information + void free_present_advanced_info(); + + advanced_info advanced_debug_info_; + //Advanced information type + advanced_info_type advanced_info_type_; +}; + +typedef std::vector<debug_info> debug_info_list; + +//Returns debug information list +const debug_info_list get_debug_information(const pe_base& pe); +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_directory.cpp b/irdb-lib/pebliss/trunk/pe_lib/pe_directory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..57ea2212a62989fd3503b5986834d609bd9da870 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_directory.cpp @@ -0,0 +1,38 @@ +#include "pe_directory.h" + +namespace pe_bliss +{ +//Default constructor +image_directory::image_directory() + :rva_(0), size_(0) +{} + +//Constructor from data +image_directory::image_directory(uint32_t rva, uint32_t size) + :rva_(rva), size_(size) +{} + +//Returns RVA +uint32_t image_directory::get_rva() const +{ + return rva_; +} + +//Returns size +uint32_t image_directory::get_size() const +{ + return size_; +} + +//Sets RVA +void image_directory::set_rva(uint32_t rva) +{ + rva_ = rva; +} + +//Sets size +void image_directory::set_size(uint32_t size) +{ + size_ = size; +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_directory.h b/irdb-lib/pebliss/trunk/pe_lib/pe_directory.h new file mode 100644 index 0000000000000000000000000000000000000000..4ec4d68c7300babad4b54a1c5a27876b312aa1cc --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_directory.h @@ -0,0 +1,36 @@ +#ifndef pebliss_pe_directory_h +#define pebliss_pe_directory_h +#pragma once +#ifndef pedir_h +#define pedir_h + +#include "stdint_defs.h" + +namespace pe_bliss +{ +//Class representing image directory data +class image_directory +{ +public: + //Default constructor + image_directory(); + //Constructor from data + image_directory(uint32_t rva, uint32_t size); + + //Returns RVA + uint32_t get_rva() const; + //Returns size + uint32_t get_size() const; + + //Sets RVA + void set_rva(uint32_t rva); + //Sets size + void set_size(uint32_t size); + +private: + uint32_t rva_; + uint32_t size_; +}; +} +#endif +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_dotnet.cpp b/irdb-lib/pebliss/trunk/pe_lib/pe_dotnet.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5d9e483e3ffc413596001abd955ffa0459f3c846 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_dotnet.cpp @@ -0,0 +1,165 @@ +#include <string.h> +#include "pe_dotnet.h" + +namespace pe_bliss +{ +using namespace pe_win; + +//.NET +basic_dotnet_info::basic_dotnet_info() +{ + memset(&header_, 0, sizeof(header_)); +} + +//Constructor from data +basic_dotnet_info::basic_dotnet_info(const image_cor20_header& header) + :header_(header) +{} + +//Returns major runtime version +uint16_t basic_dotnet_info::get_major_runtime_version() const +{ + return header_.MajorRuntimeVersion; +} + +//Returns minor runtime version +uint16_t basic_dotnet_info::get_minor_runtime_version() const +{ + return header_.MinorRuntimeVersion; +} + +//Returns RVA of metadata (symbol table and startup information) +uint32_t basic_dotnet_info::get_rva_of_metadata() const +{ + return header_.MetaData.VirtualAddress; +} + +//Returns size of metadata (symbol table and startup information) +uint32_t basic_dotnet_info::get_size_of_metadata() const +{ + return header_.MetaData.Size; +} + +//Returns flags +uint32_t basic_dotnet_info::get_flags() const +{ + return header_.Flags; +} + +//Returns true if entry point is native +bool basic_dotnet_info::is_native_entry_point() const +{ + return (header_.Flags & comimage_flags_native_entrypoint) ? true : false; +} + +//Returns true if 32 bit required +bool basic_dotnet_info::is_32bit_required() const +{ + return (header_.Flags & comimage_flags_32bitrequired) ? true : false; +} + +//Returns true if image is IL library +bool basic_dotnet_info::is_il_library() const +{ + return (header_.Flags & comimage_flags_il_library) ? true : false; +} + +//Returns true if image uses IL only +bool basic_dotnet_info::is_il_only() const +{ + return (header_.Flags & comimage_flags_ilonly) ? true : false; +} + +//Returns entry point RVA (if entry point is native) +//Returns entry point managed token (if entry point is managed) +uint32_t basic_dotnet_info::get_entry_point_rva_or_token() const +{ + return header_.EntryPointToken; +} + +//Returns RVA of managed resources +uint32_t basic_dotnet_info::get_rva_of_resources() const +{ + return header_.Resources.VirtualAddress; +} + +//Returns size of managed resources +uint32_t basic_dotnet_info::get_size_of_resources() const +{ + return header_.Resources.Size; +} + +//Returns RVA of strong name signature +uint32_t basic_dotnet_info::get_rva_of_strong_name_signature() const +{ + return header_.StrongNameSignature.VirtualAddress; +} + +//Returns size of strong name signature +uint32_t basic_dotnet_info::get_size_of_strong_name_signature() const +{ + return header_.StrongNameSignature.Size; +} + +//Returns RVA of code manager table +uint32_t basic_dotnet_info::get_rva_of_code_manager_table() const +{ + return header_.CodeManagerTable.VirtualAddress; +} + +//Returns size of code manager table +uint32_t basic_dotnet_info::get_size_of_code_manager_table() const +{ + return header_.CodeManagerTable.Size; +} + +//Returns RVA of VTable fixups +uint32_t basic_dotnet_info::get_rva_of_vtable_fixups() const +{ + return header_.VTableFixups.VirtualAddress; +} + +//Returns size of VTable fixups +uint32_t basic_dotnet_info::get_size_of_vtable_fixups() const +{ + return header_.VTableFixups.Size; +} + +//Returns RVA of export address table jumps +uint32_t basic_dotnet_info::get_rva_of_export_address_table_jumps() const +{ + return header_.ExportAddressTableJumps.VirtualAddress; +} + +//Returns size of export address table jumps +uint32_t basic_dotnet_info::get_size_of_export_address_table_jumps() const +{ + return header_.ExportAddressTableJumps.Size; +} + +//Returns RVA of managed native header +//(precompiled header info, usually set to zero, for internal use) +uint32_t basic_dotnet_info::get_rva_of_managed_native_header() const +{ + return header_.ManagedNativeHeader.VirtualAddress; +} + +//Returns size of managed native header +//(precompiled header info, usually set to zero, for internal use) +uint32_t basic_dotnet_info::get_size_of_managed_native_header() const +{ + return header_.ManagedNativeHeader.Size; +} + +//Returns basic .NET information +//If image is not native, throws an exception +const basic_dotnet_info get_basic_dotnet_info(const pe_base& pe) +{ + //If there's no debug directory, return empty list + if(!pe.is_dotnet()) + throw pe_exception("Image does not have managed code", pe_exception::image_does_not_have_managed_code); + + //Return basic .NET information + return basic_dotnet_info(pe.section_data_from_rva<image_cor20_header>(pe.get_directory_rva(image_directory_entry_com_descriptor), section_data_virtual, true)); +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_dotnet.h b/irdb-lib/pebliss/trunk/pe_lib/pe_dotnet.h new file mode 100644 index 0000000000000000000000000000000000000000..615be9daff4cdb66fb7f0f9a50ef8c81961130db --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_dotnet.h @@ -0,0 +1,79 @@ +#ifndef pebliss_pe_dotnet_h +#define pebliss_pe_dotnet_h +#pragma once +#include "pe_structures.h" +#include "pe_base.h" + +namespace pe_bliss +{ +//Class representing basic .NET header information +class basic_dotnet_info +{ +public: + //Default constructor + basic_dotnet_info(); + //Constructor from data + explicit basic_dotnet_info(const pe_win::image_cor20_header& header); + + //Returns major runtime version + uint16_t get_major_runtime_version() const; + //Returns minor runtime version + uint16_t get_minor_runtime_version() const; + + //Returns RVA of metadata (symbol table and startup information) + uint32_t get_rva_of_metadata() const; + //Returns size of metadata (symbol table and startup information) + uint32_t get_size_of_metadata() const; + + //Returns flags + uint32_t get_flags() const; + + //Returns true if entry point is native + bool is_native_entry_point() const; + //Returns true if 32 bit required + bool is_32bit_required() const; + //Returns true if image is IL library + bool is_il_library() const; + //Returns true if image uses IL only + bool is_il_only() const; + + //Returns entry point RVA (if entry point is native) + //Returns entry point managed token (if entry point is managed) + uint32_t get_entry_point_rva_or_token() const; + + //Returns RVA of managed resources + uint32_t get_rva_of_resources() const; + //Returns size of managed resources + uint32_t get_size_of_resources() const; + //Returns RVA of strong name signature + uint32_t get_rva_of_strong_name_signature() const; + //Returns size of strong name signature + uint32_t get_size_of_strong_name_signature() const; + //Returns RVA of code manager table + uint32_t get_rva_of_code_manager_table() const; + //Returns size of code manager table + uint32_t get_size_of_code_manager_table() const; + //Returns RVA of VTable fixups + uint32_t get_rva_of_vtable_fixups() const; + //Returns size of VTable fixups + uint32_t get_size_of_vtable_fixups() const; + //Returns RVA of export address table jumps + uint32_t get_rva_of_export_address_table_jumps() const; + //Returns size of export address table jumps + uint32_t get_size_of_export_address_table_jumps() const; + //Returns RVA of managed native header + //(precompiled header info, usually set to zero, for internal use) + uint32_t get_rva_of_managed_native_header() const; + //Returns size of managed native header + //(precompiled header info, usually set to zero, for internal use) + uint32_t get_size_of_managed_native_header() const; + +private: + pe_win::image_cor20_header header_; +}; + +//Returns basic .NET information +//If image is not native, throws an exception +const basic_dotnet_info get_basic_dotnet_info(const pe_base& pe); +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_exception.cpp b/irdb-lib/pebliss/trunk/pe_lib/pe_exception.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0292f8064cb2ab76daf382c63b015202d19d2aad --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_exception.cpp @@ -0,0 +1,20 @@ +#include "pe_exception.h" +#include <string> + +namespace pe_bliss +{ +//PE exception class constructors +pe_exception::pe_exception(const char* text, exception_id id) + :std::runtime_error((std::string)text), id_(id) +{} + +pe_exception::pe_exception(const std::string& text, exception_id id) + :std::runtime_error(text), id_(id) +{} + +//Returns exception ID +pe_exception::exception_id pe_exception::get_id() const +{ + return id_; +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_exception.h b/irdb-lib/pebliss/trunk/pe_lib/pe_exception.h new file mode 100644 index 0000000000000000000000000000000000000000..c06a7a0d1388d289bee6df3ea27a54cab6d705d6 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_exception.h @@ -0,0 +1,115 @@ +#ifndef pebliss_pe_exception_h +#define pebliss_pe_exception_h +#pragma once +#ifndef pebliss_peexception_h +#define pebliss_peexception_h +#include <exception> +#include <stdexcept> + +namespace pe_bliss +{ +//PE exception class +class pe_exception : public std::runtime_error +{ +public: + //Exception IDs + enum exception_id + { + unknown_error, + bad_pe_file, + bad_dos_header, + image_nt_headers_not_found, + error_reading_image_nt_headers, + error_reading_data_directories, + error_reading_file, + pe_signature_incorrect, + incorrect_number_of_rva_and_sizes, + error_changing_section_virtual_size, + section_number_incorrect, + section_table_incorrect, + incorrect_section_alignment, + incorrect_file_alignment, + incorrect_size_of_image, + incorrect_size_of_headers, + image_section_headers_not_found, + zero_section_sizes, + section_incorrect_addr_or_size, + section_not_found, + image_section_data_not_found, + no_section_found, + image_section_table_incorrect, + directory_does_not_exist, + rva_not_exists, + error_reading_section_header, + error_reading_overlay, + incorrect_address_conversion, + + incorrect_export_directory, + incorrect_import_directory, + incorrect_relocation_directory, + incorrect_tls_directory, + incorrect_config_directory, + incorrect_bound_import_directory, + incorrect_resource_directory, + incorrect_exception_directory, + incorrect_debug_directory, + + resource_directory_entry_error, + resource_directory_entry_not_found, + resource_data_entry_not_found, + resource_incorrect_bitmap, + resource_incorrect_icon, + resource_incorrect_cursor, + resource_incorrect_string_table, + resource_string_not_found, + resource_incorrect_message_table, + resource_incorrect_version_info, + + advanced_debug_information_request_error, + image_does_not_have_managed_code, + + section_is_empty, + data_is_empty, + stream_is_bad, + + section_is_not_attached, + insufficient_space, + + cannot_rebase_relocations, + + exports_list_is_empty, + duplicate_exported_function_ordinal, + duplicate_exported_function_name, + + version_info_string_does_not_exist, + + no_more_sections_can_be_added, + + no_icon_group_found, + no_cursor_group_found, + + encoding_convertion_error, + + error_expanding_section, + + cannot_rebuild_image + }; + +public: + //Class constructors + explicit pe_exception(const char* text, exception_id id = unknown_error); + explicit pe_exception(const std::string& text, exception_id id = unknown_error); + + //Returns exception ID from exception_id enumeration + exception_id get_id() const; + + //Destructor + virtual ~pe_exception() throw() + {} + +private: + exception_id id_; +}; +} +#endif +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_exception_directory.cpp b/irdb-lib/pebliss/trunk/pe_lib/pe_exception_directory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3447e5bd7a53292db4582e93f7dfc505b92e9cb5 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_exception_directory.cpp @@ -0,0 +1,156 @@ +#include "pe_exception_directory.h" + +namespace pe_bliss +{ +using namespace pe_win; + +//EXCEPTION DIRECTORY (exists on PE+ only) +//Default constructor +exception_entry::exception_entry() + :begin_address_(0), end_address_(0), unwind_info_address_(0), + unwind_info_version_(0), + flags_(0), + size_of_prolog_(0), + count_of_codes_(0), + frame_register_(0), + frame_offset_(0) +{} + +//Constructor from data +exception_entry::exception_entry(const image_runtime_function_entry& entry, const unwind_info& unwind_info) + :begin_address_(entry.BeginAddress), end_address_(entry.EndAddress), unwind_info_address_(entry.UnwindInfoAddress), + unwind_info_version_(unwind_info.Version), + flags_(unwind_info.Flags), + size_of_prolog_(unwind_info.SizeOfProlog), + count_of_codes_(unwind_info.CountOfCodes), + frame_register_(unwind_info.FrameRegister), + frame_offset_(unwind_info.FrameOffset) +{} + +//Returns starting address of function, affected by exception unwinding +uint32_t exception_entry::get_begin_address() const +{ + return begin_address_; +} + +//Returns ending address of function, affected by exception unwinding +uint32_t exception_entry::get_end_address() const +{ + return end_address_; +} + +//Returns unwind info address +uint32_t exception_entry::get_unwind_info_address() const +{ + return unwind_info_address_; +} + +//Returns UNWIND_INFO structure version +uint8_t exception_entry::get_unwind_info_version() const +{ + return unwind_info_version_; +} + +//Returns unwind info flags +uint8_t exception_entry::get_flags() const +{ + return flags_; +} + +//The function has an exception handler that should be called +//when looking for functions that need to examine exceptions +bool exception_entry::has_exception_handler() const +{ + return (flags_ & unw_flag_ehandler) ? true : false; +} + +//The function has a termination handler that should be called +//when unwinding an exception +bool exception_entry::has_termination_handler() const +{ + return (flags_ & unw_flag_uhandler) ? true : false; +} + +//The unwind info structure is not the primary one for the procedure +bool exception_entry::is_chaininfo() const +{ + return (flags_ & unw_flag_chaininfo) ? true : false; +} + +//Returns size of function prolog +uint8_t exception_entry::get_size_of_prolog() const +{ + return size_of_prolog_; +} + +//Returns number of unwind slots +uint8_t exception_entry::get_number_of_unwind_slots() const +{ + return count_of_codes_; +} + +//If the function uses frame pointer +bool exception_entry::uses_frame_pointer() const +{ + return frame_register_ != 0; +} + +//Number of the nonvolatile register used as the frame pointer, +//using the same encoding for the operation info field of UNWIND_CODE nodes +uint8_t exception_entry::get_frame_pointer_register_number() const +{ + return frame_register_; +} + +//The scaled offset from RSP that is applied to the FP reg when it is established. +//The actual FP reg is set to RSP + 16 * this number, allowing offsets from 0 to 240 +uint8_t exception_entry::get_scaled_rsp_offset() const +{ + return frame_offset_; +} + +//Returns exception directory data (exists on PE+ only) +//Unwind opcodes are not listed, because their format and list are subject to change +const exception_entry_list get_exception_directory_data(const pe_base& pe) +{ + exception_entry_list ret; + + //If image doesn't have exception directory, return empty list + if(!pe.has_exception_directory()) + return ret; + + //Check the length in bytes of the section containing exception directory + if(pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_exception), pe.get_directory_rva(image_directory_entry_exception), section_data_virtual, true) + < sizeof(image_runtime_function_entry)) + throw pe_exception("Incorrect exception directory", pe_exception::incorrect_exception_directory); + + unsigned long current_pos = pe.get_directory_rva(image_directory_entry_exception); + + //Check if structures are DWORD-aligned + if(current_pos % sizeof(uint32_t)) + throw pe_exception("Incorrect exception directory", pe_exception::incorrect_exception_directory); + + //First IMAGE_RUNTIME_FUNCTION_ENTRY table + image_runtime_function_entry exception_table = pe.section_data_from_rva<image_runtime_function_entry>(current_pos, section_data_virtual, true); + + //todo: virtual addresses BeginAddress and EndAddress are not checked to be inside image + while(exception_table.BeginAddress) + { + //Check addresses + if(exception_table.BeginAddress > exception_table.EndAddress) + throw pe_exception("Incorrect exception directory", pe_exception::incorrect_exception_directory); + + //Get unwind information + unwind_info info = pe.section_data_from_rva<unwind_info>(exception_table.UnwindInfoAddress, section_data_virtual, true); + + //Create exception entry and save it + ret.push_back(exception_entry(exception_table, info)); + + //Go to next exception entry + current_pos += sizeof(image_runtime_function_entry); + exception_table = pe.section_data_from_rva<image_runtime_function_entry>(current_pos, section_data_virtual, true); + } + + return ret; +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_exception_directory.h b/irdb-lib/pebliss/trunk/pe_lib/pe_exception_directory.h new file mode 100644 index 0000000000000000000000000000000000000000..c38dfae0ac221ece63e159a498c2f1dffbfcae30 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_exception_directory.h @@ -0,0 +1,70 @@ +#ifndef pebliss_pe_exception_directory_h +#define pebliss_pe_exception_directory_h +#pragma once +#include <vector> +#include "pe_structures.h" +#include "pe_base.h" + +namespace pe_bliss +{ +//Class representing exception directory entry +class exception_entry +{ +public: + //Default constructor + exception_entry(); + //Constructor from data + exception_entry(const pe_win::image_runtime_function_entry& entry, const pe_win::unwind_info& unwind_info); + + //Returns starting address of function, affected by exception unwinding + uint32_t get_begin_address() const; + //Returns ending address of function, affected by exception unwinding + uint32_t get_end_address() const; + //Returns unwind info address + uint32_t get_unwind_info_address() const; + + //Returns UNWIND_INFO structure version + uint8_t get_unwind_info_version() const; + + //Returns unwind info flags + uint8_t get_flags() const; + //The function has an exception handler that should be called + //when looking for functions that need to examine exceptions + bool has_exception_handler() const; + //The function has a termination handler that should be called + //when unwinding an exception + bool has_termination_handler() const; + //The unwind info structure is not the primary one for the procedure + bool is_chaininfo() const; + + //Returns size of function prolog + uint8_t get_size_of_prolog() const; + + //Returns number of unwind slots + uint8_t get_number_of_unwind_slots() const; + + //If the function uses frame pointer + bool uses_frame_pointer() const; + //Number of the nonvolatile register used as the frame pointer, + //using the same encoding for the operation info field of UNWIND_CODE nodes + uint8_t get_frame_pointer_register_number() const; + //The scaled offset from RSP that is applied to the FP reg when it is established. + //The actual FP reg is set to RSP + 16 * this number, allowing offsets from 0 to 240 + uint8_t get_scaled_rsp_offset() const; + +private: + uint32_t begin_address_, end_address_, unwind_info_address_; + uint8_t unwind_info_version_; + uint8_t flags_; + uint8_t size_of_prolog_; + uint8_t count_of_codes_; + uint8_t frame_register_, frame_offset_; +}; + +typedef std::vector<exception_entry> exception_entry_list; + +//Returns exception directory data (exists on PE+ only) +//Unwind opcodes are not listed, because their format and list are subject to change +const exception_entry_list get_exception_directory_data(const pe_base& pe); +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_exports.cpp b/irdb-lib/pebliss/trunk/pe_lib/pe_exports.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4a1bc1d82ff5c52ac4b9b12dda731b5895843e11 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_exports.cpp @@ -0,0 +1,679 @@ +#include <set> +#include <algorithm> +#include <string.h> +#include "pe_exports.h" +#include "utils.h" + +namespace pe_bliss +{ +using namespace pe_win; + +//EXPORTS +//Default constructor +exported_function::exported_function() + :ordinal_(0), rva_(0), has_name_(false), name_ordinal_(0), forward_(false) +{} + +//Returns ordinal of function (actually, ordinal = hint + ordinal base) +uint16_t exported_function::get_ordinal() const +{ + return ordinal_; +} + +//Returns RVA of function +uint32_t exported_function::get_rva() const +{ + return rva_; +} + +//Returns name of function +const std::string& exported_function::get_name() const +{ + return name_; +} + +//Returns true if function has name and name ordinal +bool exported_function::has_name() const +{ + return has_name_; +} + +//Returns name ordinal of function +uint16_t exported_function::get_name_ordinal() const +{ + return name_ordinal_; +} + +//Returns true if function is forwarded to other library +bool exported_function::is_forwarded() const +{ + return forward_; +} + +//Returns the name of forwarded function +const std::string& exported_function::get_forwarded_name() const +{ + return forward_name_; +} + +//Sets ordinal of function +void exported_function::set_ordinal(uint16_t ordinal) +{ + ordinal_ = ordinal; +} + +//Sets RVA of function +void exported_function::set_rva(uint32_t rva) +{ + rva_ = rva; +} + +//Sets name of function (or clears it, if empty name is passed) +void exported_function::set_name(const std::string& name) +{ + name_ = name; + has_name_ = !name.empty(); +} + +//Sets name ordinal +void exported_function::set_name_ordinal(uint16_t name_ordinal) +{ + name_ordinal_ = name_ordinal; +} + +//Sets forwarded function name (or clears it, if empty name is passed) +void exported_function::set_forwarded_name(const std::string& name) +{ + forward_name_ = name; + forward_ = !name.empty(); +} + +//Default constructor +export_info::export_info() + :characteristics_(0), + timestamp_(0), + major_version_(0), + minor_version_(0), + ordinal_base_(0), + number_of_functions_(0), + number_of_names_(0), + address_of_functions_(0), + address_of_names_(0), + address_of_name_ordinals_(0) +{} + +//Returns characteristics +uint32_t export_info::get_characteristics() const +{ + return characteristics_; +} + +//Returns timestamp +uint32_t export_info::get_timestamp() const +{ + return timestamp_; +} + +//Returns major version +uint16_t export_info::get_major_version() const +{ + return major_version_; +} + +//Returns minor version +uint16_t export_info::get_minor_version() const +{ + return minor_version_; +} + +//Returns DLL name +const std::string& export_info::get_name() const +{ + return name_; +} + +//Returns ordinal base +uint32_t export_info::get_ordinal_base() const +{ + return ordinal_base_; +} + +//Returns number of functions +uint32_t export_info::get_number_of_functions() const +{ + return number_of_functions_; +} + +//Returns number of function names +uint32_t export_info::get_number_of_names() const +{ + return number_of_names_; +} + +//Returns RVA of function address table +uint32_t export_info::get_rva_of_functions() const +{ + return address_of_functions_; +} + +//Returns RVA of function name address table +uint32_t export_info::get_rva_of_names() const +{ + return address_of_names_; +} + +//Returns RVA of name ordinals table +uint32_t export_info::get_rva_of_name_ordinals() const +{ + return address_of_name_ordinals_; +} + +//Sets characteristics +void export_info::set_characteristics(uint32_t characteristics) +{ + characteristics_ = characteristics; +} + +//Sets timestamp +void export_info::set_timestamp(uint32_t timestamp) +{ + timestamp_ = timestamp; +} + +//Sets major version +void export_info::set_major_version(uint16_t major_version) +{ + major_version_ = major_version; +} + +//Sets minor version +void export_info::set_minor_version(uint16_t minor_version) +{ + minor_version_ = minor_version; +} + +//Sets DLL name +void export_info::set_name(const std::string& name) +{ + name_ = name; +} + +//Sets ordinal base +void export_info::set_ordinal_base(uint32_t ordinal_base) +{ + ordinal_base_ = ordinal_base; +} + +//Sets number of functions +void export_info::set_number_of_functions(uint32_t number_of_functions) +{ + number_of_functions_ = number_of_functions; +} + +//Sets number of function names +void export_info::set_number_of_names(uint32_t number_of_names) +{ + number_of_names_ = number_of_names; +} + +//Sets RVA of function address table +void export_info::set_rva_of_functions(uint32_t rva_of_functions) +{ + address_of_functions_ = rva_of_functions; +} + +//Sets RVA of function name address table +void export_info::set_rva_of_names(uint32_t rva_of_names) +{ + address_of_names_ = rva_of_names; +} + +//Sets RVA of name ordinals table +void export_info::set_rva_of_name_ordinals(uint32_t rva_of_name_ordinals) +{ + address_of_name_ordinals_ = rva_of_name_ordinals; +} + +const exported_functions_list get_exported_functions(const pe_base& pe, export_info* info); + +//Returns array of exported functions +const exported_functions_list get_exported_functions(const pe_base& pe) +{ + return get_exported_functions(pe, 0); +} + +//Returns array of exported functions and information about export +const exported_functions_list get_exported_functions(const pe_base& pe, export_info& info) +{ + return get_exported_functions(pe, &info); +} + +//Helper: sorts exported function list by ordinals +struct ordinal_sorter +{ +public: + bool operator()(const exported_function& func1, const exported_function& func2) const; +}; + +//Returns array of exported functions and information about export (if info != 0) +const exported_functions_list get_exported_functions(const pe_base& pe, export_info* info) +{ + //Returned exported functions info array + std::vector<exported_function> ret; + + if(pe.has_exports()) + { + //Check the length in bytes of the section containing export directory + if(pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_export), + pe.get_directory_rva(image_directory_entry_export), section_data_virtual, true) + < sizeof(image_export_directory)) + throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory); + + image_export_directory exports = pe.section_data_from_rva<image_export_directory>(pe.get_directory_rva(image_directory_entry_export), section_data_virtual, true); + + unsigned long max_name_length; + + if(info) + { + //Save some export info data + info->set_characteristics(exports.Characteristics); + info->set_major_version(exports.MajorVersion); + info->set_minor_version(exports.MinorVersion); + + //Get byte count that we have for dll name + if((max_name_length = pe.section_data_length_from_rva(exports.Name, exports.Name, section_data_virtual, true)) < 2) + throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory); + + //Get dll name pointer + const char* dll_name = pe.section_data_from_rva(exports.Name, section_data_virtual, true); + + //Check for null-termination + if(!pe_utils::is_null_terminated(dll_name, max_name_length)) + throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory); + + //Save the rest of export information data + info->set_name(dll_name); + info->set_number_of_functions(exports.NumberOfFunctions); + info->set_number_of_names(exports.NumberOfNames); + info->set_ordinal_base(exports.Base); + info->set_rva_of_functions(exports.AddressOfFunctions); + info->set_rva_of_names(exports.AddressOfNames); + info->set_rva_of_name_ordinals(exports.AddressOfNameOrdinals); + info->set_timestamp(exports.TimeDateStamp); + } + + if(!exports.NumberOfFunctions) + return ret; + + //Check IMAGE_EXPORT_DIRECTORY fields + if(exports.NumberOfNames > exports.NumberOfFunctions) + throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory); + + //Check some export directory fields + if((!exports.AddressOfNameOrdinals && exports.AddressOfNames) || + (exports.AddressOfNameOrdinals && !exports.AddressOfNames) || + !exports.AddressOfFunctions + || exports.NumberOfFunctions >= pe_utils::max_dword / sizeof(uint32_t) + || exports.NumberOfNames > pe_utils::max_dword / sizeof(uint32_t) + || !pe_utils::is_sum_safe(exports.AddressOfFunctions, exports.NumberOfFunctions * sizeof(uint32_t)) + || !pe_utils::is_sum_safe(exports.AddressOfNames, exports.NumberOfNames * sizeof(uint32_t)) + || !pe_utils::is_sum_safe(exports.AddressOfNameOrdinals, exports.NumberOfFunctions * sizeof(uint32_t)) + || !pe_utils::is_sum_safe(pe.get_directory_rva(image_directory_entry_export), pe.get_directory_size(image_directory_entry_export))) + throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory); + + //Check if it is enough bytes to hold AddressOfFunctions table + if(pe.section_data_length_from_rva(exports.AddressOfFunctions, exports.AddressOfFunctions, section_data_virtual, true) + < exports.NumberOfFunctions * sizeof(uint32_t)) + throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory); + + if(exports.AddressOfNames) + { + //Check if it is enough bytes to hold name and ordinal tables + if(pe.section_data_length_from_rva(exports.AddressOfNameOrdinals, exports.AddressOfNameOrdinals, section_data_virtual, true) + < exports.NumberOfNames * sizeof(uint16_t)) + throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory); + + if(pe.section_data_length_from_rva(exports.AddressOfNames, exports.AddressOfNames, section_data_virtual, true) + < exports.NumberOfNames * sizeof(uint32_t)) + throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory); + } + + for(uint32_t ordinal = 0; ordinal < exports.NumberOfFunctions; ordinal++) + { + //Get function address + //Sum and multiplication are safe (checked above) + uint32_t rva = pe.section_data_from_rva<uint32_t>(exports.AddressOfFunctions + ordinal * sizeof(uint32_t), section_data_virtual, true); + + //If we have a skip + if(!rva) + continue; + + exported_function func; + func.set_rva(rva); + + if(!pe_utils::is_sum_safe(exports.Base, ordinal) || exports.Base + ordinal > pe_utils::max_word) + throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory); + + func.set_ordinal(static_cast<uint16_t>(ordinal + exports.Base)); + + //Scan for function name ordinal + for(uint32_t i = 0; i < exports.NumberOfNames; i++) + { + uint16_t ordinal2 = pe.section_data_from_rva<uint16_t>(exports.AddressOfNameOrdinals + i * sizeof(uint16_t), section_data_virtual, true); + + //If function has name (and name ordinal) + if(ordinal == ordinal2) + { + //Get function name + //Sum and multiplication are safe (checked above) + uint32_t function_name_rva = pe.section_data_from_rva<uint32_t>(exports.AddressOfNames + i * sizeof(uint32_t), section_data_virtual, true); + + //Get byte count that we have for function name + if((max_name_length = pe.section_data_length_from_rva(function_name_rva, function_name_rva, section_data_virtual, true)) < 2) + throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory); + + //Get function name pointer + const char* func_name = pe.section_data_from_rva(function_name_rva, section_data_virtual, true); + + //Check for null-termination + if(!pe_utils::is_null_terminated(func_name, max_name_length)) + throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory); + + //Save function info + func.set_name(func_name); + func.set_name_ordinal(ordinal2); + + //If the function is just a redirect, save its name + if(rva >= pe.get_directory_rva(image_directory_entry_export) + sizeof(image_directory_entry_export) && + rva < pe.get_directory_rva(image_directory_entry_export) + pe.get_directory_size(image_directory_entry_export)) + { + if((max_name_length = pe.section_data_length_from_rva(rva, rva, section_data_virtual, true)) < 2) + throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory); + + //Get forwarded function name pointer + const char* forwarded_func_name = pe.section_data_from_rva(rva, section_data_virtual, true); + + //Check for null-termination + if(!pe_utils::is_null_terminated(forwarded_func_name, max_name_length)) + throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory); + + //Set the name of forwarded function + func.set_forwarded_name(forwarded_func_name); + } + + break; + } + } + + //Add function info to output array + ret.push_back(func); + } + } + + return ret; +} + +//Helper export functions +//Returns pair: <ordinal base for supplied functions; maximum ordinal value for supplied functions> +const std::pair<uint16_t, uint16_t> get_export_ordinal_limits(const exported_functions_list& exports) +{ + if(exports.empty()) + return std::make_pair(0, 0); + + uint16_t max_ordinal = 0; //Maximum ordinal number + uint16_t ordinal_base = pe_utils::max_word; //Minimum ordinal value + for(exported_functions_list::const_iterator it = exports.begin(); it != exports.end(); ++it) + { + const exported_function& func = (*it); + + //Calculate maximum and minimum ordinal numbers + max_ordinal = std::max<uint16_t>(max_ordinal, func.get_ordinal()); + ordinal_base = std::min<uint16_t>(ordinal_base, func.get_ordinal()); + } + + return std::make_pair(ordinal_base, max_ordinal); +} + +//Checks if exported function name already exists +bool exported_name_exists(const std::string& function_name, const exported_functions_list& exports) +{ + for(exported_functions_list::const_iterator it = exports.begin(); it != exports.end(); ++it) + { + if((*it).has_name() && (*it).get_name() == function_name) + return true; + } + + return false; +} + +//Checks if exported function name already exists +bool exported_ordinal_exists(uint16_t ordinal, const exported_functions_list& exports) +{ + for(exported_functions_list::const_iterator it = exports.begin(); it != exports.end(); ++it) + { + if((*it).get_ordinal() == ordinal) + return true; + } + + return false; +} + +//Helper: sorts exported function list by ordinals +bool ordinal_sorter::operator()(const exported_function& func1, const exported_function& func2) const +{ + return func1.get_ordinal() < func2.get_ordinal(); +} + +//Export directory rebuilder +//info - export information +//exported_functions_list - list of exported functions +//exports_section - section where export directory will be placed (must be attached to PE image) +//offset_from_section_start - offset from exports_section raw data start +//save_to_pe_headers - if true, new export directory information will be saved to PE image headers +//auto_strip_last_section - if true and exports are placed in the last section, it will be automatically stripped +//number_of_functions and number_of_names parameters don't matter in "info" when rebuilding, they're calculated independently +//characteristics, major_version, minor_version, timestamp and name are the only used members of "info" structure +//Returns new export directory information +//exported_functions_list is copied intentionally to be sorted by ordinal values later +//Name ordinals in exported function don't matter, they will be recalculated +const image_directory rebuild_exports(pe_base& pe, const export_info& info, exported_functions_list exports, section& exports_section, uint32_t offset_from_section_start, bool save_to_pe_header, bool auto_strip_last_section) +{ + //Check that exports_section is attached to this PE image + if(!pe.section_attached(exports_section)) + throw pe_exception("Exports section must be attached to PE file", pe_exception::section_is_not_attached); + + //Needed space for strings + uint32_t needed_size_for_strings = static_cast<uint32_t>(info.get_name().length() + 1); + uint32_t number_of_names = 0; //Number of named functions + uint32_t max_ordinal = 0; //Maximum ordinal number + uint32_t ordinal_base = static_cast<uint32_t>(-1); //Minimum ordinal value + + if(exports.empty()) + ordinal_base = info.get_ordinal_base(); + + uint32_t needed_size_for_function_names = 0; //Needed space for function name strings + uint32_t needed_size_for_function_forwards = 0; //Needed space for function forwards names + + //List all exported functions + //Calculate needed size for function list + { + //Also check that there're no duplicate names and ordinals + std::set<std::string> used_function_names; + std::set<uint16_t> used_function_ordinals; + + for(exported_functions_list::const_iterator it = exports.begin(); it != exports.end(); ++it) + { + const exported_function& func = (*it); + //Calculate maximum and minimum ordinal numbers + max_ordinal = std::max<uint32_t>(max_ordinal, func.get_ordinal()); + ordinal_base = std::min<uint32_t>(ordinal_base, func.get_ordinal()); + + //Check if ordinal is unique + if(!used_function_ordinals.insert(func.get_ordinal()).second) + throw pe_exception("Duplicate exported function ordinal", pe_exception::duplicate_exported_function_ordinal); + + if(func.has_name()) + { + //If function is named + ++number_of_names; + needed_size_for_function_names += static_cast<uint32_t>(func.get_name().length() + 1); + + //Check if it's name and name ordinal are unique + if(!used_function_names.insert(func.get_name()).second) + throw pe_exception("Duplicate exported function name", pe_exception::duplicate_exported_function_name); + } + + //If function is forwarded to another DLL + if(func.is_forwarded()) + needed_size_for_function_forwards += static_cast<uint32_t>(func.get_forwarded_name().length() + 1); + } + } + + //Sort functions by ordinal value + std::sort(exports.begin(), exports.end(), ordinal_sorter()); + + //Calculate needed space for different things... + needed_size_for_strings += needed_size_for_function_names; + needed_size_for_strings += needed_size_for_function_forwards; + uint32_t needed_size_for_function_name_ordinals = number_of_names * sizeof(uint16_t); + uint32_t needed_size_for_function_name_rvas = number_of_names * sizeof(uint32_t); + uint32_t needed_size_for_function_addresses = (max_ordinal - ordinal_base + 1) * sizeof(uint32_t); + + //Export directory header will be placed first + uint32_t directory_pos = pe_utils::align_up(offset_from_section_start, sizeof(uint32_t)); + + uint32_t needed_size = sizeof(image_export_directory); //Calculate needed size for export tables and strings + //sizeof(IMAGE_EXPORT_DIRECTORY) = export directory header + + //Total needed space... + needed_size += needed_size_for_function_name_ordinals; //For list of names ordinals + needed_size += needed_size_for_function_addresses; //For function RVAs + needed_size += needed_size_for_strings; //For all strings + needed_size += needed_size_for_function_name_rvas; //For function name strings RVAs + + //Check if exports_section is last one. If it's not, check if there's enough place for exports data + if(&exports_section != &*(pe.get_image_sections().end() - 1) && + (exports_section.empty() || pe_utils::align_up(exports_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + directory_pos)) + throw pe_exception("Insufficient space for export directory", pe_exception::insufficient_space); + + std::string& raw_data = exports_section.get_raw_data(); + + //This will be done only if exports_section is the last section of image or for section with unaligned raw length of data + if(raw_data.length() < needed_size + directory_pos) + raw_data.resize(needed_size + directory_pos); //Expand section raw data + + //Library name will be placed after it + uint32_t current_pos_of_function_names = static_cast<uint32_t>(info.get_name().length() + 1 + directory_pos + sizeof(image_export_directory)); + //Next - function names + uint32_t current_pos_of_function_name_ordinals = current_pos_of_function_names + needed_size_for_function_names; + //Next - function name ordinals + uint32_t current_pos_of_function_forwards = current_pos_of_function_name_ordinals + needed_size_for_function_name_ordinals; + //Finally - function addresses + uint32_t current_pos_of_function_addresses = current_pos_of_function_forwards + needed_size_for_function_forwards; + //Next - function names RVAs + uint32_t current_pos_of_function_names_rvas = current_pos_of_function_addresses + needed_size_for_function_addresses; + + { + //Create export directory and fill it + image_export_directory dir = {0}; + dir.Characteristics = info.get_characteristics(); + dir.MajorVersion = info.get_major_version(); + dir.MinorVersion = info.get_minor_version(); + dir.TimeDateStamp = info.get_timestamp(); + dir.NumberOfFunctions = max_ordinal - ordinal_base + 1; + dir.NumberOfNames = number_of_names; + dir.Base = ordinal_base; + dir.AddressOfFunctions = pe.rva_from_section_offset(exports_section, current_pos_of_function_addresses); + dir.AddressOfNameOrdinals = pe.rva_from_section_offset(exports_section, current_pos_of_function_name_ordinals); + dir.AddressOfNames = pe.rva_from_section_offset(exports_section, current_pos_of_function_names_rvas); + dir.Name = pe.rva_from_section_offset(exports_section, directory_pos + sizeof(image_export_directory)); + + //Save it + memcpy(&raw_data[directory_pos], &dir, sizeof(dir)); + } + + //Sve library name + memcpy(&raw_data[directory_pos + sizeof(image_export_directory)], info.get_name().c_str(), info.get_name().length() + 1); + + //A map to sort function names alphabetically + typedef std::map<std::string, uint16_t> funclist; //function name; function name ordinal + funclist funcs; + + uint32_t last_ordinal = ordinal_base; + //Enumerate all exported functions + for(exported_functions_list::const_iterator it = exports.begin(); it != exports.end(); ++it) + { + const exported_function& func = (*it); + + //If we're skipping some ordinals... + if(func.get_ordinal() > last_ordinal) + { + //Fill this function RVAs data with zeros + uint32_t len = sizeof(uint32_t) * (func.get_ordinal() - last_ordinal - 1); + if(len) + { + memset(&raw_data[current_pos_of_function_addresses], 0, len); + current_pos_of_function_addresses += len; + } + + //Save last encountered ordinal + last_ordinal = func.get_ordinal(); + } + + //If function is named, save its name ordinal and name in sorted alphabetically order + if(func.has_name()) + funcs.insert(std::make_pair(func.get_name(), static_cast<uint16_t>(func.get_ordinal() - ordinal_base))); //Calculate name ordinal + + //If function is forwarded to another DLL + if(func.is_forwarded()) + { + //Write its forwarded name and its RVA + uint32_t function_rva = pe.rva_from_section_offset(exports_section, current_pos_of_function_forwards); + memcpy(&raw_data[current_pos_of_function_addresses], &function_rva, sizeof(function_rva)); + current_pos_of_function_addresses += sizeof(function_rva); + + memcpy(&raw_data[current_pos_of_function_forwards], func.get_forwarded_name().c_str(), func.get_forwarded_name().length() + 1); + current_pos_of_function_forwards += static_cast<uint32_t>(func.get_forwarded_name().length() + 1); + } + else + { + //Write actual function RVA + uint32_t function_rva = func.get_rva(); + memcpy(&raw_data[current_pos_of_function_addresses], &function_rva, sizeof(function_rva)); + current_pos_of_function_addresses += sizeof(function_rva); + } + } + + //Enumerate sorted function names + for(funclist::const_iterator it = funcs.begin(); it != funcs.end(); ++it) + { + //Save function name RVA + uint32_t function_name_rva = pe.rva_from_section_offset(exports_section, current_pos_of_function_names); + memcpy(&raw_data[current_pos_of_function_names_rvas], &function_name_rva, sizeof(function_name_rva)); + current_pos_of_function_names_rvas += sizeof(function_name_rva); + + //Save function name + memcpy(&raw_data[current_pos_of_function_names], (*it).first.c_str(), (*it).first.length() + 1); + current_pos_of_function_names += static_cast<uint32_t>((*it).first.length() + 1); + + //Save function name ordinal + uint16_t name_ordinal = (*it).second; + memcpy(&raw_data[current_pos_of_function_name_ordinals], &name_ordinal, sizeof(name_ordinal)); + current_pos_of_function_name_ordinals += sizeof(name_ordinal); + } + + //Adjust section raw and virtual sizes + pe.recalculate_section_sizes(exports_section, auto_strip_last_section); + + image_directory ret(pe.rva_from_section_offset(exports_section, directory_pos), needed_size); + + //If auto-rewrite of PE headers is required + if(save_to_pe_header) + { + pe.set_directory_rva(image_directory_entry_export, ret.get_rva()); + pe.set_directory_size(image_directory_entry_export, ret.get_size()); + } + + return ret; +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_exports.h b/irdb-lib/pebliss/trunk/pe_lib/pe_exports.h new file mode 100644 index 0000000000000000000000000000000000000000..6a90fe45111341c4a9f9863e0b4f051c94459035 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_exports.h @@ -0,0 +1,166 @@ +#ifndef pebliss_pe_exports_h +#define pebliss_pe_exports_h +#pragma once +#include <vector> +#include <string> +#include "pe_structures.h" +#include "pe_base.h" +#include "pe_directory.h" + +namespace pe_bliss +{ +//Class representing exported function +class exported_function +{ +public: + //Default constructor + exported_function(); + + //Returns ordinal of function (actually, ordinal = hint + ordinal base) + uint16_t get_ordinal() const; + + //Returns RVA of function + uint32_t get_rva() const; + + //Returns true if function has name and name ordinal + bool has_name() const; + //Returns name of function + const std::string& get_name() const; + //Returns name ordinal of function + uint16_t get_name_ordinal() const; + + //Returns true if function is forwarded to other library + bool is_forwarded() const; + //Returns the name of forwarded function + const std::string& get_forwarded_name() const; + +public: //Setters do not change everything inside image, they are used by PE class + //You can also use them to rebuild export directory + + //Sets ordinal of function + void set_ordinal(uint16_t ordinal); + + //Sets RVA of function + void set_rva(uint32_t rva); + + //Sets name of function (or clears it, if empty name is passed) + void set_name(const std::string& name); + //Sets name ordinal + void set_name_ordinal(uint16_t name_ordinal); + + //Sets forwarded function name (or clears it, if empty name is passed) + void set_forwarded_name(const std::string& name); + +private: + uint16_t ordinal_; //Function ordinal + uint32_t rva_; //Function RVA + std::string name_; //Function name + bool has_name_; //true == function has name + uint16_t name_ordinal_; //Function name ordinal + bool forward_; //true == function is forwarded + std::string forward_name_; //Name of forwarded function +}; + +//Class representing export information +class export_info +{ +public: + //Default constructor + export_info(); + + //Returns characteristics + uint32_t get_characteristics() const; + //Returns timestamp + uint32_t get_timestamp() const; + //Returns major version + uint16_t get_major_version() const; + //Returns minor version + uint16_t get_minor_version() const; + //Returns DLL name + const std::string& get_name() const; + //Returns ordinal base + uint32_t get_ordinal_base() const; + //Returns number of functions + uint32_t get_number_of_functions() const; + //Returns number of function names + uint32_t get_number_of_names() const; + //Returns RVA of function address table + uint32_t get_rva_of_functions() const; + //Returns RVA of function name address table + uint32_t get_rva_of_names() const; + //Returns RVA of name ordinals table + uint32_t get_rva_of_name_ordinals() const; + +public: //Setters do not change everything inside image, they are used by PE class + //You can also use them to rebuild export directory using rebuild_exports + + //Sets characteristics + void set_characteristics(uint32_t characteristics); + //Sets timestamp + void set_timestamp(uint32_t timestamp); + //Sets major version + void set_major_version(uint16_t major_version); + //Sets minor version + void set_minor_version(uint16_t minor_version); + //Sets DLL name + void set_name(const std::string& name); + //Sets ordinal base + void set_ordinal_base(uint32_t ordinal_base); + //Sets number of functions + void set_number_of_functions(uint32_t number_of_functions); + //Sets number of function names + void set_number_of_names(uint32_t number_of_names); + //Sets RVA of function address table + void set_rva_of_functions(uint32_t rva_of_functions); + //Sets RVA of function name address table + void set_rva_of_names(uint32_t rva_of_names); + //Sets RVA of name ordinals table + void set_rva_of_name_ordinals(uint32_t rva_of_name_ordinals); + +private: + uint32_t characteristics_; + uint32_t timestamp_; + uint16_t major_version_; + uint16_t minor_version_; + std::string name_; + uint32_t ordinal_base_; + uint32_t number_of_functions_; + uint32_t number_of_names_; + uint32_t address_of_functions_; + uint32_t address_of_names_; + uint32_t address_of_name_ordinals_; +}; + +//Exported functions list typedef +typedef std::vector<exported_function> exported_functions_list; + +//Returns array of exported functions +const exported_functions_list get_exported_functions(const pe_base& pe); +//Returns array of exported functions and information about export +const exported_functions_list get_exported_functions(const pe_base& pe, export_info& info); + +//Helper export functions +//Returns pair: <ordinal base for supplied functions; maximum ordinal value for supplied functions> +const std::pair<uint16_t, uint16_t> get_export_ordinal_limits(const exported_functions_list& exports); + +//Checks if exported function name already exists +bool exported_name_exists(const std::string& function_name, const exported_functions_list& exports); + +//Checks if exported function ordinal already exists +bool exported_ordinal_exists(uint16_t ordinal, const exported_functions_list& exports); + +//Export directory rebuilder +//info - export information +//exported_functions_list - list of exported functions +//exports_section - section where export directory will be placed (must be attached to PE image) +//offset_from_section_start - offset from exports_section raw data start +//save_to_pe_headers - if true, new export directory information will be saved to PE image headers +//auto_strip_last_section - if true and exports are placed in the last section, it will be automatically stripped +//number_of_functions and number_of_names parameters don't matter in "info" when rebuilding, they're calculated independently +//characteristics, major_version, minor_version, timestamp and name are the only used members of "info" structure +//Returns new export directory information +//exported_functions_list is copied intentionally to be sorted by ordinal values later +//Name ordinals in exported function don't matter, they will be recalculated +const image_directory rebuild_exports(pe_base& pe, const export_info& info, exported_functions_list exports, section& exports_section, uint32_t offset_from_section_start = 0, bool save_to_pe_header = true, bool auto_strip_last_section = true); +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_factory.cpp b/irdb-lib/pebliss/trunk/pe_lib/pe_factory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..193e7e21d6bc61bc68a17e7da6a10279e964531c --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_factory.cpp @@ -0,0 +1,12 @@ +#include "pe_factory.h" +#include "pe_properties_generic.h" + +namespace pe_bliss +{ +pe_base pe_factory::create_pe(std::istream& file, bool read_debug_raw_data) +{ + return pe_base::get_pe_type(file) == pe_type_32 + ? pe_base(file, pe_properties_32(), read_debug_raw_data) + : pe_base(file, pe_properties_64(), read_debug_raw_data); +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_factory.h b/irdb-lib/pebliss/trunk/pe_lib/pe_factory.h new file mode 100644 index 0000000000000000000000000000000000000000..5ba1f13be8a63786ea8e32f67a5803d9ba8a11ea --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_factory.h @@ -0,0 +1,19 @@ +#ifndef pebliss_pe_factory_h +#define pebliss_pe_factory_h +#pragma once +#include <memory> +#include <istream> +#include "pe_base.h" + +namespace pe_bliss +{ +class pe_factory +{ +public: + //Creates pe_base class instance from PE or PE+ istream + //If read_bound_import_raw_data, raw bound import data will be read (used to get bound import info) + //If read_debug_raw_data, raw debug data will be read (used to get image debug info) + static pe_base create_pe(std::istream& file, bool read_debug_raw_data = true); +}; +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_imports.cpp b/irdb-lib/pebliss/trunk/pe_lib/pe_imports.cpp new file mode 100644 index 0000000000000000000000000000000000000000..704d5fca9971ebafc02d13158cf4fe0fafb2475f --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_imports.cpp @@ -0,0 +1,756 @@ +#include <string.h> +#include "pe_imports.h" +#include "pe_properties_generic.h" + +namespace pe_bliss +{ +using namespace pe_win; + +//IMPORTS +//Default constructor +//If set_to_pe_headers = true, IMAGE_DIRECTORY_ENTRY_IMPORT entry will be reset +//to new value after import rebuilding +//If auto_zero_directory_entry_iat = true, IMAGE_DIRECTORY_ENTRY_IAT will be set to zero +//IMAGE_DIRECTORY_ENTRY_IAT is used by loader to temporarily make section, where IMAGE_DIRECTORY_ENTRY_IAT RVA points, writeable +//to be able to modify IAT thunks +import_rebuilder_settings::import_rebuilder_settings(bool set_to_pe_headers, bool auto_zero_directory_entry_iat) + :offset_from_section_start_(0), + build_original_iat_(true), + save_iat_and_original_iat_rvas_(true), + fill_missing_original_iats_(false), + set_to_pe_headers_(set_to_pe_headers), + zero_directory_entry_iat_(auto_zero_directory_entry_iat), + rewrite_iat_and_original_iat_contents_(false), + auto_strip_last_section_(true) +{} + +//Returns offset from section start where import directory data will be placed +uint32_t import_rebuilder_settings::get_offset_from_section_start() const +{ + return offset_from_section_start_; +} + +//Returns true if Original import address table (IAT) will be rebuilt +bool import_rebuilder_settings::build_original_iat() const +{ + return build_original_iat_; +} + +//Returns true if Original import address and import address tables will not be rebuilt, +//works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero +bool import_rebuilder_settings::save_iat_and_original_iat_rvas() const +{ + return save_iat_and_original_iat_rvas_; +} + +//Returns true if Original import address and import address tables contents will be rewritten +//works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero +//and save_iat_and_original_iat_rvas is true +bool import_rebuilder_settings::rewrite_iat_and_original_iat_contents() const +{ + return rewrite_iat_and_original_iat_contents_; +} + +//Returns true if original missing IATs will be rebuilt +//(only if IATs are saved) +bool import_rebuilder_settings::fill_missing_original_iats() const +{ + return fill_missing_original_iats_; +} + +//Returns true if PE headers should be updated automatically after rebuilding of imports +bool import_rebuilder_settings::auto_set_to_pe_headers() const +{ + return set_to_pe_headers_; +} + +//Returns true if IMAGE_DIRECTORY_ENTRY_IAT must be zeroed, works only if auto_set_to_pe_headers = true +bool import_rebuilder_settings::zero_directory_entry_iat() const +{ + return zero_directory_entry_iat_; +} + +//Returns true if the last section should be stripped automatically, if imports are inside it +bool import_rebuilder_settings::auto_strip_last_section_enabled() const +{ + return auto_strip_last_section_; +} + +//Sets offset from section start where import directory data will be placed +void import_rebuilder_settings::set_offset_from_section_start(uint32_t offset) +{ + offset_from_section_start_ = offset; +} + +//Sets if Original import address table (IAT) will be rebuilt +void import_rebuilder_settings::build_original_iat(bool enable) +{ + build_original_iat_ = enable; +} + +//Sets if Original import address and import address tables will not be rebuilt, +//works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero +void import_rebuilder_settings::save_iat_and_original_iat_rvas(bool enable, bool enable_rewrite_iat_and_original_iat_contents) +{ + save_iat_and_original_iat_rvas_ = enable; + if(save_iat_and_original_iat_rvas_) + rewrite_iat_and_original_iat_contents_ = enable_rewrite_iat_and_original_iat_contents; + else + rewrite_iat_and_original_iat_contents_ = false; +} + +//Sets if original missing IATs will be rebuilt +//(only if IATs are saved) +void import_rebuilder_settings::fill_missing_original_iats(bool enable) +{ + fill_missing_original_iats_ = enable; +} + +//Sets if PE headers should be updated automatically after rebuilding of imports +void import_rebuilder_settings::auto_set_to_pe_headers(bool enable) +{ + set_to_pe_headers_ = enable; +} + +//Sets if IMAGE_DIRECTORY_ENTRY_IAT must be zeroed, works only if auto_set_to_pe_headers = true +void import_rebuilder_settings::zero_directory_entry_iat(bool enable) +{ + zero_directory_entry_iat_ = enable; +} + +//Sets if the last section should be stripped automatically, if imports are inside it, default true +void import_rebuilder_settings::enable_auto_strip_last_section(bool enable) +{ + auto_strip_last_section_ = enable; +} + +//Default constructor +imported_function::imported_function() + :hint_(0), ordinal_(0), iat_va_(0) +{} + +//Returns name of function +const std::string& imported_function::get_name() const +{ + return name_; +} + +//Returns true if imported function has name (and hint) +bool imported_function::has_name() const +{ + return !name_.empty(); +} + +//Returns hint +uint16_t imported_function::get_hint() const +{ + return hint_; +} + +//Returns ordinal of function +uint16_t imported_function::get_ordinal() const +{ + return ordinal_; +} + +//Returns IAT entry VA (usable if image has both IAT and original IAT and is bound) +uint64_t imported_function::get_iat_va() const +{ + return iat_va_; +} + +//Sets name of function +void imported_function::set_name(const std::string& name) +{ + name_ = name; +} + +//Sets hint +void imported_function::set_hint(uint16_t hint) +{ + hint_ = hint; +} + +//Sets ordinal +void imported_function::set_ordinal(uint16_t ordinal) +{ + ordinal_ = ordinal; +} + +//Sets IAT entry VA (usable if image has both IAT and original IAT and is bound) +void imported_function::set_iat_va(uint64_t va) +{ + iat_va_ = va; +} + +//Default constructor +import_library::import_library() + :rva_to_iat_(0), rva_to_original_iat_(0), timestamp_(0) +{} + +//Returns name of library +const std::string& import_library::get_name() const +{ + return name_; +} + +//Returns RVA to Import Address Table (IAT) +uint32_t import_library::get_rva_to_iat() const +{ + return rva_to_iat_; +} + +//Returns RVA to Original Import Address Table (Original IAT) +uint32_t import_library::get_rva_to_original_iat() const +{ + return rva_to_original_iat_; +} + +//Returns timestamp +uint32_t import_library::get_timestamp() const +{ + return timestamp_; +} + +//Sets name of library +void import_library::set_name(const std::string& name) +{ + name_ = name; +} + +//Sets RVA to Import Address Table (IAT) +void import_library::set_rva_to_iat(uint32_t rva_to_iat) +{ + rva_to_iat_ = rva_to_iat; +} + +//Sets RVA to Original Import Address Table (Original IAT) +void import_library::set_rva_to_original_iat(uint32_t rva_to_original_iat) +{ + rva_to_original_iat_ = rva_to_original_iat; +} + +//Sets timestamp +void import_library::set_timestamp(uint32_t timestamp) +{ + timestamp_ = timestamp; +} + +//Returns imported functions list +const import_library::imported_list& import_library::get_imported_functions() const +{ + return imports_; +} + +//Adds imported function +void import_library::add_import(const imported_function& func) +{ + imports_.push_back(func); +} + +//Clears imported functions list +void import_library::clear_imports() +{ + imports_.clear(); +} + +const imported_functions_list get_imported_functions(const pe_base& pe) +{ + return (pe.get_pe_type() == pe_type_32 ? + get_imported_functions_base<pe_types_class_32>(pe) + : get_imported_functions_base<pe_types_class_64>(pe)); +} + +const image_directory rebuild_imports(pe_base& pe, const imported_functions_list& imports, section& import_section, const import_rebuilder_settings& import_settings) +{ + return (pe.get_pe_type() == pe_type_32 ? + rebuild_imports_base<pe_types_class_32>(pe, imports, import_section, import_settings) + : rebuild_imports_base<pe_types_class_64>(pe, imports, import_section, import_settings)); +} + +//Returns imported functions list with related libraries info +template<typename PEClassType> +const imported_functions_list get_imported_functions_base(const pe_base& pe) +{ + imported_functions_list ret; + + //If image has no imports, return empty array + if(!pe.has_imports()) + return ret; + + unsigned long current_descriptor_pos = pe.get_directory_rva(image_directory_entry_import); + //Get first IMAGE_IMPORT_DESCRIPTOR + image_import_descriptor import_descriptor = pe.section_data_from_rva<image_import_descriptor>(current_descriptor_pos, section_data_virtual, true); + + //Iterate them until we reach zero-element + //We don't need to check correctness of this, because exception will be thrown + //inside of loop if we go outsize of section + while(import_descriptor.Name) + { + //Get imported library information + import_library lib; + + unsigned long max_name_length; + //Get byte count that we have for library name + if((max_name_length = pe.section_data_length_from_rva(import_descriptor.Name, import_descriptor.Name, section_data_virtual, true)) < 2) + throw pe_exception("Incorrect import directory", pe_exception::incorrect_import_directory); + + //Get DLL name pointer + const char* dll_name = pe.section_data_from_rva(import_descriptor.Name, section_data_virtual, true); + + //Check for null-termination + if(!pe_utils::is_null_terminated(dll_name, max_name_length)) + throw pe_exception("Incorrect import directory", pe_exception::incorrect_import_directory); + + //Set library name + lib.set_name(dll_name); + //Set library timestamp + lib.set_timestamp(import_descriptor.TimeDateStamp); + //Set library RVA to IAT and original IAT + lib.set_rva_to_iat(import_descriptor.FirstThunk); + lib.set_rva_to_original_iat(import_descriptor.OriginalFirstThunk); + + //Get RVA to IAT (it must be filled by loader when loading PE) + uint32_t current_thunk_rva = import_descriptor.FirstThunk; + typename PEClassType::BaseSize import_address_table = pe.section_data_from_rva<typename PEClassType::BaseSize>(current_thunk_rva, section_data_virtual, true); + + //Get RVA to original IAT (lookup table), which must handle imported functions names + //Some linkers leave this pointer zero-filled + //Such image is valid, but it is not possible to restore imported functions names + //afted image was loaded, because IAT becomes the only one table + //containing both function names and function RVAs after loading + uint32_t current_original_thunk_rva = import_descriptor.OriginalFirstThunk; + typename PEClassType::BaseSize import_lookup_table = current_original_thunk_rva == 0 ? import_address_table : pe.section_data_from_rva<typename PEClassType::BaseSize>(current_original_thunk_rva, section_data_virtual, true); + if(current_original_thunk_rva == 0) + current_original_thunk_rva = current_thunk_rva; + + //List all imported functions for current DLL + if(import_lookup_table != 0 && import_address_table != 0) + { + while(true) + { + //Imported function description + imported_function func; + + //Get VA from IAT + typename PEClassType::BaseSize address = pe.section_data_from_rva<typename PEClassType::BaseSize>(current_thunk_rva, section_data_virtual, true); + //Move pointer + current_thunk_rva += sizeof(typename PEClassType::BaseSize); + + //Jump to next DLL if we finished with this one + if(!address) + break; + + func.set_iat_va(address); + + //Get VA from original IAT + typename PEClassType::BaseSize lookup = pe.section_data_from_rva<typename PEClassType::BaseSize>(current_original_thunk_rva, section_data_virtual, true); + //Move pointer + current_original_thunk_rva += sizeof(typename PEClassType::BaseSize); + + //Check if function is imported by ordinal + if((lookup & PEClassType::ImportSnapFlag) != 0) + { + //Set function ordinal + func.set_ordinal(static_cast<uint16_t>(lookup & 0xffff)); + } + else + { + //Get byte count that we have for function name + if(lookup > static_cast<uint32_t>(-1) - sizeof(uint16_t)) + throw pe_exception("Incorrect import directory", pe_exception::incorrect_import_directory); + + //Get maximum available length of function name + if((max_name_length = pe.section_data_length_from_rva(static_cast<uint32_t>(lookup + sizeof(uint16_t)), static_cast<uint32_t>(lookup + sizeof(uint16_t)), section_data_virtual, true)) < 2) + throw pe_exception("Incorrect import directory", pe_exception::incorrect_import_directory); + + //Get imported function name + const char* func_name = pe.section_data_from_rva(static_cast<uint32_t>(lookup + sizeof(uint16_t)), section_data_virtual, true); + + //Check for null-termination + if(!pe_utils::is_null_terminated(func_name, max_name_length)) + throw pe_exception("Incorrect import directory", pe_exception::incorrect_import_directory); + + //HINT in import table is ORDINAL in export table + uint16_t hint = pe.section_data_from_rva<uint16_t>(static_cast<uint32_t>(lookup), section_data_virtual, true); + + //Save hint and name + func.set_name(func_name); + func.set_hint(hint); + } + + //Add function to list + lib.add_import(func); + } + } + + //Check possible overflow + if(!pe_utils::is_sum_safe(current_descriptor_pos, sizeof(image_import_descriptor))) + throw pe_exception("Incorrect import directory", pe_exception::incorrect_import_directory); + + //Go to next library + current_descriptor_pos += sizeof(image_import_descriptor); + import_descriptor = pe.section_data_from_rva<image_import_descriptor>(current_descriptor_pos, section_data_virtual, true); + + //Save import information + ret.push_back(lib); + } + + //Return resulting list + return ret; +} + + +//Simple import directory rebuilder +//You can get all image imports with get_imported_functions() function +//You can use returned value to, for example, add new imported library with some functions +//to the end of list of imported libraries +//To keep PE file working, rebuild its imports with save_iat_and_original_iat_rvas = true (default) +//Don't add new imported functions to existing imported library entries, because this can cause +//rewriting of some used memory (or other IAT/orig.IAT fields) by system loader +//The safest way is just adding import libraries with functions to the end of imported_functions_list array +template<typename PEClassType> +const image_directory rebuild_imports_base(pe_base& pe, const imported_functions_list& imports, section& import_section, const import_rebuilder_settings& import_settings) +{ + //Check that import_section is attached to this PE image + if(!pe.section_attached(import_section)) + throw pe_exception("Import section must be attached to PE file", pe_exception::section_is_not_attached); + + uint32_t needed_size = 0; //Calculate needed size for import structures and strings + uint32_t needed_size_for_strings = 0; //Calculate needed size for import strings (library and function names and hints) + uint32_t size_of_iat = 0; //Size of IAT structures + + needed_size += static_cast<uint32_t>((1 /* ending null descriptor */ + imports.size()) * sizeof(image_import_descriptor)); + + //Enumerate imported functions + for(imported_functions_list::const_iterator it = imports.begin(); it != imports.end(); ++it) + { + needed_size_for_strings += static_cast<uint32_t>((*it).get_name().length() + 1 /* nullbyte */); + + const import_library::imported_list& funcs = (*it).get_imported_functions(); + + //IMAGE_THUNK_DATA + size_of_iat += static_cast<uint32_t>(sizeof(typename PEClassType::BaseSize) * (1 /*ending null */ + funcs.size())); + + //Enumerate all imported functions in library + for(import_library::imported_list::const_iterator f = funcs.begin(); f != funcs.end(); ++f) + { + if((*f).has_name()) + needed_size_for_strings += static_cast<uint32_t>((*f).get_name().length() + 1 /* nullbyte */ + sizeof(uint16_t) /* hint */); + } + } + + if(import_settings.build_original_iat() || import_settings.fill_missing_original_iats()) + needed_size += size_of_iat * 2; //We'll have two similar-sized IATs if we're building original IAT + else + needed_size += size_of_iat; + + needed_size += sizeof(typename PEClassType::BaseSize); //Maximum align for IAT and original IAT + + //Total needed size for import structures and strings + needed_size += needed_size_for_strings; + + //Check if import_section is last one. If it's not, check if there's enough place for import data + if(&import_section != &*(pe.get_image_sections().end() - 1) && + (import_section.empty() || pe_utils::align_up(import_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + import_settings.get_offset_from_section_start())) + throw pe_exception("Insufficient space for import directory", pe_exception::insufficient_space); + + std::string& raw_data = import_section.get_raw_data(); + + //This will be done only if image_section is the last section of image or for section with unaligned raw length of data + if(raw_data.length() < needed_size + import_settings.get_offset_from_section_start()) + raw_data.resize(needed_size + import_settings.get_offset_from_section_start()); //Expand section raw data + + uint32_t current_string_pointer = import_settings.get_offset_from_section_start();/* we will paste structures after strings */ + + //Position for IAT + uint32_t current_pos_for_iat = pe_utils::align_up(static_cast<uint32_t>(needed_size_for_strings + import_settings.get_offset_from_section_start() + (1 + imports.size()) * sizeof(image_import_descriptor)), sizeof(typename PEClassType::BaseSize)); + //Position for original IAT + uint32_t current_pos_for_original_iat = current_pos_for_iat + size_of_iat; + //Position for import descriptors + uint32_t current_pos_for_descriptors = needed_size_for_strings + import_settings.get_offset_from_section_start(); + + //Build imports + for(imported_functions_list::const_iterator it = imports.begin(); it != imports.end(); ++it) + { + //Create import descriptor + image_import_descriptor descr; + memset(&descr, 0, sizeof(descr)); + descr.TimeDateStamp = (*it).get_timestamp(); //Restore timestamp + descr.Name = pe.rva_from_section_offset(import_section, current_string_pointer); //Library name RVA + + //If we should save IAT for current import descriptor + bool save_iats_for_this_descriptor = import_settings.save_iat_and_original_iat_rvas() && (*it).get_rva_to_iat() != 0; + //If we should write original IAT + bool write_original_iat = (!save_iats_for_this_descriptor && import_settings.build_original_iat()) || import_settings.fill_missing_original_iats(); + + //If we should rewrite saved original IAT for current import descriptor (without changing its position) + bool rewrite_saved_original_iat = save_iats_for_this_descriptor && import_settings.rewrite_iat_and_original_iat_contents() && import_settings.build_original_iat(); + //If we should rewrite saved IAT for current import descriptor (without changing its position) + bool rewrite_saved_iat = save_iats_for_this_descriptor && import_settings.rewrite_iat_and_original_iat_contents() && (*it).get_rva_to_iat() != 0; + + //Helper values if we're rewriting existing IAT or orig.IAT + uint32_t original_first_thunk = 0; + uint32_t first_thunk = 0; + + if(save_iats_for_this_descriptor) + { + //If there's no original IAT and we're asked to rebuild missing original IATs + if(!(*it).get_rva_to_original_iat() && import_settings.fill_missing_original_iats()) + descr.OriginalFirstThunk = import_settings.build_original_iat() ? pe.rva_from_section_offset(import_section, current_pos_for_original_iat) : 0; + else + descr.OriginalFirstThunk = import_settings.build_original_iat() ? (*it).get_rva_to_original_iat() : 0; + + descr.FirstThunk = (*it).get_rva_to_iat(); + + original_first_thunk = descr.OriginalFirstThunk; + first_thunk = descr.FirstThunk; + + if(rewrite_saved_original_iat) + { + if((*it).get_rva_to_original_iat()) + write_original_iat = true; + else + rewrite_saved_original_iat = false; + } + + if(rewrite_saved_iat) + save_iats_for_this_descriptor = false; + } + else + { + //We are creating new IAT and original IAT (if needed) + descr.OriginalFirstThunk = import_settings.build_original_iat() ? pe.rva_from_section_offset(import_section, current_pos_for_original_iat) : 0; + descr.FirstThunk = pe.rva_from_section_offset(import_section, current_pos_for_iat); + } + + //Save import descriptor + memcpy(&raw_data[current_pos_for_descriptors], &descr, sizeof(descr)); + current_pos_for_descriptors += sizeof(descr); + + //Save library name + memcpy(&raw_data[current_string_pointer], (*it).get_name().c_str(), (*it).get_name().length() + 1 /* nullbyte */); + current_string_pointer += static_cast<uint32_t>((*it).get_name().length() + 1 /* nullbyte */); + + //List all imported functions + const import_library::imported_list& funcs = (*it).get_imported_functions(); + for(import_library::imported_list::const_iterator f = funcs.begin(); f != funcs.end(); ++f) + { + if((*f).has_name()) //If function is imported by name + { + //Get RVA of IMAGE_IMPORT_BY_NAME + typename PEClassType::BaseSize rva_of_named_import = pe.rva_from_section_offset(import_section, current_string_pointer); + + if(!save_iats_for_this_descriptor) + { + if(write_original_iat) + { + //We're creating original IATs - so we can write to IAT saved VA (because IMAGE_IMPORT_BY_NAME will be read + //by PE loader from original IAT) + typename PEClassType::BaseSize iat_value = static_cast<typename PEClassType::BaseSize>((*f).get_iat_va()); + + if(rewrite_saved_iat) + { + if(pe.section_data_length_from_rva(first_thunk, first_thunk, section_data_raw, true) <= sizeof(iat_value)) + throw pe_exception("Insufficient space inside initial IAT", pe_exception::insufficient_space); + + memcpy(pe.section_data_from_rva(first_thunk, true), &iat_value, sizeof(iat_value)); + + first_thunk += sizeof(iat_value); + } + else + { + memcpy(&raw_data[current_pos_for_iat], &iat_value, sizeof(iat_value)); + current_pos_for_iat += sizeof(rva_of_named_import); + } + } + else + { + //Else - write to IAT RVA of IMAGE_IMPORT_BY_NAME + if(rewrite_saved_iat) + { + if(pe.section_data_length_from_rva(first_thunk, first_thunk, section_data_raw, true) <= sizeof(rva_of_named_import)) + throw pe_exception("Insufficient space inside initial IAT", pe_exception::insufficient_space); + + memcpy(pe.section_data_from_rva(first_thunk, true), &rva_of_named_import, sizeof(rva_of_named_import)); + + first_thunk += sizeof(rva_of_named_import); + } + else + { + memcpy(&raw_data[current_pos_for_iat], &rva_of_named_import, sizeof(rva_of_named_import)); + current_pos_for_iat += sizeof(rva_of_named_import); + } + } + } + + if(write_original_iat) + { + if(rewrite_saved_original_iat) + { + if(pe.section_data_length_from_rva(original_first_thunk, original_first_thunk, section_data_raw, true) <= sizeof(rva_of_named_import)) + throw pe_exception("Insufficient space inside initial original IAT", pe_exception::insufficient_space); + + memcpy(pe.section_data_from_rva(original_first_thunk, true), &rva_of_named_import, sizeof(rva_of_named_import)); + + original_first_thunk += sizeof(rva_of_named_import); + } + else + { + //We're creating original IATs + memcpy(&raw_data[current_pos_for_original_iat], &rva_of_named_import, sizeof(rva_of_named_import)); + current_pos_for_original_iat += sizeof(rva_of_named_import); + } + } + + //Write IMAGE_IMPORT_BY_NAME (WORD hint + string function name) + uint16_t hint = (*f).get_hint(); + memcpy(&raw_data[current_string_pointer], &hint, sizeof(hint)); + memcpy(&raw_data[current_string_pointer + sizeof(uint16_t)], (*f).get_name().c_str(), (*f).get_name().length() + 1 /* nullbyte */); + current_string_pointer += static_cast<uint32_t>((*f).get_name().length() + 1 /* nullbyte */ + sizeof(uint16_t) /* hint */); + } + else //Function is imported by ordinal + { + uint16_t ordinal = (*f).get_ordinal(); + typename PEClassType::BaseSize thunk_value = ordinal; + thunk_value |= PEClassType::ImportSnapFlag; //Imported by ordinal + + if(!save_iats_for_this_descriptor) + { + if(write_original_iat) + { + //We're creating original IATs - so we can wtire to IAT saved VA (because ordinal will be read + //by PE loader from original IAT) + typename PEClassType::BaseSize iat_value = static_cast<typename PEClassType::BaseSize>((*f).get_iat_va()); + if(rewrite_saved_iat) + { + if(pe.section_data_length_from_rva(first_thunk, first_thunk, section_data_raw, true) <= sizeof(iat_value)) + throw pe_exception("Insufficient space inside initial IAT", pe_exception::insufficient_space); + + memcpy(pe.section_data_from_rva(first_thunk, true), &iat_value, sizeof(iat_value)); + + first_thunk += sizeof(iat_value); + } + else + { + memcpy(&raw_data[current_pos_for_iat], &iat_value, sizeof(iat_value)); + current_pos_for_iat += sizeof(thunk_value); + } + } + else + { + //Else - write ordinal to IAT + if(rewrite_saved_iat) + { + if(pe.section_data_length_from_rva(first_thunk, first_thunk, section_data_raw, true) <= sizeof(thunk_value)) + throw pe_exception("Insufficient space inside initial IAT", pe_exception::insufficient_space); + + memcpy(pe.section_data_from_rva(first_thunk, true), &thunk_value, sizeof(thunk_value)); + + first_thunk += sizeof(thunk_value); + } + else + { + memcpy(&raw_data[current_pos_for_iat], &thunk_value, sizeof(thunk_value)); + } + } + } + + //We're writing ordinal to original IAT slot + if(write_original_iat) + { + if(rewrite_saved_original_iat) + { + if(pe.section_data_length_from_rva(original_first_thunk, original_first_thunk, section_data_raw, true) <= sizeof(thunk_value)) + throw pe_exception("Insufficient space inside initial original IAT", pe_exception::insufficient_space); + + memcpy(pe.section_data_from_rva(original_first_thunk, true), &thunk_value, sizeof(thunk_value)); + + original_first_thunk += sizeof(thunk_value); + } + else + { + memcpy(&raw_data[current_pos_for_original_iat], &thunk_value, sizeof(thunk_value)); + current_pos_for_original_iat += sizeof(thunk_value); + } + } + } + } + + if(!save_iats_for_this_descriptor) + { + //Ending null thunks + typename PEClassType::BaseSize thunk_value = 0; + + if(rewrite_saved_iat) + { + if(pe.section_data_length_from_rva(first_thunk, first_thunk, section_data_raw, true) <= sizeof(thunk_value)) + throw pe_exception("Insufficient space inside initial IAT", pe_exception::insufficient_space); + + memcpy(pe.section_data_from_rva(first_thunk, true), &thunk_value, sizeof(thunk_value)); + + first_thunk += sizeof(thunk_value); + } + else + { + memcpy(&raw_data[current_pos_for_iat], &thunk_value, sizeof(thunk_value)); + current_pos_for_iat += sizeof(thunk_value); + } + } + + if(write_original_iat) + { + //Ending null thunks + typename PEClassType::BaseSize thunk_value = 0; + + if(rewrite_saved_original_iat) + { + if(pe.section_data_length_from_rva(original_first_thunk, original_first_thunk, section_data_raw, true) <= sizeof(thunk_value)) + throw pe_exception("Insufficient space inside initial original IAT", pe_exception::insufficient_space); + + memcpy(pe.section_data_from_rva(original_first_thunk, true), &thunk_value, sizeof(thunk_value)); + + original_first_thunk += sizeof(thunk_value); + } + else + { + memcpy(&raw_data[current_pos_for_original_iat], &thunk_value, sizeof(thunk_value)); + current_pos_for_original_iat += sizeof(thunk_value); + } + } + } + + { + //Null ending descriptor + image_import_descriptor descr; + memset(&descr, 0, sizeof(descr)); + memcpy(&raw_data[current_pos_for_descriptors], &descr, sizeof(descr)); + } + + //Strip data a little, if we saved some place + //We're allocating more space than needed, if present original IAT and IAT are saved + raw_data.resize(current_pos_for_original_iat); + + //Adjust section raw and virtual sizes + pe.recalculate_section_sizes(import_section, import_settings.auto_strip_last_section_enabled()); + + //Return information about rebuilt import directory + image_directory ret(pe.rva_from_section_offset(import_section, import_settings.get_offset_from_section_start() + needed_size_for_strings), needed_size - needed_size_for_strings); + + //If auto-rewrite of PE headers is required + if(import_settings.auto_set_to_pe_headers()) + { + pe.set_directory_rva(image_directory_entry_import, ret.get_rva()); + pe.set_directory_size(image_directory_entry_import, ret.get_size()); + + //If we are requested to zero IMAGE_DIRECTORY_ENTRY_IAT also + if(import_settings.zero_directory_entry_iat()) + { + pe.set_directory_rva(image_directory_entry_iat, 0); + pe.set_directory_size(image_directory_entry_iat, 0); + } + } + + return ret; +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_imports.h b/irdb-lib/pebliss/trunk/pe_lib/pe_imports.h new file mode 100644 index 0000000000000000000000000000000000000000..b2ec9487dd4b35744a6e72a5b7db1636dc531419 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_imports.h @@ -0,0 +1,190 @@ +#ifndef pebliss_pe_imports_h +#define pebliss_pe_imports_h +#pragma once +#include <vector> +#include <string> +#include "pe_structures.h" +#include "pe_directory.h" +#include "pe_base.h" + +namespace pe_bliss +{ +//Class representing imported function +class imported_function +{ +public: + //Default constructor + imported_function(); + + //Returns true if imported function has name (and hint) + bool has_name() const; + //Returns name of function + const std::string& get_name() const; + //Returns hint + uint16_t get_hint() const; + //Returns ordinal of function + uint16_t get_ordinal() const; + + //Returns IAT entry VA (usable if image has both IAT and original IAT and is bound) + uint64_t get_iat_va() const; + +public: //Setters do not change everything inside image, they are used by PE class + //You also can use them to rebuild image imports + //Sets name of function + void set_name(const std::string& name); + //Sets hint + void set_hint(uint16_t hint); + //Sets ordinal + void set_ordinal(uint16_t ordinal); + + //Sets IAT entry VA (usable if image has both IAT and original IAT and is bound) + void set_iat_va(uint64_t rva); + +private: + std::string name_; //Function name + uint16_t hint_; //Hint + uint16_t ordinal_; //Ordinal + uint64_t iat_va_; +}; + +//Class representing imported library information +class import_library +{ +public: + typedef std::vector<imported_function> imported_list; + +public: + //Default constructor + import_library(); + + //Returns name of library + const std::string& get_name() const; + //Returns RVA to Import Address Table (IAT) + uint32_t get_rva_to_iat() const; + //Returns RVA to Original Import Address Table (Original IAT) + uint32_t get_rva_to_original_iat() const; + //Returns timestamp + uint32_t get_timestamp() const; + + //Returns imported functions list + const imported_list& get_imported_functions() const; + +public: //Setters do not change everything inside image, they are used by PE class + //You also can use them to rebuild image imports + //Sets name of library + void set_name(const std::string& name); + //Sets RVA to Import Address Table (IAT) + void set_rva_to_iat(uint32_t rva_to_iat); + //Sets RVA to Original Import Address Table (Original IAT) + void set_rva_to_original_iat(uint32_t rva_to_original_iat); + //Sets timestamp + void set_timestamp(uint32_t timestamp); + + //Adds imported function + void add_import(const imported_function& func); + //Clears imported functions list + void clear_imports(); + +private: + std::string name_; //Library name + uint32_t rva_to_iat_; //RVA to IAT + uint32_t rva_to_original_iat_; //RVA to original IAT + uint32_t timestamp_; //DLL TimeStamp + + imported_list imports_; +}; + +//Simple import directory rebuilder +//Class representing import rebuilder advanced settings +class import_rebuilder_settings +{ +public: + //Default constructor + //Default constructor + //If set_to_pe_headers = true, IMAGE_DIRECTORY_ENTRY_IMPORT entry will be reset + //to new value after import rebuilding + //If auto_zero_directory_entry_iat = true, IMAGE_DIRECTORY_ENTRY_IAT will be set to zero + //IMAGE_DIRECTORY_ENTRY_IAT is used by loader to temporarily make section, where IMAGE_DIRECTORY_ENTRY_IAT RVA points, writeable + //to be able to modify IAT thunks + explicit import_rebuilder_settings(bool set_to_pe_headers = true, bool auto_zero_directory_entry_iat = false); + + //Returns offset from section start where import directory data will be placed + uint32_t get_offset_from_section_start() const; + //Returns true if Original import address table (IAT) will be rebuilt + bool build_original_iat() const; + + //Returns true if Original import address and import address tables will not be rebuilt, + //works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero + bool save_iat_and_original_iat_rvas() const; + //Returns true if Original import address and import address tables contents will be rewritten + //works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero + //and save_iat_and_original_iat_rvas is true + bool rewrite_iat_and_original_iat_contents() const; + + //Returns true if original missing IATs will be rebuilt + //(only if IATs are saved) + bool fill_missing_original_iats() const; + //Returns true if PE headers should be updated automatically after rebuilding of imports + bool auto_set_to_pe_headers() const; + //Returns true if IMAGE_DIRECTORY_ENTRY_IAT must be zeroed, works only if auto_set_to_pe_headers = true + bool zero_directory_entry_iat() const; + + //Returns true if the last section should be stripped automatically, if imports are inside it + bool auto_strip_last_section_enabled() const; + +public: //Setters + //Sets offset from section start where import directory data will be placed + void set_offset_from_section_start(uint32_t offset); + //Sets if Original import address table (IAT) will be rebuilt + void build_original_iat(bool enable); + //Sets if Original import address and import address tables will not be rebuilt, + //works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero + //enable_rewrite_iat_and_original_iat_contents sets if Original import address and import address tables contents will be rewritten + //works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero + //and save_iat_and_original_iat_rvas is true + void save_iat_and_original_iat_rvas(bool enable, bool enable_rewrite_iat_and_original_iat_contents = false); + //Sets if original missing IATs will be rebuilt + //(only if IATs are saved) + void fill_missing_original_iats(bool enable); + //Sets if PE headers should be updated automatically after rebuilding of imports + void auto_set_to_pe_headers(bool enable); + //Sets if IMAGE_DIRECTORY_ENTRY_IAT must be zeroed, works only if auto_set_to_pe_headers = true + void zero_directory_entry_iat(bool enable); + + //Sets if the last section should be stripped automatically, if imports are inside it, default true + void enable_auto_strip_last_section(bool enable); + +private: + uint32_t offset_from_section_start_; + bool build_original_iat_; + bool save_iat_and_original_iat_rvas_; + bool fill_missing_original_iats_; + bool set_to_pe_headers_; + bool zero_directory_entry_iat_; + bool rewrite_iat_and_original_iat_contents_; + bool auto_strip_last_section_; +}; + +typedef std::vector<import_library> imported_functions_list; + + +//Returns imported functions list with related libraries info +const imported_functions_list get_imported_functions(const pe_base& pe); + +template<typename PEClassType> +const imported_functions_list get_imported_functions_base(const pe_base& pe); + + +//You can get all image imports with get_imported_functions() function +//You can use returned value to, for example, add new imported library with some functions +//to the end of list of imported libraries +//To keep PE file working, rebuild its imports with save_iat_and_original_iat_rvas = true (default) +//Don't add new imported functions to existing imported library entries, because this can cause +//rewriting of some used memory (or other IAT/orig.IAT fields) by system loader +//The safest way is just adding import libraries with functions to the end of imported_functions_list array +const image_directory rebuild_imports(pe_base& pe, const imported_functions_list& imports, section& import_section, const import_rebuilder_settings& import_settings = import_rebuilder_settings()); + +template<typename PEClassType> +const image_directory rebuild_imports_base(pe_base& pe, const imported_functions_list& imports, section& import_section, const import_rebuilder_settings& import_settings = import_rebuilder_settings()); +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_lib.vcproj b/irdb-lib/pebliss/trunk/pe_lib/pe_lib.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..783912c0254e9a959cc0fbd342c96911de9115f0 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_lib.vcproj @@ -0,0 +1,639 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="pe_bliss" + ProjectGUID="{4B658F8F-1722-4EEA-880C-A4A64DCA9F2C}" + RootNamespace="pe_bliss" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="_WIN64;_DEBUG;_LIB" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + PreprocessorDefinitions="_WIN64;NDEBUG;_LIB" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\pe_base.cpp" + > + </File> + <File + RelativePath=".\pe_exception.cpp" + > + </File> + <File + RelativePath=".\pe_factory.cpp" + > + </File> + <File + RelativePath=".\pe_properties.cpp" + > + </File> + <File + RelativePath=".\pe_properties_generic.cpp" + > + </File> + <File + RelativePath=".\pe_rebuilder.cpp" + > + </File> + <File + RelativePath=".\pe_section.cpp" + > + </File> + <Filter + Name="Other" + > + <File + RelativePath=".\entropy.cpp" + > + </File> + <File + RelativePath=".\pe_checksum.cpp" + > + </File> + <File + RelativePath=".\pe_rich_data.cpp" + > + </File> + <File + RelativePath=".\utils.cpp" + > + </File> + </Filter> + <Filter + Name="PE Resources" + > + <File + RelativePath=".\file_version_info.cpp" + > + </File> + <File + RelativePath=".\message_table.cpp" + > + </File> + <File + RelativePath=".\pe_resource_manager.cpp" + > + </File> + <File + RelativePath=".\pe_resource_viewer.cpp" + > + </File> + <File + RelativePath=".\resource_bitmap_reader.cpp" + > + </File> + <File + RelativePath=".\resource_bitmap_writer.cpp" + > + </File> + <File + RelativePath=".\resource_cursor_icon_reader.cpp" + > + </File> + <File + RelativePath=".\resource_cursor_icon_writer.cpp" + > + </File> + <File + RelativePath=".\resource_data_info.cpp" + > + </File> + <File + RelativePath=".\resource_message_list_reader.cpp" + > + </File> + <File + RelativePath=".\resource_string_table_reader.cpp" + > + </File> + <File + RelativePath=".\resource_version_info_reader.cpp" + > + </File> + <File + RelativePath=".\resource_version_info_writer.cpp" + > + </File> + <File + RelativePath=".\version_info_editor.cpp" + > + </File> + <File + RelativePath=".\version_info_viewer.cpp" + > + </File> + </Filter> + <Filter + Name="PE Directories" + > + <File + RelativePath=".\pe_bound_import.cpp" + > + </File> + <File + RelativePath=".\pe_debug.cpp" + > + </File> + <File + RelativePath=".\pe_directory.cpp" + > + </File> + <File + RelativePath=".\pe_dotnet.cpp" + > + </File> + <File + RelativePath=".\pe_exception_directory.cpp" + > + </File> + <File + RelativePath=".\pe_exports.cpp" + > + </File> + <File + RelativePath=".\pe_imports.cpp" + > + </File> + <File + RelativePath=".\pe_load_config.cpp" + > + </File> + <File + RelativePath=".\pe_relocations.cpp" + > + </File> + <File + RelativePath=".\pe_resources.cpp" + > + </File> + <File + RelativePath=".\pe_tls.cpp" + > + </File> + </Filter> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\pe_base.h" + > + </File> + <File + RelativePath=".\pe_bliss.h" + > + </File> + <File + RelativePath=".\pe_bliss_resources.h" + > + </File> + <File + RelativePath=".\pe_exception.h" + > + </File> + <File + RelativePath=".\pe_factory.h" + > + </File> + <File + RelativePath=".\pe_properties.h" + > + </File> + <File + RelativePath=".\pe_properties_generic.h" + > + </File> + <File + RelativePath=".\pe_rebuilder.h" + > + </File> + <File + RelativePath=".\pe_section.h" + > + </File> + <File + RelativePath=".\pe_structures.h" + > + </File> + <File + RelativePath=".\stdint_defs.h" + > + </File> + <Filter + Name="Other" + > + <File + RelativePath=".\entropy.h" + > + </File> + <File + RelativePath=".\pe_checksum.h" + > + </File> + <File + RelativePath=".\pe_rich_data.h" + > + </File> + <File + RelativePath=".\utils.h" + > + </File> + </Filter> + <Filter + Name="PE Resources" + > + <File + RelativePath=".\file_version_info.h" + > + </File> + <File + RelativePath=".\message_table.h" + > + </File> + <File + RelativePath=".\pe_resource_manager.h" + > + </File> + <File + RelativePath=".\pe_resource_viewer.h" + > + </File> + <File + RelativePath=".\resource_bitmap_reader.h" + > + </File> + <File + RelativePath=".\resource_bitmap_writer.h" + > + </File> + <File + RelativePath=".\resource_cursor_icon_reader.h" + > + </File> + <File + RelativePath=".\resource_cursor_icon_writer.h" + > + </File> + <File + RelativePath=".\resource_data_info.h" + > + </File> + <File + RelativePath=".\resource_internal.h" + > + </File> + <File + RelativePath=".\resource_message_list_reader.h" + > + </File> + <File + RelativePath=".\resource_string_table_reader.h" + > + </File> + <File + RelativePath=".\resource_version_info_reader.h" + > + </File> + <File + RelativePath=".\resource_version_info_writer.h" + > + </File> + <File + RelativePath=".\version_info_editor.h" + > + </File> + <File + RelativePath=".\version_info_viewer.h" + > + </File> + </Filter> + <Filter + Name="PE Directories" + > + <File + RelativePath=".\pe_bound_import.h" + > + </File> + <File + RelativePath=".\pe_debug.h" + > + </File> + <File + RelativePath=".\pe_directory.h" + > + </File> + <File + RelativePath=".\pe_dotnet.h" + > + </File> + <File + RelativePath=".\pe_exception_directory.h" + > + </File> + <File + RelativePath=".\pe_exports.h" + > + </File> + <File + RelativePath=".\pe_imports.h" + > + </File> + <File + RelativePath=".\pe_load_config.h" + > + </File> + <File + RelativePath=".\pe_relocations.h" + > + </File> + <File + RelativePath=".\pe_resources.h" + > + </File> + <File + RelativePath=".\pe_tls.h" + > + </File> + </Filter> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + <File + RelativePath=".\readme.txt" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_lib.vcxproj b/irdb-lib/pebliss/trunk/pe_lib/pe_lib.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..845bf5c35e83f572c0ff5aa33c4d319c6c14d768 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_lib.vcxproj @@ -0,0 +1,228 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <ItemGroup> + <ClCompile Include="entropy.cpp" /> + <ClCompile Include="file_version_info.cpp" /> + <ClCompile Include="message_table.cpp" /> + <ClCompile Include="pe_bound_import.cpp" /> + <ClCompile Include="pe_checksum.cpp" /> + <ClCompile Include="pe_directory.cpp" /> + <ClCompile Include="pe_load_config.cpp" /> + <ClCompile Include="pe_properties.cpp" /> + <ClCompile Include="pe_properties_generic.cpp" /> + <ClCompile Include="pe_rebuilder.cpp" /> + <ClCompile Include="pe_resource_viewer.cpp" /> + <ClCompile Include="pe_section.cpp" /> + <ClCompile Include="pe_tls.cpp" /> + <ClCompile Include="pe_debug.cpp" /> + <ClCompile Include="pe_dotnet.cpp" /> + <ClCompile Include="pe_exception_directory.cpp" /> + <ClCompile Include="pe_exports.cpp" /> + <ClCompile Include="pe_imports.cpp" /> + <ClCompile Include="pe_base.cpp" /> + <ClCompile Include="pe_exception.cpp" /> + <ClCompile Include="pe_factory.cpp" /> + <ClCompile Include="pe_resource_manager.cpp" /> + <ClCompile Include="pe_relocations.cpp" /> + <ClCompile Include="pe_resources.cpp" /> + <ClCompile Include="pe_rich_data.cpp" /> + <ClCompile Include="resource_bitmap_reader.cpp" /> + <ClCompile Include="resource_bitmap_writer.cpp" /> + <ClCompile Include="resource_cursor_icon_writer.cpp" /> + <ClCompile Include="resource_data_info.cpp" /> + <ClCompile Include="resource_cursor_icon_reader.cpp" /> + <ClCompile Include="resource_message_list_reader.cpp" /> + <ClCompile Include="resource_string_table_reader.cpp" /> + <ClCompile Include="resource_version_info_reader.cpp" /> + <ClCompile Include="resource_version_info_writer.cpp" /> + <ClCompile Include="utils.cpp" /> + <ClCompile Include="version_info_editor.cpp" /> + <ClCompile Include="version_info_viewer.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="entropy.h" /> + <ClInclude Include="file_version_info.h" /> + <ClInclude Include="message_table.h" /> + <ClInclude Include="pe_bliss_resources.h" /> + <ClInclude Include="pe_bound_import.h" /> + <ClInclude Include="pe_checksum.h" /> + <ClInclude Include="pe_debug.h" /> + <ClInclude Include="pe_directory.h" /> + <ClInclude Include="pe_dotnet.h" /> + <ClInclude Include="pe_exception_directory.h" /> + <ClInclude Include="pe_exports.h" /> + <ClInclude Include="pe_imports.h" /> + <ClInclude Include="pe_base.h" /> + <ClInclude Include="pe_bliss.h" /> + <ClInclude Include="pe_exception.h" /> + <ClInclude Include="pe_factory.h" /> + <ClInclude Include="pe_load_config.h" /> + <ClInclude Include="pe_properties.h" /> + <ClInclude Include="pe_properties_generic.h" /> + <ClInclude Include="pe_rebuilder.h" /> + <ClInclude Include="pe_resource_manager.h" /> + <ClInclude Include="pe_resource_viewer.h" /> + <ClInclude Include="pe_section.h" /> + <ClInclude Include="pe_structures.h" /> + <ClInclude Include="pe_relocations.h" /> + <ClInclude Include="pe_resources.h" /> + <ClInclude Include="pe_rich_data.h" /> + <ClInclude Include="pe_tls.h" /> + <ClInclude Include="resource_bitmap_reader.h" /> + <ClInclude Include="resource_bitmap_writer.h" /> + <ClInclude Include="resource_data_info.h" /> + <ClInclude Include="resource_cursor_icon_reader.h" /> + <ClInclude Include="resource_cursor_icon_writer.h" /> + <ClInclude Include="resource_internal.h" /> + <ClInclude Include="resource_message_list_reader.h" /> + <ClInclude Include="resource_string_table_reader.h" /> + <ClInclude Include="resource_version_info_reader.h" /> + <ClInclude Include="resource_version_info_writer.h" /> + <ClInclude Include="stdint_defs.h" /> + <ClInclude Include="utils.h" /> + <ClInclude Include="version_info_editor.h" /> + <ClInclude Include="version_info_types.h" /> + <ClInclude Include="version_info_viewer.h" /> + </ItemGroup> + <ItemGroup> + <None Include="readme.txt" /> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{1461F543-D1FA-4E4C-B6D7-0F879F566035}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>pe_bliss</RootNamespace> + <ProjectName>pe_bliss</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_lib.vcxproj.filters b/irdb-lib/pebliss/trunk/pe_lib/pe_lib.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..0cb924dcf10d505851d8d888dc90f7bf935564d0 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_lib.vcxproj.filters @@ -0,0 +1,282 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + <Filter Include="Header Files\Other"> + <UniqueIdentifier>{a442c791-435d-43d3-9545-28196fb75dd9}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files\PE Directories"> + <UniqueIdentifier>{f1eddfb5-ad88-4a6f-8516-031af6cbcff1}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files\PE Resources"> + <UniqueIdentifier>{5e3db017-30ee-4ba1-878c-9e1fe4155555}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files\PE Resources"> + <UniqueIdentifier>{9f2f9f68-41ae-41a6-b8ae-74eb7b966c8f}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files\Other"> + <UniqueIdentifier>{58541054-25c2-412f-93c4-c6f3d8da7c70}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files\PE Directories"> + <UniqueIdentifier>{8429c41b-f602-42fb-994f-0fa4ee6f0601}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="pe_base.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="pe_exception.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="pe_factory.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="pe_section.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="pe_debug.cpp"> + <Filter>Source Files\PE Directories</Filter> + </ClCompile> + <ClCompile Include="pe_directory.cpp"> + <Filter>Source Files\PE Directories</Filter> + </ClCompile> + <ClCompile Include="pe_dotnet.cpp"> + <Filter>Source Files\PE Directories</Filter> + </ClCompile> + <ClCompile Include="pe_exception_directory.cpp"> + <Filter>Source Files\PE Directories</Filter> + </ClCompile> + <ClCompile Include="pe_exports.cpp"> + <Filter>Source Files\PE Directories</Filter> + </ClCompile> + <ClCompile Include="pe_imports.cpp"> + <Filter>Source Files\PE Directories</Filter> + </ClCompile> + <ClCompile Include="pe_load_config.cpp"> + <Filter>Source Files\PE Directories</Filter> + </ClCompile> + <ClCompile Include="pe_relocations.cpp"> + <Filter>Source Files\PE Directories</Filter> + </ClCompile> + <ClCompile Include="pe_resources.cpp"> + <Filter>Source Files\PE Directories</Filter> + </ClCompile> + <ClCompile Include="pe_tls.cpp"> + <Filter>Source Files\PE Directories</Filter> + </ClCompile> + <ClCompile Include="pe_resource_manager.cpp"> + <Filter>Source Files\PE Resources</Filter> + </ClCompile> + <ClCompile Include="pe_rich_data.cpp"> + <Filter>Source Files\Other</Filter> + </ClCompile> + <ClCompile Include="entropy.cpp"> + <Filter>Source Files\Other</Filter> + </ClCompile> + <ClCompile Include="utils.cpp"> + <Filter>Source Files\Other</Filter> + </ClCompile> + <ClCompile Include="message_table.cpp"> + <Filter>Source Files\PE Resources</Filter> + </ClCompile> + <ClCompile Include="file_version_info.cpp"> + <Filter>Source Files\PE Resources</Filter> + </ClCompile> + <ClCompile Include="version_info_viewer.cpp"> + <Filter>Source Files\PE Resources</Filter> + </ClCompile> + <ClCompile Include="version_info_editor.cpp"> + <Filter>Source Files\PE Resources</Filter> + </ClCompile> + <ClCompile Include="pe_resource_viewer.cpp"> + <Filter>Source Files\PE Resources</Filter> + </ClCompile> + <ClCompile Include="pe_properties_generic.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="pe_properties.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="pe_checksum.cpp"> + <Filter>Source Files\Other</Filter> + </ClCompile> + <ClCompile Include="pe_bound_import.cpp"> + <Filter>Source Files\PE Directories</Filter> + </ClCompile> + <ClCompile Include="resource_data_info.cpp"> + <Filter>Source Files\PE Resources</Filter> + </ClCompile> + <ClCompile Include="resource_bitmap_reader.cpp"> + <Filter>Source Files\PE Resources</Filter> + </ClCompile> + <ClCompile Include="resource_bitmap_writer.cpp"> + <Filter>Source Files\PE Resources</Filter> + </ClCompile> + <ClCompile Include="resource_cursor_icon_reader.cpp"> + <Filter>Source Files\PE Resources</Filter> + </ClCompile> + <ClCompile Include="resource_cursor_icon_writer.cpp"> + <Filter>Source Files\PE Resources</Filter> + </ClCompile> + <ClCompile Include="resource_version_info_reader.cpp"> + <Filter>Source Files\PE Resources</Filter> + </ClCompile> + <ClCompile Include="resource_version_info_writer.cpp"> + <Filter>Source Files\PE Resources</Filter> + </ClCompile> + <ClCompile Include="resource_string_table_reader.cpp"> + <Filter>Source Files\PE Resources</Filter> + </ClCompile> + <ClCompile Include="resource_message_list_reader.cpp"> + <Filter>Source Files\PE Resources</Filter> + </ClCompile> + <ClCompile Include="pe_rebuilder.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="pe_base.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="pe_exception.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="pe_factory.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="pe_structures.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="stdint_defs.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="pe_bliss.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="pe_section.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="pe_bound_import.h"> + <Filter>Header Files\PE Directories</Filter> + </ClInclude> + <ClInclude Include="pe_debug.h"> + <Filter>Header Files\PE Directories</Filter> + </ClInclude> + <ClInclude Include="pe_directory.h"> + <Filter>Header Files\PE Directories</Filter> + </ClInclude> + <ClInclude Include="pe_dotnet.h"> + <Filter>Header Files\PE Directories</Filter> + </ClInclude> + <ClInclude Include="pe_exception_directory.h"> + <Filter>Header Files\PE Directories</Filter> + </ClInclude> + <ClInclude Include="pe_exports.h"> + <Filter>Header Files\PE Directories</Filter> + </ClInclude> + <ClInclude Include="pe_imports.h"> + <Filter>Header Files\PE Directories</Filter> + </ClInclude> + <ClInclude Include="pe_relocations.h"> + <Filter>Header Files\PE Directories</Filter> + </ClInclude> + <ClInclude Include="pe_resources.h"> + <Filter>Header Files\PE Directories</Filter> + </ClInclude> + <ClInclude Include="pe_tls.h"> + <Filter>Header Files\PE Directories</Filter> + </ClInclude> + <ClInclude Include="pe_load_config.h"> + <Filter>Header Files\PE Directories</Filter> + </ClInclude> + <ClInclude Include="entropy.h"> + <Filter>Header Files\Other</Filter> + </ClInclude> + <ClInclude Include="utils.h"> + <Filter>Header Files\Other</Filter> + </ClInclude> + <ClInclude Include="pe_rich_data.h"> + <Filter>Header Files\Other</Filter> + </ClInclude> + <ClInclude Include="pe_resource_manager.h"> + <Filter>Header Files\PE Resources</Filter> + </ClInclude> + <ClInclude Include="message_table.h"> + <Filter>Header Files\PE Resources</Filter> + </ClInclude> + <ClInclude Include="file_version_info.h"> + <Filter>Header Files\PE Resources</Filter> + </ClInclude> + <ClInclude Include="version_info_viewer.h"> + <Filter>Header Files\PE Resources</Filter> + </ClInclude> + <ClInclude Include="pe_resource_viewer.h"> + <Filter>Header Files\PE Resources</Filter> + </ClInclude> + <ClInclude Include="version_info_editor.h"> + <Filter>Header Files\PE Resources</Filter> + </ClInclude> + <ClInclude Include="resource_internal.h"> + <Filter>Header Files\PE Resources</Filter> + </ClInclude> + <ClInclude Include="pe_properties.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="pe_properties_generic.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="pe_checksum.h"> + <Filter>Header Files\Other</Filter> + </ClInclude> + <ClInclude Include="pe_bliss_resources.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="resource_data_info.h"> + <Filter>Header Files\PE Resources</Filter> + </ClInclude> + <ClInclude Include="resource_bitmap_reader.h"> + <Filter>Header Files\PE Resources</Filter> + </ClInclude> + <ClInclude Include="resource_bitmap_writer.h"> + <Filter>Header Files\PE Resources</Filter> + </ClInclude> + <ClInclude Include="resource_cursor_icon_reader.h"> + <Filter>Header Files\PE Resources</Filter> + </ClInclude> + <ClInclude Include="resource_cursor_icon_writer.h"> + <Filter>Header Files\PE Resources</Filter> + </ClInclude> + <ClInclude Include="resource_version_info_reader.h"> + <Filter>Header Files\PE Resources</Filter> + </ClInclude> + <ClInclude Include="resource_version_info_writer.h"> + <Filter>Header Files\PE Resources</Filter> + </ClInclude> + <ClInclude Include="resource_string_table_reader.h"> + <Filter>Header Files\PE Resources</Filter> + </ClInclude> + <ClInclude Include="resource_message_list_reader.h"> + <Filter>Header Files\PE Resources</Filter> + </ClInclude> + <ClInclude Include="pe_rebuilder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="version_info_types.h"> + <Filter>Header Files\PE Resources</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <None Include="readme.txt" /> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_load_config.cpp b/irdb-lib/pebliss/trunk/pe_lib/pe_load_config.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dedb2a61a16c4a7b4e9dbd9fa9cda195a9f825de --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_load_config.cpp @@ -0,0 +1,536 @@ +#include <algorithm> +#include <string.h> +#include "pe_load_config.h" +#include "pe_properties_generic.h" + +namespace pe_bliss +{ +using namespace pe_win; + +//IMAGE CONFIG +//Default constructor +image_config_info::image_config_info() + :time_stamp_(0), + major_version_(0), minor_version_(0), + global_flags_clear_(0), global_flags_set_(0), + critical_section_default_timeout_(0), + decommit_free_block_threshold_(0), decommit_total_free_threshold_(0), + lock_prefix_table_va_(0), + max_allocation_size_(0), + virtual_memory_threshold_(0), + process_affinity_mask_(0), + process_heap_flags_(0), + service_pack_version_(0), + edit_list_va_(0), + security_cookie_va_(0), + se_handler_table_va_(0), + se_handler_count_(0) +{} + +//Constructors from PE structures +template<typename ConfigStructure> +image_config_info::image_config_info(const ConfigStructure& info) + :time_stamp_(info.TimeDateStamp), + major_version_(info.MajorVersion), minor_version_(info.MinorVersion), + global_flags_clear_(info.GlobalFlagsClear), global_flags_set_(info.GlobalFlagsSet), + critical_section_default_timeout_(info.CriticalSectionDefaultTimeout), + decommit_free_block_threshold_(info.DeCommitFreeBlockThreshold), decommit_total_free_threshold_(info.DeCommitTotalFreeThreshold), + lock_prefix_table_va_(info.LockPrefixTable), + max_allocation_size_(info.MaximumAllocationSize), + virtual_memory_threshold_(info.VirtualMemoryThreshold), + process_affinity_mask_(info.ProcessAffinityMask), + process_heap_flags_(info.ProcessHeapFlags), + service_pack_version_(info.CSDVersion), + edit_list_va_(info.EditList), + security_cookie_va_(info.SecurityCookie), + se_handler_table_va_(info.SEHandlerTable), + se_handler_count_(info.SEHandlerCount) +{} + +//Instantiate template constructor with needed structures +template image_config_info::image_config_info(const image_load_config_directory32& info); +template image_config_info::image_config_info(const image_load_config_directory64& info); + +//Returns the date and time stamp value +uint32_t image_config_info::get_time_stamp() const +{ + return time_stamp_; +} + +//Returns major version number +uint16_t image_config_info::get_major_version() const +{ + return major_version_; +} + +//Returns minor version number +uint16_t image_config_info::get_minor_version() const +{ + return minor_version_; +} + +//Returns clear global flags +uint32_t image_config_info::get_global_flags_clear() const +{ + return global_flags_clear_; +} + +//Returns set global flags +uint32_t image_config_info::get_global_flags_set() const +{ + return global_flags_set_; +} + +//Returns critical section default timeout +uint32_t image_config_info::get_critical_section_default_timeout() const +{ + return critical_section_default_timeout_; +} + +//Get the size of the minimum block that +//must be freed before it is freed (de-committed), in bytes +uint64_t image_config_info::get_decommit_free_block_threshold() const +{ + return decommit_free_block_threshold_; +} + +//Returns the size of the minimum total memory +//that must be freed in the process heap before it is freed (de-committed), in bytes +uint64_t image_config_info::get_decommit_total_free_threshold() const +{ + return decommit_total_free_threshold_; +} + +//Returns VA of a list of addresses where the LOCK prefix is used +uint64_t image_config_info::get_lock_prefix_table_va() const +{ + return lock_prefix_table_va_; +} + +//Returns the maximum allocation size, in bytes +uint64_t image_config_info::get_max_allocation_size() const +{ + return max_allocation_size_; +} + +//Returns the maximum block size that can be allocated from heap segments, in bytes +uint64_t image_config_info::get_virtual_memory_threshold() const +{ + return virtual_memory_threshold_; +} + +//Returns process affinity mask +uint64_t image_config_info::get_process_affinity_mask() const +{ + return process_affinity_mask_; +} + +//Returns process heap flags +uint32_t image_config_info::get_process_heap_flags() const +{ + return process_heap_flags_; +} + +//Returns service pack version (CSDVersion) +uint16_t image_config_info::get_service_pack_version() const +{ + return service_pack_version_; +} + +//Returns VA of edit list (reserved by system) +uint64_t image_config_info::get_edit_list_va() const +{ + return edit_list_va_; +} + +//Returns a pointer to a cookie that is used by Visual C++ or GS implementation +uint64_t image_config_info::get_security_cookie_va() const +{ + return security_cookie_va_; +} + +//Returns VA of the sorted table of RVAs of each valid, unique handler in the image +uint64_t image_config_info::get_se_handler_table_va() const +{ + return se_handler_table_va_; +} + +//Returns the count of unique handlers in the table +uint64_t image_config_info::get_se_handler_count() const +{ + return se_handler_count_; +} + +//Returns SE Handler RVA list +const image_config_info::se_handler_list& image_config_info::get_se_handler_rvas() const +{ + return se_handlers_; +} + +//Returns Lock Prefix RVA list +const image_config_info::lock_prefix_rva_list& image_config_info::get_lock_prefix_rvas() const +{ + return lock_prefixes_; +} + +//Adds SE Handler RVA to list +void image_config_info::add_se_handler_rva(uint32_t rva) +{ + se_handlers_.push_back(rva); +} + +//Clears SE Handler list +void image_config_info::clear_se_handler_list() +{ + se_handlers_.clear(); +} + +//Adds Lock Prefix RVA to list +void image_config_info::add_lock_prefix_rva(uint32_t rva) +{ + lock_prefixes_.push_back(rva); +} + +//Clears Lock Prefix list +void image_config_info::clear_lock_prefix_list() +{ + lock_prefixes_.clear(); +} + +//Sets the date and time stamp value +void image_config_info::set_time_stamp(uint32_t time_stamp) +{ + time_stamp_ = time_stamp; +} + +//Sets major version number +void image_config_info::set_major_version(uint16_t major_version) +{ + major_version_ = major_version; +} + +//Sets minor version number +void image_config_info::set_minor_version(uint16_t minor_version) +{ + minor_version_ = minor_version; +} + +//Sets clear global flags +void image_config_info::set_global_flags_clear(uint32_t global_flags_clear) +{ + global_flags_clear_ = global_flags_clear; +} + +//Sets set global flags +void image_config_info::set_global_flags_set(uint32_t global_flags_set) +{ + global_flags_set_ = global_flags_set; +} + +//Sets critical section default timeout +void image_config_info::set_critical_section_default_timeout(uint32_t critical_section_default_timeout) +{ + critical_section_default_timeout_ = critical_section_default_timeout; +} + +//Sets the size of the minimum block that +//must be freed before it is freed (de-committed), in bytes +void image_config_info::set_decommit_free_block_threshold(uint64_t decommit_free_block_threshold) +{ + decommit_free_block_threshold_ = decommit_free_block_threshold; +} + +//Sets the size of the minimum total memory +//that must be freed in the process heap before it is freed (de-committed), in bytes +void image_config_info::set_decommit_total_free_threshold(uint64_t decommit_total_free_threshold) +{ + decommit_total_free_threshold_ = decommit_total_free_threshold; +} + +//Sets VA of a list of addresses where the LOCK prefix is used +//If you rebuild this list, VA will be re-assigned automatically +void image_config_info::set_lock_prefix_table_va(uint64_t lock_prefix_table_va) +{ + lock_prefix_table_va_ = lock_prefix_table_va; +} + +//Sets the maximum allocation size, in bytes +void image_config_info::set_max_allocation_size(uint64_t max_allocation_size) +{ + max_allocation_size_ = max_allocation_size; +} + +//Sets the maximum block size that can be allocated from heap segments, in bytes +void image_config_info::set_virtual_memory_threshold(uint64_t virtual_memory_threshold) +{ + virtual_memory_threshold_ = virtual_memory_threshold; +} + +//Sets process affinity mask +void image_config_info::set_process_affinity_mask(uint64_t process_affinity_mask) +{ + process_affinity_mask_ = process_affinity_mask; +} + +//Sets process heap flags +void image_config_info::set_process_heap_flags(uint32_t process_heap_flags) +{ + process_heap_flags_ = process_heap_flags; +} + +//Sets service pack version (CSDVersion) +void image_config_info::set_service_pack_version(uint16_t service_pack_version) +{ + service_pack_version_ = service_pack_version; +} + +//Sets VA of edit list (reserved by system) +void image_config_info::set_edit_list_va(uint64_t edit_list_va) +{ + edit_list_va_ = edit_list_va; +} + +//Sets a pointer to a cookie that is used by Visual C++ or GS implementation +void image_config_info::set_security_cookie_va(uint64_t security_cookie_va) +{ + security_cookie_va_ = security_cookie_va; +} + +//Sets VA of the sorted table of RVAs of each valid, unique handler in the image +//If you rebuild this list, VA will be re-assigned automatically +void image_config_info::set_se_handler_table_va(uint64_t se_handler_table_va) +{ + se_handler_table_va_ = se_handler_table_va; +} + +//Returns SE Handler RVA list +image_config_info::se_handler_list& image_config_info::get_se_handler_rvas() +{ + return se_handlers_; +} + +//Returns Lock Prefix RVA list +image_config_info::lock_prefix_rva_list& image_config_info::get_lock_prefix_rvas() +{ + return lock_prefixes_; +} + +//Returns image config info +//If image does not have config info, throws an exception +const image_config_info get_image_config(const pe_base& pe) +{ + return pe.get_pe_type() == pe_type_32 + ? get_image_config_base<pe_types_class_32>(pe) + : get_image_config_base<pe_types_class_64>(pe); +} + +//Image config rebuilder +const image_directory rebuild_image_config(pe_base& pe, const image_config_info& info, section& image_config_section, uint32_t offset_from_section_start, bool write_se_handlers, bool write_lock_prefixes, bool save_to_pe_header, bool auto_strip_last_section) +{ + return pe.get_pe_type() == pe_type_32 + ? rebuild_image_config_base<pe_types_class_32>(pe, info, image_config_section, offset_from_section_start, write_se_handlers, write_lock_prefixes, save_to_pe_header, auto_strip_last_section) + : rebuild_image_config_base<pe_types_class_64>(pe, info, image_config_section, offset_from_section_start, write_se_handlers, write_lock_prefixes, save_to_pe_header, auto_strip_last_section); +} + + +//Returns image config info +//If image does not have config info, throws an exception +template<typename PEClassType> +const image_config_info get_image_config_base(const pe_base& pe) +{ + //Check if image has config directory + if(!pe.has_config()) + throw pe_exception("Image does not have load config directory", pe_exception::directory_does_not_exist); + + //Get load config structure + typename PEClassType::ConfigStruct config_info = pe.section_data_from_rva<typename PEClassType::ConfigStruct>(pe.get_directory_rva(image_directory_entry_load_config), section_data_virtual); + + //Check size of config directory + if(config_info.Size != sizeof(config_info)) + throw pe_exception("Incorrect (or old) load config directory", pe_exception::incorrect_config_directory); + + //Fill return structure + image_config_info ret(config_info); + + //Check possible overflow + if(config_info.SEHandlerCount >= pe_utils::max_dword / sizeof(uint32_t) + || config_info.SEHandlerTable >= static_cast<typename PEClassType::BaseSize>(-1) - config_info.SEHandlerCount * sizeof(uint32_t)) + throw pe_exception("Incorrect load config directory", pe_exception::incorrect_config_directory); + + //Read sorted SE handler RVA list (if any) + for(typename PEClassType::BaseSize i = 0; i != config_info.SEHandlerCount; ++i) + ret.add_se_handler_rva(pe.section_data_from_va<uint32_t>(static_cast<typename PEClassType::BaseSize>(config_info.SEHandlerTable + i * sizeof(uint32_t)))); + + if(config_info.LockPrefixTable) + { + //Read Lock Prefix VA list (if any) + unsigned long current = 0; + while(true) + { + typename PEClassType::BaseSize lock_prefix_va = pe.section_data_from_va<typename PEClassType::BaseSize>(static_cast<typename PEClassType::BaseSize>(config_info.LockPrefixTable + current * sizeof(typename PEClassType::BaseSize))); + if(!lock_prefix_va) + break; + + ret.add_lock_prefix_rva(pe.va_to_rva(lock_prefix_va)); + + ++current; + } + } + + return ret; +} + +//Image config directory rebuilder +//auto_strip_last_section - if true and TLS are placed in the last section, it will be automatically stripped +//If write_se_handlers = true, SE Handlers list will be written just after image config directory structure +//If write_lock_prefixes = true, Lock Prefixes address list will be written just after image config directory structure +template<typename PEClassType> +const image_directory rebuild_image_config_base(pe_base& pe, const image_config_info& info, section& image_config_section, uint32_t offset_from_section_start, bool write_se_handlers, bool write_lock_prefixes, bool save_to_pe_header, bool auto_strip_last_section) +{ + //Check that image_config_section is attached to this PE image + if(!pe.section_attached(image_config_section)) + throw pe_exception("Image Config section must be attached to PE file", pe_exception::section_is_not_attached); + + uint32_t alignment = pe_utils::align_up(offset_from_section_start, sizeof(typename PEClassType::BaseSize)) - offset_from_section_start; + + uint32_t needed_size = sizeof(typename PEClassType::ConfigStruct); //Calculate needed size for Image Config table + + uint32_t image_config_data_pos = offset_from_section_start + alignment; + + uint32_t current_pos_of_se_handlers = 0; + uint32_t current_pos_of_lock_prefixes = 0; + + if(write_se_handlers) + { + current_pos_of_se_handlers = needed_size + image_config_data_pos; + needed_size += static_cast<uint32_t>(info.get_se_handler_rvas().size()) * sizeof(uint32_t); //RVAs of SE Handlers + } + + if(write_lock_prefixes) + { + current_pos_of_lock_prefixes = needed_size + image_config_data_pos; + needed_size += static_cast<uint32_t>((info.get_lock_prefix_rvas().size() + 1) * sizeof(typename PEClassType::BaseSize)); //VAs of Lock Prefixes (and ending null element) + } + + //Check if image_config_section is last one. If it's not, check if there's enough place for Image Config data + if(&image_config_section != &*(pe.get_image_sections().end() - 1) && + (image_config_section.empty() || pe_utils::align_up(image_config_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + image_config_data_pos)) + throw pe_exception("Insufficient space for TLS directory", pe_exception::insufficient_space); + + std::string& raw_data = image_config_section.get_raw_data(); + + //This will be done only if image_config_section is the last section of image or for section with unaligned raw length of data + if(raw_data.length() < needed_size + image_config_data_pos) + raw_data.resize(needed_size + image_config_data_pos); //Expand section raw data + + //Create and fill Image Config structure + typename PEClassType::ConfigStruct image_config_section_struct = {0}; + image_config_section_struct.Size = sizeof(image_config_section_struct); + image_config_section_struct.TimeDateStamp = info.get_time_stamp(); + image_config_section_struct.MajorVersion = info.get_major_version(); + image_config_section_struct.MinorVersion = info.get_minor_version(); + image_config_section_struct.GlobalFlagsClear = info.get_global_flags_clear(); + image_config_section_struct.GlobalFlagsSet = info.get_global_flags_set(); + image_config_section_struct.CriticalSectionDefaultTimeout = info.get_critical_section_default_timeout(); + image_config_section_struct.DeCommitFreeBlockThreshold = static_cast<typename PEClassType::BaseSize>(info.get_decommit_free_block_threshold()); + image_config_section_struct.DeCommitTotalFreeThreshold = static_cast<typename PEClassType::BaseSize>(info.get_decommit_total_free_threshold()); + image_config_section_struct.MaximumAllocationSize = static_cast<typename PEClassType::BaseSize>(info.get_max_allocation_size()); + image_config_section_struct.VirtualMemoryThreshold = static_cast<typename PEClassType::BaseSize>(info.get_virtual_memory_threshold()); + image_config_section_struct.ProcessHeapFlags = info.get_process_heap_flags(); + image_config_section_struct.ProcessAffinityMask = static_cast<typename PEClassType::BaseSize>(info.get_process_affinity_mask()); + image_config_section_struct.CSDVersion = info.get_service_pack_version(); + image_config_section_struct.EditList = static_cast<typename PEClassType::BaseSize>(info.get_edit_list_va()); + image_config_section_struct.SecurityCookie = static_cast<typename PEClassType::BaseSize>(info.get_security_cookie_va()); + image_config_section_struct.SEHandlerCount = static_cast<typename PEClassType::BaseSize>(info.get_se_handler_rvas().size()); + + + if(write_se_handlers) + { + if(info.get_se_handler_rvas().empty()) + { + write_se_handlers = false; + image_config_section_struct.SEHandlerTable = 0; + } + else + { + typename PEClassType::BaseSize va; + pe.rva_to_va(pe.rva_from_section_offset(image_config_section, current_pos_of_se_handlers), va); + image_config_section_struct.SEHandlerTable = va; + } + } + else + { + image_config_section_struct.SEHandlerTable = static_cast<typename PEClassType::BaseSize>(info.get_se_handler_table_va()); + } + + if(write_lock_prefixes) + { + if(info.get_lock_prefix_rvas().empty()) + { + write_lock_prefixes = false; + image_config_section_struct.LockPrefixTable = 0; + } + else + { + typename PEClassType::BaseSize va; + pe.rva_to_va(pe.rva_from_section_offset(image_config_section, current_pos_of_lock_prefixes), va); + image_config_section_struct.LockPrefixTable = va; + } + } + else + { + image_config_section_struct.LockPrefixTable = static_cast<typename PEClassType::BaseSize>(info.get_lock_prefix_table_va()); + } + + //Write image config section + memcpy(&raw_data[image_config_data_pos], &image_config_section_struct, sizeof(image_config_section_struct)); + + if(write_se_handlers) + { + //Sort SE Handlers list + image_config_info::se_handler_list sorted_list = info.get_se_handler_rvas(); + std::sort(sorted_list.begin(), sorted_list.end()); + + //Write SE Handlers table + for(image_config_info::se_handler_list::const_iterator it = sorted_list.begin(); it != sorted_list.end(); ++it) + { + uint32_t se_handler_rva = *it; + memcpy(&raw_data[current_pos_of_se_handlers], &se_handler_rva, sizeof(se_handler_rva)); + current_pos_of_se_handlers += sizeof(se_handler_rva); + } + } + + if(write_lock_prefixes) + { + //Write Lock Prefixes VA list + for(image_config_info::lock_prefix_rva_list::const_iterator it = info.get_lock_prefix_rvas().begin(); it != info.get_lock_prefix_rvas().end(); ++it) + { + typename PEClassType::BaseSize lock_prefix_va; + pe.rva_to_va(*it, lock_prefix_va); + memcpy(&raw_data[current_pos_of_lock_prefixes], &lock_prefix_va, sizeof(lock_prefix_va)); + current_pos_of_lock_prefixes += sizeof(lock_prefix_va); + } + + { + //Ending null VA + typename PEClassType::BaseSize lock_prefix_va = 0; + memcpy(&raw_data[current_pos_of_lock_prefixes], &lock_prefix_va, sizeof(lock_prefix_va)); + } + } + + //Adjust section raw and virtual sizes + pe.recalculate_section_sizes(image_config_section, auto_strip_last_section); + + image_directory ret(pe.rva_from_section_offset(image_config_section, image_config_data_pos), sizeof(typename PEClassType::ConfigStruct)); + + //If auto-rewrite of PE headers is required + if(save_to_pe_header) + { + pe.set_directory_rva(image_directory_entry_load_config, ret.get_rva()); + pe.set_directory_size(image_directory_entry_load_config, ret.get_size()); + } + + return ret; +} + +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_load_config.h b/irdb-lib/pebliss/trunk/pe_lib/pe_load_config.h new file mode 100644 index 0000000000000000000000000000000000000000..5fb6b96c90a834a7252f88f1bd71bbad54ae29a9 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_load_config.h @@ -0,0 +1,166 @@ +#ifndef pebliss_pe_load_config_h +#define pebliss_pe_load_config_h +#pragma once +#include <vector> +#include "pe_structures.h" +#include "pe_base.h" +#include "pe_directory.h" + +namespace pe_bliss +{ +//Class representing image configuration information +class image_config_info +{ +public: + typedef std::vector<uint32_t> se_handler_list; + typedef std::vector<uint32_t> lock_prefix_rva_list; + +public: + //Default constructor + image_config_info(); + //Constructors from PE structures (no checks) + template<typename ConfigStructure> + explicit image_config_info(const ConfigStructure& info); + + //Returns the date and time stamp value + uint32_t get_time_stamp() const; + //Returns major version number + uint16_t get_major_version() const; + //Returns minor version number + uint16_t get_minor_version() const; + //Returns clear global flags + uint32_t get_global_flags_clear() const; + //Returns set global flags + uint32_t get_global_flags_set() const; + //Returns critical section default timeout + uint32_t get_critical_section_default_timeout() const; + //Get the size of the minimum block that + //must be freed before it is freed (de-committed), in bytes + uint64_t get_decommit_free_block_threshold() const; + //Returns the size of the minimum total memory + //that must be freed in the process heap before it is freed (de-committed), in bytes + uint64_t get_decommit_total_free_threshold() const; + //Returns VA of a list of addresses where the LOCK prefix is used + uint64_t get_lock_prefix_table_va() const; + //Returns the maximum allocation size, in bytes + uint64_t get_max_allocation_size() const; + //Returns the maximum block size that can be allocated from heap segments, in bytes + uint64_t get_virtual_memory_threshold() const; + //Returns process affinity mask + uint64_t get_process_affinity_mask() const; + //Returns process heap flags + uint32_t get_process_heap_flags() const; + //Returns service pack version (CSDVersion) + uint16_t get_service_pack_version() const; + //Returns VA of edit list (reserved by system) + uint64_t get_edit_list_va() const; + //Returns a pointer to a cookie that is used by Visual C++ or GS implementation + uint64_t get_security_cookie_va() const; + //Returns VA of the sorted table of RVAs of each valid, unique handler in the image + uint64_t get_se_handler_table_va() const; + //Returns the count of unique handlers in the table + uint64_t get_se_handler_count() const; + + //Returns SE Handler RVA list + const se_handler_list& get_se_handler_rvas() const; + + //Returns Lock Prefix RVA list + const lock_prefix_rva_list& get_lock_prefix_rvas() const; + +public: //These functions do not change everything inside image, they are used by PE class + //Also you can use these functions to rebuild image config directory + + //Adds SE Handler RVA to list + void add_se_handler_rva(uint32_t rva); + //Clears SE Handler list + void clear_se_handler_list(); + + //Adds Lock Prefix RVA to list + void add_lock_prefix_rva(uint32_t rva); + //Clears Lock Prefix list + void clear_lock_prefix_list(); + + //Sets the date and time stamp value + void set_time_stamp(uint32_t time_stamp); + //Sets major version number + void set_major_version(uint16_t major_version); + //Sets minor version number + void set_minor_version(uint16_t minor_version); + //Sets clear global flags + void set_global_flags_clear(uint32_t global_flags_clear); + //Sets set global flags + void set_global_flags_set(uint32_t global_flags_set); + //Sets critical section default timeout + void set_critical_section_default_timeout(uint32_t critical_section_default_timeout); + //Sets the size of the minimum block that + //must be freed before it is freed (de-committed), in bytes + void set_decommit_free_block_threshold(uint64_t decommit_free_block_threshold); + //Sets the size of the minimum total memory + //that must be freed in the process heap before it is freed (de-committed), in bytes + void set_decommit_total_free_threshold(uint64_t decommit_total_free_threshold); + //Sets VA of a list of addresses where the LOCK prefix is used + //If you rebuild this list, VA will be re-assigned automatically + void set_lock_prefix_table_va(uint64_t lock_prefix_table_va); + //Sets the maximum allocation size, in bytes + void set_max_allocation_size(uint64_t max_allocation_size); + //Sets the maximum block size that can be allocated from heap segments, in bytes + void set_virtual_memory_threshold(uint64_t virtual_memory_threshold); + //Sets process affinity mask + void set_process_affinity_mask(uint64_t process_affinity_mask); + //Sets process heap flags + void set_process_heap_flags(uint32_t process_heap_flags); + //Sets service pack version (CSDVersion) + void set_service_pack_version(uint16_t service_pack_version); + //Sets VA of edit list (reserved by system) + void set_edit_list_va(uint64_t edit_list_va); + //Sets a pointer to a cookie that is used by Visual C++ or GS implementation + void set_security_cookie_va(uint64_t security_cookie_va); + //Sets VA of the sorted table of RVAs of each valid, unique handler in the image + //If you rebuild this list, VA will be re-assigned automatically + void set_se_handler_table_va(uint64_t se_handler_table_va); + + //Returns SE Handler RVA list + se_handler_list& get_se_handler_rvas(); + + //Returns Lock Prefix RVA list + lock_prefix_rva_list& get_lock_prefix_rvas(); + +private: + uint32_t time_stamp_; + uint16_t major_version_, minor_version_; + uint32_t global_flags_clear_, global_flags_set_; + uint32_t critical_section_default_timeout_; + uint64_t decommit_free_block_threshold_, decommit_total_free_threshold_; + uint64_t lock_prefix_table_va_; + uint64_t max_allocation_size_; + uint64_t virtual_memory_threshold_; + uint64_t process_affinity_mask_; + uint32_t process_heap_flags_; + uint16_t service_pack_version_; + uint64_t edit_list_va_; + uint64_t security_cookie_va_; + uint64_t se_handler_table_va_; + uint64_t se_handler_count_; + + se_handler_list se_handlers_; + lock_prefix_rva_list lock_prefixes_; +}; + +//Returns image config info +//If image does not have config info, throws an exception +const image_config_info get_image_config(const pe_base& pe); + +template<typename PEClassType> +const image_config_info get_image_config_base(const pe_base& pe); + + +//Image config directory rebuilder +//auto_strip_last_section - if true and TLS are placed in the last section, it will be automatically stripped +//If write_se_handlers = true, SE Handlers list will be written just after image config directory structure +//If write_lock_prefixes = true, Lock Prefixes address list will be written just after image config directory structure +const image_directory rebuild_image_config(pe_base& pe, const image_config_info& info, section& image_config_section, uint32_t offset_from_section_start = 0, bool write_se_handlers = true, bool write_lock_prefixes = true, bool save_to_pe_header = true, bool auto_strip_last_section = true); + +template<typename PEClassType> +const image_directory rebuild_image_config_base(pe_base& pe, const image_config_info& info, section& image_config_section, uint32_t offset_from_section_start = 0, bool write_se_handlers = true, bool write_lock_prefixes = true, bool save_to_pe_header = true, bool auto_strip_last_section = true); +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_properties.cpp b/irdb-lib/pebliss/trunk/pe_lib/pe_properties.cpp new file mode 100644 index 0000000000000000000000000000000000000000..134bf29caf048f357a8af5c49d503f9a36aeddb3 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_properties.cpp @@ -0,0 +1,20 @@ +#include "pe_properties.h" + +namespace pe_bliss +{ +//Destructor +pe_properties::~pe_properties() +{} + +//Clears PE characteristics flag +void pe_properties::clear_characteristics_flags(uint16_t flags) +{ + set_characteristics(get_characteristics() & ~flags); +} + +//Sets PE characteristics flag +void pe_properties::set_characteristics_flags(uint16_t flags) +{ + set_characteristics(get_characteristics() | flags); +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_properties.h b/irdb-lib/pebliss/trunk/pe_lib/pe_properties.h new file mode 100644 index 0000000000000000000000000000000000000000..f878045f615a93498a803f26b9d2ba5dbfe67e20 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_properties.h @@ -0,0 +1,221 @@ +#ifndef pebliss_pe_properties_h +#define pebliss_pe_properties_h +#pragma once +#ifndef pebliss_props_h +#define pebliss_props_h +#include <memory> +#include "pe_structures.h" + +namespace pe_bliss +{ +class pe_properties +{ +public: //Constructors + virtual std::auto_ptr<pe_properties> duplicate() const = 0; + + //Fills properly PE structures + virtual void create_pe(uint32_t section_alignment, uint16_t subsystem) = 0; + +public: + //Destructor + virtual ~pe_properties(); + + +public: //DIRECTORIES + //Returns true if directory exists + virtual bool directory_exists(uint32_t id) const = 0; + + //Removes directory + virtual void remove_directory(uint32_t id) = 0; + + //Returns directory RVA + virtual uint32_t get_directory_rva(uint32_t id) const = 0; + //Returns directory size + virtual uint32_t get_directory_size(uint32_t id) const = 0; + + //Sets directory RVA (just a value of PE header, no moving occurs) + virtual void set_directory_rva(uint32_t id, uint32_t rva) = 0; + //Sets directory size (just a value of PE header, no moving occurs) + virtual void set_directory_size(uint32_t id, uint32_t size) = 0; + + //Strips only zero DATA_DIRECTORY entries to count = min_count + //Returns resulting number of data directories + //strip_iat_directory - if true, even not empty IAT directory will be stripped + virtual uint32_t strip_data_directories(uint32_t min_count = 1, bool strip_iat_directory = true) = 0; + + +public: //IMAGE + //Returns PE type of this image + virtual pe_type get_pe_type() const = 0; + + +public: //PE HEADER + //Returns image base for PE32 and PE64 respectively + virtual uint32_t get_image_base_32() const = 0; + virtual uint64_t get_image_base_64() const = 0; + + //Sets new image base for PE32 + virtual void set_image_base(uint32_t base) = 0; + //Sets new image base for PE32/PE+ + virtual void set_image_base_64(uint64_t base) = 0; + + //Returns image entry point + virtual uint32_t get_ep() const = 0; + //Sets image entry point + virtual void set_ep(uint32_t new_ep) = 0; + + //Returns file alignment + virtual uint32_t get_file_alignment() const = 0; + //Returns section alignment + virtual uint32_t get_section_alignment() const = 0; + + //Sets heap size commit for PE32 and PE64 respectively + virtual void set_heap_size_commit(uint32_t size) = 0; + virtual void set_heap_size_commit(uint64_t size) = 0; + //Sets heap size reserve for PE32 and PE64 respectively + virtual void set_heap_size_reserve(uint32_t size) = 0; + virtual void set_heap_size_reserve(uint64_t size) = 0; + //Sets stack size commit for PE32 and PE64 respectively + virtual void set_stack_size_commit(uint32_t size) = 0; + virtual void set_stack_size_commit(uint64_t size) = 0; + //Sets stack size reserve for PE32 and PE64 respectively + virtual void set_stack_size_reserve(uint32_t size) = 0; + virtual void set_stack_size_reserve(uint64_t size) = 0; + + //Returns heap size commit for PE32 and PE64 respectively + virtual uint32_t get_heap_size_commit_32() const = 0; + virtual uint64_t get_heap_size_commit_64() const = 0; + //Returns heap size reserve for PE32 and PE64 respectively + virtual uint32_t get_heap_size_reserve_32() const = 0; + virtual uint64_t get_heap_size_reserve_64() const = 0; + //Returns stack size commit for PE32 and PE64 respectively + virtual uint32_t get_stack_size_commit_32() const = 0; + virtual uint64_t get_stack_size_commit_64() const = 0; + //Returns stack size reserve for PE32 and PE64 respectively + virtual uint32_t get_stack_size_reserve_32() const = 0; + virtual uint64_t get_stack_size_reserve_64() const = 0; + + //Returns virtual size of image + virtual uint32_t get_size_of_image() const = 0; + + //Returns number of RVA and sizes (number of DATA_DIRECTORY entries) + virtual uint32_t get_number_of_rvas_and_sizes() const = 0; + //Sets number of RVA and sizes (number of DATA_DIRECTORY entries) + virtual void set_number_of_rvas_and_sizes(uint32_t number) = 0; + + //Returns PE characteristics + virtual uint16_t get_characteristics() const = 0; + //Sets PE characteristics + virtual void set_characteristics(uint16_t ch) = 0; + + //Clears PE characteristics flag + void clear_characteristics_flags(uint16_t flags); + //Sets PE characteristics flag + void set_characteristics_flags(uint16_t flags); + + //Returns size of headers + virtual uint32_t get_size_of_headers() const = 0; + + //Returns subsystem + virtual uint16_t get_subsystem() const = 0; + + //Sets subsystem + virtual void set_subsystem(uint16_t subsystem) = 0; + + //Returns size of optional header + virtual uint16_t get_size_of_optional_header() const = 0; + + //Returns PE signature + virtual uint32_t get_pe_signature() const = 0; + + //Returns PE magic value + virtual uint32_t get_magic() const = 0; + + //Returns checksum of PE file from header + virtual uint32_t get_checksum() const = 0; + + //Sets checksum of PE file + virtual void set_checksum(uint32_t checksum) = 0; + + //Returns timestamp of PE file from header + virtual uint32_t get_time_date_stamp() const = 0; + + //Sets timestamp of PE file + virtual void set_time_date_stamp(uint32_t timestamp) = 0; + + //Returns Machine field value of PE file from header + virtual uint16_t get_machine() const = 0; + + //Sets Machine field value of PE file + virtual void set_machine(uint16_t machine) = 0; + + //Returns DLL Characteristics + virtual uint16_t get_dll_characteristics() const = 0; + + //Sets DLL Characteristics + virtual void set_dll_characteristics(uint16_t characteristics) = 0; + + //Sets required operation system version + virtual void set_os_version(uint16_t major, uint16_t minor) = 0; + + //Returns required operation system version (minor word) + virtual uint16_t get_minor_os_version() const = 0; + + //Returns required operation system version (major word) + virtual uint16_t get_major_os_version() const = 0; + + //Sets required subsystem version + virtual void set_subsystem_version(uint16_t major, uint16_t minor) = 0; + + //Returns required subsystem version (minor word) + virtual uint16_t get_minor_subsystem_version() const = 0; + + //Returns required subsystem version (major word) + virtual uint16_t get_major_subsystem_version() const = 0; + +public: //ADDRESS CONVERTIONS + //Virtual Address (VA) to Relative Virtual Address (RVA) convertions + //for PE32 and PE64 respectively + //bound_check checks integer overflow + virtual uint32_t va_to_rva(uint32_t va, bool bound_check = true) const = 0; + virtual uint32_t va_to_rva(uint64_t va, bool bound_check = true) const = 0; + + //Relative Virtual Address (RVA) to Virtual Address (VA) convertions + //for PE32 and PE64 respectively + virtual uint32_t rva_to_va_32(uint32_t rva) const = 0; + virtual uint64_t rva_to_va_64(uint32_t rva) const = 0; + + +public: //SECTIONS + //Returns number of sections + virtual uint16_t get_number_of_sections() const = 0; + +public: + //Sets number of sections + virtual void set_number_of_sections(uint16_t number) = 0; + //Sets virtual size of image + virtual void set_size_of_image(uint32_t size) = 0; + //Sets size of headers + virtual void set_size_of_headers(uint32_t size) = 0; + //Sets size of optional headers + virtual void set_size_of_optional_header(uint16_t size) = 0; + //Returns nt headers data pointer + virtual char* get_nt_headers_ptr() = 0; + //Returns nt headers data pointer + virtual const char* get_nt_headers_ptr() const = 0; + //Returns size of NT header + virtual uint32_t get_sizeof_nt_header() const = 0; + //Returns size of optional headers + virtual uint32_t get_sizeof_opt_headers() const = 0; + //Sets file alignment (no checks) + virtual void set_file_alignment_unchecked(uint32_t alignment) = 0; + //Sets base of code + virtual void set_base_of_code(uint32_t base) = 0; + //Returns base of code + virtual uint32_t get_base_of_code() const = 0; + //Returns needed PE magic for PE or PE+ (from template parameters) + virtual uint32_t get_needed_magic() const = 0; +}; +} +#endif +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_properties_generic.cpp b/irdb-lib/pebliss/trunk/pe_lib/pe_properties_generic.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3b1dadd0f949075582731368d9978a797ededb6e --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_properties_generic.cpp @@ -0,0 +1,624 @@ +#include <string.h> +#include "pe_properties_generic.h" +#include "pe_exception.h" +#include "utils.h" + +namespace pe_bliss +{ +using namespace pe_win; + +//Constructor +template<typename PEClassType> +std::auto_ptr<pe_properties> pe_properties_generic<PEClassType>::duplicate() const +{ + return std::auto_ptr<pe_properties>(new pe_properties_generic<PEClassType>(*this)); +} + +//Fills properly PE structures +template<typename PEClassType> +void pe_properties_generic<PEClassType>::create_pe(uint32_t section_alignment, uint16_t subsystem) +{ + memset(&nt_headers_, 0, sizeof(nt_headers_)); + nt_headers_.Signature = 0x4550; //"PE" + nt_headers_.FileHeader.Machine = 0x14C; //i386 + nt_headers_.FileHeader.SizeOfOptionalHeader = sizeof(nt_headers_.OptionalHeader); + nt_headers_.OptionalHeader.Magic = PEClassType::Id; + nt_headers_.OptionalHeader.ImageBase = 0x400000; + nt_headers_.OptionalHeader.SectionAlignment = section_alignment; + nt_headers_.OptionalHeader.FileAlignment = 0x200; + nt_headers_.OptionalHeader.SizeOfHeaders = 1024; + nt_headers_.OptionalHeader.Subsystem = subsystem; + nt_headers_.OptionalHeader.SizeOfHeapReserve = 0x100000; + nt_headers_.OptionalHeader.SizeOfHeapCommit = 0x1000; + nt_headers_.OptionalHeader.SizeOfStackReserve = 0x100000; + nt_headers_.OptionalHeader.SizeOfStackCommit = 0x1000; + nt_headers_.OptionalHeader.NumberOfRvaAndSizes = 0x10; +} + +//Duplicate +template<typename PEClassType> +pe_properties_generic<PEClassType>::~pe_properties_generic() +{} + +//Returns true if directory exists +template<typename PEClassType> +bool pe_properties_generic<PEClassType>::directory_exists(uint32_t id) const +{ + return (nt_headers_.OptionalHeader.NumberOfRvaAndSizes - 1) >= id && + nt_headers_.OptionalHeader.DataDirectory[id].VirtualAddress; +} + +//Removes directory +template<typename PEClassType> +void pe_properties_generic<PEClassType>::remove_directory(uint32_t id) +{ + if(directory_exists(id)) + { + nt_headers_.OptionalHeader.DataDirectory[id].VirtualAddress = 0; + nt_headers_.OptionalHeader.DataDirectory[id].Size = 0; + + if(id == image_directory_entry_basereloc) + { + set_characteristics_flags(image_file_relocs_stripped); + set_dll_characteristics(get_dll_characteristics() & ~image_dllcharacteristics_dynamic_base); + } + else if(id == image_directory_entry_export) + { + clear_characteristics_flags(image_file_dll); + } + } +} + +//Returns directory RVA +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::get_directory_rva(uint32_t id) const +{ + //Check if directory exists + if(nt_headers_.OptionalHeader.NumberOfRvaAndSizes <= id) + throw pe_exception("Specified directory does not exist", pe_exception::directory_does_not_exist); + + return nt_headers_.OptionalHeader.DataDirectory[id].VirtualAddress; +} + +//Returns directory size +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_directory_rva(uint32_t id, uint32_t va) +{ + //Check if directory exists + if(nt_headers_.OptionalHeader.NumberOfRvaAndSizes <= id) + throw pe_exception("Specified directory does not exist", pe_exception::directory_does_not_exist); + + nt_headers_.OptionalHeader.DataDirectory[id].VirtualAddress = va; +} + +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_directory_size(uint32_t id, uint32_t size) +{ + //Check if directory exists + if(nt_headers_.OptionalHeader.NumberOfRvaAndSizes <= id) + throw pe_exception("Specified directory does not exist", pe_exception::directory_does_not_exist); + + nt_headers_.OptionalHeader.DataDirectory[id].Size = size; +} + +//Returns directory size +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::get_directory_size(uint32_t id) const +{ + //Check if directory exists + if(nt_headers_.OptionalHeader.NumberOfRvaAndSizes <= id) + throw pe_exception("Specified directory does not exist", pe_exception::directory_does_not_exist); + + return nt_headers_.OptionalHeader.DataDirectory[id].Size; +} + +//Strips only zero DATA_DIRECTORY entries to count = min_count +//Returns resulting number of data directories +//strip_iat_directory - if true, even not empty IAT directory will be stripped +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::strip_data_directories(uint32_t min_count, bool strip_iat_directory) +{ + int i = nt_headers_.OptionalHeader.NumberOfRvaAndSizes - 1; + + //Enumerate all data directories from the end + for(; i >= 0; i--) + { + //If directory exists, break + if(nt_headers_.OptionalHeader.DataDirectory[i].VirtualAddress && (static_cast<uint32_t>(i) != image_directory_entry_iat || !strip_iat_directory)) + break; + + if(i <= static_cast<int>(min_count) - 2) + break; + } + + if(i == image_numberof_directory_entries - 1) + return image_numberof_directory_entries; + + //Return new number of data directories + return nt_headers_.OptionalHeader.NumberOfRvaAndSizes = i + 1; +} + +//Returns image base for PE32 +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::get_image_base_32() const +{ + return static_cast<uint32_t>(nt_headers_.OptionalHeader.ImageBase); +} + +//Returns image base for PE32/PE64 +template<typename PEClassType> +uint64_t pe_properties_generic<PEClassType>::get_image_base_64() const +{ + return static_cast<uint64_t>(nt_headers_.OptionalHeader.ImageBase); +} + +//Sets new image base +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_image_base(uint32_t base) +{ + nt_headers_.OptionalHeader.ImageBase = base; +} + +//Sets new image base +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_image_base_64(uint64_t base) +{ + nt_headers_.OptionalHeader.ImageBase = static_cast<typename PEClassType::BaseSize>(base); +} + +//Returns image entry point +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::get_ep() const +{ + return nt_headers_.OptionalHeader.AddressOfEntryPoint; +} + +//Sets image entry point +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_ep(uint32_t new_ep) +{ + nt_headers_.OptionalHeader.AddressOfEntryPoint = new_ep; +} + +//Returns file alignment +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::get_file_alignment() const +{ + return nt_headers_.OptionalHeader.FileAlignment; +} + +//Returns section alignment +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::get_section_alignment() const +{ + return nt_headers_.OptionalHeader.SectionAlignment; +} + +//Sets heap size commit for PE32 +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_heap_size_commit(uint32_t size) +{ + nt_headers_.OptionalHeader.SizeOfHeapCommit = static_cast<typename PEClassType::BaseSize>(size); +} + +//Sets heap size commit for PE32/PE64 +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_heap_size_commit(uint64_t size) +{ + nt_headers_.OptionalHeader.SizeOfHeapCommit = static_cast<typename PEClassType::BaseSize>(size); +} + +//Sets heap size reserve for PE32 +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_heap_size_reserve(uint32_t size) +{ + nt_headers_.OptionalHeader.SizeOfHeapReserve = static_cast<typename PEClassType::BaseSize>(size); +} + +//Sets heap size reserve for PE32/PE64 +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_heap_size_reserve(uint64_t size) +{ + nt_headers_.OptionalHeader.SizeOfHeapReserve = static_cast<typename PEClassType::BaseSize>(size); +} + +//Sets stack size commit for PE32 +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_stack_size_commit(uint32_t size) +{ + nt_headers_.OptionalHeader.SizeOfStackCommit = static_cast<typename PEClassType::BaseSize>(size); +} + +//Sets stack size commit for PE32/PE64 +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_stack_size_commit(uint64_t size) +{ + nt_headers_.OptionalHeader.SizeOfStackCommit = static_cast<typename PEClassType::BaseSize>(size); +} + +//Sets stack size reserve for PE32 +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_stack_size_reserve(uint32_t size) +{ + nt_headers_.OptionalHeader.SizeOfStackReserve = static_cast<typename PEClassType::BaseSize>(size); +} + +//Sets stack size reserve for PE32/PE64 +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_stack_size_reserve(uint64_t size) +{ + nt_headers_.OptionalHeader.SizeOfStackReserve = static_cast<typename PEClassType::BaseSize>(size); +} + +//Returns heap size commit for PE32 +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::get_heap_size_commit_32() const +{ + return static_cast<uint32_t>(nt_headers_.OptionalHeader.SizeOfHeapCommit); +} + +//Returns heap size commit for PE32/PE64 +template<typename PEClassType> +uint64_t pe_properties_generic<PEClassType>::get_heap_size_commit_64() const +{ + return static_cast<uint64_t>(nt_headers_.OptionalHeader.SizeOfHeapCommit); +} + +//Returns heap size reserve for PE32 +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::get_heap_size_reserve_32() const +{ + return static_cast<uint32_t>(nt_headers_.OptionalHeader.SizeOfHeapReserve); +} + +//Returns heap size reserve for PE32/PE64 +template<typename PEClassType> +uint64_t pe_properties_generic<PEClassType>::get_heap_size_reserve_64() const +{ + return static_cast<uint64_t>(nt_headers_.OptionalHeader.SizeOfHeapReserve); +} + +//Returns stack size commit for PE32 +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::get_stack_size_commit_32() const +{ + return static_cast<uint32_t>(nt_headers_.OptionalHeader.SizeOfStackCommit); +} + +//Returns stack size commit for PE32/PE64 +template<typename PEClassType> +uint64_t pe_properties_generic<PEClassType>::get_stack_size_commit_64() const +{ + return static_cast<uint64_t>(nt_headers_.OptionalHeader.SizeOfStackCommit); +} + +//Returns stack size reserve for PE32 +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::get_stack_size_reserve_32() const +{ + return static_cast<uint32_t>(nt_headers_.OptionalHeader.SizeOfStackReserve); +} + +//Returns stack size reserve for PE32/PE64 +template<typename PEClassType> +uint64_t pe_properties_generic<PEClassType>::get_stack_size_reserve_64() const +{ + return static_cast<uint64_t>(nt_headers_.OptionalHeader.SizeOfStackReserve); +} + +//Returns virtual size of image +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::get_size_of_image() const +{ + return nt_headers_.OptionalHeader.SizeOfImage; +} + +//Returns number of RVA and sizes (number of DATA_DIRECTORY entries) +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::get_number_of_rvas_and_sizes() const +{ + return nt_headers_.OptionalHeader.NumberOfRvaAndSizes; +} + +//Sets number of RVA and sizes (number of DATA_DIRECTORY entries) +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_number_of_rvas_and_sizes(uint32_t number) +{ + nt_headers_.OptionalHeader.NumberOfRvaAndSizes = number; +} + +//Returns PE characteristics +template<typename PEClassType> +uint16_t pe_properties_generic<PEClassType>::get_characteristics() const +{ + return nt_headers_.FileHeader.Characteristics; +} + +//Returns checksum of PE file from header +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::get_checksum() const +{ + return nt_headers_.OptionalHeader.CheckSum; +} + +//Sets checksum of PE file +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_checksum(uint32_t checksum) +{ + nt_headers_.OptionalHeader.CheckSum = checksum; +} + +//Returns DLL Characteristics +template<typename PEClassType> +uint16_t pe_properties_generic<PEClassType>::get_dll_characteristics() const +{ + return nt_headers_.OptionalHeader.DllCharacteristics; +} + +//Returns timestamp of PE file from header +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::get_time_date_stamp() const +{ + return nt_headers_.FileHeader.TimeDateStamp; +} + +//Sets timestamp of PE file +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_time_date_stamp(uint32_t timestamp) +{ + nt_headers_.FileHeader.TimeDateStamp = timestamp; +} + +//Sets DLL Characteristics +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_dll_characteristics(uint16_t characteristics) +{ + nt_headers_.OptionalHeader.DllCharacteristics = characteristics; +} + +//Returns Machine field value of PE file from header +template<typename PEClassType> +uint16_t pe_properties_generic<PEClassType>::get_machine() const +{ + return nt_headers_.FileHeader.Machine; +} + +//Sets Machine field value of PE file +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_machine(uint16_t machine) +{ + nt_headers_.FileHeader.Machine = machine; +} + +//Sets PE characteristics +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_characteristics(uint16_t ch) +{ + nt_headers_.FileHeader.Characteristics = ch; +} + +//Returns size of headers +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::get_size_of_headers() const +{ + return nt_headers_.OptionalHeader.SizeOfHeaders; +} + +//Returns subsystem +template<typename PEClassType> +uint16_t pe_properties_generic<PEClassType>::get_subsystem() const +{ + return nt_headers_.OptionalHeader.Subsystem; +} + +//Sets subsystem +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_subsystem(uint16_t subsystem) +{ + nt_headers_.OptionalHeader.Subsystem = subsystem; +} + +//Returns size of optional header +template<typename PEClassType> +uint16_t pe_properties_generic<PEClassType>::get_size_of_optional_header() const +{ + return nt_headers_.FileHeader.SizeOfOptionalHeader; +} + +//Returns PE signature +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::get_pe_signature() const +{ + return nt_headers_.Signature; +} + +//Returns PE magic value +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::get_magic() const +{ + return nt_headers_.OptionalHeader.Magic; +} + +//Sets required operation system version +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_os_version(uint16_t major, uint16_t minor) +{ + nt_headers_.OptionalHeader.MinorOperatingSystemVersion = minor; + nt_headers_.OptionalHeader.MajorOperatingSystemVersion = major; +} + +//Returns required operation system version (minor word) +template<typename PEClassType> +uint16_t pe_properties_generic<PEClassType>::get_minor_os_version() const +{ + return nt_headers_.OptionalHeader.MinorOperatingSystemVersion; +} + +//Returns required operation system version (major word) +template<typename PEClassType> +uint16_t pe_properties_generic<PEClassType>::get_major_os_version() const +{ + return nt_headers_.OptionalHeader.MajorOperatingSystemVersion; +} + +//Sets required subsystem version +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_subsystem_version(uint16_t major, uint16_t minor) +{ + nt_headers_.OptionalHeader.MinorSubsystemVersion = minor; + nt_headers_.OptionalHeader.MajorSubsystemVersion = major; +} + +//Returns required subsystem version (minor word) +template<typename PEClassType> +uint16_t pe_properties_generic<PEClassType>::get_minor_subsystem_version() const +{ + return nt_headers_.OptionalHeader.MinorSubsystemVersion; +} + +//Returns required subsystem version (major word) +template<typename PEClassType> +uint16_t pe_properties_generic<PEClassType>::get_major_subsystem_version() const +{ + return nt_headers_.OptionalHeader.MajorSubsystemVersion; +} + +//Virtual Address (VA) to Relative Virtual Address (RVA) convertions for PE32 +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::va_to_rva(uint32_t va, bool bound_check) const +{ + if(bound_check && static_cast<uint64_t>(va) - nt_headers_.OptionalHeader.ImageBase > pe_utils::max_dword) + throw pe_exception("Incorrect address conversion", pe_exception::incorrect_address_conversion); + + return static_cast<uint32_t>(va - nt_headers_.OptionalHeader.ImageBase); +} + +//Virtual Address (VA) to Relative Virtual Address (RVA) convertions for PE32/PE64 +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::va_to_rva(uint64_t va, bool bound_check) const +{ + if(bound_check && va - nt_headers_.OptionalHeader.ImageBase > pe_utils::max_dword) + throw pe_exception("Incorrect address conversion", pe_exception::incorrect_address_conversion); + + return static_cast<uint32_t>(va - nt_headers_.OptionalHeader.ImageBase); +} + +//Relative Virtual Address (RVA) to Virtual Address (VA) convertions for PE32 +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::rva_to_va_32(uint32_t rva) const +{ + if(!pe_utils::is_sum_safe(rva, static_cast<uint32_t>(nt_headers_.OptionalHeader.ImageBase))) + throw pe_exception("Incorrect address conversion", pe_exception::incorrect_address_conversion); + + return static_cast<uint32_t>(rva + nt_headers_.OptionalHeader.ImageBase); +} + +//Relative Virtual Address (RVA) to Virtual Address (VA) convertions for PE32/PE64 +template<typename PEClassType> +uint64_t pe_properties_generic<PEClassType>::rva_to_va_64(uint32_t rva) const +{ + return static_cast<uint64_t>(rva) + nt_headers_.OptionalHeader.ImageBase; +} + +//Returns number of sections +template<typename PEClassType> +uint16_t pe_properties_generic<PEClassType>::get_number_of_sections() const +{ + return nt_headers_.FileHeader.NumberOfSections; +} + +//Sets number of sections +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_number_of_sections(uint16_t number) +{ + nt_headers_.FileHeader.NumberOfSections = number; +} + +//Sets virtual size of image +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_size_of_image(uint32_t size) +{ + nt_headers_.OptionalHeader.SizeOfImage = size; +} + +//Sets size of headers +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_size_of_headers(uint32_t size) +{ + nt_headers_.OptionalHeader.SizeOfHeaders = size; +} + +//Sets size of optional headers +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_size_of_optional_header(uint16_t size) +{ + nt_headers_.FileHeader.SizeOfOptionalHeader = size; +} + +//Returns nt headers data pointer +template<typename PEClassType> +char* pe_properties_generic<PEClassType>::get_nt_headers_ptr() +{ + return reinterpret_cast<char*>(&nt_headers_); +} + +//Returns nt headers data pointer +template<typename PEClassType> +const char* pe_properties_generic<PEClassType>::get_nt_headers_ptr() const +{ + return reinterpret_cast<const char*>(&nt_headers_); +} + +//Returns size of NT header +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::get_sizeof_nt_header() const +{ + return sizeof(typename PEClassType::NtHeaders); +} + +//Returns size of optional headers +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::get_sizeof_opt_headers() const +{ + return sizeof(typename PEClassType::OptHeaders); +} + +//Sets file alignment (no checks) +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_file_alignment_unchecked(uint32_t alignment) +{ + nt_headers_.OptionalHeader.FileAlignment = alignment; +} + +//Sets base of code +template<typename PEClassType> +void pe_properties_generic<PEClassType>::set_base_of_code(uint32_t base) +{ + nt_headers_.OptionalHeader.BaseOfCode = base; +} + +//Returns base of code +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::get_base_of_code() const +{ + return nt_headers_.OptionalHeader.BaseOfCode; +} + +//Returns needed PE magic for PE or PE+ (from template parameters) +template<typename PEClassType> +uint32_t pe_properties_generic<PEClassType>::get_needed_magic() const +{ + return PEClassType::Id; +} + +//Returns PE type of this image +template<typename PEClassType> +pe_type pe_properties_generic<PEClassType>::get_pe_type() const +{ + return PEClassType::Id == image_nt_optional_hdr32_magic ? pe_type_32 : pe_type_64; +} + +//Two used instantiations for PE32 (PE) and PE64 (PE+) +template class pe_properties_generic<pe_types_class_32>; +template class pe_properties_generic<pe_types_class_64>; +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_properties_generic.h b/irdb-lib/pebliss/trunk/pe_lib/pe_properties_generic.h new file mode 100644 index 0000000000000000000000000000000000000000..9a575524c397a90137d41e53de57786d92f30b13 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_properties_generic.h @@ -0,0 +1,259 @@ +#ifndef pebliss_pe_properties_generic_h +#define pebliss_pe_properties_generic_h +#include "pe_properties.h" + +namespace pe_bliss +{ +//Helper class to reduce code size and ease its editing +template< + typename NtHeadersType, + typename OptHeadersType, + uint16_t IdVal, + typename BaseSizeType, + BaseSizeType ImportSnapFlagVal, + typename TLSStructType, + typename ConfigStructType> +class pe_types +{ +public: + typedef NtHeadersType NtHeaders; //NT HEADERS type + typedef OptHeadersType OptHeaders; //NT OPTIONAL HEADER type + typedef BaseSizeType BaseSize; //Base size of different values: DWORD or ULONGLONG + typedef TLSStructType TLSStruct; //TLS structure type + typedef ConfigStructType ConfigStruct; //Configuration structure type + + static const uint16_t Id = IdVal; //Magic of PE or PE+ + static const BaseSize ImportSnapFlag = ImportSnapFlagVal; //Import snap flag value +}; + +//Portable Executable derived class for PE and PE+ +//Describes PE/PE+ dependent things +template<typename PEClassType> +class pe_properties_generic : public pe_properties +{ +public: //Constructor + virtual std::auto_ptr<pe_properties> duplicate() const; + + //Fills properly PE structures + virtual void create_pe(uint32_t section_alignment, uint16_t subsystem); + +public: + //Destructor + virtual ~pe_properties_generic(); + + +public: //DIRECTORIES + //Returns true if directory exists + virtual bool directory_exists(uint32_t id) const; + + //Removes directory + virtual void remove_directory(uint32_t id); + + //Returns directory RVA + virtual uint32_t get_directory_rva(uint32_t id) const; + //Returns directory size + virtual uint32_t get_directory_size(uint32_t id) const; + + //Sets directory RVA (just a value of PE header, no moving occurs) + virtual void set_directory_rva(uint32_t id, uint32_t rva); + //Sets directory size (just a value of PE header, no moving occurs) + virtual void set_directory_size(uint32_t id, uint32_t size); + + //Strips only zero DATA_DIRECTORY entries to count = min_count + //Returns resulting number of data directories + //strip_iat_directory - if true, even not empty IAT directory will be stripped + virtual uint32_t strip_data_directories(uint32_t min_count = 1, bool strip_iat_directory = true); + + +public: //IMAGE + //Returns PE type of this image + virtual pe_type get_pe_type() const; + + +public: //PE HEADER + //Returns image base for PE32 and PE64 respectively + virtual uint32_t get_image_base_32() const; + virtual uint64_t get_image_base_64() const; + + //Sets new image base for PE32 + virtual void set_image_base(uint32_t base); + //Sets new image base for PE32/PE+ + virtual void set_image_base_64(uint64_t base); + + //Returns image entry point + virtual uint32_t get_ep() const; + //Sets image entry point + virtual void set_ep(uint32_t new_ep); + + //Returns file alignment + virtual uint32_t get_file_alignment() const; + //Returns section alignment + virtual uint32_t get_section_alignment() const; + + //Sets heap size commit for PE32 and PE64 respectively + virtual void set_heap_size_commit(uint32_t size); + virtual void set_heap_size_commit(uint64_t size); + //Sets heap size reserve for PE32 and PE64 respectively + virtual void set_heap_size_reserve(uint32_t size); + virtual void set_heap_size_reserve(uint64_t size); + //Sets stack size commit for PE32 and PE64 respectively + virtual void set_stack_size_commit(uint32_t size); + virtual void set_stack_size_commit(uint64_t size); + //Sets stack size reserve for PE32 and PE64 respectively + virtual void set_stack_size_reserve(uint32_t size); + virtual void set_stack_size_reserve(uint64_t size); + + //Returns heap size commit for PE32 and PE64 respectively + virtual uint32_t get_heap_size_commit_32() const; + virtual uint64_t get_heap_size_commit_64() const; + //Returns heap size reserve for PE32 and PE64 respectively + virtual uint32_t get_heap_size_reserve_32() const; + virtual uint64_t get_heap_size_reserve_64() const; + //Returns stack size commit for PE32 and PE64 respectively + virtual uint32_t get_stack_size_commit_32() const; + virtual uint64_t get_stack_size_commit_64() const; + //Returns stack size reserve for PE32 and PE64 respectively + virtual uint32_t get_stack_size_reserve_32() const; + virtual uint64_t get_stack_size_reserve_64() const; + + //Returns virtual size of image + virtual uint32_t get_size_of_image() const; + + //Returns number of RVA and sizes (number of DATA_DIRECTORY entries) + virtual uint32_t get_number_of_rvas_and_sizes() const; + //Sets number of RVA and sizes (number of DATA_DIRECTORY entries) + virtual void set_number_of_rvas_and_sizes(uint32_t number); + + //Returns PE characteristics + virtual uint16_t get_characteristics() const; + //Sets PE characteristics + virtual void set_characteristics(uint16_t ch); + + //Returns size of headers + virtual uint32_t get_size_of_headers() const; + + //Returns subsystem + virtual uint16_t get_subsystem() const; + + //Sets subsystem + virtual void set_subsystem(uint16_t subsystem); + + //Returns size of optional header + virtual uint16_t get_size_of_optional_header() const; + + //Returns PE signature + virtual uint32_t get_pe_signature() const; + + //Returns PE magic value + virtual uint32_t get_magic() const; + + //Returns checksum of PE file from header + virtual uint32_t get_checksum() const; + + //Sets checksum of PE file + virtual void set_checksum(uint32_t checksum); + + //Returns timestamp of PE file from header + virtual uint32_t get_time_date_stamp() const; + + //Sets timestamp of PE file + virtual void set_time_date_stamp(uint32_t timestamp); + + //Returns Machine field value of PE file from header + virtual uint16_t get_machine() const; + + //Sets Machine field value of PE file + virtual void set_machine(uint16_t machine); + + //Returns DLL Characteristics + virtual uint16_t get_dll_characteristics() const; + + //Sets DLL Characteristics + virtual void set_dll_characteristics(uint16_t characteristics); + + //Sets required operation system version + virtual void set_os_version(uint16_t major, uint16_t minor); + + //Returns required operation system version (minor word) + virtual uint16_t get_minor_os_version() const; + + //Returns required operation system version (major word) + virtual uint16_t get_major_os_version() const; + + //Sets required subsystem version + virtual void set_subsystem_version(uint16_t major, uint16_t minor); + + //Returns required subsystem version (minor word) + virtual uint16_t get_minor_subsystem_version() const; + + //Returns required subsystem version (major word) + virtual uint16_t get_major_subsystem_version() const; + +public: //ADDRESS CONVERTIONS + //Virtual Address (VA) to Relative Virtual Address (RVA) convertions + //for PE32 and PE64 respectively + //bound_check checks integer overflow + virtual uint32_t va_to_rva(uint32_t va, bool bound_check = true) const; + virtual uint32_t va_to_rva(uint64_t va, bool bound_check = true) const; + + //Relative Virtual Address (RVA) to Virtual Address (VA) convertions + //for PE32 and PE64 respectively + virtual uint32_t rva_to_va_32(uint32_t rva) const; + virtual uint64_t rva_to_va_64(uint32_t rva) const; + + +public: //SECTIONS + //Returns number of sections + virtual uint16_t get_number_of_sections() const; + +protected: + typename PEClassType::NtHeaders nt_headers_; //NT headers (PE32 or PE64) + +public: + //Sets number of sections + virtual void set_number_of_sections(uint16_t number); + //Sets virtual size of image + virtual void set_size_of_image(uint32_t size); + //Sets size of headers + virtual void set_size_of_headers(uint32_t size); + //Sets size of optional headers + virtual void set_size_of_optional_header(uint16_t size); + //Returns nt headers data pointer + virtual char* get_nt_headers_ptr(); + //Returns nt headers data pointer + virtual const char* get_nt_headers_ptr() const; + //Returns size of NT header + virtual uint32_t get_sizeof_nt_header() const; + //Returns size of optional headers + virtual uint32_t get_sizeof_opt_headers() const; + //Sets file alignment (no checks) + virtual void set_file_alignment_unchecked(uint32_t alignment); + //Sets base of code + virtual void set_base_of_code(uint32_t base); + //Returns base of code + virtual uint32_t get_base_of_code() const; + //Returns needed PE magic for PE or PE+ (from template parameters) + virtual uint32_t get_needed_magic() const; +}; + +//Two used typedefs for PE32 (PE) and PE64 (PE+) +typedef pe_types<pe_win::image_nt_headers32, + pe_win::image_optional_header32, + pe_win::image_nt_optional_hdr32_magic, + uint32_t, + pe_win::image_ordinal_flag32, + pe_win::image_tls_directory32, + pe_win::image_load_config_directory32> pe_types_class_32; + +typedef pe_types<pe_win::image_nt_headers64, + pe_win::image_optional_header64, + pe_win::image_nt_optional_hdr64_magic, + uint64_t, + pe_win::image_ordinal_flag64, + pe_win::image_tls_directory64, + pe_win::image_load_config_directory64> pe_types_class_64; + +typedef pe_properties_generic<pe_types_class_32> pe_properties_32; +typedef pe_properties_generic<pe_types_class_64> pe_properties_64; +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_rebuilder.cpp b/irdb-lib/pebliss/trunk/pe_lib/pe_rebuilder.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4cc6faf14ac5ac6fb123de12740d4311a3fa9724 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_rebuilder.cpp @@ -0,0 +1,177 @@ +#include "pe_rebuilder.h" +#include "pe_base.h" +#include "pe_structures.h" +#include "pe_exception.h" + +namespace pe_bliss +{ +using namespace pe_win; + +//Rebuilds PE image headers +//If strip_dos_header is true, DOS headers partially will be used for PE headers +//If change_size_of_headers == true, SizeOfHeaders will be recalculated automatically +//If save_bound_import == true, existing bound import directory will be saved correctly (because some compilers and bind.exe put it to PE headers) +void rebuild_pe(pe_base& pe, image_dos_header& dos_header, bool strip_dos_header, bool change_size_of_headers, bool save_bound_import) +{ + dos_header = pe.get_dos_header(); + + if(strip_dos_header) + { + //Strip stub overlay + pe.strip_stub_overlay(); + //BaseOfCode NT Headers field now overlaps + //e_lfanew field, so we're acrually setting + //e_lfanew with this call + pe.set_base_of_code(8 * sizeof(uint16_t)); + } + else + { + //Set start of PE headers + dos_header.e_lfanew = sizeof(image_dos_header) + + pe_utils::align_up(static_cast<uint32_t>(pe.get_stub_overlay().size()), sizeof(uint32_t)); + } + + section_list& sections = pe.get_image_sections(); + + //Calculate pointer to section data + size_t ptr_to_section_data = (strip_dos_header ? 8 * sizeof(uint16_t) : sizeof(image_dos_header)) + pe.get_sizeof_nt_header() + + pe_utils::align_up(pe.get_stub_overlay().size(), sizeof(uint32_t)) + - sizeof(image_data_directory) * (image_numberof_directory_entries - pe.get_number_of_rvas_and_sizes()) + + sections.size() * sizeof(image_section_header); + + if(save_bound_import && pe.has_bound_import()) + { + //It will be aligned to DWORD, because we're aligning to DWORD everything above it + pe.set_directory_rva(image_directory_entry_bound_import, static_cast<uint32_t>(ptr_to_section_data)); + ptr_to_section_data += pe.get_directory_size(image_directory_entry_bound_import); + } + + ptr_to_section_data = pe_utils::align_up(ptr_to_section_data, pe.get_file_alignment()); + + //Set size of headers and size of optional header + if(change_size_of_headers) + { + if(!pe.get_image_sections().empty()) + { + if(static_cast<uint32_t>(ptr_to_section_data) > (*sections.begin()).get_virtual_address()) + throw pe_exception("Headers of PE file are too long. Try to strip STUB or don't build bound import", pe_exception::cannot_rebuild_image); + } + + pe.set_size_of_headers(static_cast<uint32_t>(ptr_to_section_data)); + } + + //Set number of sections in PE header + pe.update_number_of_sections(); + + pe.update_image_size(); + + pe.set_size_of_optional_header(static_cast<uint16_t>(pe.get_sizeof_opt_headers() + - sizeof(image_data_directory) * (image_numberof_directory_entries - pe.get_number_of_rvas_and_sizes()))); + + //Recalculate pointer to raw data according to section list + for(section_list::iterator it = sections.begin(); it != sections.end(); ++it) + { + //Save section headers PointerToRawData + (*it).set_pointer_to_raw_data(static_cast<uint32_t>(ptr_to_section_data)); + ptr_to_section_data += (*it).get_aligned_raw_size(pe.get_file_alignment()); + } +} + +//Rebuild PE image and write it to "out" ostream +//If strip_dos_header is true, DOS headers partially will be used for PE headers +//If change_size_of_headers == true, SizeOfHeaders will be recalculated automatically +//If save_bound_import == true, existing bound import directory will be saved correctly (because some compilers and bind.exe put it to PE headers) +void rebuild_pe(pe_base& pe, std::ostream& out, bool strip_dos_header, bool change_size_of_headers, bool save_bound_import) +{ + if(out.bad()) + throw pe_exception("Stream is bad", pe_exception::stream_is_bad); + + if(save_bound_import && pe.has_bound_import()) + { + if(pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_bound_import), pe.get_directory_rva(image_directory_entry_bound_import), section_data_raw, true) + < pe.get_directory_size(image_directory_entry_bound_import)) + throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory); + } + + //Change ostream state + out.exceptions(std::ios::goodbit); + out.clear(); + + uint32_t original_bound_import_rva = pe.has_bound_import() ? pe.get_directory_rva(image_directory_entry_bound_import) : 0; + if(original_bound_import_rva && original_bound_import_rva > pe.get_size_of_headers()) + { + //No need to do anything with bound import directory + //if it is placed inside of any section, not headers + original_bound_import_rva = 0; + save_bound_import = false; + } + + { + image_dos_header dos_header; + + //Rebuild PE image headers + rebuild_pe(pe, dos_header, strip_dos_header, change_size_of_headers, save_bound_import); + + //Write DOS header + out.write(reinterpret_cast<const char*>(&dos_header), strip_dos_header ? 8 * sizeof(uint16_t) : sizeof(image_dos_header)); + } + + //If we have stub overlay, write it too + { + const std::string& stub = pe.get_stub_overlay(); + if(stub.size()) + { + out.write(stub.data(), stub.size()); + size_t aligned_size = pe_utils::align_up(stub.size(), sizeof(uint32_t)); + //Align PE header, which is right after rich overlay + while(aligned_size > stub.size()) + { + out.put('\0'); + --aligned_size; + } + } + } + + //Write NT headers + out.write(static_cast<const pe_base&>(pe).get_nt_headers_ptr(), pe.get_sizeof_nt_header() + - sizeof(image_data_directory) * (image_numberof_directory_entries - pe.get_number_of_rvas_and_sizes())); + + //Write section headers + const section_list& sections = pe.get_image_sections(); + for(section_list::const_iterator it = sections.begin(); it != sections.end(); ++it) + { + if(it == sections.end() - 1) //If last section encountered + { + image_section_header header((*it).get_raw_header()); + header.SizeOfRawData = static_cast<uint32_t>((*it).get_raw_data().length()); //Set non-aligned actual data length for it + out.write(reinterpret_cast<const char*>(&header), sizeof(image_section_header)); + } + else + { + out.write(reinterpret_cast<const char*>(&(*it).get_raw_header()), sizeof(image_section_header)); + } + } + + //Write bound import data if requested + if(save_bound_import && pe.has_bound_import()) + { + out.write(pe.section_data_from_rva(original_bound_import_rva, section_data_raw, true), + pe.get_directory_size(image_directory_entry_bound_import)); + } + + //Write section data finally + for(section_list::const_iterator it = sections.begin(); it != sections.end(); ++it) + { + const section& s = *it; + + std::streamoff wpos = out.tellp(); + + //Fill unused overlay data between sections with null bytes + for(unsigned int i = 0; i < s.get_pointer_to_raw_data() - wpos; i++) + out.put(0); + + //Write raw section data + out.write(s.get_raw_data().data(), s.get_raw_data().length()); + } +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_rebuilder.h b/irdb-lib/pebliss/trunk/pe_lib/pe_rebuilder.h new file mode 100644 index 0000000000000000000000000000000000000000..ad9d7cc6fa736652336243d062d86522fa014819 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_rebuilder.h @@ -0,0 +1,14 @@ +#ifndef pebliss_pe_rebuilder_h +#define pebliss_pe_rebuilder_h +#pragma once +#include <ostream> + +namespace pe_bliss +{ +class pe_base; +//Rebuilds PE image, writes resulting image to ostream "out". If strip_dos_header == true, DOS header will be stripped a little +//If change_size_of_headers == true, SizeOfHeaders will be recalculated automatically +//If save_bound_import == true, existing bound import directory will be saved correctly (because some compilers and bind.exe put it to PE headers) +void rebuild_pe(pe_base& pe, std::ostream& out, bool strip_dos_header = false, bool change_size_of_headers = true, bool save_bound_import = true); +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_relocations.cpp b/irdb-lib/pebliss/trunk/pe_lib/pe_relocations.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2d674e1346f1d946bff887fcda2b3b687827e5e3 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_relocations.cpp @@ -0,0 +1,299 @@ +#include <string.h> +#include "pe_relocations.h" +#include "pe_properties_generic.h" + +namespace pe_bliss +{ +using namespace pe_win; + +//RELOCATIONS +//Default constructor +relocation_entry::relocation_entry() + :rva_(0), type_(0) +{} + +//Constructor from relocation item (WORD) +relocation_entry::relocation_entry(uint16_t relocation_value) + :rva_(relocation_value & ((1 << 12) - 1)), type_(relocation_value >> 12) +{} + +//Constructor from relative rva and relocation type +relocation_entry::relocation_entry(uint16_t rrva, uint16_t type) + :rva_(rrva), type_(type) +{} + +//Returns RVA of relocation +uint16_t relocation_entry::get_rva() const +{ + return rva_; +} + +//Returns type of relocation +uint16_t relocation_entry::get_type() const +{ + return type_; +} + +//Sets RVA of relocation +void relocation_entry::set_rva(uint16_t rva) +{ + rva_ = rva; +} + +//Sets type of relocation +void relocation_entry::set_type(uint16_t type) +{ + type_ = type; +} + +//Returns relocation item (rrva + type) +uint16_t relocation_entry::get_item() const +{ + return rva_ | (type_ << 12); +} + +//Sets relocation item (rrva + type) +void relocation_entry::set_item(uint16_t item) +{ + rva_ = item & ((1 << 12) - 1); + type_ = item >> 12; +} + +//Returns relocation list +const relocation_table::relocation_list& relocation_table::get_relocations() const +{ + return relocations_; +} + +//Adds relocation to table +void relocation_table::add_relocation(const relocation_entry& entry) +{ + relocations_.push_back(entry); +} + +//Default constructor +relocation_table::relocation_table() + :rva_(0) +{} + +//Constructor from RVA of relocation table +relocation_table::relocation_table(uint32_t rva) + :rva_(rva) +{} + +//Returns RVA of block +uint32_t relocation_table::get_rva() const +{ + return rva_; +} + +//Sets RVA of block +void relocation_table::set_rva(uint32_t rva) +{ + rva_ = rva; +} + +//Returns changeable relocation list +relocation_table::relocation_list& relocation_table::get_relocations() +{ + return relocations_; +} + +//Get relocation list of pe file, supports one-word sized relocations only +//If list_absolute_entries = true, IMAGE_REL_BASED_ABSOLUTE will be listed +const relocation_table_list get_relocations(const pe_base& pe, bool list_absolute_entries) +{ + relocation_table_list ret; + + //If image does not have relocations + if(!pe.has_reloc()) + return ret; + + //Check the length in bytes of the section containing relocation directory + if(pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_basereloc), + pe.get_directory_rva(image_directory_entry_basereloc), section_data_virtual, true) + < sizeof(image_base_relocation)) + throw pe_exception("Incorrect relocation directory", pe_exception::incorrect_relocation_directory); + + unsigned long current_pos = pe.get_directory_rva(image_directory_entry_basereloc); + //First IMAGE_BASE_RELOCATION table + image_base_relocation reloc_table = pe.section_data_from_rva<image_base_relocation>(current_pos, section_data_virtual, true); + + if(reloc_table.SizeOfBlock % 2) + throw pe_exception("Incorrect relocation directory", pe_exception::incorrect_relocation_directory); + + unsigned long reloc_size = pe.get_directory_size(image_directory_entry_basereloc); + unsigned long read_size = 0; + + //reloc_table.VirtualAddress is not checked (not so important) + while(reloc_table.SizeOfBlock && read_size < reloc_size) + { + //Create relocation table + relocation_table table; + //Save RVA + table.set_rva(reloc_table.VirtualAddress); + + if(!pe_utils::is_sum_safe(current_pos, reloc_table.SizeOfBlock)) + throw pe_exception("Incorrect relocation directory", pe_exception::incorrect_relocation_directory); + + //List all relocations + for(unsigned long i = sizeof(image_base_relocation); i < reloc_table.SizeOfBlock; i += sizeof(uint16_t)) + { + relocation_entry entry(pe.section_data_from_rva<uint16_t>(current_pos + i, section_data_virtual, true)); + if(list_absolute_entries || entry.get_type() != image_rel_based_absolute) + table.add_relocation(entry); + } + + //Save table + ret.push_back(table); + + //Go to next relocation block + if(!pe_utils::is_sum_safe(current_pos, reloc_table.SizeOfBlock)) + throw pe_exception("Incorrect relocation directory", pe_exception::incorrect_relocation_directory); + + current_pos += reloc_table.SizeOfBlock; + read_size += reloc_table.SizeOfBlock; + reloc_table = pe.section_data_from_rva<image_base_relocation>(current_pos, section_data_virtual, true); + } + + return ret; +} + +//Simple relocations rebuilder +//To keep PE file working, don't remove any of existing relocations in +//relocation_table_list returned by a call to get_relocations() function +//auto_strip_last_section - if true and relocations are placed in the last section, it will be automatically stripped +//offset_from_section_start - offset from the beginning of reloc_section, where relocations data will be situated +//If save_to_pe_header is true, PE header will be modified automatically +const image_directory rebuild_relocations(pe_base& pe, const relocation_table_list& relocs, section& reloc_section, uint32_t offset_from_section_start, bool save_to_pe_header, bool auto_strip_last_section) +{ + //Check that reloc_section is attached to this PE image + if(!pe.section_attached(reloc_section)) + throw pe_exception("Relocations section must be attached to PE file", pe_exception::section_is_not_attached); + + uint32_t current_reloc_data_pos = pe_utils::align_up(offset_from_section_start, sizeof(uint32_t)); + + uint32_t needed_size = current_reloc_data_pos - offset_from_section_start; //Calculate needed size for relocation tables + uint32_t size_delta = needed_size; + + uint32_t start_reloc_pos = current_reloc_data_pos; + + //Enumerate relocation tables + for(relocation_table_list::const_iterator it = relocs.begin(); it != relocs.end(); ++it) + { + needed_size += static_cast<uint32_t>((*it).get_relocations().size() * sizeof(uint16_t) /* relocations */ + sizeof(image_base_relocation) /* table header */); + //End of each table will be DWORD-aligned + if((start_reloc_pos + needed_size - size_delta) % sizeof(uint32_t)) + needed_size += sizeof(uint16_t); //Align it with IMAGE_REL_BASED_ABSOLUTE relocation + } + + //Check if reloc_section is last one. If it's not, check if there's enough place for relocations data + if(&reloc_section != &*(pe.get_image_sections().end() - 1) && + (reloc_section.empty() || pe_utils::align_up(reloc_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + current_reloc_data_pos)) + throw pe_exception("Insufficient space for relocations directory", pe_exception::insufficient_space); + + std::string& raw_data = reloc_section.get_raw_data(); + + //This will be done only if reloc_section is the last section of image or for section with unaligned raw length of data + if(raw_data.length() < needed_size + current_reloc_data_pos) + raw_data.resize(needed_size + current_reloc_data_pos); //Expand section raw data + + //Enumerate relocation tables + for(relocation_table_list::const_iterator it = relocs.begin(); it != relocs.end(); ++it) + { + //Create relocation table header + image_base_relocation reloc; + reloc.VirtualAddress = (*it).get_rva(); + const relocation_table::relocation_list& reloc_list = (*it).get_relocations(); + reloc.SizeOfBlock = static_cast<uint32_t>(sizeof(image_base_relocation) + sizeof(uint16_t) * reloc_list.size()); + if((reloc_list.size() * sizeof(uint16_t)) % sizeof(uint32_t)) //If we must align end of relocation table + reloc.SizeOfBlock += sizeof(uint16_t); + + memcpy(&raw_data[current_reloc_data_pos], &reloc, sizeof(reloc)); + current_reloc_data_pos += sizeof(reloc); + + //Enumerate relocations in table + for(relocation_table::relocation_list::const_iterator r = reloc_list.begin(); r != reloc_list.end(); ++r) + { + //Save relocations + uint16_t reloc_value = (*r).get_item(); + memcpy(&raw_data[current_reloc_data_pos], &reloc_value, sizeof(reloc_value)); + current_reloc_data_pos += sizeof(reloc_value); + } + + if(current_reloc_data_pos % sizeof(uint32_t)) //If end of table is not DWORD-aligned + { + memset(&raw_data[current_reloc_data_pos], 0, sizeof(uint16_t)); //Align it with IMAGE_REL_BASED_ABSOLUTE relocation + current_reloc_data_pos += sizeof(uint16_t); + } + } + + image_directory ret(pe.rva_from_section_offset(reloc_section, start_reloc_pos), needed_size - size_delta); + + //Adjust section raw and virtual sizes + pe.recalculate_section_sizes(reloc_section, auto_strip_last_section); + + //If auto-rewrite of PE headers is required + if(save_to_pe_header) + { + pe.set_directory_rva(image_directory_entry_basereloc, ret.get_rva()); + pe.set_directory_size(image_directory_entry_basereloc, ret.get_size()); + + pe.clear_characteristics_flags(image_file_relocs_stripped); + pe.set_dll_characteristics(pe.get_dll_characteristics() | image_dllcharacteristics_dynamic_base); + } + + return ret; +} + +//Recalculates image base with the help of relocation tables +void rebase_image(pe_base& pe, const relocation_table_list& tables, uint64_t new_base) +{ + pe.get_pe_type() == pe_type_32 + ? rebase_image_base<pe_types_class_32>(pe, tables, new_base) + : rebase_image_base<pe_types_class_64>(pe, tables, new_base); +} + +//RELOCATIONS +//Recalculates image base with the help of relocation tables +//Recalculates VAs of DWORDS/QWORDS in image according to relocations +//Notice: if you move some critical structures like TLS, image relocations will not fix new +//positions of TLS VAs. Instead, some bytes that now doesn't belong to TLS will be fixed. +//It is recommended to rebase image in the very beginning and move all structures afterwards. +template<typename PEClassType> +void rebase_image_base(pe_base& pe, const relocation_table_list& tables, uint64_t new_base) +{ + //Get current image base value + typename PEClassType::BaseSize image_base; + pe.get_image_base(image_base); + + //ImageBase difference + typename PEClassType::BaseSize base_rel = static_cast<typename PEClassType::BaseSize>(static_cast<int64_t>(new_base) - image_base); + + //We need to fix addresses from relocation tables + //Enumerate relocation tables + for(relocation_table_list::const_iterator it = tables.begin(); it != tables.end(); ++it) + { + const relocation_table::relocation_list& relocs = (*it).get_relocations(); + + uint32_t base_rva = (*it).get_rva(); + + //Enumerate relocations + for(relocation_table::relocation_list::const_iterator rel = relocs.begin(); rel != relocs.end(); ++rel) + { + //Skip ABSOLUTE entries + if((*rel).get_type() == pe_win::image_rel_based_absolute) + continue; + + //Recalculate value by RVA and rewrite it + uint32_t current_rva = base_rva + (*rel).get_rva(); + typename PEClassType::BaseSize value = pe.section_data_from_rva<typename PEClassType::BaseSize>(current_rva, section_data_raw, true); + value += base_rel; + memcpy(pe.section_data_from_rva(current_rva, true), &value, sizeof(value)); + } + } + + //Finally, save new image base + pe.set_image_base_64(new_base); +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_relocations.h b/irdb-lib/pebliss/trunk/pe_lib/pe_relocations.h new file mode 100644 index 0000000000000000000000000000000000000000..313dafb65d57397bf93501c14d9bbed8ebff7cf4 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_relocations.h @@ -0,0 +1,104 @@ +#ifndef pebliss_pe_relocations_h +#define pebliss_pe_relocations_h +#pragma once +#include <vector> +#include "pe_structures.h" +#include "pe_base.h" +#include "pe_directory.h" + +namespace pe_bliss +{ +//Class representing relocation entry +//RVA of relocation is not actually RVA, but +//(real RVA) - (RVA of table) +class relocation_entry +{ +public: + //Default constructor + relocation_entry(); + //Constructor from relocation item (WORD) + explicit relocation_entry(uint16_t relocation_value); + //Constructor from relative rva and relocation type + relocation_entry(uint16_t rrva, uint16_t type); + + //Returns RVA of relocation (actually, relative RVA from relocation table RVA) + uint16_t get_rva() const; + //Returns type of relocation + uint16_t get_type() const; + + //Returns relocation item (rrva + type) + uint16_t get_item() const; + +public: //Setters do not change everything inside image, they are used by PE class + //You can also use them to rebuild relocations using rebuild_relocations() + + //Sets RVA of relocation (actually, relative RVA from relocation table RVA) + void set_rva(uint16_t rva); + //Sets type of relocation + void set_type(uint16_t type); + + //Sets relocation item (rrva + type) + void set_item(uint16_t item); + +private: + uint16_t rva_; + uint16_t type_; +}; + +//Class representing relocation table +class relocation_table +{ +public: + typedef std::vector<relocation_entry> relocation_list; + +public: + //Default constructor + relocation_table(); + //Constructor from RVA of relocation table + explicit relocation_table(uint32_t rva); + + //Returns relocation list + const relocation_list& get_relocations() const; + //Returns RVA of block + uint32_t get_rva() const; + +public: //These functions do not change everything inside image, they are used by PE class + //You can also use them to rebuild relocations using rebuild_relocations() + + //Adds relocation to table + void add_relocation(const relocation_entry& entry); + //Returns changeable relocation list + relocation_list& get_relocations(); + //Sets RVA of block + void set_rva(uint32_t rva); + +private: + uint32_t rva_; + relocation_list relocations_; +}; + +typedef std::vector<relocation_table> relocation_table_list; + +//Get relocation list of pe file, supports one-word sized relocations only +//If list_absolute_entries = true, IMAGE_REL_BASED_ABSOLUTE will be listed +const relocation_table_list get_relocations(const pe_base& pe, bool list_absolute_entries = false); + +//Simple relocations rebuilder +//To keep PE file working, don't remove any of existing relocations in +//relocation_table_list returned by a call to get_relocations() function +//auto_strip_last_section - if true and relocations are placed in the last section, it will be automatically stripped +//offset_from_section_start - offset from the beginning of reloc_section, where relocations data will be situated +//If save_to_pe_header is true, PE header will be modified automatically +const image_directory rebuild_relocations(pe_base& pe, const relocation_table_list& relocs, section& reloc_section, uint32_t offset_from_section_start = 0, bool save_to_pe_header = true, bool auto_strip_last_section = true); + +//Recalculates image base with the help of relocation tables +//Recalculates VAs of DWORDS/QWORDS in image according to relocations +//Notice: if you move some critical structures like TLS, image relocations will not fix new +//positions of TLS VAs. Instead, some bytes that now doesn't belong to TLS will be fixed. +//It is recommended to rebase image in the very beginning and move all structures afterwards. +void rebase_image(pe_base& pe, const relocation_table_list& tables, uint64_t new_base); + +template<typename PEClassType> +void rebase_image_base(pe_base& pe, const relocation_table_list& tables, uint64_t new_base); +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_resource_manager.cpp b/irdb-lib/pebliss/trunk/pe_lib/pe_resource_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1db952efcb5e7dce69c5672c40719a4b481b63fb --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_resource_manager.cpp @@ -0,0 +1,265 @@ +#include <algorithm> +#include <sstream> +#include <iomanip> +#include <math.h> +#include <string.h> +#include "pe_resource_manager.h" +#include "resource_internal.h" + +namespace pe_bliss +{ +using namespace pe_win; + +//Constructor from root resource directory +pe_resource_manager::pe_resource_manager(resource_directory& root_directory) + :pe_resource_viewer(root_directory), root_dir_edit_(root_directory) +{} + +resource_directory& pe_resource_manager::get_root_directory() +{ + return root_dir_edit_; +} + +//Removes all resources of given type or root name +//If there's more than one directory entry of a given type, only the +//first one will be deleted (that's an unusual situation) +//Returns true if resource was deleted +bool pe_resource_manager::remove_resource_type(resource_type type) +{ + //Search for resource type + resource_directory::entry_list& entries = root_dir_edit_.get_entry_list(); + resource_directory::entry_list::iterator it = std::find_if(entries.begin(), entries.end(), resource_directory::id_entry_finder(type)); + if(it != entries.end()) + { + //Remove it, if found + entries.erase(it); + return true; + } + + return false; +} + +bool pe_resource_manager::remove_resource(const std::wstring& root_name) +{ + //Search for resource type + resource_directory::entry_list& entries = root_dir_edit_.get_entry_list(); + resource_directory::entry_list::iterator it = std::find_if(entries.begin(), entries.end(), resource_directory::name_entry_finder(root_name)); + if(it != entries.end()) + { + //Remove it, if found + entries.erase(it); + return true; + } + + return false; +} + +//Helper to remove resource +bool pe_resource_manager::remove_resource(const resource_directory::entry_finder& root_finder, const resource_directory::entry_finder& finder) +{ + //Search for resource type + resource_directory::entry_list& entries_type = root_dir_edit_.get_entry_list(); + resource_directory::entry_list::iterator it_type = std::find_if(entries_type.begin(), entries_type.end(), root_finder); + if(it_type != entries_type.end()) + { + //Search for resource name/ID with "finder" + resource_directory::entry_list& entries_name = (*it_type).get_resource_directory().get_entry_list(); + resource_directory::entry_list::iterator it_name = std::find_if(entries_name.begin(), entries_name.end(), finder); + if(it_name != entries_name.end()) + { + //Erase resource, if found + entries_name.erase(it_name); + if(entries_name.empty()) + entries_type.erase(it_type); + + return true; + } + } + + return false; +} + +//Removes all resource languages by resource type/root name and name +//Deletes only one entry of given type and name +//Returns true if resource was deleted +bool pe_resource_manager::remove_resource(resource_type type, const std::wstring& name) +{ + return remove_resource(resource_directory::entry_finder(type), resource_directory::entry_finder(name)); +} + +bool pe_resource_manager::remove_resource(const std::wstring& root_name, const std::wstring& name) +{ + return remove_resource(resource_directory::entry_finder(root_name), resource_directory::entry_finder(name)); +} + +//Removes all resource languages by resource type/root name and ID +//Deletes only one entry of given type and ID +//Returns true if resource was deleted +bool pe_resource_manager::remove_resource(resource_type type, uint32_t id) +{ + return remove_resource(resource_directory::entry_finder(type), resource_directory::entry_finder(id)); +} + +bool pe_resource_manager::remove_resource(const std::wstring& root_name, uint32_t id) +{ + return remove_resource(resource_directory::entry_finder(root_name), resource_directory::entry_finder(id)); +} + +//Helper to remove resource +bool pe_resource_manager::remove_resource(const resource_directory::entry_finder& root_finder, const resource_directory::entry_finder& finder, uint32_t language) +{ + //Search for resource type + resource_directory::entry_list& entries_type = root_dir_edit_.get_entry_list(); + resource_directory::entry_list::iterator it_type = std::find_if(entries_type.begin(), entries_type.end(), root_finder); + if(it_type != entries_type.end()) + { + //Search for resource name/ID with "finder" + resource_directory::entry_list& entries_name = (*it_type).get_resource_directory().get_entry_list(); + resource_directory::entry_list::iterator it_name = std::find_if(entries_name.begin(), entries_name.end(), finder); + if(it_name != entries_name.end()) + { + //Search for resource language + resource_directory::entry_list& entries_lang = (*it_name).get_resource_directory().get_entry_list(); + resource_directory::entry_list::iterator it_lang = std::find_if(entries_lang.begin(), entries_lang.end(), resource_directory::id_entry_finder(language)); + if(it_lang != entries_lang.end()) + { + //Erase resource, if found + entries_lang.erase(it_lang); + if(entries_lang.empty()) + { + entries_name.erase(it_name); + if(entries_name.empty()) + entries_type.erase(it_type); + } + + return true; + } + } + } + + return false; +} + +//Removes resource language by resource type/root name and name +//Deletes only one entry of given type, name and language +//Returns true if resource was deleted +bool pe_resource_manager::remove_resource(resource_type type, const std::wstring& name, uint32_t language) +{ + return remove_resource(resource_directory::entry_finder(type), resource_directory::entry_finder(name), language); +} + +bool pe_resource_manager::remove_resource(const std::wstring& root_name, const std::wstring& name, uint32_t language) +{ + return remove_resource(resource_directory::entry_finder(root_name), resource_directory::entry_finder(name), language); +} + +//Removes recource language by resource type/root name and ID +//Deletes only one entry of given type, ID and language +//Returns true if resource was deleted +bool pe_resource_manager::remove_resource(resource_type type, uint32_t id, uint32_t language) +{ + return remove_resource(resource_directory::entry_finder(type), resource_directory::entry_finder(id), language); +} + +bool pe_resource_manager::remove_resource(const std::wstring& root_name, uint32_t id, uint32_t language) +{ + return remove_resource(resource_directory::entry_finder(root_name), resource_directory::entry_finder(id), language); +} + +//Helper to add/replace resource +void pe_resource_manager::add_resource(const std::string& data, resource_type type, resource_directory_entry& new_entry, const resource_directory::entry_finder& finder, uint32_t language, uint32_t codepage, uint32_t timestamp) +{ + resource_directory_entry new_type_entry; + new_type_entry.set_id(type); + + add_resource(data, new_type_entry, resource_directory::entry_finder(type), new_entry, finder, language, codepage, timestamp); +} + +//Helper to add/replace resource +void pe_resource_manager::add_resource(const std::string& data, const std::wstring& root_name, resource_directory_entry& new_entry, const resource_directory::entry_finder& finder, uint32_t language, uint32_t codepage, uint32_t timestamp) +{ + resource_directory_entry new_type_entry; + new_type_entry.set_name(root_name); + + add_resource(data, new_type_entry, resource_directory::entry_finder(root_name), new_entry, finder, language, codepage, timestamp); +} + +//Helper to add/replace resource +void pe_resource_manager::add_resource(const std::string& data, resource_directory_entry& new_root_entry, const resource_directory::entry_finder& root_finder, resource_directory_entry& new_entry, const resource_directory::entry_finder& finder, uint32_t language, uint32_t codepage, uint32_t timestamp) +{ + //Search for resource type + resource_directory::entry_list* entries = &root_dir_edit_.get_entry_list(); + resource_directory::entry_list::iterator it = std::find_if(entries->begin(), entries->end(), root_finder); + if(it == entries->end()) + { + //Add resource type directory, if it was not found + resource_directory dir; + dir.set_timestamp(timestamp); + new_root_entry.add_resource_directory(dir); + entries->push_back(new_root_entry); + it = entries->end() - 1; + } + + //Search for resource name/ID directory with "finder" + entries = &(*it).get_resource_directory().get_entry_list(); + it = std::find_if(entries->begin(), entries->end(), finder); + if(it == entries->end()) + { + //Add resource name/ID directory, if it was not found + resource_directory dir; + dir.set_timestamp(timestamp); + new_entry.add_resource_directory(dir); + entries->push_back(new_entry); + it = entries->end() - 1; + } + + //Search for data resource entry by language + entries = &(*it).get_resource_directory().get_entry_list(); + it = std::find_if(entries->begin(), entries->end(), resource_directory::id_entry_finder(language)); + if(it != entries->end()) + entries->erase(it); //Erase it, if found + + //Add new data entry + resource_directory_entry new_dir_data_entry; + resource_data_entry data_dir(data, codepage); + new_dir_data_entry.add_data_entry(data_dir); + new_dir_data_entry.set_id(language); + entries->push_back(new_dir_data_entry); +} + +//Adds resource. If resource already exists, replaces it +void pe_resource_manager::add_resource(const std::string& data, resource_type type, const std::wstring& name, uint32_t language, uint32_t codepage, uint32_t timestamp) +{ + resource_directory_entry new_entry; + new_entry.set_name(name); + + add_resource(data, type, new_entry, resource_directory::entry_finder(name), language, codepage, timestamp); +} + +//Adds resource. If resource already exists, replaces it +void pe_resource_manager::add_resource(const std::string& data, const std::wstring& root_name, const std::wstring& name, uint32_t language, uint32_t codepage, uint32_t timestamp) +{ + resource_directory_entry new_entry; + new_entry.set_name(name); + + add_resource(data, root_name, new_entry, resource_directory::entry_finder(name), language, codepage, timestamp); +} + +//Adds resource. If resource already exists, replaces it +void pe_resource_manager::add_resource(const std::string& data, resource_type type, uint32_t id, uint32_t language, uint32_t codepage, uint32_t timestamp) +{ + resource_directory_entry new_entry; + new_entry.set_id(id); + + add_resource(data, type, new_entry, resource_directory::entry_finder(id), language, codepage, timestamp); +} + +//Adds resource. If resource already exists, replaces it +void pe_resource_manager::add_resource(const std::string& data, const std::wstring& root_name, uint32_t id, uint32_t language, uint32_t codepage, uint32_t timestamp) +{ + resource_directory_entry new_entry; + new_entry.set_id(id); + + add_resource(data, root_name, new_entry, resource_directory::entry_finder(id), language, codepage, timestamp); +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_resource_manager.h b/irdb-lib/pebliss/trunk/pe_lib/pe_resource_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..d40a48de8b222a0855fb1937e397821acfd7ada3 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_resource_manager.h @@ -0,0 +1,95 @@ +#ifndef pebliss_pe_resource_manager_h +#define pebliss_pe_resource_manager_h +#pragma once +#include <map> +#include <sstream> +#include <string> +#include <memory> +#include "pe_base.h" +#include "pe_structures.h" +#include "pe_resources.h" +#include "message_table.h" +#include "file_version_info.h" +#include "pe_resource_viewer.h" +#include "resource_data_info.h" + +namespace pe_bliss +{ +//Derived class to edit PE resources +class pe_resource_manager : public pe_resource_viewer +{ +public: + //Constructor from root resource directory + explicit pe_resource_manager(resource_directory& root_directory); + + resource_directory& get_root_directory(); + +public: //Resource editing + //Removes all resources of given type or root name + //If there's more than one directory entry of a given type, only the + //first one will be deleted (that's an unusual situation) + //Returns true if resource was deleted + bool remove_resource_type(resource_type type); + bool remove_resource(const std::wstring& root_name); + + //Removes all resource languages by resource type/root name and name + //Deletes only one entry of given type and name + //Returns true if resource was deleted + bool remove_resource(resource_type type, const std::wstring& name); + bool remove_resource(const std::wstring& root_name, const std::wstring& name); + //Removes all resource languages by resource type/root name and ID + //Deletes only one entry of given type and ID + //Returns true if resource was deleted + bool remove_resource(resource_type type, uint32_t id); + bool remove_resource(const std::wstring& root_name, uint32_t id); + + //Removes resource language by resource type/root name and name + //Deletes only one entry of given type, name and language + //Returns true if resource was deleted + bool remove_resource(resource_type type, const std::wstring& name, uint32_t language); + bool remove_resource(const std::wstring& root_name, const std::wstring& name, uint32_t language); + //Removes recource language by resource type/root name and ID + //Deletes only one entry of given type, ID and language + //Returns true if resource was deleted + bool remove_resource(resource_type type, uint32_t id, uint32_t language); + bool remove_resource(const std::wstring& root_name, uint32_t id, uint32_t language); + + //Adds resource. If resource already exists, replaces it + //timestamp will be used for directories that will be added + void add_resource(const std::string& data, resource_type type, const std::wstring& name, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0); + void add_resource(const std::string& data, const std::wstring& root_name, const std::wstring& name, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0); + //Adds resource. If resource already exists, replaces it + //timestamp will be used for directories that will be added + void add_resource(const std::string& data, resource_type type, uint32_t id, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0); + void add_resource(const std::string& data, const std::wstring& root_name, uint32_t id, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0); + +public: + //Helpers to add/replace resource + void add_resource(const std::string& data, resource_type type, + resource_directory_entry& new_entry, + const resource_directory::entry_finder& finder, + uint32_t language, uint32_t codepage, uint32_t timestamp); + + void add_resource(const std::string& data, const std::wstring& root_name, + resource_directory_entry& new_entry, + const resource_directory::entry_finder& finder, + uint32_t language, uint32_t codepage, uint32_t timestamp); + + void add_resource(const std::string& data, resource_directory_entry& new_root_entry, + const resource_directory::entry_finder& root_finder, + resource_directory_entry& new_entry, + const resource_directory::entry_finder& finder, + uint32_t language, uint32_t codepage, uint32_t timestamp); + +private: + //Root resource directory. We're not copying it, because it might be heavy + resource_directory& root_dir_edit_; + + //Helper to remove resource + bool remove_resource(const resource_directory::entry_finder& root_finder, const resource_directory::entry_finder& finder); + + //Helper to remove resource + bool remove_resource(const resource_directory::entry_finder& root_finder, const resource_directory::entry_finder& finder, uint32_t language); +}; +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_resource_viewer.cpp b/irdb-lib/pebliss/trunk/pe_lib/pe_resource_viewer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1414c33feda1720bf43cc4a1e124df9f766ab742 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_resource_viewer.cpp @@ -0,0 +1,361 @@ +#include <algorithm> +#include <cmath> +#include "pe_resource_viewer.h" +#include "pe_structures.h" + +namespace pe_bliss +{ +using namespace pe_win; + +//Constructor from root resource_directory +pe_resource_viewer::pe_resource_viewer(const resource_directory& root_directory) + :root_dir_(root_directory) +{} + +const resource_directory& pe_resource_viewer::get_root_directory() const +{ + return root_dir_; +} + +//Finder helpers +bool pe_resource_viewer::has_name::operator()(const resource_directory_entry& entry) const +{ + return entry.is_named(); +} + +bool pe_resource_viewer::has_id::operator()(const resource_directory_entry& entry) const +{ + return !entry.is_named(); +} + +//Lists resource types existing in PE file (non-named only) +const pe_resource_viewer::resource_type_list pe_resource_viewer::list_resource_types() const +{ + resource_type_list ret; + + //Get root directory entries list + const resource_directory::entry_list& entries = root_dir_.get_entry_list(); + for(resource_directory::entry_list::const_iterator it = entries.begin(); it != entries.end(); ++it) + { + //List all non-named items + if(!(*it).is_named()) + ret.push_back((*it).get_id()); + } + + return ret; +} + +//Returns true if resource type exists +bool pe_resource_viewer::resource_exists(resource_type type) const +{ + const resource_directory::entry_list& entries = root_dir_.get_entry_list(); + return std::find_if(entries.begin(), entries.end(), resource_directory::id_entry_finder(type)) != entries.end(); +} + +//Returns true if resource name exists +bool pe_resource_viewer::resource_exists(const std::wstring& root_name) const +{ + const resource_directory::entry_list& entries = root_dir_.get_entry_list(); + return std::find_if(entries.begin(), entries.end(), resource_directory::name_entry_finder(root_name)) != entries.end(); +} + +//Helper function to get name list from entry list +const pe_resource_viewer::resource_name_list pe_resource_viewer::get_name_list(const resource_directory::entry_list& entries) +{ + resource_name_list ret; + + for(resource_directory::entry_list::const_iterator it = entries.begin(); it != entries.end(); ++it) + { + //List all named items + if((*it).is_named()) + ret.push_back((*it).get_name()); + } + + return ret; +} + +//Helper function to get ID list from entry list +const pe_resource_viewer::resource_id_list pe_resource_viewer::get_id_list(const resource_directory::entry_list& entries) +{ + resource_id_list ret; + + for(resource_directory::entry_list::const_iterator it = entries.begin(); it != entries.end(); ++it) + { + //List all non-named items + if(!(*it).is_named()) + ret.push_back((*it).get_id()); + } + + return ret; +} + +//Lists resource names existing in PE file by resource type +const pe_resource_viewer::resource_name_list pe_resource_viewer::list_resource_names(resource_type type) const +{ + return get_name_list(root_dir_.entry_by_id(type).get_resource_directory().get_entry_list()); +} + +//Lists resource names existing in PE file by resource name +const pe_resource_viewer::resource_name_list pe_resource_viewer::list_resource_names(const std::wstring& root_name) const +{ + return get_name_list(root_dir_.entry_by_name(root_name).get_resource_directory().get_entry_list()); +} + +//Lists resource IDs existing in PE file by resource type +const pe_resource_viewer::resource_id_list pe_resource_viewer::list_resource_ids(resource_type type) const +{ + return get_id_list(root_dir_.entry_by_id(type).get_resource_directory().get_entry_list()); +} + +//Lists resource IDs existing in PE file by resource name +const pe_resource_viewer::resource_id_list pe_resource_viewer::list_resource_ids(const std::wstring& root_name) const +{ + return get_id_list(root_dir_.entry_by_name(root_name).get_resource_directory().get_entry_list()); +} + +//Returns resource count by type +unsigned long pe_resource_viewer::get_resource_count(resource_type type) const +{ + return static_cast<unsigned long>( + root_dir_ //Type directory + .entry_by_id(type) + .get_resource_directory() //Name/ID directory + .get_entry_list() + .size()); +} + +//Returns resource count by name +unsigned long pe_resource_viewer::get_resource_count(const std::wstring& root_name) const +{ + return static_cast<unsigned long>( + root_dir_ //Type directory + .entry_by_name(root_name) + .get_resource_directory() //Name/ID directory + .get_entry_list() + .size()); +} + +//Returns language count of resource by resource type and name +unsigned long pe_resource_viewer::get_language_count(resource_type type, const std::wstring& name) const +{ + const resource_directory::entry_list& entries = + root_dir_ //Type directory + .entry_by_id(type) + .get_resource_directory() //Name/ID directory + .entry_by_name(name) + .get_resource_directory() //Language directory + .get_entry_list(); + + return static_cast<unsigned long>(std::count_if(entries.begin(), entries.end(), has_id())); +} + +//Returns language count of resource by resource names +unsigned long pe_resource_viewer::get_language_count(const std::wstring& root_name, const std::wstring& name) const +{ + const resource_directory::entry_list& entries = + root_dir_ //Type directory + .entry_by_name(root_name) + .get_resource_directory() //Name/ID directory + .entry_by_name(name) + .get_resource_directory() //Language directory + .get_entry_list(); + + return static_cast<unsigned long>(std::count_if(entries.begin(), entries.end(), has_id())); +} + +//Returns language count of resource by resource type and ID +unsigned long pe_resource_viewer::get_language_count(resource_type type, uint32_t id) const +{ + const resource_directory::entry_list& entries = + root_dir_ //Type directory + .entry_by_id(type) + .get_resource_directory() //Name/ID directory + .entry_by_id(id) + .get_resource_directory() //Language directory + .get_entry_list(); + + return static_cast<unsigned long>(std::count_if(entries.begin(), entries.end(), has_id())); +} + +//Returns language count of resource by resource name and ID +unsigned long pe_resource_viewer::get_language_count(const std::wstring& root_name, uint32_t id) const +{ + const resource_directory::entry_list& entries = + root_dir_ //Type directory + .entry_by_name(root_name) + .get_resource_directory() //Name/ID directory + .entry_by_id(id) + .get_resource_directory() //Language directory + .get_entry_list(); + + return static_cast<unsigned long>(std::count_if(entries.begin(), entries.end(), has_id())); +} + +//Lists resource languages by resource type and name +const pe_resource_viewer::resource_language_list pe_resource_viewer::list_resource_languages(resource_type type, const std::wstring& name) const +{ + const resource_directory::entry_list& entries = + root_dir_ //Type directory + .entry_by_id(type) + .get_resource_directory() //Name/ID directory + .entry_by_name(name) + .get_resource_directory() //Language directory + .get_entry_list(); + + return get_id_list(entries); +} + +//Lists resource languages by resource names +const pe_resource_viewer::resource_language_list pe_resource_viewer::list_resource_languages(const std::wstring& root_name, const std::wstring& name) const +{ + const resource_directory::entry_list& entries = + root_dir_ //Type directory + .entry_by_name(root_name) + .get_resource_directory() //Name/ID directory + .entry_by_name(name) + .get_resource_directory() //Language directory + .get_entry_list(); + + return get_id_list(entries); +} + +//Lists resource languages by resource type and ID +const pe_resource_viewer::resource_language_list pe_resource_viewer::list_resource_languages(resource_type type, uint32_t id) const +{ + const resource_directory::entry_list& entries = + root_dir_ //Type directory + .entry_by_id(type) + .get_resource_directory() //Name/ID directory + .entry_by_id(id) + .get_resource_directory() //Language directory + .get_entry_list(); + + return get_id_list(entries); +} + +//Lists resource languages by resource name and ID +const pe_resource_viewer::resource_language_list pe_resource_viewer::list_resource_languages(const std::wstring& root_name, uint32_t id) const +{ + const resource_directory::entry_list& entries = + root_dir_ //Type directory + .entry_by_name(root_name) + .get_resource_directory() //Name/ID directory + .entry_by_id(id) + .get_resource_directory() //Language directory + .get_entry_list(); + + return get_id_list(entries); +} + +//Returns raw resource data by type, name and language +const resource_data_info pe_resource_viewer::get_resource_data_by_name(uint32_t language, resource_type type, const std::wstring& name) const +{ + return resource_data_info(root_dir_ //Type directory + .entry_by_id(type) + .get_resource_directory() //Name/ID directory + .entry_by_name(name) + .get_resource_directory() //Language directory + .entry_by_id(language) + .get_data_entry()); //Data directory +} + +//Returns raw resource data by root name, name and language +const resource_data_info pe_resource_viewer::get_resource_data_by_name(uint32_t language, const std::wstring& root_name, const std::wstring& name) const +{ + return resource_data_info(root_dir_ //Type directory + .entry_by_name(root_name) + .get_resource_directory() //Name/ID directory + .entry_by_name(name) + .get_resource_directory() //Language directory + .entry_by_id(language) + .get_data_entry()); //Data directory +} + +//Returns raw resource data by type, ID and language +const resource_data_info pe_resource_viewer::get_resource_data_by_id(uint32_t language, resource_type type, uint32_t id) const +{ + return resource_data_info(root_dir_ //Type directory + .entry_by_id(type) + .get_resource_directory() //Name/ID directory + .entry_by_id(id) + .get_resource_directory() //Language directory + .entry_by_id(language) + .get_data_entry()); //Data directory +} + +//Returns raw resource data by root name, ID and language +const resource_data_info pe_resource_viewer::get_resource_data_by_id(uint32_t language, const std::wstring& root_name, uint32_t id) const +{ + return resource_data_info(root_dir_ //Type directory + .entry_by_name(root_name) + .get_resource_directory() //Name/ID directory + .entry_by_id(id) + .get_resource_directory() //Language directory + .entry_by_id(language) + .get_data_entry()); //Data directory +} + +//Returns raw resource data by type, name and index in language directory (instead of language) +const resource_data_info pe_resource_viewer::get_resource_data_by_name(resource_type type, const std::wstring& name, uint32_t index) const +{ + const resource_directory::entry_list& entries = root_dir_ //Type directory + .entry_by_id(type) + .get_resource_directory() //Name/ID directory + .entry_by_name(name) + .get_resource_directory() //Language directory + .get_entry_list(); + + if(entries.size() <= index) + throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found); + + return resource_data_info(entries.at(index).get_data_entry()); //Data directory +} + +//Returns raw resource data by root name, name and index in language directory (instead of language) +const resource_data_info pe_resource_viewer::get_resource_data_by_name(const std::wstring& root_name, const std::wstring& name, uint32_t index) const +{ + const resource_directory::entry_list& entries = root_dir_ //Type directory + .entry_by_name(root_name) + .get_resource_directory() //Name/ID directory + .entry_by_name(name) + .get_resource_directory() //Language directory + .get_entry_list(); + + if(entries.size() <= index) + throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found); + + return resource_data_info(entries.at(index).get_data_entry()); //Data directory +} + +//Returns raw resource data by type, ID and index in language directory (instead of language) +const resource_data_info pe_resource_viewer::get_resource_data_by_id(resource_type type, uint32_t id, uint32_t index) const +{ + const resource_directory::entry_list& entries = root_dir_ //Type directory + .entry_by_id(type) + .get_resource_directory() //Name/ID directory + .entry_by_id(id) + .get_resource_directory() //Language directory + .get_entry_list(); + + if(entries.size() <= index) + throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found); + + return resource_data_info(entries.at(index).get_data_entry()); //Data directory +} + +//Returns raw resource data by root name, ID and index in language directory (instead of language) +const resource_data_info pe_resource_viewer::get_resource_data_by_id(const std::wstring& root_name, uint32_t id, uint32_t index) const +{ + const resource_directory::entry_list& entries = root_dir_ //Type directory + .entry_by_name(root_name) + .get_resource_directory() //Name/ID directory + .entry_by_id(id) + .get_resource_directory() //Language directory + .get_entry_list(); + + if(entries.size() <= index) + throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found); + + return resource_data_info(entries.at(index).get_data_entry()); //Data directory +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_resource_viewer.h b/irdb-lib/pebliss/trunk/pe_lib/pe_resource_viewer.h new file mode 100644 index 0000000000000000000000000000000000000000..d68fb105c6884bc914afbd2cc8274379b26209c0 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_resource_viewer.h @@ -0,0 +1,135 @@ +#ifndef pebliss_pe_resource_viewer_h +#define pebliss_pe_resource_viewer_h +#pragma once +#include <map> +#include <string> +#include "pe_structures.h" +#include "pe_resources.h" +#include "message_table.h" +#include "resource_data_info.h" + +namespace pe_bliss +{ + //PE resource manager allows to read resources from PE files +class pe_resource_viewer +{ +public: + //Resource type enumeration + enum resource_type + { + resource_cursor = 1, + resource_bitmap = 2, + resource_icon = 3, + resource_menu = 4, + resource_dialog = 5, + resource_string = 6, + resource_fontdir = 7, + resource_font = 8, + resource_accelerator = 9, + resource_rcdata = 10, + resource_message_table = 11, + resource_cursor_group = 12, + resource_icon_group = 14, + resource_version = 16, + resource_dlginclude = 17, + resource_plugplay = 19, + resource_vxd = 20, + resource_anicursor = 21, + resource_aniicon = 22, + resource_html = 23, + resource_manifest = 24 + }; + +public: + //Some useful typedefs + typedef std::vector<uint32_t> resource_type_list; + typedef std::vector<uint32_t> resource_id_list; + typedef std::vector<std::wstring> resource_name_list; + typedef std::vector<uint32_t> resource_language_list; + +public: + //Constructor from root resource_directory from PE file + explicit pe_resource_viewer(const resource_directory& root_directory); + + const resource_directory& get_root_directory() const; + + //Lists resource types existing in PE file (non-named only) + const resource_type_list list_resource_types() const; + //Returns true if resource type exists + bool resource_exists(resource_type type) const; + //Returns true if resource name exists + bool resource_exists(const std::wstring& root_name) const; + + //Lists resource names existing in PE file by resource type + const resource_name_list list_resource_names(resource_type type) const; + //Lists resource names existing in PE file by resource name + const resource_name_list list_resource_names(const std::wstring& root_name) const; + //Lists resource IDs existing in PE file by resource type + const resource_id_list list_resource_ids(resource_type type) const; + //Lists resource IDs existing in PE file by resource name + const resource_id_list list_resource_ids(const std::wstring& root_name) const; + //Returns resource count by type + unsigned long get_resource_count(resource_type type) const; + //Returns resource count by name + unsigned long get_resource_count(const std::wstring& root_name) const; + + //Returns language count of resource by resource type and name + unsigned long get_language_count(resource_type type, const std::wstring& name) const; + //Returns language count of resource by resource names + unsigned long get_language_count(const std::wstring& root_name, const std::wstring& name) const; + //Returns language count of resource by resource type and ID + unsigned long get_language_count(resource_type type, uint32_t id) const; + //Returns language count of resource by resource name and ID + unsigned long get_language_count(const std::wstring& root_name, uint32_t id) const; + //Lists resource languages by resource type and name + const resource_language_list list_resource_languages(resource_type type, const std::wstring& name) const; + //Lists resource languages by resource names + const resource_language_list list_resource_languages(const std::wstring& root_name, const std::wstring& name) const; + //Lists resource languages by resource type and ID + const resource_language_list list_resource_languages(resource_type type, uint32_t id) const; + //Lists resource languages by resource name and ID + const resource_language_list list_resource_languages(const std::wstring& root_name, uint32_t id) const; + + //Returns raw resource data by type, name and language + const resource_data_info get_resource_data_by_name(uint32_t language, resource_type type, const std::wstring& name) const; + //Returns raw resource data by root name, name and language + const resource_data_info get_resource_data_by_name(uint32_t language, const std::wstring& root_name, const std::wstring& name) const; + //Returns raw resource data by type, ID and language + const resource_data_info get_resource_data_by_id(uint32_t language, resource_type type, uint32_t id) const; + //Returns raw resource data by root name, ID and language + const resource_data_info get_resource_data_by_id(uint32_t language, const std::wstring& root_name, uint32_t id) const; + //Returns raw resource data by type, name and index in language directory (instead of language) + const resource_data_info get_resource_data_by_name(resource_type type, const std::wstring& name, uint32_t index = 0) const; + //Returns raw resource data by root name, name and index in language directory (instead of language) + const resource_data_info get_resource_data_by_name(const std::wstring& root_name, const std::wstring& name, uint32_t index = 0) const; + //Returns raw resource data by type, ID and index in language directory (instead of language) + const resource_data_info get_resource_data_by_id(resource_type type, uint32_t id, uint32_t index = 0) const; + //Returns raw resource data by root name, ID and index in language directory (instead of language) + const resource_data_info get_resource_data_by_id(const std::wstring& root_name, uint32_t id, uint32_t index = 0) const; + +protected: + //Root resource directory. We're not copying it, because it might be heavy + const resource_directory& root_dir_; + + //Helper function to get ID list from entry list + static const resource_id_list get_id_list(const resource_directory::entry_list& entries); + //Helper function to get name list from entry list + static const resource_name_list get_name_list(const resource_directory::entry_list& entries); + +protected: + //Helper structure - finder of resource_directory_entry that is named + struct has_name + { + public: + bool operator()(const resource_directory_entry& entry) const; + }; + + //Helper structure - finder of resource_directory_entry that is not named (has id) + struct has_id + { + public: + bool operator()(const resource_directory_entry& entry) const; + }; +}; +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_resources.cpp b/irdb-lib/pebliss/trunk/pe_lib/pe_resources.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a819c7bb719d7b34f08b3ed464dddda168aa6357 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_resources.cpp @@ -0,0 +1,705 @@ +#include <algorithm> +#include <string.h> +#include "pe_resources.h" + +namespace pe_bliss +{ +using namespace pe_win; + +//RESOURCES +//Default constructor +resource_data_entry::resource_data_entry() + :codepage_(0) +{} + +//Constructor from data +resource_data_entry::resource_data_entry(const std::string& data, uint32_t codepage) + :codepage_(codepage), data_(data) +{} + +//Returns resource data codepage +uint32_t resource_data_entry::get_codepage() const +{ + return codepage_; +} + +//Returns resource data +const std::string& resource_data_entry::get_data() const +{ + return data_; +} + +//Sets resource data codepage +void resource_data_entry::set_codepage(uint32_t codepage) +{ + codepage_ = codepage; +} + +//Sets resource data +void resource_data_entry::set_data(const std::string& data) +{ + data_ = data; +} + +//Default constructor +resource_directory_entry::includes::includes() + :data_(0) +{} + +//Default constructor +resource_directory_entry::resource_directory_entry() + :id_(0), includes_data_(false), named_(false) +{} + +//Copy constructor +resource_directory_entry::resource_directory_entry(const resource_directory_entry& other) + :id_(other.id_), name_(other.name_), includes_data_(other.includes_data_), named_(other.named_) +{ + //If union'ed pointer is not zero + if(other.ptr_.data_) + { + if(other.includes_data()) + ptr_.data_ = new resource_data_entry(*other.ptr_.data_); + else + ptr_.dir_ = new resource_directory(*other.ptr_.dir_); + } +} + +//Copy assignment operator +resource_directory_entry& resource_directory_entry::operator=(const resource_directory_entry& other) +{ + release(); + + id_ = other.id_; + name_ = other.name_; + includes_data_ = other.includes_data_; + named_ = other.named_; + + //If other union'ed pointer is not zero + if(other.ptr_.data_) + { + if(other.includes_data()) + ptr_.data_ = new resource_data_entry(*other.ptr_.data_); + else + ptr_.dir_ = new resource_directory(*other.ptr_.dir_); + } + + return *this; +} + +//Destroys included data +void resource_directory_entry::release() +{ + //If union'ed pointer is not zero + if(ptr_.data_) + { + if(includes_data()) + delete ptr_.data_; + else + delete ptr_.dir_; + + ptr_.data_ = 0; + } +} + +//Destructor +resource_directory_entry::~resource_directory_entry() +{ + release(); +} + +//Returns entry ID +uint32_t resource_directory_entry::get_id() const +{ + return id_; +} + +//Returns entry name +const std::wstring& resource_directory_entry::get_name() const +{ + return name_; +} + +//Returns true, if entry has name +//Returns false, if entry has ID +bool resource_directory_entry::is_named() const +{ + return named_; +} + +//Returns true, if entry includes resource_data_entry +//Returns false, if entry includes resource_directory +bool resource_directory_entry::includes_data() const +{ + return includes_data_; +} + +//Returns resource_directory if entry includes it, otherwise throws an exception +const resource_directory& resource_directory_entry::get_resource_directory() const +{ + if(!ptr_.dir_ || includes_data_) + throw pe_exception("Resource directory entry does not contain resource directory", pe_exception::resource_directory_entry_error); + + return *ptr_.dir_; +} + +//Returns resource_data_entry if entry includes it, otherwise throws an exception +const resource_data_entry& resource_directory_entry::get_data_entry() const +{ + if(!ptr_.data_ || !includes_data_) + throw pe_exception("Resource directory entry does not contain resource data entry", pe_exception::resource_directory_entry_error); + + return *ptr_.data_; +} + +//Returns resource_directory if entry includes it, otherwise throws an exception +resource_directory& resource_directory_entry::get_resource_directory() +{ + if(!ptr_.dir_ || includes_data_) + throw pe_exception("Resource directory entry does not contain resource directory", pe_exception::resource_directory_entry_error); + + return *ptr_.dir_; +} + +//Returns resource_data_entry if entry includes it, otherwise throws an exception +resource_data_entry& resource_directory_entry::get_data_entry() +{ + if(!ptr_.data_ || !includes_data_) + throw pe_exception("Resource directory entry does not contain resource data entry", pe_exception::resource_directory_entry_error); + + return *ptr_.data_; +} + +//Sets entry name +void resource_directory_entry::set_name(const std::wstring& name) +{ + name_ = name; + named_ = true; + id_ = 0; +} + +//Sets entry ID +void resource_directory_entry::set_id(uint32_t id) +{ + id_ = id; + named_ = false; + name_.clear(); +} + +//Adds resource_data_entry +void resource_directory_entry::add_data_entry(const resource_data_entry& entry) +{ + release(); + ptr_.data_ = new resource_data_entry(entry); + includes_data_ = true; +} + +//Adds resource_directory +void resource_directory_entry::add_resource_directory(const resource_directory& dir) +{ + release(); + ptr_.dir_ = new resource_directory(dir); + includes_data_ = false; +} + +//Default constructor +resource_directory::resource_directory() + :characteristics_(0), + timestamp_(0), + major_version_(0), minor_version_(0), + number_of_named_entries_(0), number_of_id_entries_(0) +{} + +//Constructor from data +resource_directory::resource_directory(const image_resource_directory& dir) + :characteristics_(dir.Characteristics), + timestamp_(dir.TimeDateStamp), + major_version_(dir.MajorVersion), minor_version_(dir.MinorVersion), + number_of_named_entries_(0), number_of_id_entries_(0) //Set to zero here, calculate on add +{} + +//Returns characteristics of directory +uint32_t resource_directory::get_characteristics() const +{ + return characteristics_; +} + +//Returns date and time stamp of directory +uint32_t resource_directory::get_timestamp() const +{ + return timestamp_; +} + +//Returns major version of directory +uint16_t resource_directory::get_major_version() const +{ + return major_version_; +} + +//Returns minor version of directory +uint16_t resource_directory::get_minor_version() const +{ + return minor_version_; +} + +//Returns number of named entries +uint32_t resource_directory::get_number_of_named_entries() const +{ + return number_of_named_entries_; +} + +//Returns number of ID entries +uint32_t resource_directory::get_number_of_id_entries() const +{ + return number_of_id_entries_; +} + +//Returns resource_directory_entry array +const resource_directory::entry_list& resource_directory::get_entry_list() const +{ + return entries_; +} + +//Returns resource_directory_entry array +resource_directory::entry_list& resource_directory::get_entry_list() +{ + return entries_; +} + +//Adds resource_directory_entry +void resource_directory::add_resource_directory_entry(const resource_directory_entry& entry) +{ + entries_.push_back(entry); + if(entry.is_named()) + ++number_of_named_entries_; + else + ++number_of_id_entries_; +} + +//Clears resource_directory_entry array +void resource_directory::clear_resource_directory_entry_list() +{ + entries_.clear(); + number_of_named_entries_ = 0; + number_of_id_entries_ = 0; +} + +//Sets characteristics of directory +void resource_directory::set_characteristics(uint32_t characteristics) +{ + characteristics_ = characteristics; +} + +//Sets date and time stamp of directory +void resource_directory::set_timestamp(uint32_t timestamp) +{ + timestamp_ = timestamp; +} + +//Sets number of named entries +void resource_directory::set_number_of_named_entries(uint32_t number) +{ + number_of_named_entries_ = number; +} + +//Sets number of ID entries +void resource_directory::set_number_of_id_entries(uint32_t number) +{ + number_of_id_entries_ = number; +} + +//Sets major version of directory +void resource_directory::set_major_version(uint16_t major_version) +{ + major_version_ = major_version; +} + +//Sets minor version of directory +void resource_directory::get_minor_version(uint16_t minor_version) +{ + minor_version_ = minor_version; +} + +//Processes resource directory +const resource_directory process_resource_directory(const pe_base& pe, uint32_t res_rva, uint32_t offset_to_directory, std::set<uint32_t>& processed) +{ + resource_directory ret; + + //Check for resource loops + if(!processed.insert(offset_to_directory).second) + throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory); + + if(!pe_utils::is_sum_safe(res_rva, offset_to_directory)) + throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory); + + //Get root IMAGE_RESOURCE_DIRECTORY + image_resource_directory directory = pe.section_data_from_rva<image_resource_directory>(res_rva + offset_to_directory, section_data_virtual, true); + + ret = resource_directory(directory); + + //Check DWORDs for possible overflows + if(!pe_utils::is_sum_safe(directory.NumberOfIdEntries, directory.NumberOfNamedEntries) + || directory.NumberOfIdEntries + directory.NumberOfNamedEntries >= pe_utils::max_dword / sizeof(image_resource_directory_entry) + sizeof(image_resource_directory)) + throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory); + + if(!pe_utils::is_sum_safe(offset_to_directory, sizeof(image_resource_directory) + (directory.NumberOfIdEntries + directory.NumberOfNamedEntries) * sizeof(image_resource_directory_entry)) + || !pe_utils::is_sum_safe(res_rva, offset_to_directory + sizeof(image_resource_directory) + (directory.NumberOfIdEntries + directory.NumberOfNamedEntries) * sizeof(image_resource_directory_entry))) + throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory); + + for(unsigned long i = 0; i != static_cast<unsigned long>(directory.NumberOfIdEntries) + directory.NumberOfNamedEntries; ++i) + { + //Read directory entries one by one + image_resource_directory_entry dir_entry = pe.section_data_from_rva<image_resource_directory_entry>( + res_rva + sizeof(image_resource_directory) + i * sizeof(image_resource_directory_entry) + offset_to_directory, section_data_virtual, true); + + //Create directory entry structure + resource_directory_entry entry; + + //If directory is named + if(dir_entry.NameIsString) + { + if(!pe_utils::is_sum_safe(res_rva + sizeof(uint16_t) /* safe */, dir_entry.NameOffset)) + throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory); + + //get directory name length + uint16_t directory_name_length = pe.section_data_from_rva<uint16_t>(res_rva + dir_entry.NameOffset, section_data_virtual, true); + + //Check name length + if(pe.section_data_length_from_rva(res_rva + dir_entry.NameOffset + sizeof(uint16_t), res_rva + dir_entry.NameOffset + sizeof(uint16_t), section_data_virtual, true) + < directory_name_length) + throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory); + +#ifdef PE_BLISS_WINDOWS + //Set entry UNICODE name + entry.set_name(std::wstring( + reinterpret_cast<const wchar_t*>(pe.section_data_from_rva(res_rva + dir_entry.NameOffset + sizeof(uint16_t), section_data_virtual, true)), + directory_name_length)); +#else + //Set entry UNICODE name + entry.set_name(pe_utils::from_ucs2(u16string( + reinterpret_cast<const unicode16_t*>(pe.section_data_from_rva(res_rva + dir_entry.NameOffset + sizeof(uint16_t), section_data_virtual, true)), + directory_name_length))); +#endif + } + else + { + //Else - set directory ID + entry.set_id(dir_entry.Id); + } + + //If directory entry has another resource directory + if(dir_entry.DataIsDirectory) + { + entry.add_resource_directory(process_resource_directory(pe, res_rva, dir_entry.OffsetToDirectory, processed)); + } + else + { + //If directory entry has data + image_resource_data_entry data_entry = pe.section_data_from_rva<image_resource_data_entry>( + res_rva + dir_entry.OffsetToData, section_data_virtual, true); + + //Check byte count that stated by data entry + if(pe.section_data_length_from_rva(data_entry.OffsetToData, data_entry.OffsetToData, section_data_virtual, true) < data_entry.Size) + throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory); + + //Add data entry to directory entry + entry.add_data_entry(resource_data_entry( + std::string(pe.section_data_from_rva(data_entry.OffsetToData, section_data_virtual, true), data_entry.Size), + data_entry.CodePage)); + } + + //Save directory entry + ret.add_resource_directory_entry(entry); + } + + //Return resource directory + return ret; +} + +//Helper function to calculate needed space for resource data +void calculate_resource_data_space(const resource_directory& root, uint32_t aligned_offset_from_section_start, uint32_t& needed_size_for_structures, uint32_t& needed_size_for_strings) +{ + needed_size_for_structures += sizeof(image_resource_directory); + for(resource_directory::entry_list::const_iterator it = root.get_entry_list().begin(); it != root.get_entry_list().end(); ++it) + { + needed_size_for_structures += sizeof(image_resource_directory_entry); + + if((*it).is_named()) + needed_size_for_strings += static_cast<uint32_t>(((*it).get_name().length() + 1) * 2 /* unicode */ + sizeof(uint16_t) /* for string length */); + + if(!(*it).includes_data()) + calculate_resource_data_space((*it).get_resource_directory(), aligned_offset_from_section_start, needed_size_for_structures, needed_size_for_strings); + } +} + +//Helper function to calculate needed space for resource data +void calculate_resource_data_space(const resource_directory& root, uint32_t needed_size_for_structures, uint32_t needed_size_for_strings, uint32_t& needed_size_for_data, uint32_t& current_data_pos) +{ + for(resource_directory::entry_list::const_iterator it = root.get_entry_list().begin(); it != root.get_entry_list().end(); ++it) + { + if((*it).includes_data()) + { + uint32_t data_size = static_cast<uint32_t>((*it).get_data_entry().get_data().length() + + sizeof(image_resource_data_entry) + + (pe_utils::align_up(current_data_pos, sizeof(uint32_t)) - current_data_pos) /* alignment */); + needed_size_for_data += data_size; + current_data_pos += data_size; + } + else + { + calculate_resource_data_space((*it).get_resource_directory(), needed_size_for_structures, needed_size_for_strings, needed_size_for_data, current_data_pos); + } + } +} + +//Helper: sorts resource directory entries +struct entry_sorter +{ +public: + bool operator()(const resource_directory_entry& entry1, const resource_directory_entry& entry2) const; +}; + +//Helper function to rebuild resource directory +void rebuild_resource_directory(pe_base& pe, section& resource_section, resource_directory& root, uint32_t& current_structures_pos, uint32_t& current_data_pos, uint32_t& current_strings_pos, uint32_t offset_from_section_start) +{ + //Create resource directory + image_resource_directory dir = {0}; + dir.Characteristics = root.get_characteristics(); + dir.MajorVersion = root.get_major_version(); + dir.MinorVersion = root.get_minor_version(); + dir.TimeDateStamp = root.get_timestamp(); + + { + resource_directory::entry_list& entries = root.get_entry_list(); + std::sort(entries.begin(), entries.end(), entry_sorter()); + } + + //Calculate number of named and ID entries + for(resource_directory::entry_list::const_iterator it = root.get_entry_list().begin(); it != root.get_entry_list().end(); ++it) + { + if((*it).is_named()) + ++dir.NumberOfNamedEntries; + else + ++dir.NumberOfIdEntries; + } + + std::string& raw_data = resource_section.get_raw_data(); + + //Save resource directory + memcpy(&raw_data[current_structures_pos], &dir, sizeof(dir)); + current_structures_pos += sizeof(dir); + + uint32_t this_current_structures_pos = current_structures_pos; + + current_structures_pos += sizeof(image_resource_directory_entry) * (dir.NumberOfNamedEntries + dir.NumberOfIdEntries); + + //Create all resource directory entries + for(resource_directory::entry_list::iterator it = root.get_entry_list().begin(); it != root.get_entry_list().end(); ++it) + { + image_resource_directory_entry entry; + if((*it).is_named()) + { + entry.Name = 0x80000000 | (current_strings_pos - offset_from_section_start); + uint16_t unicode_length = static_cast<uint16_t>((*it).get_name().length()); + memcpy(&raw_data[current_strings_pos], &unicode_length, sizeof(unicode_length)); + current_strings_pos += sizeof(unicode_length); + +#ifdef PE_BLISS_WINDOWS + memcpy(&raw_data[current_strings_pos], (*it).get_name().c_str(), (*it).get_name().length() * sizeof(uint16_t) + sizeof(uint16_t) /* unicode */); +#else + { + u16string str(pe_utils::to_ucs2((*it).get_name())); + memcpy(&raw_data[current_strings_pos], str.c_str(), (*it).get_name().length() * sizeof(uint16_t) + sizeof(uint16_t) /* unicode */); + } +#endif + + current_strings_pos += static_cast<unsigned long>((*it).get_name().length() * sizeof(uint16_t) + sizeof(uint16_t) /* unicode */); + } + else + { + entry.Name = (*it).get_id(); + } + + if((*it).includes_data()) + { + current_data_pos = pe_utils::align_up(current_data_pos, sizeof(uint32_t)); + image_resource_data_entry data_entry = {0}; + data_entry.CodePage = (*it).get_data_entry().get_codepage(); + data_entry.Size = static_cast<uint32_t>((*it).get_data_entry().get_data().length()); + data_entry.OffsetToData = pe.rva_from_section_offset(resource_section, current_data_pos + sizeof(data_entry)); + + entry.OffsetToData = current_data_pos - offset_from_section_start; + + memcpy(&raw_data[current_data_pos], &data_entry, sizeof(data_entry)); + current_data_pos += sizeof(data_entry); + + memcpy(&raw_data[current_data_pos], (*it).get_data_entry().get_data().data(), data_entry.Size); + current_data_pos += data_entry.Size; + + memcpy(&raw_data[this_current_structures_pos], &entry, sizeof(entry)); + this_current_structures_pos += sizeof(entry); + } + else + { + entry.OffsetToData = 0x80000000 | (current_structures_pos - offset_from_section_start); + + memcpy(&raw_data[this_current_structures_pos], &entry, sizeof(entry)); + this_current_structures_pos += sizeof(entry); + + rebuild_resource_directory(pe, resource_section, (*it).get_resource_directory(), current_structures_pos, current_data_pos, current_strings_pos, offset_from_section_start); + } + } +} + +//Helper function to rebuild resource directory +bool entry_sorter::operator()(const resource_directory_entry& entry1, const resource_directory_entry& entry2) const +{ + if(entry1.is_named() && entry2.is_named()) + return entry1.get_name() < entry2.get_name(); + else if(!entry1.is_named() && !entry2.is_named()) + return entry1.get_id() < entry2.get_id(); + else + return entry1.is_named(); +} + +//Resources rebuilder +//resource_directory - root resource directory +//resources_section - section where resource directory will be placed (must be attached to PE image) +//offset_from_section_start - offset from resources_section raw data start +//resource_directory is non-constant, because it will be sorted +//save_to_pe_headers - if true, new resource directory information will be saved to PE image headers +//auto_strip_last_section - if true and resources are placed in the last section, it will be automatically stripped +//number_of_id_entries and number_of_named_entries for resource directories are recalculated and not used +const image_directory rebuild_resources(pe_base& pe, resource_directory& info, section& resources_section, uint32_t offset_from_section_start, bool save_to_pe_header, bool auto_strip_last_section) +{ + //Check that resources_section is attached to this PE image + if(!pe.section_attached(resources_section)) + throw pe_exception("Resource section must be attached to PE file", pe_exception::section_is_not_attached); + + //Check resource directory correctness + if(info.get_entry_list().empty()) + throw pe_exception("Empty resource directory", pe_exception::incorrect_resource_directory); + + uint32_t aligned_offset_from_section_start = pe_utils::align_up(offset_from_section_start, sizeof(uint32_t)); + uint32_t needed_size_for_structures = aligned_offset_from_section_start - offset_from_section_start; //Calculate needed size for resource tables and data + uint32_t needed_size_for_strings = 0; + uint32_t needed_size_for_data = 0; + + calculate_resource_data_space(info, aligned_offset_from_section_start, needed_size_for_structures, needed_size_for_strings); + + { + uint32_t current_data_pos = aligned_offset_from_section_start + needed_size_for_structures + needed_size_for_strings; + calculate_resource_data_space(info, needed_size_for_structures, needed_size_for_strings, needed_size_for_data, current_data_pos); + } + + uint32_t needed_size = needed_size_for_structures + needed_size_for_strings + needed_size_for_data; + + //Check if resources_section is last one. If it's not, check if there's enough place for resource data + if(&resources_section != &*(pe.get_image_sections().end() - 1) && + (resources_section.empty() || pe_utils::align_up(resources_section.get_size_of_raw_data(), pe.get_file_alignment()) + < needed_size + aligned_offset_from_section_start)) + throw pe_exception("Insufficient space for resource directory", pe_exception::insufficient_space); + + std::string& raw_data = resources_section.get_raw_data(); + + //This will be done only if resources_section is the last section of image or for section with unaligned raw length of data + if(raw_data.length() < needed_size + aligned_offset_from_section_start) + raw_data.resize(needed_size + aligned_offset_from_section_start); //Expand section raw data + + uint32_t current_structures_pos = aligned_offset_from_section_start; + uint32_t current_strings_pos = current_structures_pos + needed_size_for_structures; + uint32_t current_data_pos = current_strings_pos + needed_size_for_strings; + rebuild_resource_directory(pe, resources_section, info, current_structures_pos, current_data_pos, current_strings_pos, aligned_offset_from_section_start); + + //Adjust section raw and virtual sizes + pe.recalculate_section_sizes(resources_section, auto_strip_last_section); + + image_directory ret(pe.rva_from_section_offset(resources_section, aligned_offset_from_section_start), needed_size); + + //If auto-rewrite of PE headers is required + if(save_to_pe_header) + { + pe.set_directory_rva(image_directory_entry_resource, ret.get_rva()); + pe.set_directory_size(image_directory_entry_resource, ret.get_size()); + } + + return ret; +} + +//Returns resources from PE file +const resource_directory get_resources(const pe_base& pe) +{ + resource_directory ret; + + if(!pe.has_resources()) + return ret; + + //Get resource directory RVA + uint32_t res_rva = pe.get_directory_rva(image_directory_entry_resource); + + //Store already processed directories to avoid resource loops + std::set<uint32_t> processed; + + //Process all directories (recursion) + ret = process_resource_directory(pe, res_rva, 0, processed); + + return ret; +} + +//Finds resource_directory_entry by ID +resource_directory::id_entry_finder::id_entry_finder(uint32_t id) + :id_(id) +{} + +bool resource_directory::id_entry_finder::operator()(const resource_directory_entry& entry) const +{ + return !entry.is_named() && entry.get_id() == id_; +} + +//Finds resource_directory_entry by name +resource_directory::name_entry_finder::name_entry_finder(const std::wstring& name) + :name_(name) +{} + +bool resource_directory::name_entry_finder::operator()(const resource_directory_entry& entry) const +{ + return entry.is_named() && entry.get_name() == name_; +} + +//Finds resource_directory_entry by name or ID (universal) +resource_directory::entry_finder::entry_finder(const std::wstring& name) + :name_(name), named_(true) +{} + +resource_directory::entry_finder::entry_finder(uint32_t id) + :id_(id), named_(false) +{} + +bool resource_directory::entry_finder::operator()(const resource_directory_entry& entry) const +{ + if(named_) + return entry.is_named() && entry.get_name() == name_; + else + return !entry.is_named() && entry.get_id() == id_; +} + +//Returns resource_directory_entry by ID. If not found - throws an exception +const resource_directory_entry& resource_directory::entry_by_id(uint32_t id) const +{ + entry_list::const_iterator i = std::find_if(entries_.begin(), entries_.end(), id_entry_finder(id)); + if(i == entries_.end()) + throw pe_exception("Resource directory entry not found", pe_exception::resource_directory_entry_not_found); + + return *i; +} + +//Returns resource_directory_entry by name. If not found - throws an exception +const resource_directory_entry& resource_directory::entry_by_name(const std::wstring& name) const +{ + entry_list::const_iterator i = std::find_if(entries_.begin(), entries_.end(), name_entry_finder(name)); + if(i == entries_.end()) + throw pe_exception("Resource directory entry not found", pe_exception::resource_directory_entry_not_found); + + return *i; +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_resources.h b/irdb-lib/pebliss/trunk/pe_lib/pe_resources.h new file mode 100644 index 0000000000000000000000000000000000000000..77cd60943dd09751b706b18993b391e0f403d0ae --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_resources.h @@ -0,0 +1,231 @@ +#ifndef pebliss_pe_resources_h +#define pebliss_pe_resources_h +#pragma once +#ifndef peresource_h +#define peresource_h + +#include <vector> +#include <string> +#include <set> +#include "pe_structures.h" +#include "pe_base.h" +#include "pe_directory.h" + +namespace pe_bliss +{ +//Class representing resource data entry +class resource_data_entry +{ +public: + //Default constructor + resource_data_entry(); + //Constructor from data + resource_data_entry(const std::string& data, uint32_t codepage); + + //Returns resource data codepage + uint32_t get_codepage() const; + //Returns resource data + const std::string& get_data() const; + +public: //These functions do not change everything inside image, they are used by PE class + //You can also use them to rebuild resource directory + + //Sets resource data codepage + void set_codepage(uint32_t codepage); + //Sets resource data + void set_data(const std::string& data); + +private: + uint32_t codepage_; //Resource data codepage + std::string data_; //Resource data +}; + +//Forward declaration +class resource_directory; + +//Class representing resource directory entry +class resource_directory_entry +{ +public: + //Default constructor + resource_directory_entry(); + //Copy constructor + resource_directory_entry(const resource_directory_entry& other); + //Copy assignment operator + resource_directory_entry& operator=(const resource_directory_entry& other); + + //Returns entry ID + uint32_t get_id() const; + //Returns entry name + const std::wstring& get_name() const; + //Returns true, if entry has name + //Returns false, if entry has ID + bool is_named() const; + + //Returns true, if entry includes resource_data_entry + //Returns false, if entry includes resource_directory + bool includes_data() const; + //Returns resource_directory if entry includes it, otherwise throws an exception + const resource_directory& get_resource_directory() const; + //Returns resource_data_entry if entry includes it, otherwise throws an exception + const resource_data_entry& get_data_entry() const; + + //Destructor + ~resource_directory_entry(); + +public: //These functions do not change everything inside image, they are used by PE class + //You can also use them to rebuild resource directory + + //Sets entry name + void set_name(const std::wstring& name); + //Sets entry ID + void set_id(uint32_t id); + + //Returns resource_directory if entry includes it, otherwise throws an exception + resource_directory& get_resource_directory(); + //Returns resource_data_entry if entry includes it, otherwise throws an exception + resource_data_entry& get_data_entry(); + + //Adds resource_data_entry + void add_data_entry(const resource_data_entry& entry); + //Adds resource_directory + void add_resource_directory(const resource_directory& dir); + +private: + //Destroys included data + void release(); + +private: + uint32_t id_; + std::wstring name_; + + union includes + { + //Default constructor + includes(); + + //We use pointers, we're doing manual copying here + class resource_data_entry* data_; + class resource_directory* dir_; //We use pointer, because structs include each other + }; + + includes ptr_; + + bool includes_data_, named_; +}; + +//Class representing resource directory +class resource_directory +{ +public: + typedef std::vector<resource_directory_entry> entry_list; + +public: + //Default constructor + resource_directory(); + //Constructor from data + explicit resource_directory(const pe_win::image_resource_directory& dir); + + //Returns characteristics of directory + uint32_t get_characteristics() const; + //Returns date and time stamp of directory + uint32_t get_timestamp() const; + //Returns number of named entries + uint32_t get_number_of_named_entries() const; + //Returns number of ID entries + uint32_t get_number_of_id_entries() const; + //Returns major version of directory + uint16_t get_major_version() const; + //Returns minor version of directory + uint16_t get_minor_version() const; + //Returns resource_directory_entry array + const entry_list& get_entry_list() const; + //Returns resource_directory_entry by ID. If not found - throws an exception + const resource_directory_entry& entry_by_id(uint32_t id) const; + //Returns resource_directory_entry by name. If not found - throws an exception + const resource_directory_entry& entry_by_name(const std::wstring& name) const; + +public: //These functions do not change everything inside image, they are used by PE class + //You can also use them to rebuild resource directory + + //Adds resource_directory_entry + void add_resource_directory_entry(const resource_directory_entry& entry); + //Clears resource_directory_entry array + void clear_resource_directory_entry_list(); + + //Sets characteristics of directory + void set_characteristics(uint32_t characteristics); + //Sets date and time stamp of directory + void set_timestamp(uint32_t timestamp); + //Sets number of named entries + void set_number_of_named_entries(uint32_t number); + //Sets number of ID entries + void set_number_of_id_entries(uint32_t number); + //Sets major version of directory + void set_major_version(uint16_t major_version); + //Sets minor version of directory + void get_minor_version(uint16_t minor_version); + + //Returns resource_directory_entry array + entry_list& get_entry_list(); + +private: + uint32_t characteristics_; + uint32_t timestamp_; + uint16_t major_version_, minor_version_; + uint32_t number_of_named_entries_, number_of_id_entries_; + entry_list entries_; + +public: //Finder helpers + //Finds resource_directory_entry by ID + struct id_entry_finder + { + public: + explicit id_entry_finder(uint32_t id); + bool operator()(const resource_directory_entry& entry) const; + + private: + uint32_t id_; + }; + + //Finds resource_directory_entry by name + struct name_entry_finder + { + public: + explicit name_entry_finder(const std::wstring& name); + bool operator()(const resource_directory_entry& entry) const; + + private: + std::wstring name_; + }; + + //Finds resource_directory_entry by name or ID (universal) + struct entry_finder + { + public: + explicit entry_finder(const std::wstring& name); + explicit entry_finder(uint32_t id); + bool operator()(const resource_directory_entry& entry) const; + + private: + std::wstring name_; + uint32_t id_; + bool named_; + }; +}; + +//Returns resources (root resource_directory) from PE file +const resource_directory get_resources(const pe_base& pe); + +//Resources rebuilder +//resource_directory - root resource directory +//resources_section - section where resource directory will be placed (must be attached to PE image) +//resource_directory is non-constant, because it will be sorted +//offset_from_section_start - offset from resources_section raw data start +//save_to_pe_headers - if true, new resource directory information will be saved to PE image headers +//auto_strip_last_section - if true and resources are placed in the last section, it will be automatically stripped +//number_of_id_entries and number_of_named_entries for resource directories are recalculated and not used +const image_directory rebuild_resources(pe_base& pe, resource_directory& info, section& resources_section, uint32_t offset_from_section_start = 0, bool save_to_pe_header = true, bool auto_strip_last_section = true); +} +#endif +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_rich_data.cpp b/irdb-lib/pebliss/trunk/pe_lib/pe_rich_data.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0497fa6469b68dd830e349e38537584ea9ef4d91 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_rich_data.cpp @@ -0,0 +1,131 @@ +#include "pe_rich_data.h" + +namespace pe_bliss +{ +//STUB OVERLAY +//Default constructor +rich_data::rich_data() + :number_(0), version_(0), times_(0) +{} + +//Who knows, what these fields mean... +uint32_t rich_data::get_number() const +{ + return number_; +} + +uint32_t rich_data::get_version() const +{ + return version_; +} + +uint32_t rich_data::get_times() const +{ + return times_; +} + +void rich_data::set_number(uint32_t number) +{ + number_ = number; +} + +void rich_data::set_version(uint32_t version) +{ + version_ = version; +} + +void rich_data::set_times(uint32_t times) +{ + times_ = times; +} + +//Returns MSVC rich data +const rich_data_list get_rich_data(const pe_base& pe) +{ + //Returned value + rich_data_list ret; + + const std::string& rich_overlay = pe.get_stub_overlay(); + + //If there's no rich overlay, return empty vector + if(rich_overlay.size() < sizeof(uint32_t)) + return ret; + + //True if rich data was found + bool found = false; + + //Rich overlay ID ("Rich" word) + static const uint32_t rich_overlay_id = 0x68636952; + + //Search for rich data overlay ID + const char* begin = &rich_overlay[0]; + const char* end = begin + rich_overlay.length(); + for(; begin != end; ++begin) + { + if(*reinterpret_cast<const uint32_t*>(begin) == rich_overlay_id) + { + found = true; //We've found it! + break; + } + } + + //If we found it + if(found) + { + //Check remaining length + if(static_cast<size_t>(end - begin) < sizeof(uint32_t)) + return ret; + + //The XOR key is after "Rich" word, we should get it + uint32_t xorkey = *reinterpret_cast<const uint32_t*>(begin + sizeof(uint32_t)); + + //True if rich data was found + found = false; + + //Second search for signature "DanS" + begin = &rich_overlay[0]; + for(; begin != end; ++begin) + { + if((*reinterpret_cast<const uint32_t*>(begin) ^ xorkey) == 0x536e6144) //"DanS" + { + found = true; + break; + } + } + + //If second signature is found + if(found) + { + begin += sizeof(uint32_t) * 3; + //List all rich data structures + while(begin < end) + { + begin += sizeof(uint32_t); + if(begin >= end) + break; + + //Check for rich overlay data end ("Rich" word reached) + if(*reinterpret_cast<const uint32_t*>(begin) == rich_overlay_id) + break; + + //Create rich_data structure + rich_data data; + data.set_number((*reinterpret_cast<const uint32_t*>(begin) ^ xorkey) >> 16); + data.set_version((*reinterpret_cast<const uint32_t*>(begin) ^ xorkey) & 0xFFFF); + + begin += sizeof(uint32_t); + if(begin >= end) + break; + + data.set_times(*reinterpret_cast<const uint32_t*>(begin) ^ xorkey); + + //Save rich data structure + ret.push_back(data); + } + } + } + + //Return rich data structures list + return ret; +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_rich_data.h b/irdb-lib/pebliss/trunk/pe_lib/pe_rich_data.h new file mode 100644 index 0000000000000000000000000000000000000000..a5689453152e368ee8b411c075e220f84827661f --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_rich_data.h @@ -0,0 +1,40 @@ +#ifndef pebliss_pe_rich_data_h +#define pebliss_pe_rich_data_h +#pragma once +#include <vector> +#include "pe_structures.h" +#include "pe_base.h" + +namespace pe_bliss +{ +//Rich data overlay class of Microsoft Visual Studio +class rich_data +{ +public: + //Default constructor + rich_data(); + +public: //Getters + //Who knows, what these fields mean... + uint32_t get_number() const; + uint32_t get_version() const; + uint32_t get_times() const; + +public: //Setters, used by PE library only + void set_number(uint32_t number); + void set_version(uint32_t version); + void set_times(uint32_t times); + +private: + uint32_t number_; + uint32_t version_; + uint32_t times_; +}; + +//Rich data list typedef +typedef std::vector<rich_data> rich_data_list; + +//Returns a vector with rich data (stub overlay) +const rich_data_list get_rich_data(const pe_base& pe); +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_section.cpp b/irdb-lib/pebliss/trunk/pe_lib/pe_section.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e7def185cb6910f98cd78216ac891c2c750627ea --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_section.cpp @@ -0,0 +1,281 @@ +#include <string.h> +#include "utils.h" +#include "pe_section.h" + +namespace pe_bliss +{ +using namespace pe_win; + +//Section structure default constructor +section::section() + :old_size_(static_cast<size_t>(-1)) +{ + memset(&header_, 0, sizeof(image_section_header)); +} + +//Sets the name of section (8 characters maximum) +void section::set_name(const std::string& name) +{ + memset(header_.Name, 0, sizeof(header_.Name)); + memcpy(header_.Name, name.c_str(), std::min<size_t>(name.length(), sizeof(header_.Name))); +} + +//Returns section name +const std::string section::get_name() const +{ + char buf[9] = {0}; + memcpy(buf, header_.Name, 8); + return std::string(buf); +} + +//Set flag (attribute) of section +section& section::set_flag(uint32_t flag, bool setflag) +{ + if(setflag) + header_.Characteristics |= flag; + else + header_.Characteristics &= ~flag; + + return *this; +} + +//Sets "readable" attribute of section +section& section::readable(bool readable) +{ + return set_flag(image_scn_mem_read, readable); +} + +//Sets "writeable" attribute of section +section& section::writeable(bool writeable) +{ + return set_flag(image_scn_mem_write, writeable); +} + +//Sets "executable" attribute of section +section& section::executable(bool executable) +{ + return set_flag(image_scn_mem_execute, executable); +} + +//Sets "shared" attribute of section +section& section::shared(bool shared) +{ + return set_flag(image_scn_mem_shared, shared); +} + +//Sets "discardable" attribute of section +section& section::discardable(bool discardable) +{ + return set_flag(image_scn_mem_discardable, discardable); +} + +//Returns true if section is readable +bool section::readable() const +{ + return (header_.Characteristics & image_scn_mem_read) != 0; +} + +//Returns true if section is writeable +bool section::writeable() const +{ + return (header_.Characteristics & image_scn_mem_write) != 0; +} + +//Returns true if section is executable +bool section::executable() const +{ + return (header_.Characteristics & image_scn_mem_execute) != 0; +} + +bool section::shared() const +{ + return (header_.Characteristics & image_scn_mem_shared) != 0; +} + +bool section::discardable() const +{ + return (header_.Characteristics & image_scn_mem_discardable) != 0; +} + +//Returns true if section has no RAW data +bool section::empty() const +{ + if(old_size_ != static_cast<size_t>(-1)) //If virtual memory is mapped, check raw data length (old_size_) + return old_size_ == 0; + else + return raw_data_.empty(); +} + +//Returns raw section data from file image +std::string& section::get_raw_data() +{ + unmap_virtual(); + return raw_data_; +} + +//Sets raw section data from file image +void section::set_raw_data(const std::string& data) +{ + old_size_ = static_cast<size_t>(-1); + raw_data_ = data; +} + +//Returns raw section data from file image +const std::string& section::get_raw_data() const +{ + unmap_virtual(); + return raw_data_; +} + +//Returns mapped virtual section data +const std::string& section::get_virtual_data(uint32_t section_alignment) const +{ + map_virtual(section_alignment); + return raw_data_; +} + +//Returns mapped virtual section data +std::string& section::get_virtual_data(uint32_t section_alignment) +{ + map_virtual(section_alignment); + return raw_data_; +} + +//Maps virtual section data +void section::map_virtual(uint32_t section_alignment) const +{ + uint32_t aligned_virtual_size = get_aligned_virtual_size(section_alignment); + if(old_size_ == static_cast<size_t>(-1) && aligned_virtual_size && aligned_virtual_size > raw_data_.length()) + { + old_size_ = raw_data_.length(); + raw_data_.resize(aligned_virtual_size, 0); + } +} + +//Unmaps virtual section data +void section::unmap_virtual() const +{ + if(old_size_ != static_cast<size_t>(-1)) + { + raw_data_.resize(old_size_, 0); + old_size_ = static_cast<size_t>(-1); + } +} + +//Returns section virtual size +uint32_t section::get_virtual_size() const +{ + return header_.Misc.VirtualSize; +} + +//Returns section virtual address +uint32_t section::get_virtual_address() const +{ + return header_.VirtualAddress; +} + +//Returns size of section raw data +uint32_t section::get_size_of_raw_data() const +{ + return header_.SizeOfRawData; +} + +//Returns pointer to raw section data in PE file +uint32_t section::get_pointer_to_raw_data() const +{ + return header_.PointerToRawData; +} + +//Returns section characteristics +uint32_t section::get_characteristics() const +{ + return header_.Characteristics; +} + +//Returns raw image section header +const pe_win::image_section_header& section::get_raw_header() const +{ + return header_; +} + +//Returns raw image section header +pe_win::image_section_header& section::get_raw_header() +{ + return header_; +} + +//Calculates aligned virtual section size +uint32_t section::get_aligned_virtual_size(uint32_t section_alignment) const +{ + if(get_size_of_raw_data()) + { + if(!get_virtual_size()) + { + //If section virtual size is zero + //Set aligned virtual size of section as aligned raw size + return pe_utils::align_up(get_size_of_raw_data(), section_alignment); + } + } + + return pe_utils::align_up(get_virtual_size(), section_alignment); +} + +//Calculates aligned raw section size +uint32_t section::get_aligned_raw_size(uint32_t file_alignment) const +{ + if(get_size_of_raw_data()) + return pe_utils::align_up(get_size_of_raw_data(), file_alignment); + else + return 0; +} + +//Sets size of raw section data +void section::set_size_of_raw_data(uint32_t size_of_raw_data) +{ + header_.SizeOfRawData = size_of_raw_data; +} + +//Sets pointer to section raw data +void section::set_pointer_to_raw_data(uint32_t pointer_to_raw_data) +{ + header_.PointerToRawData = pointer_to_raw_data; +} + +//Sets section characteristics +void section::set_characteristics(uint32_t characteristics) +{ + header_.Characteristics = characteristics; +} + +//Sets section virtual size +void section::set_virtual_size(uint32_t virtual_size) +{ + header_.Misc.VirtualSize = virtual_size; +} + +//Sets section virtual address +void section::set_virtual_address(uint32_t virtual_address) +{ + header_.VirtualAddress = virtual_address; +} + +//Section by file offset finder helper (4gb max) +section_by_raw_offset::section_by_raw_offset(uint32_t offset) + :offset_(offset) +{} + +bool section_by_raw_offset::operator()(const section& s) const +{ + return (s.get_pointer_to_raw_data() <= offset_) + && (s.get_pointer_to_raw_data() + s.get_size_of_raw_data() > offset_); +} + +section_ptr_finder::section_ptr_finder(const section& s) + :s_(s) +{} + +bool section_ptr_finder::operator()(const section& s) const +{ + return &s == &s_; +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_section.h b/irdb-lib/pebliss/trunk/pe_lib/pe_section.h new file mode 100644 index 0000000000000000000000000000000000000000..552959c6833da6716610d801a7e33bd00e2fbd95 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_section.h @@ -0,0 +1,144 @@ +#ifndef pebliss_pe_section_h +#define pebliss_pe_section_h +#pragma once +#ifndef pebliss_section_h +#define pebliss_section_h + +#include <string> +#include <vector> +#include "pe_structures.h" + +namespace pe_bliss +{ +//Enumeration of section data types, used in functions below +enum section_data_type +{ + section_data_raw, + section_data_virtual +}; + +//Class representing image section +class section +{ +public: + //Default constructor + section(); + + //Sets the name of section (stripped to 8 characters) + void set_name(const std::string& name); + + //Returns the name of section + const std::string get_name() const; + + //Changes attributes of section + section& readable(bool readable); + section& writeable(bool writeable); + section& executable(bool executable); + section& shared(bool shared); + section& discardable(bool discardable); + + //Returns attributes of section + bool readable() const; + bool writeable() const; + bool executable() const; + bool shared() const; + bool discardable() const; + + //Returns true if section has no RAW data + bool empty() const; + + //Returns raw section data from file image + std::string& get_raw_data(); + //Returns raw section data from file image + const std::string& get_raw_data() const; + //Returns mapped virtual section data + const std::string& get_virtual_data(uint32_t section_alignment) const; + //Returns mapped virtual section data + std::string& get_virtual_data(uint32_t section_alignment); + +public: //Header getters + //Returns section virtual size + uint32_t get_virtual_size() const; + //Returns section virtual address (RVA) + uint32_t get_virtual_address() const; + //Returns size of section raw data + uint32_t get_size_of_raw_data() const; + //Returns pointer to raw section data in PE file + uint32_t get_pointer_to_raw_data() const; + //Returns section characteristics + uint32_t get_characteristics() const; + + //Returns raw image section header + const pe_win::image_section_header& get_raw_header() const; + +public: //Aligned sizes calculation + //Calculates aligned virtual section size + uint32_t get_aligned_virtual_size(uint32_t section_alignment) const; + //Calculates aligned raw section size + uint32_t get_aligned_raw_size(uint32_t file_alignment) const; + +public: //Setters + //Sets size of raw section data + void set_size_of_raw_data(uint32_t size_of_raw_data); + //Sets pointer to section raw data + void set_pointer_to_raw_data(uint32_t pointer_to_raw_data); + //Sets section characteristics + void set_characteristics(uint32_t characteristics); + //Sets raw section data from file image + void set_raw_data(const std::string& data); + +public: //Setters, be careful + //Sets section virtual size (doesn't set internal aligned virtual size, changes only header value) + //Better use pe_base::set_section_virtual_size + void set_virtual_size(uint32_t virtual_size); + //Sets section virtual address + void set_virtual_address(uint32_t virtual_address); + //Returns raw image section header + pe_win::image_section_header& get_raw_header(); + +private: + //Section header + pe_win::image_section_header header_; + + //Maps virtual section data + void map_virtual(uint32_t section_alignment) const; + + //Unmaps virtual section data + void unmap_virtual() const; + + //Set flag (attribute) of section + section& set_flag(uint32_t flag, bool setflag); + + //Old size of section (stored after mapping of virtual section memory) + mutable std::size_t old_size_; + + //Section raw/virtual data + mutable std::string raw_data_; +}; + +//Section by file offset finder helper (4gb max) +struct section_by_raw_offset +{ +public: + explicit section_by_raw_offset(uint32_t offset); + bool operator()(const section& s) const; + +private: + uint32_t offset_; +}; + +//Helper: finder of section* in sections list +struct section_ptr_finder +{ +public: + explicit section_ptr_finder(const section& s); + bool operator()(const section& s) const; + +private: + const section& s_; +}; + +typedef std::vector<section> section_list; +} +#endif +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_structures.h b/irdb-lib/pebliss/trunk/pe_lib/pe_structures.h new file mode 100644 index 0000000000000000000000000000000000000000..0487d02683af92f4509641336028f444e9933ab7 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_structures.h @@ -0,0 +1,1030 @@ +#ifndef pebliss_pe_structures_h +#define pebliss_pe_structures_h +#pragma once +#ifndef pe_struct_h +#define pe_struct_h + +#include <string> +#include <sstream> +#include "stdint_defs.h" +#if defined(_MSC_VER) +#define PE_BLISS_WINDOWS +#endif + +namespace pe_bliss +{ +//Enumeration of PE types +enum pe_type +{ + pe_type_32, + pe_type_64 +}; + +namespace pe_win +{ +const uint32_t image_numberof_directory_entries = 16; +const uint32_t image_nt_optional_hdr32_magic = 0x10b; +const uint32_t image_nt_optional_hdr64_magic = 0x20b; +const uint32_t image_resource_name_is_string = 0x80000000; +const uint32_t image_resource_data_is_directory = 0x80000000; + +const uint32_t image_dllcharacteristics_dynamic_base = 0x0040; // DLL can move. +const uint32_t image_dllcharacteristics_force_integrity = 0x0080; // Code Integrity Image +const uint32_t image_dllcharacteristics_nx_compat = 0x0100; // Image is NX compatible +const uint32_t image_dllcharacteristics_no_isolation = 0x0200; // Image understands isolation and doesn't want it +const uint32_t image_dllcharacteristics_no_seh = 0x0400; // Image does not use SEH. No SE handler may reside in this image +const uint32_t image_dllcharacteristics_no_bind = 0x0800; // Do not bind this image. +const uint32_t image_dllcharacteristics_wdm_driver = 0x2000; // Driver uses WDM model +const uint32_t image_dllcharacteristics_terminal_server_aware = 0x8000; + +const uint32_t image_sizeof_file_header = 20; + +const uint32_t image_file_relocs_stripped = 0x0001; // Relocation info stripped from file. +const uint32_t image_file_executable_image = 0x0002; // File is executable (i.e. no unresolved externel references). +const uint32_t image_file_line_nums_stripped = 0x0004; // Line nunbers stripped from file. +const uint32_t image_file_local_syms_stripped = 0x0008; // Local symbols stripped from file. +const uint32_t image_file_aggresive_ws_trim = 0x0010; // Agressively trim working set +const uint32_t image_file_large_address_aware = 0x0020; // App can handle >2gb addresses +const uint32_t image_file_bytes_reversed_lo = 0x0080; // Bytes of machine word are reversed. +const uint32_t image_file_32bit_machine = 0x0100; // 32 bit word machine. +const uint32_t image_file_debug_stripped = 0x0200; // Debugging info stripped from file in .DBG file +const uint32_t image_file_removable_run_from_swap = 0x0400; // If Image is on removable media, copy and run from the swap file. +const uint32_t image_file_net_run_from_swap = 0x0800; // If Image is on Net, copy and run from the swap file. +const uint32_t image_file_system = 0x1000; // System File. +const uint32_t image_file_dll = 0x2000; // File is a DLL. +const uint32_t image_file_up_system_only = 0x4000; // File should only be run on a UP machine +const uint32_t image_file_bytes_reversed_hi = 0x8000; // Bytes of machine word are reversed. + +const uint32_t image_scn_lnk_nreloc_ovfl = 0x01000000; // Section contains extended relocations. +const uint32_t image_scn_mem_discardable = 0x02000000; // Section can be discarded. +const uint32_t image_scn_mem_not_cached = 0x04000000; // Section is not cachable. +const uint32_t image_scn_mem_not_paged = 0x08000000; // Section is not pageable. +const uint32_t image_scn_mem_shared = 0x10000000; // Section is shareable. +const uint32_t image_scn_mem_execute = 0x20000000; // Section is executable. +const uint32_t image_scn_mem_read = 0x40000000; // Section is readable. +const uint32_t image_scn_mem_write = 0x80000000; // Section is writeable. + +const uint32_t image_scn_cnt_code = 0x00000020; // Section contains code. +const uint32_t image_scn_cnt_initialized_data = 0x00000040; // Section contains initialized data. +const uint32_t image_scn_cnt_uninitialized_data = 0x00000080; // Section contains uninitialized data. + +//Directory Entries +const uint32_t image_directory_entry_export = 0; // Export Directory +const uint32_t image_directory_entry_import = 1; // Import Directory +const uint32_t image_directory_entry_resource = 2; // Resource Directory +const uint32_t image_directory_entry_exception = 3; // Exception Directory +const uint32_t image_directory_entry_security = 4; // Security Directory +const uint32_t image_directory_entry_basereloc = 5; // Base Relocation Table +const uint32_t image_directory_entry_debug = 6; // Debug Directory +const uint32_t image_directory_entry_architecture = 7; // Architecture Specific Data +const uint32_t image_directory_entry_globalptr = 8; // RVA of GP +const uint32_t image_directory_entry_tls = 9; // TLS Directory +const uint32_t image_directory_entry_load_config = 10; // Load Configuration Directory +const uint32_t image_directory_entry_bound_import = 11; // Bound Import Directory in headers +const uint32_t image_directory_entry_iat = 12; // Import Address Table +const uint32_t image_directory_entry_delay_import = 13; // Delay Load Import Descriptors +const uint32_t image_directory_entry_com_descriptor = 14; // COM Runtime descriptor + +//Subsystem Values +const uint32_t image_subsystem_unknown = 0; // Unknown subsystem. +const uint32_t image_subsystem_native = 1; // Image doesn't require a subsystem. +const uint32_t image_subsystem_windows_gui = 2; // Image runs in the Windows GUI subsystem. +const uint32_t image_subsystem_windows_cui = 3; // Image runs in the Windows character subsystem. +const uint32_t image_subsystem_os2_cui = 5; // image runs in the OS/2 character subsystem. +const uint32_t image_subsystem_posix_cui = 7; // image runs in the Posix character subsystem. +const uint32_t image_subsystem_native_windows = 8; // image is a native Win9x driver. +const uint32_t image_subsystem_windows_ce_gui = 9; // Image runs in the Windows CE subsystem. +const uint32_t image_subsystem_efi_application = 10; // +const uint32_t image_subsystem_efi_boot_service_driver = 11; // +const uint32_t image_subsystem_efi_runtime_driver = 12; // +const uint32_t image_subsystem_efi_rom = 13; +const uint32_t image_subsystem_xbox = 14; +const uint32_t image_subsystem_windows_boot_application = 16; + +//Imports +const uint64_t image_ordinal_flag64 = 0x8000000000000000ull; +const uint32_t image_ordinal_flag32 = 0x80000000; + +//Based relocation types +const uint32_t image_rel_based_absolute = 0; +const uint32_t image_rel_based_high = 1; +const uint32_t image_rel_based_low = 2; +const uint32_t image_rel_based_highlow = 3; +const uint32_t image_rel_based_highadj = 4; +const uint32_t image_rel_based_mips_jmpaddr = 5; +const uint32_t image_rel_based_mips_jmpaddr16 = 9; +const uint32_t image_rel_based_ia64_imm64 = 9; +const uint32_t image_rel_based_dir64 = 10; + +//Exception directory +//The function has an exception handler that should be called when looking for functions that need to examine exceptions +const uint32_t unw_flag_ehandler = 0x01; +//The function has a termination handler that should be called when unwinding an exception +const uint32_t unw_flag_uhandler = 0x02; +//This unwind info structure is not the primary one for the procedure. +//Instead, the chained unwind info entry is the contents of a previous RUNTIME_FUNCTION entry. +//If this flag is set, then the UNW_FLAG_EHANDLER and UNW_FLAG_UHANDLER flags must be cleared. +//Also, the frame register and fixed-stack allocation fields must have the same values as in the primary unwind info +const uint32_t unw_flag_chaininfo = 0x04; + +//Debug +const uint32_t image_debug_misc_exename = 1; +const uint32_t image_debug_type_unknown = 0; +const uint32_t image_debug_type_coff = 1; +const uint32_t image_debug_type_codeview = 2; +const uint32_t image_debug_type_fpo = 3; +const uint32_t image_debug_type_misc = 4; +const uint32_t image_debug_type_exception = 5; +const uint32_t image_debug_type_fixup = 6; +const uint32_t image_debug_type_omap_to_src = 7; +const uint32_t image_debug_type_omap_from_src = 8; +const uint32_t image_debug_type_borland = 9; +const uint32_t image_debug_type_reserved10 = 10; +const uint32_t image_debug_type_clsid = 11; + + +//Storage classes +const uint32_t image_sym_class_end_of_function = static_cast<uint8_t>(-1); +const uint32_t image_sym_class_null = 0x0000; +const uint32_t image_sym_class_automatic = 0x0001; +const uint32_t image_sym_class_external = 0x0002; +const uint32_t image_sym_class_static = 0x0003; +const uint32_t image_sym_class_register = 0x0004; +const uint32_t image_sym_class_external_def = 0x0005; +const uint32_t image_sym_class_label = 0x0006; +const uint32_t image_sym_class_undefined_label = 0x0007; +const uint32_t image_sym_class_member_of_struct = 0x0008; +const uint32_t image_sym_class_argument = 0x0009; +const uint32_t image_sym_class_struct_tag = 0x000a; +const uint32_t image_sym_class_member_of_union = 0x000b; +const uint32_t image_sym_class_union_tag = 0x000c; +const uint32_t image_sym_class_type_definition = 0x000d; +const uint32_t image_sym_class_undefined_static = 0x000e; +const uint32_t image_sym_class_enum_tag = 0x000f; +const uint32_t image_sym_class_member_of_enum = 0x0010; +const uint32_t image_sym_class_register_param = 0x0011; +const uint32_t image_sym_class_bit_field = 0x0012; + +const uint32_t image_sym_class_far_external = 0x0044; + +const uint32_t image_sym_class_block = 0x0064; +const uint32_t image_sym_class_function = 0x0065; +const uint32_t image_sym_class_end_of_struct = 0x0066; +const uint32_t image_sym_class_file = 0x0067; + +const uint32_t image_sym_class_section = 0x0068; +const uint32_t image_sym_class_weak_external = 0x0069; + +const uint32_t image_sym_class_clr_token = 0x006b; + +//type packing constants +const uint32_t n_btmask = 0x000f; +const uint32_t n_tmask = 0x0030; +const uint32_t n_tmask1 = 0x00c0; +const uint32_t n_tmask2 = 0x00f0; +const uint32_t n_btshft = 4; +const uint32_t n_tshift = 2; + +//Type (derived) values. +const uint32_t image_sym_dtype_null = 0; // no derived type. +const uint32_t image_sym_dtype_pointer = 1; // pointer. +const uint32_t image_sym_dtype_function = 2; // function. +const uint32_t image_sym_dtype_array = 3; // array. + +// Is x a function? +//TODO +#ifndef ISFCN +#define ISFCN(x) (((x) & n_tmask) == (image_sym_dtype_function << n_btshft)) +#endif + +//Version info +const uint32_t vs_ffi_fileflagsmask = 0x0000003FL; + +const uint32_t vs_ffi_signature = 0xFEEF04BDL; +const uint32_t vs_ffi_strucversion = 0x00010000L; + +/* ----- VS_VERSION.dwFileFlags ----- */ +const uint32_t vs_ff_debug = 0x00000001L; +const uint32_t vs_ff_prerelease = 0x00000002L; +const uint32_t vs_ff_patched = 0x00000004L; +const uint32_t vs_ff_privatebuild = 0x00000008L; +const uint32_t vs_ff_infoinferred = 0x00000010L; +const uint32_t vs_ff_specialbuild = 0x00000020L; + +/* ----- VS_VERSION.dwFileOS ----- */ +const uint32_t vos_unknown = 0x00000000L; +const uint32_t vos_dos = 0x00010000L; +const uint32_t vos_os216 = 0x00020000L; +const uint32_t vos_os232 = 0x00030000L; +const uint32_t vos_nt = 0x00040000L; +const uint32_t vos_wince = 0x00050000L; + +const uint32_t vos__base = 0x00000000L; +const uint32_t vos__windows16 = 0x00000001L; +const uint32_t vos__pm16 = 0x00000002L; +const uint32_t vos__pm32 = 0x00000003L; +const uint32_t vos__windows32 = 0x00000004L; + +const uint32_t vos_dos_windows16 = 0x00010001L; +const uint32_t vos_dos_windows32 = 0x00010004L; +const uint32_t vos_os216_pm16 = 0x00020002L; +const uint32_t vos_os232_pm32 = 0x00030003L; +const uint32_t vos_nt_windows32 = 0x00040004L; + +/* ----- VS_VERSION.dwFileType ----- */ +const uint32_t vft_unknown = 0x00000000L; +const uint32_t vft_app = 0x00000001L; +const uint32_t vft_dll = 0x00000002L; +const uint32_t vft_drv = 0x00000003L; +const uint32_t vft_font = 0x00000004L; +const uint32_t vft_vxd = 0x00000005L; +const uint32_t vft_static_lib = 0x00000007L; + +const uint32_t message_resource_unicode = 0x0001; + +#ifndef SOLARIS +#pragma pack(push, 1) +#endif + +//Windows GUID structure +struct guid +{ + uint32_t Data1; + uint16_t Data2; + uint16_t Data3; + uint8_t Data4[8]; +}; + +//DOS .EXE header +struct image_dos_header +{ + uint16_t e_magic; // Magic number + uint16_t e_cblp; // Bytes on last page of file + uint16_t e_cp; // Pages in file + uint16_t e_crlc; // Relocations + uint16_t e_cparhdr; // Size of header in paragraphs + uint16_t e_minalloc; // Minimum extra paragraphs needed + uint16_t e_maxalloc; // Maximum extra paragraphs needed + uint16_t e_ss; // Initial (relative) SS value + uint16_t e_sp; // Initial SP value + uint16_t e_csum; // Checksum + uint16_t e_ip; // Initial IP value + uint16_t e_cs; // Initial (relative) CS value + uint16_t e_lfarlc; // File address of relocation table + uint16_t e_ovno; // Overlay number + uint16_t e_res[4]; // Reserved words + uint16_t e_oemid; // OEM identifier (for e_oeminfo) + uint16_t e_oeminfo; // OEM information; e_oemid specific + uint16_t e_res2[10]; // Reserved words + int32_t e_lfanew; // File address of new exe header +}; + +//Directory format +struct image_data_directory +{ + uint32_t VirtualAddress; + uint32_t Size; +}; + +//Optional header format +struct image_optional_header32 +{ + //Standard fields + uint16_t Magic; + uint8_t MajorLinkerVersion; + uint8_t MinorLinkerVersion; + uint32_t SizeOfCode; + uint32_t SizeOfInitializedData; + uint32_t SizeOfUninitializedData; + uint32_t AddressOfEntryPoint; + uint32_t BaseOfCode; + uint32_t BaseOfData; + + //NT additional fields + uint32_t ImageBase; + uint32_t SectionAlignment; + uint32_t FileAlignment; + uint16_t MajorOperatingSystemVersion; + uint16_t MinorOperatingSystemVersion; + uint16_t MajorImageVersion; + uint16_t MinorImageVersion; + uint16_t MajorSubsystemVersion; + uint16_t MinorSubsystemVersion; + uint32_t Win32VersionValue; + uint32_t SizeOfImage; + uint32_t SizeOfHeaders; + uint32_t CheckSum; + uint16_t Subsystem; + uint16_t DllCharacteristics; + uint32_t SizeOfStackReserve; + uint32_t SizeOfStackCommit; + uint32_t SizeOfHeapReserve; + uint32_t SizeOfHeapCommit; + uint32_t LoaderFlags; + uint32_t NumberOfRvaAndSizes; + image_data_directory DataDirectory[image_numberof_directory_entries]; +}; + +struct image_optional_header64 +{ + uint16_t Magic; + uint8_t MajorLinkerVersion; + uint8_t MinorLinkerVersion; + uint32_t SizeOfCode; + uint32_t SizeOfInitializedData; + uint32_t SizeOfUninitializedData; + uint32_t AddressOfEntryPoint; + uint32_t BaseOfCode; + uint64_t ImageBase; + uint32_t SectionAlignment; + uint32_t FileAlignment; + uint16_t MajorOperatingSystemVersion; + uint16_t MinorOperatingSystemVersion; + uint16_t MajorImageVersion; + uint16_t MinorImageVersion; + uint16_t MajorSubsystemVersion; + uint16_t MinorSubsystemVersion; + uint32_t Win32VersionValue; + uint32_t SizeOfImage; + uint32_t SizeOfHeaders; + uint32_t CheckSum; + uint16_t Subsystem; + uint16_t DllCharacteristics; + uint64_t SizeOfStackReserve; + uint64_t SizeOfStackCommit; + uint64_t SizeOfHeapReserve; + uint64_t SizeOfHeapCommit; + uint32_t LoaderFlags; + uint32_t NumberOfRvaAndSizes; + image_data_directory DataDirectory[image_numberof_directory_entries]; +}; + +struct image_file_header +{ + uint16_t Machine; + uint16_t NumberOfSections; + uint32_t TimeDateStamp; + uint32_t PointerToSymbolTable; + uint32_t NumberOfSymbols; + uint16_t SizeOfOptionalHeader; + uint16_t Characteristics; +}; + +struct image_nt_headers64 +{ + uint32_t Signature; + image_file_header FileHeader; + image_optional_header64 OptionalHeader; +}; + +struct image_nt_headers32 +{ + uint32_t Signature; + image_file_header FileHeader; + image_optional_header32 OptionalHeader; +}; + +//Section header format +struct image_section_header +{ + uint8_t Name[8]; + union + { + uint32_t PhysicalAddress; + uint32_t VirtualSize; + } Misc; + + uint32_t VirtualAddress; + uint32_t SizeOfRawData; + uint32_t PointerToRawData; + uint32_t PointerToRelocations; + uint32_t PointerToLinenumbers; + uint16_t NumberOfRelocations; + uint16_t NumberOfLinenumbers; + uint32_t Characteristics; +}; + + +/// RESOURCES /// +struct image_resource_directory +{ + uint32_t Characteristics; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint16_t NumberOfNamedEntries; + uint16_t NumberOfIdEntries; + // IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[]; +}; + +struct vs_fixedfileinfo +{ + uint32_t dwSignature; /* e.g. 0xfeef04bd */ + uint32_t dwStrucVersion; /* e.g. 0x00000042 = "0.42" */ + uint32_t dwFileVersionMS; /* e.g. 0x00030075 = "3.75" */ + uint32_t dwFileVersionLS; /* e.g. 0x00000031 = "0.31" */ + uint32_t dwProductVersionMS; /* e.g. 0x00030010 = "3.10" */ + uint32_t dwProductVersionLS; /* e.g. 0x00000031 = "0.31" */ + uint32_t dwFileFlagsMask; /* = 0x3F for version "0.42" */ + uint32_t dwFileFlags; /* e.g. VFF_DEBUG | VFF_PRERELEASE */ + uint32_t dwFileOS; /* e.g. VOS_DOS_WINDOWS16 */ + uint32_t dwFileType; /* e.g. VFT_DRIVER */ + uint32_t dwFileSubtype; /* e.g. VFT2_DRV_KEYBOARD */ + uint32_t dwFileDateMS; /* e.g. 0 */ + uint32_t dwFileDateLS; /* e.g. 0 */ +}; + +struct bitmapinfoheader +{ + uint32_t biSize; + int32_t biWidth; + int32_t biHeight; + uint16_t biPlanes; + uint16_t biBitCount; + uint32_t biCompression; + uint32_t biSizeImage; + int32_t biXPelsPerMeter; + int32_t biYPelsPerMeter; + uint32_t biClrUsed; + uint32_t biClrImportant; +}; + +struct message_resource_entry +{ + uint16_t Length; + uint16_t Flags; + uint8_t Text[1]; +}; + +struct message_resource_block +{ + uint32_t LowId; + uint32_t HighId; + uint32_t OffsetToEntries; +}; + +struct message_resource_data +{ + uint32_t NumberOfBlocks; + message_resource_block Blocks[1]; +}; + +struct image_resource_directory_entry +{ + union + { + struct + { + uint32_t NameOffset:31; + uint32_t NameIsString:1; + }; + uint32_t Name; + uint16_t Id; + }; + + union + { + uint32_t OffsetToData; + struct + { + uint32_t OffsetToDirectory:31; + uint32_t DataIsDirectory:1; + }; + }; +}; + +struct image_resource_data_entry +{ + uint32_t OffsetToData; + uint32_t Size; + uint32_t CodePage; + uint32_t Reserved; +}; + +#ifndef SOLARIS +#pragma pack(push, 2) +#endif +struct bitmapfileheader +{ + uint16_t bfType; + uint32_t bfSize; + uint16_t bfReserved1; + uint16_t bfReserved2; + uint32_t bfOffBits; +}; +#ifndef SOLARIS +#pragma pack(pop) +#endif + + + +//Structure representing ICON file header +struct ico_header +{ + uint16_t Reserved; + uint16_t Type; //1 + uint16_t Count; //Count of icons included in icon group +}; + +//Structure that is stored in icon group directory in PE resources +struct icon_group +{ + uint8_t Width; + uint8_t Height; + uint8_t ColorCount; + uint8_t Reserved; + uint16_t Planes; + uint16_t BitCount; + uint32_t SizeInBytes; + uint16_t Number; //Represents resource ID in PE icon list +}; + +//Structure representing ICON directory entry inside ICON file +struct icondirentry +{ + uint8_t Width; + uint8_t Height; + uint8_t ColorCount; + uint8_t Reserved; + uint16_t Planes; + uint16_t BitCount; + uint32_t SizeInBytes; + uint32_t ImageOffset; //Offset from start of header to the image +}; + +//Structure representing CURSOR file header +struct cursor_header +{ + uint16_t Reserved; + uint16_t Type; //2 + uint16_t Count; //Count of cursors included in cursor group +}; + +struct cursor_group +{ + uint16_t Width; + uint16_t Height; //Divide by 2 to get the actual height. + uint16_t Planes; + uint16_t BitCount; + uint32_t SizeInBytes; + uint16_t Number; //Represents resource ID in PE icon list +}; + +//Structure representing CURSOR directory entry inside CURSOR file +struct cursordirentry +{ + uint8_t Width; //Set to CURSOR_GROUP::Height/2. + uint8_t Height; + uint8_t ColorCount; + uint8_t Reserved; + uint16_t HotspotX; + uint16_t HotspotY; + uint32_t SizeInBytes; + uint32_t ImageOffset; //Offset from start of header to the image +}; + +//Structure representing BLOCK in version info resource +struct version_info_block //(always aligned on 32-bit (DWORD) boundary) +{ + uint16_t Length; //Length of this block (doesn't include padding) + uint16_t ValueLength; //Value length (if any) + uint16_t Type; //Value type (0 = binary, 1 = text) + uint16_t Key[1]; //Value name (block key) (always NULL terminated) + + ////////// + //WORD padding1[]; //Padding, if any (ALIGNMENT) + //xxxxx Value[]; //Value data, if any (*ALIGNED*) + //WORD padding2[]; //Padding, if any (ALIGNMENT) + //xxxxx Child[]; //Child block(s), if any (*ALIGNED*) + ////////// +}; + + +/// IMPORTS /// +#ifndef SOLARIS +#pragma pack(push, 8) +#endif +struct image_thunk_data64 +{ + union + { + uint64_t ForwarderString; // PBYTE + uint64_t Function; // PDWORD + uint64_t Ordinal; + uint64_t AddressOfData; // PIMAGE_IMPORT_BY_NAME + } u1; +}; +#ifndef SOLARIS +#pragma pack(pop) +#endif + +struct image_thunk_data32 +{ + union + { + uint32_t ForwarderString; // PBYTE + uint32_t Function; // PDWORD + uint32_t Ordinal; + uint32_t AddressOfData; // PIMAGE_IMPORT_BY_NAME + } u1; +}; + +struct image_import_descriptor +{ + union + { + uint32_t Characteristics; // 0 for terminating null import descriptor + uint32_t OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA) + }; + + uint32_t TimeDateStamp; // 0 if not bound, + // -1 if bound, and real date\time stamp + // in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND) + // O.W. date/time stamp of DLL bound to (Old BIND) + + uint32_t ForwarderChain; // -1 if no forwarders + uint32_t Name; + uint32_t FirstThunk; // RVA to IAT (if bound this IAT has actual addresses) +}; + + +/// TLS /// +struct image_tls_directory64 +{ + uint64_t StartAddressOfRawData; + uint64_t EndAddressOfRawData; + uint64_t AddressOfIndex; // PDWORD + uint64_t AddressOfCallBacks; // PIMAGE_TLS_CALLBACK *; + uint32_t SizeOfZeroFill; + uint32_t Characteristics; +}; + +struct image_tls_directory32 +{ + uint32_t StartAddressOfRawData; + uint32_t EndAddressOfRawData; + uint32_t AddressOfIndex; // PDWORD + uint32_t AddressOfCallBacks; // PIMAGE_TLS_CALLBACK * + uint32_t SizeOfZeroFill; + uint32_t Characteristics; +}; + + +/// Export Format /// +struct image_export_directory +{ + uint32_t Characteristics; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t Name; + uint32_t Base; + uint32_t NumberOfFunctions; + uint32_t NumberOfNames; + uint32_t AddressOfFunctions; // RVA from base of image + uint32_t AddressOfNames; // RVA from base of image + uint32_t AddressOfNameOrdinals; // RVA from base of image +}; + + +/// Based relocation format /// +struct image_base_relocation +{ + uint32_t VirtualAddress; + uint32_t SizeOfBlock; + // uint16_t TypeOffset[1]; +}; + + +/// New format import descriptors pointed to by DataDirectory[ IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT ] /// +struct image_bound_import_descriptor +{ + uint32_t TimeDateStamp; + uint16_t OffsetModuleName; + uint16_t NumberOfModuleForwarderRefs; + // Array of zero or more IMAGE_BOUND_FORWARDER_REF follows +}; + +struct image_bound_forwarder_ref +{ + uint32_t TimeDateStamp; + uint16_t OffsetModuleName; + uint16_t Reserved; +}; + + +/// Exception directory /// +struct image_runtime_function_entry +{ + uint32_t BeginAddress; + uint32_t EndAddress; + uint32_t UnwindInfoAddress; +}; + +enum unwind_op_codes +{ + uwop_push_nonvol = 0, /* info == register number */ + uwop_alloc_large, /* no info, alloc size in next 2 slots */ + uwop_alloc_small, /* info == size of allocation / 8 - 1 */ + uwop_set_fpreg, /* no info, FP = RSP + UNWIND_INFO.FPRegOffset*16 */ + uwop_save_nonvol, /* info == register number, offset in next slot */ + uwop_save_nonvol_far, /* info == register number, offset in next 2 slots */ + uwop_save_xmm128, /* info == XMM reg number, offset in next slot */ + uwop_save_xmm128_far, /* info == XMM reg number, offset in next 2 slots */ + uwop_push_machframe /* info == 0: no error-code, 1: error-code */ +}; + +union unwind_code +{ + struct s + { + uint8_t CodeOffset; + uint8_t UnwindOp : 4; + uint8_t OpInfo : 4; + }; + + uint16_t FrameOffset; +}; + +struct unwind_info +{ + uint8_t Version : 3; + uint8_t Flags : 5; + uint8_t SizeOfProlog; + uint8_t CountOfCodes; + uint8_t FrameRegister : 4; + uint8_t FrameOffset : 4; + unwind_code UnwindCode[1]; + /* unwind_code MoreUnwindCode[((CountOfCodes + 1) & ~1) - 1]; + * union { + * OPTIONAL ULONG ExceptionHandler; + * OPTIONAL ULONG FunctionEntry; + * }; + * OPTIONAL ULONG ExceptionData[]; */ +}; + + + +/// Debug /// +struct image_debug_misc +{ + uint32_t DataType; // type of misc data, see defines + uint32_t Length; // total length of record, rounded to four + // byte multiple. + uint8_t Unicode; // TRUE if data is unicode string + uint8_t Reserved[3]; + uint8_t Data[1]; // Actual data +}; + +struct image_coff_symbols_header +{ + uint32_t NumberOfSymbols; + uint32_t LvaToFirstSymbol; + uint32_t NumberOfLinenumbers; + uint32_t LvaToFirstLinenumber; + uint32_t RvaToFirstByteOfCode; + uint32_t RvaToLastByteOfCode; + uint32_t RvaToFirstByteOfData; + uint32_t RvaToLastByteOfData; +}; + +struct image_debug_directory +{ + uint32_t Characteristics; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t Type; + uint32_t SizeOfData; + uint32_t AddressOfRawData; + uint32_t PointerToRawData; +}; + + +#ifndef SOLARIS +#pragma pack(push, 2) +#endif +struct image_symbol +{ + union + { + uint8_t ShortName[8]; + struct + { + uint32_t Short; // if 0, use LongName + uint32_t Long; // offset into string table + } Name; + uint32_t LongName[2]; // PBYTE [2] + } N; + uint32_t Value; + int16_t SectionNumber; + uint16_t Type; + uint8_t StorageClass; + uint8_t NumberOfAuxSymbols; +}; +#ifndef SOLARIS +#pragma pack(pop) +#endif + +//CodeView Debug OMF signature. The signature at the end of the file is +//a negative offset from the end of the file to another signature. At +//the negative offset (base address) is another signature whose filepos +//field points to the first OMFDirHeader in a chain of directories. +//The NB05 signature is used by the link utility to indicated a completely +//unpacked file. The NB06 signature is used by ilink to indicate that the +//executable has had CodeView information from an incremental link appended +//to the executable. The NB08 signature is used by cvpack to indicate that +//the CodeView Debug OMF has been packed. CodeView will only process +//executables with the NB08 signature. +struct OMFSignature +{ + char Signature[4]; // "NBxx" + uint32_t filepos; // offset in file +}; + +struct CV_INFO_PDB20 +{ + OMFSignature CvHeader; + uint32_t Signature; + uint32_t Age; + uint8_t PdbFileName[1]; +}; + +struct CV_INFO_PDB70 +{ + uint32_t CvSignature; + guid Signature; + uint32_t Age; + uint8_t PdbFileName[1]; +}; + +// directory information structure +// This structure contains the information describing the directory. +// It is pointed to by the signature at the base address or the directory +// link field of a preceeding directory. The directory entries immediately +// follow this structure. +struct OMFDirHeader +{ + uint16_t cbDirHeader; // length of this structure + uint16_t cbDirEntry; // number of bytes in each directory entry + uint32_t cDir; // number of directorie entries + int32_t lfoNextDir; // offset from base of next directory + uint32_t flags; // status flags +}; + +// directory structure +// The data in this structure is used to reference the data for each +// subsection of the CodeView Debug OMF information. Tables that are +// not associated with a specific module will have a module index of +// oxffff. These tables are the global types table, the global symbol +// table, the global public table and the library table. +struct OMFDirEntry +{ + uint16_t SubSection; // subsection type (sst...) + uint16_t iMod; // module index + int32_t lfo; // large file offset of subsection + uint32_t cb; // number of bytes in subsection +}; + + +/// CLR 2.0 header structure /// +struct image_cor20_header +{ + //Header versioning + uint32_t cb; + uint16_t MajorRuntimeVersion; + uint16_t MinorRuntimeVersion; + + // Symbol table and startup information + image_data_directory MetaData; + uint32_t Flags; + + // If COMIMAGE_FLAGS_NATIVE_ENTRYPOINT is not set, EntryPointToken represents a managed entrypoint. + // If COMIMAGE_FLAGS_NATIVE_ENTRYPOINT is set, EntryPointRVA represents an RVA to a native entrypoint. + union + { + uint32_t EntryPointToken; + uint32_t EntryPointRVA; + }; + + // Binding information + image_data_directory Resources; + image_data_directory StrongNameSignature; + + // Regular fixup and binding information + image_data_directory CodeManagerTable; + image_data_directory VTableFixups; + image_data_directory ExportAddressTableJumps; + + // Precompiled image info (internal use only - set to zero) + image_data_directory ManagedNativeHeader; +}; + +enum replaces_cor_hdr_numeric_defines +{ + // COM+ Header entry point flags. + comimage_flags_ilonly =0x00000001, + comimage_flags_32bitrequired =0x00000002, + comimage_flags_il_library =0x00000004, + comimage_flags_strongnamesigned =0x00000008, + comimage_flags_native_entrypoint =0x00000010, + comimage_flags_trackdebugdata =0x00010000, + + // Version flags for image. + cor_version_major_v2 =2, + cor_version_major =cor_version_major_v2, + cor_version_minor =0, + cor_deleted_name_length =8, + cor_vtablegap_name_length =8, + + // Maximum size of a NativeType descriptor. + native_type_max_cb =1, + cor_ilmethod_sect_small_max_datasize=0xff, + + // #defines for the MIH FLAGS + image_cor_mih_methodrva =0x01, + image_cor_mih_ehrva =0x02, + image_cor_mih_basicblock =0x08, + + // V-table constants + cor_vtable_32bit =0x01, // V-table slots are 32-bits in size. + cor_vtable_64bit =0x02, // V-table slots are 64-bits in size. + cor_vtable_from_unmanaged =0x04, // If set, transition from unmanaged. + cor_vtable_from_unmanaged_retain_appdomain =0x08, // If set, transition from unmanaged with keeping the current appdomain. + cor_vtable_call_most_derived =0x10, // Call most derived method described by + + // EATJ constants + image_cor_eatj_thunk_size =32, // Size of a jump thunk reserved range. + + // Max name lengths + //@todo: Change to unlimited name lengths. + max_class_name =1024, + max_package_name =1024 +}; + +/// Load Configuration Directory Entry /// +struct image_load_config_directory32 +{ + uint32_t Size; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t GlobalFlagsClear; + uint32_t GlobalFlagsSet; + uint32_t CriticalSectionDefaultTimeout; + uint32_t DeCommitFreeBlockThreshold; + uint32_t DeCommitTotalFreeThreshold; + uint32_t LockPrefixTable; // VA + uint32_t MaximumAllocationSize; + uint32_t VirtualMemoryThreshold; + uint32_t ProcessHeapFlags; + uint32_t ProcessAffinityMask; + uint16_t CSDVersion; + uint16_t Reserved1; + uint32_t EditList; // VA + uint32_t SecurityCookie; // VA + uint32_t SEHandlerTable; // VA + uint32_t SEHandlerCount; +}; + +struct image_load_config_directory64 +{ + uint32_t Size; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t GlobalFlagsClear; + uint32_t GlobalFlagsSet; + uint32_t CriticalSectionDefaultTimeout; + uint64_t DeCommitFreeBlockThreshold; + uint64_t DeCommitTotalFreeThreshold; + uint64_t LockPrefixTable; // VA + uint64_t MaximumAllocationSize; + uint64_t VirtualMemoryThreshold; + uint64_t ProcessAffinityMask; + uint32_t ProcessHeapFlags; + uint16_t CSDVersion; + uint16_t Reserved1; + uint64_t EditList; // VA + uint64_t SecurityCookie; // VA + uint64_t SEHandlerTable; // VA + uint64_t SEHandlerCount; +}; + +#ifndef SOLARIS +#pragma pack(pop) +#endif +} //namespace pe_win + +#ifdef PE_BLISS_WINDOWS +typedef wchar_t unicode16_t; +typedef std::basic_string<unicode16_t> u16string; +#else +//Instead of wchar_t for windows +typedef unsigned short unicode16_t; +typedef std::basic_string<unicode16_t> u16string; +#endif + +} //namespace pe_bliss +#endif +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_tls.cpp b/irdb-lib/pebliss/trunk/pe_lib/pe_tls.cpp new file mode 100644 index 0000000000000000000000000000000000000000..182859f1bf564f0cbc36cfa0b9828a5c9f678e5b --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_tls.cpp @@ -0,0 +1,375 @@ +#include <string.h> +#include "pe_tls.h" +#include "pe_properties_generic.h" + +namespace pe_bliss +{ +using namespace pe_win; + +//TLS +//Default constructor +tls_info::tls_info() + :start_rva_(0), end_rva_(0), index_rva_(0), callbacks_rva_(0), + size_of_zero_fill_(0), characteristics_(0) +{} + +//Returns start RVA of TLS raw data +uint32_t tls_info::get_raw_data_start_rva() const +{ + return start_rva_; +} + +//Returns end RVA of TLS raw data +uint32_t tls_info::get_raw_data_end_rva() const +{ + return end_rva_; +} + +//Returns TLS index RVA +uint32_t tls_info::get_index_rva() const +{ + return index_rva_; +} + +//Returns TLS callbacks RVA +uint32_t tls_info::get_callbacks_rva() const +{ + return callbacks_rva_; +} + +//Returns size of zero fill +uint32_t tls_info::get_size_of_zero_fill() const +{ + return size_of_zero_fill_; +} + +//Returns characteristics +uint32_t tls_info::get_characteristics() const +{ + return characteristics_; +} + +//Returns raw TLS data +const std::string& tls_info::get_raw_data() const +{ + return raw_data_; +} + +//Returns TLS callbacks addresses +const tls_info::tls_callback_list& tls_info::get_tls_callbacks() const +{ + return callbacks_; +} + +//Returns TLS callbacks addresses +tls_info::tls_callback_list& tls_info::get_tls_callbacks() +{ + return callbacks_; +} + +//Adds TLS callback +void tls_info::add_tls_callback(uint32_t rva) +{ + callbacks_.push_back(rva); +} + +//Clears TLS callbacks list +void tls_info::clear_tls_callbacks() +{ + callbacks_.clear(); +} + +//Recalculates end address of raw TLS data +void tls_info::recalc_raw_data_end_rva() +{ + end_rva_ = static_cast<uint32_t>(start_rva_ + raw_data_.length()); +} + +//Sets start RVA of TLS raw data +void tls_info::set_raw_data_start_rva(uint32_t rva) +{ + start_rva_ = rva; +} + +//Sets end RVA of TLS raw data +void tls_info::set_raw_data_end_rva(uint32_t rva) +{ + end_rva_ = rva; +} + +//Sets TLS index RVA +void tls_info::set_index_rva(uint32_t rva) +{ + index_rva_ = rva; +} + +//Sets TLS callbacks RVA +void tls_info::set_callbacks_rva(uint32_t rva) +{ + callbacks_rva_ = rva; +} + +//Sets size of zero fill +void tls_info::set_size_of_zero_fill(uint32_t size) +{ + size_of_zero_fill_ = size; +} + +//Sets characteristics +void tls_info::set_characteristics(uint32_t characteristics) +{ + characteristics_ = characteristics; +} + +//Sets raw TLS data +void tls_info::set_raw_data(const std::string& data) +{ + raw_data_ = data; +} + +//If image does not have TLS, throws an exception +const tls_info get_tls_info(const pe_base& pe) +{ + return pe.get_pe_type() == pe_type_32 + ? get_tls_info_base<pe_types_class_32>(pe) + : get_tls_info_base<pe_types_class_64>(pe); +} + +//TLS Rebuilder +const image_directory rebuild_tls(pe_base& pe, const tls_info& info, section& tls_section, uint32_t offset_from_section_start, bool write_tls_callbacks, bool write_tls_data, tls_data_expand_type expand, bool save_to_pe_header, bool auto_strip_last_section) +{ + return pe.get_pe_type() == pe_type_32 + ? rebuild_tls_base<pe_types_class_32>(pe, info, tls_section, offset_from_section_start, write_tls_callbacks, write_tls_data, expand, save_to_pe_header, auto_strip_last_section) + : rebuild_tls_base<pe_types_class_64>(pe, info, tls_section, offset_from_section_start, write_tls_callbacks, write_tls_data, expand, save_to_pe_header, auto_strip_last_section); +} + +//Get TLS info +//If image does not have TLS, throws an exception +template<typename PEClassType> +const tls_info get_tls_info_base(const pe_base& pe) +{ + tls_info ret; + + //If there's no TLS directory, throw an exception + if(!pe.has_tls()) + throw pe_exception("Image does not have TLS directory", pe_exception::directory_does_not_exist); + + //Get TLS directory data + typename PEClassType::TLSStruct tls_directory_data = pe.section_data_from_rva<typename PEClassType::TLSStruct>(pe.get_directory_rva(image_directory_entry_tls), section_data_virtual, true); + + //Check data addresses + if(tls_directory_data.EndAddressOfRawData == tls_directory_data.StartAddressOfRawData) + { + try + { + pe.va_to_rva(static_cast<typename PEClassType::BaseSize>(tls_directory_data.EndAddressOfRawData)); + } + catch(const pe_exception&) + { + //Fix addressess on incorrect conversion + tls_directory_data.EndAddressOfRawData = tls_directory_data.StartAddressOfRawData = 0; + } + } + + if(tls_directory_data.StartAddressOfRawData && + pe.section_data_length_from_va(static_cast<typename PEClassType::BaseSize>(tls_directory_data.StartAddressOfRawData), + static_cast<typename PEClassType::BaseSize>(tls_directory_data.StartAddressOfRawData), section_data_virtual, true) + < (tls_directory_data.EndAddressOfRawData - tls_directory_data.StartAddressOfRawData)) + throw pe_exception("Incorrect TLS directory", pe_exception::incorrect_tls_directory); + + //Fill TLS info + //VAs are not checked + ret.set_raw_data_start_rva(tls_directory_data.StartAddressOfRawData ? pe.va_to_rva(static_cast<typename PEClassType::BaseSize>(tls_directory_data.StartAddressOfRawData)) : 0); + ret.set_raw_data_end_rva(tls_directory_data.EndAddressOfRawData ? pe.va_to_rva(static_cast<typename PEClassType::BaseSize>(tls_directory_data.EndAddressOfRawData)) : 0); + ret.set_index_rva(tls_directory_data.AddressOfIndex ? pe.va_to_rva(static_cast<typename PEClassType::BaseSize>(tls_directory_data.AddressOfIndex)) : 0); + ret.set_callbacks_rva(tls_directory_data.AddressOfCallBacks ? pe.va_to_rva(static_cast<typename PEClassType::BaseSize>(tls_directory_data.AddressOfCallBacks)) : 0); + ret.set_size_of_zero_fill(tls_directory_data.SizeOfZeroFill); + ret.set_characteristics(tls_directory_data.Characteristics); + + if(tls_directory_data.StartAddressOfRawData && tls_directory_data.StartAddressOfRawData != tls_directory_data.EndAddressOfRawData) + { + //Read and save TLS RAW data + ret.set_raw_data(std::string( + pe.section_data_from_va(static_cast<typename PEClassType::BaseSize>(tls_directory_data.StartAddressOfRawData), section_data_virtual, true), + static_cast<uint32_t>(tls_directory_data.EndAddressOfRawData - tls_directory_data.StartAddressOfRawData))); + } + + //If file has TLS callbacks + if(ret.get_callbacks_rva()) + { + //Read callbacks VAs + uint32_t current_tls_callback = 0; + + while(true) + { + //Read TLS callback VA + typename PEClassType::BaseSize va = pe.section_data_from_va<typename PEClassType::BaseSize>(static_cast<typename PEClassType::BaseSize>(tls_directory_data.AddressOfCallBacks + current_tls_callback), section_data_virtual, true); + if(va == 0) + break; + + //Save it + ret.add_tls_callback(pe.va_to_rva(va, false)); + + //Move to next callback VA + current_tls_callback += sizeof(va); + } + } + + return ret; +} + +//Rebuilder of TLS structures +//If write_tls_callbacks = true, TLS callbacks VAs will be written to their place +//If write_tls_data = true, TLS data will be written to its place +//If you have chosen to rewrite raw data, only (EndAddressOfRawData - StartAddressOfRawData) bytes will be written, not the full length of string +//representing raw data content +//auto_strip_last_section - if true and TLS are placed in the last section, it will be automatically stripped +//Note/TODO: TLS Callbacks array is not DWORD-aligned (seems to work on WinXP - Win7) +template<typename PEClassType> +const image_directory rebuild_tls_base(pe_base& pe, const tls_info& info, section& tls_section, uint32_t offset_from_section_start, bool write_tls_callbacks, bool write_tls_data, tls_data_expand_type expand, bool save_to_pe_header, bool auto_strip_last_section) +{ + //Check that tls_section is attached to this PE image + if(!pe.section_attached(tls_section)) + throw pe_exception("TLS section must be attached to PE file", pe_exception::section_is_not_attached); + + uint32_t tls_data_pos = pe_utils::align_up(offset_from_section_start, sizeof(typename PEClassType::BaseSize)); + uint32_t needed_size = sizeof(typename PEClassType::TLSStruct); //Calculate needed size for TLS table + + //Check if tls_section is last one. If it's not, check if there's enough place for TLS data + if(&tls_section != &*(pe.get_image_sections().end() - 1) && + (tls_section.empty() || pe_utils::align_up(tls_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + tls_data_pos)) + throw pe_exception("Insufficient space for TLS directory", pe_exception::insufficient_space); + + //Check raw data positions + if(info.get_raw_data_end_rva() < info.get_raw_data_start_rva() || info.get_index_rva() == 0) + throw pe_exception("Incorrect TLS directory", pe_exception::incorrect_tls_directory); + + std::string& raw_data = tls_section.get_raw_data(); + + //This will be done only if tls_section is the last section of image or for section with unaligned raw length of data + if(raw_data.length() < needed_size + tls_data_pos) + raw_data.resize(needed_size + tls_data_pos); //Expand section raw data + + //Create and fill TLS structure + typename PEClassType::TLSStruct tls_struct = {0}; + + typename PEClassType::BaseSize va; + if(info.get_raw_data_start_rva()) + { + pe.rva_to_va(info.get_raw_data_start_rva(), va); + tls_struct.StartAddressOfRawData = va; + tls_struct.SizeOfZeroFill = info.get_size_of_zero_fill(); + } + + if(info.get_raw_data_end_rva()) + { + pe.rva_to_va(info.get_raw_data_end_rva(), va); + tls_struct.EndAddressOfRawData = va; + } + + pe.rva_to_va(info.get_index_rva(), va); + tls_struct.AddressOfIndex = va; + + if(info.get_callbacks_rva()) + { + pe.rva_to_va(info.get_callbacks_rva(), va); + tls_struct.AddressOfCallBacks = va; + } + + tls_struct.Characteristics = info.get_characteristics(); + + //Save TLS structure + memcpy(&raw_data[tls_data_pos], &tls_struct, sizeof(tls_struct)); + + //If we are asked to rewrite TLS raw data + if(write_tls_data && info.get_raw_data_start_rva() && info.get_raw_data_start_rva() != info.get_raw_data_end_rva()) + { + try + { + //Check if we're going to write TLS raw data to an existing section (not to PE headers) + section& raw_data_section = pe.section_from_rva(info.get_raw_data_start_rva()); + pe.expand_section(raw_data_section, info.get_raw_data_start_rva(), info.get_raw_data_end_rva() - info.get_raw_data_start_rva(), expand == tls_data_expand_raw ? pe_base::expand_section_raw : pe_base::expand_section_virtual); + } + catch(const pe_exception&) + { + //If no section is presented by StartAddressOfRawData, just go to next step + } + + unsigned long write_raw_data_size = info.get_raw_data_end_rva() - info.get_raw_data_start_rva(); + unsigned long available_raw_length = 0; + + //Check if there's enough RAW space to write raw TLS data... + if((available_raw_length = pe.section_data_length_from_rva(info.get_raw_data_start_rva(), info.get_raw_data_start_rva(), section_data_raw, true)) + < info.get_raw_data_end_rva() - info.get_raw_data_start_rva()) + { + //Check if there's enough virtual space for it... + if(pe.section_data_length_from_rva(info.get_raw_data_start_rva(), info.get_raw_data_start_rva(), section_data_virtual, true) + < info.get_raw_data_end_rva() - info.get_raw_data_start_rva()) + throw pe_exception("Insufficient space for TLS raw data", pe_exception::insufficient_space); + else + write_raw_data_size = available_raw_length; //We'll write just a part of full raw data + } + + //Write raw TLS data, if any + if(write_raw_data_size != 0) + memcpy(pe.section_data_from_rva(info.get_raw_data_start_rva(), true), info.get_raw_data().data(), write_raw_data_size); + } + + //If we are asked to rewrite TLS callbacks addresses + if(write_tls_callbacks && info.get_callbacks_rva()) + { + unsigned long needed_callback_size = static_cast<unsigned long>((info.get_tls_callbacks().size() + 1 /* last null element */) * sizeof(typename PEClassType::BaseSize)); + + try + { + //Check if we're going to write TLS callbacks VAs to an existing section (not to PE headers) + section& raw_data_section = pe.section_from_rva(info.get_callbacks_rva()); + pe.expand_section(raw_data_section, info.get_callbacks_rva(), needed_callback_size, pe_base::expand_section_raw); + } + catch(const pe_exception&) + { + //If no section is presented by RVA of callbacks, just go to next step + } + + //Check if there's enough space to write callbacks TLS data... + if(pe.section_data_length_from_rva(info.get_callbacks_rva(), info.get_callbacks_rva(), section_data_raw, true) + < needed_callback_size - sizeof(typename PEClassType::BaseSize) /* last zero element can be virtual only */) + throw pe_exception("Insufficient space for TLS callbacks data", pe_exception::insufficient_space); + + if(pe.section_data_length_from_rva(info.get_callbacks_rva(), info.get_callbacks_rva(), section_data_virtual, true) + < needed_callback_size /* check here full virtual data length available */) + throw pe_exception("Insufficient space for TLS callbacks data", pe_exception::insufficient_space); + + std::vector<typename PEClassType::BaseSize> callbacks_virtual_addresses; + callbacks_virtual_addresses.reserve(info.get_tls_callbacks().size() + 1 /* last null element */); + + //Convert TLS RVAs to VAs + for(tls_info::tls_callback_list::const_iterator it = info.get_tls_callbacks().begin(); it != info.get_tls_callbacks().end(); ++it) + { + typename PEClassType::BaseSize cb_va = 0; + pe.rva_to_va(*it, cb_va); + callbacks_virtual_addresses.push_back(cb_va); + } + + //Ending null element + callbacks_virtual_addresses.push_back(0); + + //Write callbacks TLS data + memcpy(pe.section_data_from_rva(info.get_callbacks_rva(), true), &callbacks_virtual_addresses[0], needed_callback_size); + } + + //Adjust section raw and virtual sizes + pe.recalculate_section_sizes(tls_section, auto_strip_last_section); + + image_directory ret(pe.rva_from_section_offset(tls_section, tls_data_pos), needed_size); + + //If auto-rewrite of PE headers is required + if(save_to_pe_header) + { + pe.set_directory_rva(image_directory_entry_tls, ret.get_rva()); + pe.set_directory_size(image_directory_entry_tls, ret.get_size()); + } + + return ret; +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/pe_tls.h b/irdb-lib/pebliss/trunk/pe_lib/pe_tls.h new file mode 100644 index 0000000000000000000000000000000000000000..9f66753c0051578034024b7962a612c03300efac --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/pe_tls.h @@ -0,0 +1,104 @@ +#ifndef pebliss_pe_tls_h +#define pebliss_pe_tls_h +#pragma once +#include <memory> +#include <istream> +#include "pe_base.h" +#include "pe_directory.h" + +namespace pe_bliss +{ +//Class representing TLS info +//We use "DWORD" type to represent RVAs, because RVA is +//always 32bit even in PE+ +class tls_info +{ +public: + typedef std::vector<uint32_t> tls_callback_list; + +public: + //Default constructor + tls_info(); + + //Returns start RVA of TLS raw data + uint32_t get_raw_data_start_rva() const; + //Returns end RVA of TLS raw data + uint32_t get_raw_data_end_rva() const; + //Returns TLS index RVA + uint32_t get_index_rva() const; + //Returns TLS callbacks RVA + uint32_t get_callbacks_rva() const; + //Returns size of zero fill + uint32_t get_size_of_zero_fill() const; + //Returns characteristics + uint32_t get_characteristics() const; + //Returns raw TLS data + const std::string& get_raw_data() const; + //Returns TLS callbacks addresses + const tls_callback_list& get_tls_callbacks() const; + +public: //These functions do not change everything inside image, they are used by PE class + //You can also use them to rebuild TLS directory + + //Sets start RVA of TLS raw data + void set_raw_data_start_rva(uint32_t rva); + //Sets end RVA of TLS raw data + void set_raw_data_end_rva(uint32_t rva); + //Sets TLS index RVA + void set_index_rva(uint32_t rva); + //Sets TLS callbacks RVA + void set_callbacks_rva(uint32_t rva); + //Sets size of zero fill + void set_size_of_zero_fill(uint32_t size); + //Sets characteristics + void set_characteristics(uint32_t characteristics); + //Sets raw TLS data + void set_raw_data(const std::string& data); + //Returns TLS callbacks addresses + tls_callback_list& get_tls_callbacks(); + //Adds TLS callback + void add_tls_callback(uint32_t rva); + //Clears TLS callbacks list + void clear_tls_callbacks(); + //Recalculates end address of raw TLS data + void recalc_raw_data_end_rva(); + +private: + uint32_t start_rva_, end_rva_, index_rva_, callbacks_rva_; + uint32_t size_of_zero_fill_, characteristics_; + + //Raw TLS data + std::string raw_data_; + + //TLS callback RVAs + tls_callback_list callbacks_; +}; + +//Represents type of expanding of TLS section containing raw data +//(Works only if you are writing TLS raw data to tls_section and it is the last one in the PE image on the moment of TLS rebuild) +enum tls_data_expand_type +{ + tls_data_expand_raw, //If there is not enough raw space for raw TLS data, it can be expanded + tls_data_expand_virtual //If there is not enough virtual place for raw TLS data, it can be expanded +}; + + +//Get TLS info +//If image does not have TLS, throws an exception +const tls_info get_tls_info(const pe_base& pe); + +template<typename PEClassType> +const tls_info get_tls_info_base(const pe_base& pe); + +//Rebuilder of TLS structures +//If write_tls_callbacks = true, TLS callbacks VAs will be written to their place +//If write_tls_data = true, TLS data will be written to its place +//If you have chosen to rewrite raw data, only (EndAddressOfRawData - StartAddressOfRawData) bytes will be written, not the full length of string +//representing raw data content +//auto_strip_last_section - if true and TLS are placed in the last section, it will be automatically stripped +const image_directory rebuild_tls(pe_base& pe, const tls_info& info, section& tls_section, uint32_t offset_from_section_start = 0, bool write_tls_callbacks = true, bool write_tls_data = true, tls_data_expand_type expand = tls_data_expand_raw, bool save_to_pe_header = true, bool auto_strip_last_section = true); + +template<typename PEClassType> +const image_directory rebuild_tls_base(pe_base& pe, const tls_info& info, section& tls_section, uint32_t offset_from_section_start = 0, bool write_tls_callbacks = true, bool write_tls_data = true, tls_data_expand_type expand = tls_data_expand_raw, bool save_to_pe_header = true, bool auto_strip_last_section = true); +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/readme.txt b/irdb-lib/pebliss/trunk/pe_lib/readme.txt new file mode 100644 index 0000000000000000000000000000000000000000..f52e7a568dfca20f839c8ea202be51d0a78c18a5 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/readme.txt @@ -0,0 +1,30 @@ +Îòêðûòàÿ áåñïëàòíàÿ áèáëèîòåêà äëÿ ðàáîòû ñ PE-ôàéëàìè PE Bliss. +Áåñïëàòíà ê èñïîëüçîâàíèþ, ìîäèôèêàöèè è ðàñïðîñòðàíåíèþ. +Àâòîð: DX +(c) DX 2011-2012, kaimi.ru + +Ñîâìåñòèìîñòü: Windows, Linux + +Âîçìîæíîñòè: +[+] Ñîçäàíèå PE èëè PE+ ôàéëà ñ íóëÿ +[+] ×òåíèå 32-ðàçðÿäíûõ è 64-ðàçðÿäíûõ PE-ôàéëîâ (PE, PE+) è åäèíîîáðàçíàÿ ðàáîòà ñ íèìè +[+] Ïåðåñáîðêà 32-ðàçðÿäíûõ è 64-ðàçðÿäíûõ PE-ôàéëîâ +[+] Ðàáîòà ñ äèðåêòîðèÿìè è çàãîëîâêàìè +[+] Êîíâåðòèðîâàíèå àäðåñîâ +[+] ×òåíèå è ðåäàêòèðîâàíèå ñåêöèé PE-ôàéëà +[+] ×òåíèå è ðåäàêòèðîâàíèå òàáëèöû èìïîðòîâ +[+] ×òåíèå è ðåäàêòèðîâàíèå òàáëèöû ýêñïîðòîâ +[+] ×òåíèå è ðåäàêòèðîâàíèå òàáëèö ðåëîêàöèé +[+] ×òåíèå è ðåäàêòèðîâàíèå ðåñóðñîâ +[+] ×òåíèå è ðåäàêòèðîâàíèå TLS +[+] ×òåíèå è ðåäàêòèðîâàíèå êîíôèãóðàöèè îáðàçà (image config) +[+] ×òåíèå áàçîâîé èíôîðìàöèè .NET +[+] ×òåíèå è ðåäàêòèðîâàíèå èíôîðìàöèè î ïðèâÿçàííîì èìïîðòå +[+] ×òåíèå äèðåêòîðèè èñêëþ÷åíèé (òîëüêî PE+) +[+] ×òåíèå îòëàäî÷íîé äèðåêòîðèè ñ ðàñøèðåííîé èíôîðìàöèåé +[+] Âû÷èñëåíèå ýíòðîïèè +[+] Èçìåíåíèå ôàéëîâîãî âûðàâíèâàíèÿ +[+] Èçìåíåíèå áàçîâîãî àäðåñà çàãðóçêè +[+] Ðàáîòà ñ DOS Stub'îì è Rich overlay +[+] Âûñîêîóðîâíåâîå ÷òåíèå ðåñóðñîâ: êàðòèíêè, èêîíêè, êóðñîðû, èíôîðìàöèÿ î âåðñèè, ñòðîêîâûå òàáëèöû, òàáëèöû ñîîáùåíèé +[+] Âûñîêîóðîâíåâîå ðåäàêòèðîâàíèå ðåñóðñîâ: êàðòèíêè, èêîíêè, êóðñîðû, èíôîðìàöèÿ î âåðñèè diff --git a/irdb-lib/pebliss/trunk/pe_lib/resource_bitmap_reader.cpp b/irdb-lib/pebliss/trunk/pe_lib/resource_bitmap_reader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..29eff549db94f625677ae8940079e4d76d564044 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/resource_bitmap_reader.cpp @@ -0,0 +1,65 @@ +#include <cmath> +#include "resource_bitmap_reader.h" +#include "pe_resource_viewer.h" +#include "pe_structures.h" + +namespace pe_bliss +{ +using namespace pe_win; + +resource_bitmap_reader::resource_bitmap_reader(const pe_resource_viewer& res) + :res_(res) +{} + +//Returns bitmap data by name and index in language directory (instead of language) (minimum checks of format correctness) +const std::string resource_bitmap_reader::get_bitmap_by_name(const std::wstring& name, uint32_t index) const +{ + return create_bitmap(res_.get_resource_data_by_name(pe_resource_viewer::resource_bitmap, name, index).get_data()); +} + +//Returns bitmap data by name and language (minimum checks of format correctness) +const std::string resource_bitmap_reader::get_bitmap_by_name(uint32_t language, const std::wstring& name) const +{ + return create_bitmap(res_.get_resource_data_by_name(language, pe_resource_viewer::resource_bitmap, name).get_data()); +} + +//Returns bitmap data by ID and language (minimum checks of format correctness) +const std::string resource_bitmap_reader::get_bitmap_by_id_lang(uint32_t language, uint32_t id) const +{ + return create_bitmap(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_bitmap, id).get_data()); +} + +//Returns bitmap data by ID and index in language directory (instead of language) (minimum checks of format correctness) +const std::string resource_bitmap_reader::get_bitmap_by_id(uint32_t id, uint32_t index) const +{ + return create_bitmap(res_.get_resource_data_by_id(pe_resource_viewer::resource_bitmap, id, index).get_data()); +} + +//Helper function of creating bitmap header +const std::string resource_bitmap_reader::create_bitmap(const std::string& resource_data) +{ + //Create bitmap file header + bitmapfileheader header = {0}; + header.bfType = 0x4d42; //Signature "BM" + header.bfOffBits = sizeof(bitmapfileheader) + sizeof(bitmapinfoheader); //Offset to bitmap bits + header.bfSize = static_cast<uint32_t>(sizeof(bitmapfileheader) + resource_data.length()); //Size of bitmap + + //Check size of resource data + if(resource_data.length() < sizeof(bitmapinfoheader)) + throw pe_exception("Incorrect resource bitmap", pe_exception::resource_incorrect_bitmap); + + { + //Get bitmap info header + const bitmapinfoheader* info = reinterpret_cast<const bitmapinfoheader*>(resource_data.data()); + + //If color table is present, skip it + if(info->biClrUsed != 0) + header.bfOffBits += 4 * info->biClrUsed; //Add this size to offset to bitmap bits + else if(info->biBitCount <= 8) + header.bfOffBits += 4 * static_cast<uint32_t>(std::pow(2.f, info->biBitCount)); //Add this size to offset to bitmap bits + } + + //Return final bitmap data + return std::string(reinterpret_cast<const char*>(&header), sizeof(bitmapfileheader)) + resource_data; +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/resource_bitmap_reader.h b/irdb-lib/pebliss/trunk/pe_lib/resource_bitmap_reader.h new file mode 100644 index 0000000000000000000000000000000000000000..e518c415577567a630a4c1f352d9cfca0abf7600 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/resource_bitmap_reader.h @@ -0,0 +1,32 @@ +#ifndef pebliss_resource_bitmap_reader_h +#define pebliss_resource_bitmap_reader_h +#pragma once +#include <string> +#include "stdint_defs.h" + +namespace pe_bliss +{ +class pe_resource_viewer; + +class resource_bitmap_reader +{ +public: + resource_bitmap_reader(const pe_resource_viewer& res); + + //Returns bitmap data by name and language (minimum checks of format correctness) + const std::string get_bitmap_by_name(uint32_t language, const std::wstring& name) const; + //Returns bitmap data by name and index in language directory (instead of language) (minimum checks of format correctness) + const std::string get_bitmap_by_name(const std::wstring& name, uint32_t index = 0) const; + //Returns bitmap data by ID and language (minimum checks of format correctness) + const std::string get_bitmap_by_id_lang(uint32_t language, uint32_t id) const; + //Returns bitmap data by ID and index in language directory (instead of language) (minimum checks of format correctness) + const std::string get_bitmap_by_id(uint32_t id, uint32_t index = 0) const; + +private: + //Helper function of creating bitmap header + static const std::string create_bitmap(const std::string& resource_data); + + const pe_resource_viewer& res_; +}; +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/resource_bitmap_writer.cpp b/irdb-lib/pebliss/trunk/pe_lib/resource_bitmap_writer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2a28ff6e68b8ddb5cec46e57e652fabb89954a47 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/resource_bitmap_writer.cpp @@ -0,0 +1,54 @@ +#include "resource_bitmap_writer.h" +#include "pe_resource_manager.h" +#include "pe_structures.h" + +namespace pe_bliss +{ +using namespace pe_win; + +resource_bitmap_writer::resource_bitmap_writer(pe_resource_manager& res) + :res_(res) +{} + +//Adds bitmap from bitmap file data. If bitmap already exists, replaces it +//timestamp will be used for directories that will be added +void resource_bitmap_writer::add_bitmap(const std::string& bitmap_file, uint32_t id, uint32_t language, uint32_t codepage, uint32_t timestamp) +{ + //Check bitmap data a little + if(bitmap_file.length() < sizeof(bitmapfileheader)) + throw pe_exception("Incorrect resource bitmap", pe_exception::resource_incorrect_bitmap); + + resource_directory_entry new_entry; + new_entry.set_id(id); + + //Add bitmap + res_.add_resource(bitmap_file.substr(sizeof(bitmapfileheader)), pe_resource_viewer::resource_bitmap, new_entry, resource_directory::entry_finder(id), language, codepage, timestamp); +} + +//Adds bitmap from bitmap file data. If bitmap already exists, replaces it +//timestamp will be used for directories that will be added +void resource_bitmap_writer::add_bitmap(const std::string& bitmap_file, const std::wstring& name, uint32_t language, uint32_t codepage, uint32_t timestamp) +{ + //Check bitmap data a little + if(bitmap_file.length() < sizeof(bitmapfileheader)) + throw pe_exception("Incorrect resource bitmap", pe_exception::resource_incorrect_bitmap); + + resource_directory_entry new_entry; + new_entry.set_name(name); + + //Add bitmap + res_.add_resource(bitmap_file.substr(sizeof(bitmapfileheader)), pe_resource_viewer::resource_bitmap, new_entry, resource_directory::entry_finder(name), language, codepage, timestamp); +} + +//Removes bitmap by name/ID and language +bool resource_bitmap_writer::remove_bitmap(const std::wstring& name, uint32_t language) +{ + return res_.remove_resource(pe_resource_viewer::resource_bitmap, name, language); +} + +//Removes bitmap by name/ID and language +bool resource_bitmap_writer::remove_bitmap(uint32_t id, uint32_t language) +{ + return res_.remove_resource(pe_resource_viewer::resource_bitmap, id, language); +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/resource_bitmap_writer.h b/irdb-lib/pebliss/trunk/pe_lib/resource_bitmap_writer.h new file mode 100644 index 0000000000000000000000000000000000000000..d3ccff2fac5281ed1f4b5382d5f9249b9dc26876 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/resource_bitmap_writer.h @@ -0,0 +1,29 @@ +#ifndef pebliss_resource_bitmap_writer_h +#define pebliss_resource_bitmap_writer_h +#pragma once +#include <string> +#include "stdint_defs.h" + +namespace pe_bliss +{ +class pe_resource_manager; + +class resource_bitmap_writer +{ +public: + resource_bitmap_writer(pe_resource_manager& res); + + //Adds bitmap from bitmap file data. If bitmap already exists, replaces it + //timestamp will be used for directories that will be added + void add_bitmap(const std::string& bitmap_file, uint32_t id, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0); + void add_bitmap(const std::string& bitmap_file, const std::wstring& name, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0); + + //Removes bitmap by name/ID and language + bool remove_bitmap(const std::wstring& name, uint32_t language); + bool remove_bitmap(uint32_t id, uint32_t language); + +private: + pe_resource_manager& res_; +}; +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/resource_cursor_icon_reader.cpp b/irdb-lib/pebliss/trunk/pe_lib/resource_cursor_icon_reader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..514e288c225b7aaa4c2df7f13b36413c27f8b07a --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/resource_cursor_icon_reader.cpp @@ -0,0 +1,500 @@ +#include <algorithm> +#include "resource_cursor_icon_reader.h" +#include "pe_structures.h" +#include "pe_resource_viewer.h" + +namespace pe_bliss +{ +using namespace pe_win; + +resource_cursor_icon_reader::resource_cursor_icon_reader(const pe_resource_viewer& res) + :res_(res) +{} + +//Helper function of creating icon headers from ICON_GROUP resource data +//Returns icon count +uint16_t resource_cursor_icon_reader::format_icon_headers(std::string& ico_data, const std::string& resource_data) +{ + //Check resource data size + if(resource_data.length() < sizeof(ico_header)) + throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon); + + //Get icon header + const ico_header* info = reinterpret_cast<const ico_header*>(resource_data.data()); + + //Check resource data size + if(resource_data.length() < sizeof(ico_header) + info->Count * sizeof(icon_group)) + throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon); + + //Reserve memory to speed up a little + ico_data.reserve(sizeof(ico_header) + info->Count * sizeof(icondirentry)); + ico_data.append(reinterpret_cast<const char*>(info), sizeof(ico_header)); + + //Iterate over all listed icons + uint32_t offset = sizeof(ico_header) + sizeof(icondirentry) * info->Count; + for(uint16_t i = 0; i != info->Count; ++i) + { + const icon_group* group = reinterpret_cast<const icon_group*>(resource_data.data() + sizeof(ico_header) + i * sizeof(icon_group)); + + //Fill icon data + icondirentry direntry; + direntry.BitCount = group->BitCount; + direntry.ColorCount = group->ColorCount; + direntry.Height = group->Height; + direntry.Planes = group->Planes; + direntry.Reserved = group->Reserved; + direntry.SizeInBytes = group->SizeInBytes; + direntry.Width = group->Width; + direntry.ImageOffset = offset; + + //Add icon header to returned value + ico_data.append(reinterpret_cast<const char*>(&direntry), sizeof(icondirentry)); + + offset += group->SizeInBytes; + } + + //Return icon count + return info->Count; +} + +//Returns single icon data by ID and language (minimum checks of format correctness) +const std::string resource_cursor_icon_reader::get_single_icon_by_id_lang(uint32_t language, uint32_t id) const +{ + //Get icon headers + std::string icon_data(lookup_icon_group_data_by_icon(id, language)); + //Append icon data + icon_data.append(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon, id).get_data()); + return icon_data; +} + +//Returns single icon data by ID and index in language directory (instead of language) (minimum checks of format correctness) +const std::string resource_cursor_icon_reader::get_single_icon_by_id(uint32_t id, uint32_t index) const +{ + pe_resource_viewer::resource_language_list languages(res_.list_resource_languages(pe_resource_viewer::resource_icon, id)); + if(languages.size() <= index) + throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found); + + //Get icon headers + std::string icon_data(lookup_icon_group_data_by_icon(id, languages.at(index))); + //Append icon data + icon_data.append(res_.get_resource_data_by_id(pe_resource_viewer::resource_icon, id, index).get_data()); + return icon_data; +} + +//Returns icon data by name and index in language directory (instead of language) (minimum checks of format correctness) +const std::string resource_cursor_icon_reader::get_icon_by_name(const std::wstring& name, uint32_t index) const +{ + std::string ret; + + //Get resource by name and index + const std::string data = res_.get_resource_data_by_name(pe_resource_viewer::resource_icon_group, name, index).get_data(); + + //Create icon headers + uint16_t icon_count = format_icon_headers(ret, data); + + //Append icon data + for(uint16_t i = 0; i != icon_count; ++i) + { + const icon_group* group = reinterpret_cast<const icon_group*>(data.data() + sizeof(ico_header) + i * sizeof(icon_group)); + ret += res_.get_resource_data_by_id(pe_resource_viewer::resource_icon, group->Number, index).get_data(); + } + + return ret; +} + +//Returns icon data by name and language (minimum checks of format correctness) +const std::string resource_cursor_icon_reader::get_icon_by_name(uint32_t language, const std::wstring& name) const +{ + std::string ret; + + //Get resource by name and language + const std::string data = res_.get_resource_data_by_name(language, pe_resource_viewer::resource_icon_group, name).get_data(); + + //Create icon headers + uint16_t icon_count = format_icon_headers(ret, data); + + //Append icon data + for(uint16_t i = 0; i != icon_count; ++i) + { + const icon_group* group = reinterpret_cast<const icon_group*>(data.data() + sizeof(ico_header) + i * sizeof(icon_group)); + ret += res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon, group->Number).get_data(); + } + + return ret; +} + +//Returns icon data by ID and language (minimum checks of format correctness) +const std::string resource_cursor_icon_reader::get_icon_by_id_lang(uint32_t language, uint32_t id) const +{ + std::string ret; + + //Get resource by language and id + const std::string data = res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon_group, id).get_data(); + + //Create icon headers + uint16_t icon_count = format_icon_headers(ret, data); + + //Append icon data + for(uint16_t i = 0; i != icon_count; ++i) + { + const icon_group* group = reinterpret_cast<const icon_group*>(data.data() + sizeof(ico_header) + i * sizeof(icon_group)); + ret += res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon, group->Number).get_data(); + } + + return ret; +} + +//Returns icon data by ID and index in language directory (instead of language) (minimum checks of format correctness) +const std::string resource_cursor_icon_reader::get_icon_by_id(uint32_t id, uint32_t index) const +{ + std::string ret; + + //Get resource by id and index + const std::string data = res_.get_resource_data_by_id(pe_resource_viewer::resource_icon_group, id, index).get_data(); + + //Create icon headers + uint16_t icon_count = format_icon_headers(ret, data); + + //Append icon data + for(uint16_t i = 0; i != icon_count; ++i) + { + const icon_group* group = reinterpret_cast<const icon_group*>(data.data() + sizeof(ico_header) + i * sizeof(icon_group)); + ret += res_.get_resource_data_by_id(pe_resource_viewer::resource_icon, group->Number, index).get_data(); + } + + return ret; +} + +//Checks for icon presence inside icon group, fills icon headers if found +bool resource_cursor_icon_reader::check_icon_presence(const std::string& icon_group_resource_data, uint32_t icon_id, std::string& ico_data) +{ + //Check resource data size + if(icon_group_resource_data.length() < sizeof(ico_header)) + throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon); + + //Get icon header + const ico_header* info = reinterpret_cast<const ico_header*>(icon_group_resource_data.data()); + + //Check resource data size + if(icon_group_resource_data.length() < sizeof(ico_header) + info->Count * sizeof(icon_group)) + throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon); + + for(uint16_t i = 0; i != info->Count; ++i) + { + const icon_group* group = reinterpret_cast<const icon_group*>(icon_group_resource_data.data() + sizeof(ico_header) + i * sizeof(icon_group)); + if(group->Number == icon_id) + { + //Reserve memory to speed up a little + ico_data.reserve(sizeof(ico_header) + sizeof(icondirentry)); + //Write single-icon icon header + ico_header new_header = *info; + new_header.Count = 1; + ico_data.append(reinterpret_cast<const char*>(&new_header), sizeof(ico_header)); + + //Fill icon data + icondirentry direntry; + direntry.BitCount = group->BitCount; + direntry.ColorCount = group->ColorCount; + direntry.Height = group->Height; + direntry.Planes = group->Planes; + direntry.Reserved = group->Reserved; + direntry.SizeInBytes = group->SizeInBytes; + direntry.Width = group->Width; + direntry.ImageOffset = sizeof(ico_header) + sizeof(icondirentry); + ico_data.append(reinterpret_cast<const char*>(&direntry), sizeof(direntry)); + + return true; + } + } + + return false; +} + +//Looks up icon group by icon id and returns full icon headers if found +const std::string resource_cursor_icon_reader::lookup_icon_group_data_by_icon(uint32_t icon_id, uint32_t language) const +{ + std::string icon_header_data; + + { + //List all ID-resources + pe_resource_viewer::resource_id_list ids(res_.list_resource_ids(pe_resource_viewer::resource_icon_group)); + + for(pe_resource_viewer::resource_id_list::const_iterator it = ids.begin(); it != ids.end(); ++it) + { + pe_resource_viewer::resource_language_list group_languages(res_.list_resource_languages(pe_resource_viewer::resource_icon_group, *it)); + if(std::find(group_languages.begin(), group_languages.end(), language) != group_languages.end() + && check_icon_presence(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon_group, *it).get_data(), icon_id, icon_header_data)) + return icon_header_data; + } + } + + { + //List all named resources + pe_resource_viewer::resource_name_list names(res_.list_resource_names(pe_resource_viewer::resource_icon_group)); + for(pe_resource_viewer::resource_name_list::const_iterator it = names.begin(); it != names.end(); ++it) + { + pe_resource_viewer::resource_language_list group_languages(res_.list_resource_languages(pe_resource_viewer::resource_icon_group, *it)); + if(std::find(group_languages.begin(), group_languages.end(), language) != group_languages.end() + && check_icon_presence(res_.get_resource_data_by_name(language, pe_resource_viewer::resource_icon_group, *it).get_data(), icon_id, icon_header_data)) + return icon_header_data; + } + } + + throw pe_exception("No icon group find for requested icon", pe_exception::no_icon_group_found); +} + +//Returns single cursor data by ID and language (minimum checks of format correctness) +const std::string resource_cursor_icon_reader::get_single_cursor_by_id_lang(uint32_t language, uint32_t id) const +{ + std::string raw_cursor_data(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor, id).get_data()); + //Get cursor headers + std::string cursor_data(lookup_cursor_group_data_by_cursor(id, language, raw_cursor_data)); + //Append cursor data + cursor_data.append(raw_cursor_data.substr(sizeof(uint16_t) * 2 /* hotspot position */)); + return cursor_data; +} + +//Returns single cursor data by ID and index in language directory (instead of language) (minimum checks of format correctness) +const std::string resource_cursor_icon_reader::get_single_cursor_by_id(uint32_t id, uint32_t index) const +{ + pe_resource_viewer::resource_language_list languages(res_.list_resource_languages(pe_resource_viewer::resource_cursor, id)); + if(languages.size() <= index) + throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found); + + std::string raw_cursor_data(res_.get_resource_data_by_id(pe_resource_viewer::resource_cursor, id, index).get_data()); + //Get cursor headers + std::string cursor_data(lookup_cursor_group_data_by_cursor(id, languages.at(index), raw_cursor_data)); + //Append cursor data + cursor_data.append(raw_cursor_data.substr(sizeof(uint16_t) * 2 /* hotspot position */)); + return cursor_data; +} + +//Helper function of creating cursor headers +//Returns cursor count +uint16_t resource_cursor_icon_reader::format_cursor_headers(std::string& cur_data, const std::string& resource_data, uint32_t language, uint32_t index) const +{ + //Check resource data length + if(resource_data.length() < sizeof(cursor_header)) + throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor); + + const cursor_header* info = reinterpret_cast<const cursor_header*>(resource_data.data()); + + //Check resource data length + if(resource_data.length() < sizeof(cursor_header) + sizeof(cursor_group) * info->Count) + throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor); + + //Reserve needed space to speed up a little + cur_data.reserve(sizeof(cursor_header) + info->Count * sizeof(cursordirentry)); + //Add cursor header + cur_data.append(reinterpret_cast<const char*>(info), sizeof(cursor_header)); + + //Iterate over all cursors listed in cursor group + uint32_t offset = sizeof(cursor_header) + sizeof(cursordirentry) * info->Count; + for(uint16_t i = 0; i != info->Count; ++i) + { + const cursor_group* group = reinterpret_cast<const cursor_group*>(resource_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group)); + + //Fill cursor info + cursordirentry direntry; + direntry.ColorCount = 0; //OK + direntry.Width = static_cast<uint8_t>(group->Width); + direntry.Height = static_cast<uint8_t>(group->Height) / 2; + direntry.Reserved = 0; + + //Now read hotspot data from cursor data directory + const std::string cursor = index == 0xFFFFFFFF + ? res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor, group->Number).get_data() + : res_.get_resource_data_by_id(pe_resource_viewer::resource_cursor, group->Number, index).get_data(); + if(cursor.length() < 2 * sizeof(uint16_t)) + throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor); + + //Here it is - two words in the very beginning of cursor data + direntry.HotspotX = *reinterpret_cast<const uint16_t*>(cursor.data()); + direntry.HotspotY = *reinterpret_cast<const uint16_t*>(cursor.data() + sizeof(uint16_t)); + + //Fill the rest data + direntry.SizeInBytes = group->SizeInBytes - 2 * sizeof(uint16_t); + direntry.ImageOffset = offset; + + //Add cursor header + cur_data.append(reinterpret_cast<const char*>(&direntry), sizeof(cursordirentry)); + + offset += direntry.SizeInBytes; + } + + //Return cursor count + return info->Count; +} + +//Returns cursor data by name and language (minimum checks of format correctness) +const std::string resource_cursor_icon_reader::get_cursor_by_name(uint32_t language, const std::wstring& name) const +{ + std::string ret; + + //Get resource by name and language + const std::string resource_data = res_.get_resource_data_by_name(language, pe_resource_viewer::resource_cursor_group, name).get_data(); + + //Create cursor headers + uint16_t cursor_count = format_cursor_headers(ret, resource_data, language); + + //Add cursor data + for(uint16_t i = 0; i != cursor_count; ++i) + { + const cursor_group* group = reinterpret_cast<const cursor_group*>(resource_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group)); + ret += res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor, group->Number).get_data().substr(2 * sizeof(uint16_t)); + } + + return ret; +} + +//Returns cursor data by name and index in language directory (instead of language) (minimum checks of format correctness) +const std::string resource_cursor_icon_reader::get_cursor_by_name(const std::wstring& name, uint32_t index) const +{ + std::string ret; + + //Get resource by name and index + const std::string resource_data = res_.get_resource_data_by_name(pe_resource_viewer::resource_cursor_group, name, index).get_data(); + + //Create cursor headers + uint16_t cursor_count = format_cursor_headers(ret, resource_data, 0, index); + + //Add cursor data + for(uint16_t i = 0; i != cursor_count; ++i) + { + const cursor_group* group = reinterpret_cast<const cursor_group*>(resource_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group)); + ret += res_.get_resource_data_by_id(pe_resource_viewer::resource_cursor, group->Number, index).get_data().substr(2 * sizeof(uint16_t)); + } + + return ret; +} + +//Returns cursor data by ID and language (minimum checks of format correctness) +const std::string resource_cursor_icon_reader::get_cursor_by_id_lang(uint32_t language, uint32_t id) const +{ + std::string ret; + + //Get resource by ID and language + const std::string resource_data = res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor_group, id).get_data(); + + //Create cursor headers + uint16_t cursor_count = format_cursor_headers(ret, resource_data, language); + + //Add cursor data + for(uint16_t i = 0; i != cursor_count; ++i) + { + const cursor_group* group = reinterpret_cast<const cursor_group*>(resource_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group)); + ret += res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor, group->Number).get_data().substr(2 * sizeof(uint16_t)); + } + + return ret; +} + +//Returns cursor data by ID and index in language directory (instead of language) (minimum checks of format correctness) +const std::string resource_cursor_icon_reader::get_cursor_by_id(uint32_t id, uint32_t index) const +{ + std::string ret; + + //Get resource by ID and index + const std::string resource_data = res_.get_resource_data_by_id(pe_resource_viewer::resource_cursor_group, id, index).get_data(); + + //Create cursor headers + uint16_t cursor_count = format_cursor_headers(ret, resource_data, 0, index); + + //Add cursor data + for(uint16_t i = 0; i != cursor_count; ++i) + { + const cursor_group* group = reinterpret_cast<const cursor_group*>(resource_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group)); + ret += res_.get_resource_data_by_id(pe_resource_viewer::resource_cursor, group->Number, index).get_data().substr(2 * sizeof(uint16_t)); + } + + return ret; +} + +//Checks for cursor presence inside cursor group, fills cursor headers if found +bool resource_cursor_icon_reader::check_cursor_presence(const std::string& cursor_group_resource_data, uint32_t cursor_id, std::string& cur_header_data, const std::string& raw_cursor_data) +{ + //Check resource data length + if(cursor_group_resource_data.length() < sizeof(cursor_header)) + throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor); + + const cursor_header* info = reinterpret_cast<const cursor_header*>(cursor_group_resource_data.data()); + + //Check resource data length + if(cursor_group_resource_data.length() < sizeof(cursor_header) + sizeof(cursor_group)) + throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor); + + //Iterate over all cursors listed in cursor group + for(uint16_t i = 0; i != info->Count; ++i) + { + const cursor_group* group = reinterpret_cast<const cursor_group*>(cursor_group_resource_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group)); + + if(group->Number == cursor_id) + { + //Reserve needed space to speed up a little + cur_header_data.reserve(sizeof(cursor_header) + sizeof(cursordirentry)); + //Write single-cursor cursor header + cursor_header new_header = *info; + new_header.Count = 1; + cur_header_data.append(reinterpret_cast<const char*>(&new_header), sizeof(cursor_header)); + + //Fill cursor info + cursordirentry direntry; + direntry.ColorCount = 0; //OK + direntry.Width = static_cast<uint8_t>(group->Width); + direntry.Height = static_cast<uint8_t>(group->Height) / 2; + direntry.Reserved = 0; + + if(raw_cursor_data.length() < 2 * sizeof(uint16_t)) + throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor); + + //Here it is - two words in the very beginning of cursor data + direntry.HotspotX = *reinterpret_cast<const uint16_t*>(raw_cursor_data.data()); + direntry.HotspotY = *reinterpret_cast<const uint16_t*>(raw_cursor_data.data() + sizeof(uint16_t)); + + //Fill the rest data + direntry.SizeInBytes = group->SizeInBytes - 2 * sizeof(uint16_t); + direntry.ImageOffset = sizeof(cursor_header) + sizeof(cursordirentry); + + //Add cursor header + cur_header_data.append(reinterpret_cast<const char*>(&direntry), sizeof(cursordirentry)); + + return true; + } + } + + return false; +} + +//Looks up cursor group by cursor id and returns full cursor headers if found +const std::string resource_cursor_icon_reader::lookup_cursor_group_data_by_cursor(uint32_t cursor_id, uint32_t language, const std::string& raw_cursor_data) const +{ + std::string cursor_header_data; + + { + //List all ID-resources + pe_resource_viewer::resource_id_list ids(res_.list_resource_ids(pe_resource_viewer::resource_cursor_group)); + + for(pe_resource_viewer::resource_id_list::const_iterator it = ids.begin(); it != ids.end(); ++it) + { + pe_resource_viewer::resource_language_list group_languages(res_.list_resource_languages(pe_resource_viewer::resource_cursor_group, *it)); + if(std::find(group_languages.begin(), group_languages.end(), language) != group_languages.end() + && check_cursor_presence(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor_group, *it).get_data(), cursor_id, cursor_header_data, raw_cursor_data)) + return cursor_header_data; + } + } + + { + //List all named resources + pe_resource_viewer::resource_name_list names(res_.list_resource_names(pe_resource_viewer::resource_cursor_group)); + for(pe_resource_viewer::resource_name_list::const_iterator it = names.begin(); it != names.end(); ++it) + { + pe_resource_viewer::resource_language_list group_languages(res_.list_resource_languages(pe_resource_viewer::resource_cursor_group, *it)); + if(std::find(group_languages.begin(), group_languages.end(), language) != group_languages.end() + && check_cursor_presence(res_.get_resource_data_by_name(language, pe_resource_viewer::resource_cursor_group, *it).get_data(), cursor_id, cursor_header_data, raw_cursor_data)) + return cursor_header_data; + } + } + + throw pe_exception("No cursor group find for requested icon", pe_exception::no_cursor_group_found); +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/resource_cursor_icon_reader.h b/irdb-lib/pebliss/trunk/pe_lib/resource_cursor_icon_reader.h new file mode 100644 index 0000000000000000000000000000000000000000..7dd1baae1be85e06d74c95cecaf53a862e2bb9a4 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/resource_cursor_icon_reader.h @@ -0,0 +1,66 @@ +#ifndef pebliss_resource_cursor_icon_reader_h +#define pebliss_resource_cursor_icon_reader_h +#pragma once +#include <string> +#include "stdint_defs.h" + +namespace pe_bliss +{ +class pe_resource_viewer; + +class resource_cursor_icon_reader +{ +public: + resource_cursor_icon_reader(const pe_resource_viewer& res); + + //Returns single icon data by ID and language (minimum checks of format correctness) + const std::string get_single_icon_by_id_lang(uint32_t language, uint32_t id) const; + //Returns single icon data by ID and index in language directory (instead of language) (minimum checks of format correctness) + const std::string get_single_icon_by_id(uint32_t id, uint32_t index = 0) const; + + //Returns icon data of group of icons by name and language (minimum checks of format correctness) + const std::string get_icon_by_name(uint32_t language, const std::wstring& icon_group_name) const; + //Returns icon data of group of icons by name and index in language directory (instead of language) (minimum checks of format correctness) + const std::string get_icon_by_name(const std::wstring& icon_group_name, uint32_t index = 0) const; + //Returns icon data of group of icons by ID and language (minimum checks of format correctness) + const std::string get_icon_by_id_lang(uint32_t language, uint32_t icon_group_id) const; + //Returns icon data of group of icons by ID and index in language directory (instead of language) (minimum checks of format correctness) + const std::string get_icon_by_id(uint32_t icon_group_id, uint32_t index = 0) const; + + //Returns single cursor data by ID and language (minimum checks of format correctness) + const std::string get_single_cursor_by_id_lang(uint32_t language, uint32_t id) const; + //Returns single cursor data by ID and index in language directory (instead of language) (minimum checks of format correctness) + const std::string get_single_cursor_by_id(uint32_t id, uint32_t index = 0) const; + + //Returns cursor data by name and language (minimum checks of format correctness) + const std::string get_cursor_by_name(uint32_t language, const std::wstring& cursor_group_name) const; + //Returns cursor data by name and index in language directory (instead of language) (minimum checks of format correctness) + const std::string get_cursor_by_name(const std::wstring& cursor_group_name, uint32_t index = 0) const; + //Returns cursor data by ID and language (minimum checks of format correctness) + const std::string get_cursor_by_id_lang(uint32_t language, uint32_t cursor_group_id) const; + //Returns cursor data by ID and index in language directory (instead of language) (minimum checks of format correctness) + const std::string get_cursor_by_id(uint32_t cursor_group_id, uint32_t index = 0) const; + +private: + const pe_resource_viewer& res_; + + //Helper function of creating icon headers from ICON_GROUP resource data + //Returns icon count + static uint16_t format_icon_headers(std::string& ico_data, const std::string& resource_data); + + //Helper function of creating cursor headers from CURSOR_GROUP resource data + //Returns cursor count + uint16_t format_cursor_headers(std::string& cur_data, const std::string& resource_data, uint32_t language, uint32_t index = 0xFFFFFFFF) const; + + //Looks up icon group by icon id and returns full icon headers if found + const std::string lookup_icon_group_data_by_icon(uint32_t icon_id, uint32_t language) const; + //Checks for icon presence inside icon group, fills icon headers if found + static bool check_icon_presence(const std::string& icon_group_resource_data, uint32_t icon_id, std::string& ico_data); + + //Looks up cursor group by cursor id and returns full cursor headers if found + const std::string lookup_cursor_group_data_by_cursor(uint32_t cursor_id, uint32_t language, const std::string& raw_cursor_data) const; + //Checks for cursor presence inside cursor group, fills cursor headers if found + static bool check_cursor_presence(const std::string& icon_group_resource_data, uint32_t cursor_id, std::string& cur_header_data, const std::string& raw_cursor_data); +}; +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/resource_cursor_icon_writer.cpp b/irdb-lib/pebliss/trunk/pe_lib/resource_cursor_icon_writer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ce52c6cbdfaf4ffe489ca2f07691f605d16f9090 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/resource_cursor_icon_writer.cpp @@ -0,0 +1,426 @@ +#include <algorithm> +#include <string.h> +#include "resource_cursor_icon_writer.h" + +namespace pe_bliss +{ +using namespace pe_win; + +resource_cursor_icon_writer::resource_cursor_icon_writer(pe_resource_manager& res) + :res_(res) +{} + +//Add icon helper +void resource_cursor_icon_writer::add_icon(const std::string& icon_file, const resource_data_info* group_icon_info /* or zero */, resource_directory_entry& new_icon_group_entry, const resource_directory::entry_finder& finder, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp) +{ + //Check icon for correctness + if(icon_file.length() < sizeof(ico_header)) + throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon); + + const ico_header* icon_header = reinterpret_cast<const ico_header*>(&icon_file[0]); + + unsigned long size_of_headers = sizeof(ico_header) + icon_header->Count * sizeof(icondirentry); + if(icon_file.length() < size_of_headers || icon_header->Count == 0) + throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon); + + //Enumerate all icons in file + for(uint16_t i = 0; i != icon_header->Count; ++i) + { + //Check icon entries + const icondirentry* icon_entry = reinterpret_cast<const icondirentry*>(&icon_file[sizeof(ico_header) + i * sizeof(icondirentry)]); + if(icon_entry->SizeInBytes == 0 + || icon_entry->ImageOffset < size_of_headers + || !pe_utils::is_sum_safe(icon_entry->ImageOffset, icon_entry->SizeInBytes) + || icon_entry->ImageOffset + icon_entry->SizeInBytes > icon_file.length()) + throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon); + } + + std::string icon_group_data; + ico_header* info = 0; + + if(group_icon_info) + { + //If icon group already exists + { + icon_group_data = group_icon_info->get_data(); + codepage = group_icon_info->get_codepage(); //Don't change codepage of icon group entry + } + + //Check resource data size + if(icon_group_data.length() < sizeof(ico_header)) + throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon); + + //Get icon header + info = reinterpret_cast<ico_header*>(&icon_group_data[0]); + + //Check resource data size + if(icon_group_data.length() < sizeof(ico_header) + info->Count * sizeof(icon_group)) + throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon); + + icon_group_data.resize(sizeof(ico_header) + (info->Count + icon_header->Count) * sizeof(icon_group)); + info = reinterpret_cast<ico_header*>(&icon_group_data[0]); //In case if memory was reallocated + } + else //Entry not found - icon group doesn't exist + { + icon_group_data.resize(sizeof(ico_header) + icon_header->Count * sizeof(icon_group)); + memcpy(&icon_group_data[0], icon_header, sizeof(ico_header)); + } + + //Search for available icon IDs + std::vector<uint16_t> icon_id_list(get_icon_or_cursor_free_id_list(pe_resource_viewer::resource_icon, mode, icon_header->Count)); + + //Enumerate all icons in file + for(uint16_t i = 0; i != icon_header->Count; ++i) + { + const icondirentry* icon_entry = reinterpret_cast<const icondirentry*>(&icon_file[sizeof(ico_header) + i * sizeof(icondirentry)]); + icon_group group = {0}; + + //Fill icon resource header + group.BitCount = icon_entry->BitCount; + group.ColorCount = icon_entry->ColorCount; + group.Height = icon_entry->Height; + group.Planes = icon_entry->Planes; + group.Reserved = icon_entry->Reserved; + group.SizeInBytes = icon_entry->SizeInBytes; + group.Width = icon_entry->Width; + group.Number = icon_id_list.at(i); + + memcpy(&icon_group_data[sizeof(ico_header) + ((info ? info->Count : 0) + i) * sizeof(icon_group)], &group, sizeof(group)); + + //Add icon to resources + resource_directory_entry new_entry; + new_entry.set_id(group.Number); + res_.add_resource(icon_file.substr(icon_entry->ImageOffset, icon_entry->SizeInBytes), pe_resource_viewer::resource_icon, new_entry, resource_directory::entry_finder(group.Number), language, codepage, timestamp); + } + + if(info) + info->Count += icon_header->Count; //Increase icon count, if we're adding icon to existing group + + { + //Add or replace icon group data entry + res_.add_resource(icon_group_data, pe_resource_viewer::resource_icon_group, new_icon_group_entry, finder, language, codepage, timestamp); + } +} + +//Returns free icon or cursor ID list depending on icon_place_mode +const std::vector<uint16_t> resource_cursor_icon_writer::get_icon_or_cursor_free_id_list(pe_resource_viewer::resource_type type, icon_place_mode mode, uint32_t count) +{ + //Search for available icon/cursor IDs + std::vector<uint16_t> icon_cursor_id_list; + + try + { + //If any icon exists + //List icon IDs + std::vector<uint32_t> id_list(res_.list_resource_ids(type)); + std::sort(id_list.begin(), id_list.end()); + + //If we are placing icon on free spaces + //I.e., icon IDs 1, 3, 4, 7, 8 already exist + //We'll place five icons on IDs 2, 5, 6, 9, 10 + if(mode != icon_place_after_max_icon_id) + { + if(!id_list.empty()) + { + //Determine and list free icon IDs + for(std::vector<uint32_t>::const_iterator it = id_list.begin(); it != id_list.end(); ++it) + { + if(it == id_list.begin()) + { + if(*it > 1) + { + for(uint16_t i = 1; i != *it; ++i) + { + icon_cursor_id_list.push_back(i); + if(icon_cursor_id_list.size() == count) + break; + } + } + } + else if(*(it - 1) - *it > 1) + { + for(uint16_t i = static_cast<uint16_t>(*(it - 1) + 1); i != static_cast<uint16_t>(*it); ++i) + { + icon_cursor_id_list.push_back(i); + if(icon_cursor_id_list.size() == count) + break; + } + } + + if(icon_cursor_id_list.size() == count) + break; + } + } + } + + uint32_t max_id = id_list.empty() ? 0 : *std::max_element(id_list.begin(), id_list.end()); + for(uint32_t i = static_cast<uint32_t>(icon_cursor_id_list.size()); i != count; ++i) + icon_cursor_id_list.push_back(static_cast<uint16_t>(++max_id)); + } + catch(const pe_exception&) //Entry not found + { + for(uint16_t i = 1; i != count + 1; ++i) + icon_cursor_id_list.push_back(i); + } + + return icon_cursor_id_list; +} + +//Add cursor helper +void resource_cursor_icon_writer::add_cursor(const std::string& cursor_file, const resource_data_info* group_cursor_info /* or zero */, resource_directory_entry& new_cursor_group_entry, const resource_directory::entry_finder& finder, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp) +{ + //Check cursor for correctness + if(cursor_file.length() < sizeof(cursor_header)) + throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor); + + const cursor_header* cur_header = reinterpret_cast<const cursor_header*>(&cursor_file[0]); + + unsigned long size_of_headers = sizeof(cursor_header) + cur_header->Count * sizeof(cursordirentry); + if(cursor_file.length() < size_of_headers || cur_header->Count == 0) + throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor); + + //Enumerate all cursors in file + for(uint16_t i = 0; i != cur_header->Count; ++i) + { + //Check cursor entries + const cursordirentry* cursor_entry = reinterpret_cast<const cursordirentry*>(&cursor_file[sizeof(cursor_header) + i * sizeof(cursordirentry)]); + if(cursor_entry->SizeInBytes == 0 + || cursor_entry->ImageOffset < size_of_headers + || !pe_utils::is_sum_safe(cursor_entry->ImageOffset, cursor_entry->SizeInBytes) + || cursor_entry->ImageOffset + cursor_entry->SizeInBytes > cursor_file.length()) + throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor); + } + + std::string cursor_group_data; + cursor_header* info = 0; + + if(group_cursor_info) + { + //If cursor group already exists + { + cursor_group_data = group_cursor_info->get_data(); + codepage = group_cursor_info->get_codepage(); //Don't change codepage of cursor group entry + } + + //Check resource data size + if(cursor_group_data.length() < sizeof(cursor_header)) + throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor); + + //Get cursor header + info = reinterpret_cast<cursor_header*>(&cursor_group_data[0]); + + //Check resource data size + if(cursor_group_data.length() < sizeof(cursor_header) + info->Count * sizeof(cursor_group)) + throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor); + + cursor_group_data.resize(sizeof(cursor_header) + (info->Count + cur_header->Count) * sizeof(cursor_group)); + info = reinterpret_cast<cursor_header*>(&cursor_group_data[0]); //In case if memory was reallocated + } + else //Entry not found - cursor group doesn't exist + { + cursor_group_data.resize(sizeof(cursor_header) + cur_header->Count * sizeof(cursor_group)); + memcpy(&cursor_group_data[0], cur_header, sizeof(cursor_header)); + } + + //Search for available cursor IDs + std::vector<uint16_t> cursor_id_list(get_icon_or_cursor_free_id_list(pe_resource_viewer::resource_cursor, mode, cur_header->Count)); + + //Enumerate all cursors in file + for(uint16_t i = 0; i != cur_header->Count; ++i) + { + const cursordirentry* cursor_entry = reinterpret_cast<const cursordirentry*>(&cursor_file[sizeof(cursor_header) + i * sizeof(cursordirentry)]); + cursor_group group = {0}; + + //Fill cursor resource header + group.Height = cursor_entry->Height * 2; + group.SizeInBytes = cursor_entry->SizeInBytes + 2 * sizeof(uint16_t) /* hotspot coordinates */; + group.Width = cursor_entry->Width; + group.Number = cursor_id_list.at(i); + + memcpy(&cursor_group_data[sizeof(cursor_header) + ((info ? info->Count : 0) + i) * sizeof(cursor_group)], &group, sizeof(group)); + + //Add cursor to resources + resource_directory_entry new_entry; + new_entry.set_id(group.Number); + + //Fill resource data (two WORDs for hotspot of cursor, and cursor bitmap data) + std::string cur_data; + cur_data.resize(sizeof(uint16_t) * 2); + memcpy(&cur_data[0], &cursor_entry->HotspotX, sizeof(uint16_t)); + memcpy(&cur_data[sizeof(uint16_t)], &cursor_entry->HotspotY, sizeof(uint16_t)); + cur_data.append(cursor_file.substr(cursor_entry->ImageOffset, cursor_entry->SizeInBytes)); + + res_.add_resource(cur_data, pe_resource_viewer::resource_cursor, new_entry, resource_directory::entry_finder(group.Number), language, codepage, timestamp); + } + + if(info) + info->Count += cur_header->Count; //Increase cursor count, if we're adding cursor to existing group + + { + //Add or replace cursor group data entry + res_.add_resource(cursor_group_data, pe_resource_viewer::resource_cursor_group, new_cursor_group_entry, finder, language, codepage, timestamp); + } +} + +//Adds icon(s) from icon file data +//timestamp will be used for directories that will be added +//If icon group with name "icon_group_name" or ID "icon_group_id" already exists, it will be appended with new icon(s) +//(Codepage of icon group and icons will not be changed in this case) +//icon_place_mode determines, how new icon(s) will be placed +void resource_cursor_icon_writer::add_icon(const std::string& icon_file, const std::wstring& icon_group_name, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp) +{ + resource_directory_entry new_icon_group_entry; + new_icon_group_entry.set_name(icon_group_name); + std::auto_ptr<resource_data_info> data_info; + + try + { + data_info.reset(new resource_data_info(res_.get_resource_data_by_name(language, pe_resource_viewer::resource_icon_group, icon_group_name))); + } + catch(const pe_exception&) //Entry not found + { + } + + add_icon(icon_file, data_info.get(), new_icon_group_entry, resource_directory::entry_finder(icon_group_name), language, mode, codepage, timestamp); +} + +void resource_cursor_icon_writer::add_icon(const std::string& icon_file, uint32_t icon_group_id, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp) +{ + resource_directory_entry new_icon_group_entry; + new_icon_group_entry.set_id(icon_group_id); + std::auto_ptr<resource_data_info> data_info; + + try + { + data_info.reset(new resource_data_info(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon_group, icon_group_id))); + } + catch(const pe_exception&) //Entry not found + { + } + + add_icon(icon_file, data_info.get(), new_icon_group_entry, resource_directory::entry_finder(icon_group_id), language, mode, codepage, timestamp); +} + +//Adds cursor(s) from cursor file data +//timestamp will be used for directories that will be added +//If cursor group with name "cursor_group_name" or ID "cursor_group_id" already exists, it will be appended with new cursor(s) +//(Codepage of cursor group and cursors will not be changed in this case) +//icon_place_mode determines, how new cursor(s) will be placed +void resource_cursor_icon_writer::add_cursor(const std::string& cursor_file, const std::wstring& cursor_group_name, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp) +{ + resource_directory_entry new_cursor_group_entry; + new_cursor_group_entry.set_name(cursor_group_name); + std::auto_ptr<resource_data_info> data_info; + + try + { + data_info.reset(new resource_data_info(res_.get_resource_data_by_name(language, pe_resource_viewer::resource_cursor_group, cursor_group_name))); + } + catch(const pe_exception&) //Entry not found + { + } + + add_cursor(cursor_file, data_info.get(), new_cursor_group_entry, resource_directory::entry_finder(cursor_group_name), language, mode, codepage, timestamp); +} + +void resource_cursor_icon_writer::add_cursor(const std::string& cursor_file, uint32_t cursor_group_id, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp) +{ + resource_directory_entry new_cursor_group_entry; + new_cursor_group_entry.set_id(cursor_group_id); + std::auto_ptr<resource_data_info> data_info; + + try + { + data_info.reset(new resource_data_info(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor_group, cursor_group_id))); + } + catch(const pe_exception&) //Entry not found + { + } + + add_cursor(cursor_file, data_info.get(), new_cursor_group_entry, resource_directory::entry_finder(cursor_group_id), language, mode, codepage, timestamp); +} + +//Remove icon group helper +void resource_cursor_icon_writer::remove_icons_from_icon_group(const std::string& icon_group_data, uint32_t language) +{ + //Check resource data size + if(icon_group_data.length() < sizeof(ico_header)) + throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon); + + //Get icon header + const ico_header* info = reinterpret_cast<const ico_header*>(icon_group_data.data()); + + uint16_t icon_count = info->Count; + + //Check resource data size + if(icon_group_data.length() < sizeof(ico_header) + icon_count * sizeof(icon_group)) + throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon); + + //Remove icon data + for(uint16_t i = 0; i != icon_count; ++i) + { + const icon_group* group = reinterpret_cast<const icon_group*>(icon_group_data.data() + sizeof(ico_header) + i * sizeof(icon_group)); + res_.remove_resource(pe_resource_viewer::resource_icon, group->Number, language); + } +} + +//Remove cursor group helper +void resource_cursor_icon_writer::remove_cursors_from_cursor_group(const std::string& cursor_group_data, uint32_t language) +{ + //Check resource data size + if(cursor_group_data.length() < sizeof(cursor_header)) + throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor); + + //Get icon header + const cursor_header* info = reinterpret_cast<const cursor_header*>(cursor_group_data.data()); + + uint16_t cursor_count = info->Count; + + //Check resource data size + if(cursor_group_data.length() < sizeof(cursor_header) + cursor_count * sizeof(cursor_group)) + throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor); + + //Remove icon data + for(uint16_t i = 0; i != cursor_count; ++i) + { + const icon_group* group = reinterpret_cast<const icon_group*>(cursor_group_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group)); + res_.remove_resource(pe_resource_viewer::resource_cursor, group->Number, language); + } +} + +//Removes cursor group and all its cursors by name/ID and language +bool resource_cursor_icon_writer::remove_cursor_group(const std::wstring& cursor_group_name, uint32_t language) +{ + //Get resource by name and language + const std::string data = res_.get_resource_data_by_name(language, pe_resource_viewer::resource_cursor_group, cursor_group_name).get_data(); + remove_cursors_from_cursor_group(data, language); + return res_.remove_resource(pe_resource_viewer::resource_cursor_group, cursor_group_name, language); +} + +//Removes cursor group and all its cursors by name/ID and language +bool resource_cursor_icon_writer::remove_cursor_group(uint32_t cursor_group_id, uint32_t language) +{ + //Get resource by name and language + const std::string data = res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor_group, cursor_group_id).get_data(); + remove_cursors_from_cursor_group(data, language); + return res_.remove_resource(pe_resource_viewer::resource_cursor_group, cursor_group_id, language); +} + +//Removes icon group and all its icons by name/ID and language +bool resource_cursor_icon_writer::remove_icon_group(const std::wstring& icon_group_name, uint32_t language) +{ + //Get resource by name and language + const std::string data = res_.get_resource_data_by_name(language, pe_resource_viewer::resource_icon_group, icon_group_name).get_data(); + remove_icons_from_icon_group(data, language); + return res_.remove_resource(pe_resource_viewer::resource_icon_group, icon_group_name, language); +} + +//Removes icon group and all its icons by name/ID and language +bool resource_cursor_icon_writer::remove_icon_group(uint32_t icon_group_id, uint32_t language) +{ + //Get resource by name and language + const std::string data = res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon_group, icon_group_id).get_data(); + remove_icons_from_icon_group(data, language); + return res_.remove_resource(pe_resource_viewer::resource_icon_group, icon_group_id, language); +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/resource_cursor_icon_writer.h b/irdb-lib/pebliss/trunk/pe_lib/resource_cursor_icon_writer.h new file mode 100644 index 0000000000000000000000000000000000000000..726826a37d801b0e4924d7713a413aa6b45bc122 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/resource_cursor_icon_writer.h @@ -0,0 +1,76 @@ +#ifndef pebliss_resource_cursor_icon_writer_h +#define pebliss_resource_cursor_icon_writer_h +#pragma once +#include <string> +#include <vector> +#include "stdint_defs.h" +#include "pe_resource_manager.h" + +namespace pe_bliss +{ +class pe_resource_manager; + +class resource_cursor_icon_writer +{ +public: + //Determines, how new icon(s) or cursor(s) will be placed + enum icon_place_mode + { + icon_place_after_max_icon_id, //Icon(s) will be placed after all existing + icon_place_free_ids //New icon(s) will take all free IDs between existing icons + }; + +public: + resource_cursor_icon_writer(pe_resource_manager& res); + + //Removes icon group and all its icons by name/ID and language + bool remove_icon_group(const std::wstring& icon_group_name, uint32_t language); + bool remove_icon_group(uint32_t icon_group_id, uint32_t language); + + //Adds icon(s) from icon file data + //timestamp will be used for directories that will be added + //If icon group with name "icon_group_name" or ID "icon_group_id" already exists, it will be appended with new icon(s) + //(Codepage of icon group and icons will not be changed in this case) + //icon_place_mode determines, how new icon(s) will be placed + void add_icon(const std::string& icon_file, + const std::wstring& icon_group_name, + uint32_t language, icon_place_mode mode = icon_place_after_max_icon_id, + uint32_t codepage = 0, uint32_t timestamp = 0); + + void add_icon(const std::string& icon_file, + uint32_t icon_group_id, + uint32_t language, icon_place_mode mode = icon_place_after_max_icon_id, + uint32_t codepage = 0, uint32_t timestamp = 0); + + //Removes cursor group and all its cursors by name/ID and language + bool remove_cursor_group(const std::wstring& cursor_group_name, uint32_t language); + bool remove_cursor_group(uint32_t cursor_group_id, uint32_t language); + + //Adds cursor(s) from cursor file data + //timestamp will be used for directories that will be added + //If cursor group with name "cursor_group_name" or ID "cursor_group_id" already exists, it will be appended with new cursor(s) + //(Codepage of cursor group and cursors will not be changed in this case) + //icon_place_mode determines, how new cursor(s) will be placed + void add_cursor(const std::string& cursor_file, const std::wstring& cursor_group_name, uint32_t language, icon_place_mode mode = icon_place_after_max_icon_id, uint32_t codepage = 0, uint32_t timestamp = 0); + void add_cursor(const std::string& cursor_file, uint32_t cursor_group_id, uint32_t language, icon_place_mode mode = icon_place_after_max_icon_id, uint32_t codepage = 0, uint32_t timestamp = 0); + +private: + pe_resource_manager& res_; + + //Add icon helper + void add_icon(const std::string& icon_file, const resource_data_info* group_icon_info /* or zero */, resource_directory_entry& new_icon_group_entry, const resource_directory::entry_finder& finder, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp); + + //Remove icon group helper + void remove_icons_from_icon_group(const std::string& icon_group_data, uint32_t language); + + //Add cursor helper + void add_cursor(const std::string& cursor_file, const resource_data_info* group_cursor_info /* or zero */, resource_directory_entry& new_cursor_group_entry, const resource_directory::entry_finder& finder, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp); + + //Remove cursor group helper + void remove_cursors_from_cursor_group(const std::string& cursor_group_data, uint32_t language); + + //Returns free icon or cursor ID list depending on icon_place_mode + const std::vector<uint16_t> get_icon_or_cursor_free_id_list(pe_resource_manager::resource_type type, icon_place_mode mode, uint32_t count); +}; +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/resource_data_info.cpp b/irdb-lib/pebliss/trunk/pe_lib/resource_data_info.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bc7b3abd7dd1f533ca45c708edfd50969413abfe --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/resource_data_info.cpp @@ -0,0 +1,27 @@ +#include "resource_data_info.h" +#include "pe_resource_viewer.h" + +namespace pe_bliss +{ +//Default constructor +resource_data_info::resource_data_info(const std::string& data, uint32_t codepage) + :data_(data), codepage_(codepage) +{} + +//Constructor from data +resource_data_info::resource_data_info(const resource_data_entry& data) + :data_(data.get_data()), codepage_(data.get_codepage()) +{} + +//Returns resource data +const std::string& resource_data_info::get_data() const +{ + return data_; +} + +//Returns resource codepage +uint32_t resource_data_info::get_codepage() const +{ + return codepage_; +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/resource_data_info.h b/irdb-lib/pebliss/trunk/pe_lib/resource_data_info.h new file mode 100644 index 0000000000000000000000000000000000000000..501036387cebacf89076292579a4dd0991227ac2 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/resource_data_info.h @@ -0,0 +1,30 @@ +#ifndef pebliss_resource_data_info_h +#define pebliss_resource_data_info_h +#pragma once +#include <string> +#include "stdint_defs.h" + +namespace pe_bliss +{ +class resource_data_entry; + +//Class representing resource data +class resource_data_info +{ +public: + //Constructor from data + resource_data_info(const std::string& data, uint32_t codepage); + //Constructor from data + explicit resource_data_info(const resource_data_entry& data); + + //Returns resource data + const std::string& get_data() const; + //Returns resource codepage + uint32_t get_codepage() const; + +private: + std::string data_; + uint32_t codepage_; +}; +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/resource_internal.h b/irdb-lib/pebliss/trunk/pe_lib/resource_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..ecb8aa0be3dfdcf67490a17c5b8f949ab73f571d --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/resource_internal.h @@ -0,0 +1,16 @@ +#ifndef pebliss_resource_internal_h +#define pebliss_resource_internal_h +#pragma once + +#define U16TEXT(t) reinterpret_cast<const unicode16_t*>( t ) + +#define StringFileInfo U16TEXT("S\0t\0r\0i\0n\0g\0F\0i\0l\0e\0I\0n\0f\0o\0\0") +#define SizeofStringFileInfo sizeof("S\0t\0r\0i\0n\0g\0F\0i\0l\0e\0I\0n\0f\0o\0\0") +#define VarFileInfo U16TEXT("V\0a\0r\0F\0i\0l\0e\0I\0n\0f\0o\0\0") +#define Translation U16TEXT("T\0r\0a\0n\0s\0l\0a\0t\0i\0o\0n\0\0") + +#define VarFileInfoAligned U16TEXT("V\0a\0r\0F\0i\0l\0e\0I\0n\0f\0o\0\0\0\0") +#define TranslationAligned U16TEXT("T\0r\0a\0n\0s\0l\0a\0t\0i\0o\0n\0\0\0\0") +#define SizeofVarFileInfoAligned sizeof("V\0a\0r\0F\0i\0l\0e\0I\0n\0f\0o\0\0\0\0") +#define SizeofTranslationAligned sizeof("T\0r\0a\0n\0s\0l\0a\0t\0i\0o\0n\0\0\0\0") +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/resource_message_list_reader.cpp b/irdb-lib/pebliss/trunk/pe_lib/resource_message_list_reader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ff9a5dd8610c6004ed0a59b870a1eb3eeac227b6 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/resource_message_list_reader.cpp @@ -0,0 +1,110 @@ +#include "resource_message_list_reader.h" +#include "pe_resource_viewer.h" + +namespace pe_bliss +{ +using namespace pe_win; + +resource_message_list_reader::resource_message_list_reader(const pe_resource_viewer& res) + :res_(res) +{} + +//Helper function of parsing message list table +const resource_message_list resource_message_list_reader::parse_message_list(const std::string& resource_data) +{ + resource_message_list ret; + + //Check resource data length + if(resource_data.length() < sizeof(message_resource_data)) + throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table); + + const message_resource_data* message_data = reinterpret_cast<const message_resource_data*>(resource_data.data()); + + //Check resource data length more carefully and some possible overflows + if(message_data->NumberOfBlocks >= pe_utils::max_dword / sizeof(message_resource_block) + || !pe_utils::is_sum_safe(message_data->NumberOfBlocks * sizeof(message_resource_block), sizeof(message_resource_data)) + || resource_data.length() < message_data->NumberOfBlocks * sizeof(message_resource_block) + sizeof(message_resource_data)) + throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table); + + //Iterate over all message resource blocks + for(unsigned long i = 0; i != message_data->NumberOfBlocks; ++i) + { + //Get block + const message_resource_block* block = + reinterpret_cast<const message_resource_block*>(resource_data.data() + sizeof(message_resource_data) - sizeof(message_resource_block) + sizeof(message_resource_block) * i); + + //Check resource data length and IDs + if(resource_data.length() < block->OffsetToEntries || block->LowId > block->HighId) + throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table); + + unsigned long current_pos = 0; + static const unsigned long size_of_entry_headers = 4; + //List all message resource entries in block + for(uint32_t curr_id = block->LowId; curr_id <= block->HighId; curr_id++) + { + //Check resource data length and some possible overflows + if(!pe_utils::is_sum_safe(block->OffsetToEntries, current_pos) + || !pe_utils::is_sum_safe(block->OffsetToEntries + current_pos, size_of_entry_headers) + || resource_data.length() < block->OffsetToEntries + current_pos + size_of_entry_headers) + throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table); + + //Get entry + const message_resource_entry* entry = reinterpret_cast<const message_resource_entry*>(resource_data.data() + block->OffsetToEntries + current_pos); + + //Check resource data length and entry length and some possible overflows + if(entry->Length < size_of_entry_headers + || !pe_utils::is_sum_safe(block->OffsetToEntries + current_pos, entry->Length) + || resource_data.length() < block->OffsetToEntries + current_pos + entry->Length + || entry->Length < size_of_entry_headers) + throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table); + + if(entry->Flags & message_resource_unicode) + { + //If string is UNICODE + //Check its length + if(entry->Length % 2) + throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table); + + //Add ID and string to message table +#ifdef PE_BLISS_WINDOWS + ret.insert(std::make_pair(curr_id, message_table_item( + std::wstring(reinterpret_cast<const wchar_t*>(resource_data.data() + block->OffsetToEntries + current_pos + size_of_entry_headers), + (entry->Length - size_of_entry_headers) / 2) + ))); +#else + ret.insert(std::make_pair(curr_id, message_table_item( + pe_utils::from_ucs2(u16string(reinterpret_cast<const unicode16_t*>(resource_data.data() + block->OffsetToEntries + current_pos + size_of_entry_headers), + (entry->Length - size_of_entry_headers) / 2)) + ))); +#endif + } + else + { + //If string is ANSI + //Add ID and string to message table + ret.insert(std::make_pair(curr_id, message_table_item( + std::string(resource_data.data() + block->OffsetToEntries + current_pos + size_of_entry_headers, + entry->Length - size_of_entry_headers) + ))); + } + + //Go to next entry + current_pos += entry->Length; + } + } + + return ret; +} + +//Returns message table data by ID and index in language directory (instead of language) +const resource_message_list resource_message_list_reader::get_message_table_by_id(uint32_t id, uint32_t index) const +{ + return parse_message_list(res_.get_resource_data_by_id(pe_resource_viewer::resource_message_table, id, index).get_data()); +} + +//Returns message table data by ID and language +const resource_message_list resource_message_list_reader::get_message_table_by_id_lang(uint32_t language, uint32_t id) const +{ + return parse_message_list(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_message_table, id).get_data()); +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/resource_message_list_reader.h b/irdb-lib/pebliss/trunk/pe_lib/resource_message_list_reader.h new file mode 100644 index 0000000000000000000000000000000000000000..fdc9e194bc94298d5d65aa8e82c41c70d2b1d745 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/resource_message_list_reader.h @@ -0,0 +1,31 @@ +#ifndef pebliss_resource_message_list_reader_h +#define pebliss_resource_message_list_reader_h +#pragma once +#include "message_table.h" + +namespace pe_bliss +{ +class pe_resource_viewer; + +//ID; message_table_item +typedef std::map<uint32_t, message_table_item> resource_message_list; + +class resource_message_list_reader +{ +public: + resource_message_list_reader(const pe_resource_viewer& res); + + //Returns message table data by ID and language + const resource_message_list get_message_table_by_id_lang(uint32_t language, uint32_t id) const; + //Returns message table data by ID and index in language directory (instead of language) + const resource_message_list get_message_table_by_id(uint32_t id, uint32_t index = 0) const; + + //Helper function of parsing message list table + //resource_data - raw message table resource data + static const resource_message_list parse_message_list(const std::string& resource_data); + +private: + const pe_resource_viewer& res_; +}; +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/resource_string_table_reader.cpp b/irdb-lib/pebliss/trunk/pe_lib/resource_string_table_reader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..33eace1935f9e4bd68685f5e6d9ce85e4d3d3a70 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/resource_string_table_reader.cpp @@ -0,0 +1,88 @@ +#include "resource_string_table_reader.h" +#include "pe_resource_viewer.h" + +namespace pe_bliss +{ +resource_string_table_reader::resource_string_table_reader(const pe_resource_viewer& res) + :res_(res) +{} + +//Returns string table data by ID and index in language directory (instead of language) +const resource_string_list resource_string_table_reader::get_string_table_by_id(uint32_t id, uint32_t index) const +{ + return parse_string_list(id, res_.get_resource_data_by_id(pe_resource_viewer::resource_string, id, index).get_data()); +} + +//Returns string table data by ID and language +const resource_string_list resource_string_table_reader::get_string_table_by_id_lang(uint32_t language, uint32_t id) const +{ + return parse_string_list(id, res_.get_resource_data_by_id(language, pe_resource_viewer::resource_string, id).get_data()); +} + +//Helper function of parsing string list table +const resource_string_list resource_string_table_reader::parse_string_list(uint32_t id, const std::string& resource_data) +{ + resource_string_list ret; + + //16 is maximum count of strings in a string table + static const unsigned long max_string_list_entries = 16; + unsigned long passed_bytes = 0; + for(unsigned long i = 0; i != max_string_list_entries; ++i) + { + //Check resource data length + if(resource_data.length() < sizeof(uint16_t) + passed_bytes) + throw pe_exception("Incorrect resource string table", pe_exception::resource_incorrect_string_table); + + //Get string length - the first WORD + uint16_t string_length = *reinterpret_cast<const uint16_t*>(resource_data.data() + passed_bytes); + passed_bytes += sizeof(uint16_t); //WORD containing string length + + //Check resource data length again + if(resource_data.length() < string_length + passed_bytes) + throw pe_exception("Incorrect resource string table", pe_exception::resource_incorrect_string_table); + + if(string_length) + { + //Create and save string (UNICODE) +#ifdef PE_BLISS_WINDOWS + ret.insert( + std::make_pair(static_cast<uint16_t>(((id - 1) << 4) + i), //ID of string is calculated such way + std::wstring(reinterpret_cast<const wchar_t*>(resource_data.data() + passed_bytes), string_length))); +#else + ret.insert( + std::make_pair(static_cast<uint16_t>(((id - 1) << 4) + i), //ID of string is calculated such way + pe_utils::from_ucs2(u16string(reinterpret_cast<const unicode16_t*>(resource_data.data() + passed_bytes), string_length)))); +#endif + } + + //Go to next string + passed_bytes += string_length * 2; + } + + return ret; +} + +//Returns string from string table by ID and language +const std::wstring resource_string_table_reader::get_string_by_id_lang(uint32_t language, uint16_t id) const +{ + //List strings by string table id and language + const resource_string_list strings(get_string_table_by_id_lang(language, (id >> 4) + 1)); + resource_string_list::const_iterator it = strings.find(id); //Find string by id + if(it == strings.end()) + throw pe_exception("Resource string not found", pe_exception::resource_string_not_found); + + return (*it).second; +} + +//Returns string from string table by ID and index in language directory (instead of language) +const std::wstring resource_string_table_reader::get_string_by_id(uint16_t id, uint32_t index) const +{ + //List strings by string table id and index + const resource_string_list strings(get_string_table_by_id((id >> 4) + 1, index)); + resource_string_list::const_iterator it = strings.find(id); //Find string by id + if(it == strings.end()) + throw pe_exception("Resource string not found", pe_exception::resource_string_not_found); + + return (*it).second; +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/resource_string_table_reader.h b/irdb-lib/pebliss/trunk/pe_lib/resource_string_table_reader.h new file mode 100644 index 0000000000000000000000000000000000000000..cd3e754cbfb04db8e1d802edceed8fe599cc5961 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/resource_string_table_reader.h @@ -0,0 +1,39 @@ +#ifndef pebliss_resource_string_table_reader_h +#define pebliss_resource_string_table_reader_h +#pragma once +#include <string> +#include <map> +#include "stdint_defs.h" + +namespace pe_bliss +{ +class pe_resource_viewer; + +//ID; string +typedef std::map<uint16_t, std::wstring> resource_string_list; + +class resource_string_table_reader +{ +public: + resource_string_table_reader(const pe_resource_viewer& res); + +public: + //Returns string table data by ID and language + const resource_string_list get_string_table_by_id_lang(uint32_t language, uint32_t id) const; + //Returns string table data by ID and index in language directory (instead of language) + const resource_string_list get_string_table_by_id(uint32_t id, uint32_t index = 0) const; + //Returns string from string table by ID and language + const std::wstring get_string_by_id_lang(uint32_t language, uint16_t id) const; + //Returns string from string table by ID and index in language directory (instead of language) + const std::wstring get_string_by_id(uint16_t id, uint32_t index = 0) const; + +private: + const pe_resource_viewer& res_; + + //Helper function of parsing string list table + //Id of resource is needed to calculate string IDs correctly + //resource_data is raw string table resource data + static const resource_string_list parse_string_list(uint32_t id, const std::string& resource_data); +}; +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/resource_version_info_reader.cpp b/irdb-lib/pebliss/trunk/pe_lib/resource_version_info_reader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4a8a2723e60f0e41722d3a4cf536db8258ad9c3a --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/resource_version_info_reader.cpp @@ -0,0 +1,290 @@ +#include "resource_version_info_reader.h" +#include "utils.h" +#include "pe_exception.h" +#include "resource_internal.h" +#include "pe_resource_viewer.h" + +namespace pe_bliss +{ +using namespace pe_win; + +//Root version info block key value +const u16string resource_version_info_reader::version_info_key(U16TEXT("V\0S\0_\0V\0E\0R\0S\0I\0O\0N\0_\0I\0N\0F\0O\0\0")); + +resource_version_info_reader::resource_version_info_reader(const pe_resource_viewer& res) + :res_(res) +{} + +//Returns aligned version block value position +uint32_t resource_version_info_reader::get_version_block_value_pos(uint32_t base_pos, const unicode16_t* key) +{ + uint32_t string_length = static_cast<uint32_t>(u16string(key).length()); + uint32_t ret = pe_utils::align_up(static_cast<uint32_t>(sizeof(uint16_t) * 3 /* headers before Key data */ + + base_pos + + (string_length + 1 /* nullbyte */) * 2), + sizeof(uint32_t)); + + //Check possible overflows + if(ret < base_pos || ret < sizeof(uint16_t) * 3 || ret < (string_length + 1) * 2) + throw_incorrect_version_info(); + + return ret; +} + +//Returns aligned version block first child position +uint32_t resource_version_info_reader::get_version_block_first_child_pos(uint32_t base_pos, uint32_t value_length, const unicode16_t* key) +{ + uint32_t string_length = static_cast<uint32_t>(u16string(key).length()); + uint32_t ret = pe_utils::align_up(static_cast<uint32_t>(sizeof(uint16_t) * 3 /* headers before Key data */ + + base_pos + + (string_length + 1 /* nullbyte */) * 2), + sizeof(uint32_t)) + + pe_utils::align_up(value_length, sizeof(uint32_t)); + + //Check possible overflows + if(ret < base_pos || ret < value_length || ret < sizeof(uint16_t) * 3 || ret < (string_length + 1) * 2) + throw_incorrect_version_info(); + + return ret; +} + +//Throws an exception (id = resource_incorrect_version_info) +void resource_version_info_reader::throw_incorrect_version_info() +{ + throw pe_exception("Incorrect resource version info", pe_exception::resource_incorrect_version_info); +} + +//Returns full version information: +//file_version_info: versions and file info +//lang_string_values_map: map of version info strings with encodings +//translation_values_map: map of translations +const file_version_info resource_version_info_reader::get_version_info(lang_string_values_map& string_values, translation_values_map& translations, const std::string& resource_data) const +{ + //Fixed file version info + file_version_info ret; + + //Check resource data length + if(resource_data.length() < sizeof(version_info_block)) + throw_incorrect_version_info(); + + //Root version info block + const version_info_block* root_block = reinterpret_cast<const version_info_block*>(resource_data.data()); + + //Check root block key for null-termination and its name + if(!pe_utils::is_null_terminated(root_block->Key, resource_data.length() - sizeof(uint16_t) * 3 /* headers before Key data */) + || version_info_key != reinterpret_cast<const unicode16_t*>(root_block->Key)) + throw_incorrect_version_info(); + + //If file has fixed version info + if(root_block->ValueLength) + { + //Get root block value position + uint32_t value_pos = get_version_block_value_pos(0, reinterpret_cast<const unicode16_t*>(root_block->Key)); + //Check value length + if(resource_data.length() < value_pos + sizeof(vs_fixedfileinfo)) + throw_incorrect_version_info(); + + //Get VS_FIXEDFILEINFO structure pointer + const vs_fixedfileinfo* file_info = reinterpret_cast<const vs_fixedfileinfo*>(resource_data.data() + value_pos); + //Check its signature and some other fields + if(file_info->dwSignature != vs_ffi_signature || file_info->dwStrucVersion != vs_ffi_strucversion) //Don't check if file_info->dwFileFlagsMask == VS_FFI_FILEFLAGSMASK + throw_incorrect_version_info(); + + //Save fixed version info + ret = file_version_info(*file_info); + } + + //Iterate over child elements of VS_VERSIONINFO (StringFileInfo or VarFileInfo) + for(uint32_t child_pos = get_version_block_first_child_pos(0, root_block->ValueLength, reinterpret_cast<const unicode16_t*>(root_block->Key)); + child_pos < root_block->Length;) + { + //Check block position + if(!pe_utils::is_sum_safe(child_pos, sizeof(version_info_block)) + || resource_data.length() < child_pos + sizeof(version_info_block)) + throw_incorrect_version_info(); + + //Get VERSION_INFO_BLOCK structure pointer + const version_info_block* block = reinterpret_cast<const version_info_block*>(resource_data.data() + child_pos); + + //Check its length + if(block->Length == 0) + throw_incorrect_version_info(); + + //Check block key for null-termination + if(!pe_utils::is_null_terminated(block->Key, resource_data.length() - child_pos - sizeof(uint16_t) * 3 /* headers before Key data */)) + throw_incorrect_version_info(); + + u16string info_type(reinterpret_cast<const unicode16_t*>(block->Key)); + //If we encountered StringFileInfo... + if(info_type == StringFileInfo) + { + //Enumerate all string tables + for(uint32_t string_table_pos = get_version_block_first_child_pos(child_pos, block->ValueLength, reinterpret_cast<const unicode16_t*>(block->Key)); + string_table_pos - child_pos < block->Length;) + { + //Check string table block position + if(resource_data.length() < string_table_pos + sizeof(version_info_block)) + throw_incorrect_version_info(); + + //Get VERSION_INFO_BLOCK structure pointer for string table + const version_info_block* string_table = reinterpret_cast<const version_info_block*>(resource_data.data() + string_table_pos); + + //Check its length + if(string_table->Length == 0) + throw_incorrect_version_info(); + + //Check string table key for null-termination + if(!pe_utils::is_null_terminated(string_table->Key, resource_data.length() - string_table_pos - sizeof(uint16_t) * 3 /* headers before Key data */)) + throw_incorrect_version_info(); + + string_values_map new_values; + + //Enumerate all strings in the string table + for(uint32_t string_pos = get_version_block_first_child_pos(string_table_pos, string_table->ValueLength, reinterpret_cast<const unicode16_t*>(string_table->Key)); + string_pos - string_table_pos < string_table->Length;) + { + //Check string block position + if(resource_data.length() < string_pos + sizeof(version_info_block)) + throw_incorrect_version_info(); + + //Get VERSION_INFO_BLOCK structure pointer for string block + const version_info_block* string_block = reinterpret_cast<const version_info_block*>(resource_data.data() + string_pos); + + //Check its length + if(string_block->Length == 0) + throw_incorrect_version_info(); + + //Check string block key for null-termination + if(!pe_utils::is_null_terminated(string_block->Key, resource_data.length() - string_pos - sizeof(uint16_t) * 3 /* headers before Key data */)) + throw_incorrect_version_info(); + + u16string data; + //If string block has value + if(string_block->ValueLength != 0) + { + //Get value position + uint32_t value_pos = get_version_block_value_pos(string_pos, reinterpret_cast<const unicode16_t*>(string_block->Key)); + //Check it + if(resource_data.length() < value_pos + string_block->ValueLength) + throw pe_exception("Incorrect resource version info", pe_exception::resource_incorrect_version_info); + + //Get UNICODE string value + data = u16string(reinterpret_cast<const unicode16_t*>(resource_data.data() + value_pos), string_block->ValueLength); + pe_utils::strip_nullbytes(data); + } + + //Save name-value pair +#ifdef PE_BLISS_WINDOWS + new_values.insert(std::make_pair(reinterpret_cast<const unicode16_t*>(string_block->Key), data)); +#else + new_values.insert(std::make_pair(pe_utils::from_ucs2(reinterpret_cast<const unicode16_t*>(string_block->Key)), + pe_utils::from_ucs2(data))); +#endif + + //Navigate to next string block + string_pos += pe_utils::align_up(string_block->Length, sizeof(uint32_t)); + } + +#ifdef PE_BLISS_WINDOWS + string_values.insert(std::make_pair(reinterpret_cast<const unicode16_t*>(string_table->Key), new_values)); +#else + string_values.insert(std::make_pair(pe_utils::from_ucs2(reinterpret_cast<const unicode16_t*>(string_table->Key)), new_values)); +#endif + + //Navigate to next string table block + string_table_pos += pe_utils::align_up(string_table->Length, sizeof(uint32_t)); + } + } + else if(info_type == VarFileInfo) //If we encountered VarFileInfo + { + for(uint32_t var_table_pos = get_version_block_first_child_pos(child_pos, block->ValueLength, reinterpret_cast<const unicode16_t*>(block->Key)); + var_table_pos - child_pos < block->Length;) + { + //Check var block position + if(resource_data.length() < var_table_pos + sizeof(version_info_block)) + throw_incorrect_version_info(); + + //Get VERSION_INFO_BLOCK structure pointer for var block + const version_info_block* var_table = reinterpret_cast<const version_info_block*>(resource_data.data() + var_table_pos); + + //Check its length + if(var_table->Length == 0) + throw_incorrect_version_info(); + + //Check its key for null-termination + if(!pe_utils::is_null_terminated(var_table->Key, resource_data.length() - var_table_pos - sizeof(uint16_t) * 3 /* headers before Key data */)) + throw_incorrect_version_info(); + + //If block is "Translation" (actually, there's no other types possible in VarFileInfo) and it has value + if(u16string(reinterpret_cast<const unicode16_t*>(var_table->Key)) == Translation && var_table->ValueLength) + { + //Get its value position + uint32_t value_pos = get_version_block_value_pos(var_table_pos, reinterpret_cast<const unicode16_t*>(var_table->Key)); + //Cherck value length + if(resource_data.length() < value_pos + var_table->ValueLength) + throw_incorrect_version_info(); + + //Get list of translations: pairs of LANGUAGE_ID - CODEPAGE_ID + for(unsigned long i = 0; i < var_table->ValueLength; i += sizeof(uint16_t) * 2) + { + //Pair of WORDs + uint16_t lang_id = *reinterpret_cast<const uint16_t*>(resource_data.data() + value_pos + i); + uint16_t codepage_id = *reinterpret_cast<const uint16_t*>(resource_data.data() + value_pos + sizeof(uint16_t) + i); + //Save translation + translations.insert(std::make_pair(lang_id, codepage_id)); + } + } + + //Navigate to next var block + var_table_pos += pe_utils::align_up(var_table->Length, sizeof(uint32_t)); + } + } + else + { + throw_incorrect_version_info(); + } + + //Navigate to next element in root block + child_pos += pe_utils::align_up(block->Length, sizeof(uint32_t)); + } + + return ret; +} + +//Returns full version information: +//file_version info: versions and file info +//lang_string_values_map: map of version info strings with encodings +//translation_values_map: map of translations +const file_version_info resource_version_info_reader::get_version_info_by_lang(lang_string_values_map& string_values, translation_values_map& translations, uint32_t language) const +{ + const std::string& resource_data = res_.get_root_directory() //Type directory + .entry_by_id(pe_resource_viewer::resource_version) + .get_resource_directory() //Name/ID directory + .entry_by_id(1) + .get_resource_directory() //Language directory + .entry_by_id(language) + .get_data_entry() //Data directory + .get_data(); + + return get_version_info(string_values, translations, resource_data); +} + +//Returns full version information: +//file_version_info: versions and file info +//lang_string_values_map: map of version info strings with encodings +//translation_values_map: map of translations +const file_version_info resource_version_info_reader::get_version_info(lang_string_values_map& string_values, translation_values_map& translations, uint32_t index) const +{ + const resource_directory::entry_list& entries = res_.get_root_directory() //Type directory + .entry_by_id(pe_resource_viewer::resource_version) + .get_resource_directory() //Name/ID directory + .entry_by_id(1) + .get_resource_directory() //Language directory + .get_entry_list(); + + if(entries.size() <= index) + throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found); + + return get_version_info(string_values, translations, entries.at(index).get_data_entry().get_data()); //Data directory +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/resource_version_info_reader.h b/irdb-lib/pebliss/trunk/pe_lib/resource_version_info_reader.h new file mode 100644 index 0000000000000000000000000000000000000000..e85c297b251bee472ca4855b48325ac98cf978f0 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/resource_version_info_reader.h @@ -0,0 +1,49 @@ +#ifndef pebliss_resource_version_info_reader_h +#define pebliss_resource_version_info_reader_h +#pragma once +#include <map> +#include "file_version_info.h" +#include "pe_structures.h" +#include "version_info_types.h" + +namespace pe_bliss +{ +class pe_resource_viewer; + +class resource_version_info_reader +{ +public: //VERSION INFO + resource_version_info_reader(const pe_resource_viewer& res); + + //Returns full version information: + //file_version_info: versions and file info + //lang_lang_string_values_map: map of version info strings with encodings with encodings + //translation_values_map: map of translations + const file_version_info get_version_info(lang_string_values_map& string_values, translation_values_map& translations, uint32_t index = 0) const; + const file_version_info get_version_info_by_lang(lang_string_values_map& string_values, translation_values_map& translations, uint32_t language) const; + +public: + //L"VS_VERSION_INFO" key of root version info block + static const u16string version_info_key; + +private: + const pe_resource_viewer& res_; + + //VERSION INFO helpers + //Returns aligned version block value position + static uint32_t get_version_block_value_pos(uint32_t base_pos, const unicode16_t* key); + + //Returns aligned version block first child position + static uint32_t get_version_block_first_child_pos(uint32_t base_pos, uint32_t value_length, const unicode16_t* key); + + //Returns full version information: + //file_version_info: versions and file info + //lang_string_values_map: map of version info strings with encodings + //translation_values_map: map of translations + const file_version_info get_version_info(lang_string_values_map& string_values, translation_values_map& translations, const std::string& resource_data) const; + + //Throws an exception (id = resource_incorrect_version_info) + static void throw_incorrect_version_info(); +}; +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/resource_version_info_writer.cpp b/irdb-lib/pebliss/trunk/pe_lib/resource_version_info_writer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..34f21c4a378a56fd13b2138e1bb4f80568de2d82 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/resource_version_info_writer.cpp @@ -0,0 +1,262 @@ +#include <string.h> +#include "resource_version_info_writer.h" +#include "pe_structures.h" +#include "resource_internal.h" +#include "utils.h" +#include "pe_resource_manager.h" +#include "resource_version_info_reader.h" + +namespace pe_bliss +{ +using namespace pe_win; + +resource_version_info_writer::resource_version_info_writer(pe_resource_manager& res) + :res_(res) +{} + +//Sets/replaces full version information: +//file_version_info: versions and file info +//lang_string_values_map: map of version info strings with encodings +//translation_values_map: map of translations +void resource_version_info_writer::set_version_info(const file_version_info& file_info, + const lang_string_values_map& string_values, + const translation_values_map& translations, + uint32_t language, + uint32_t codepage, + uint32_t timestamp) +{ + std::string version_data; + + //Calculate total size of version resource data + uint32_t total_version_info_length = + static_cast<uint32_t>(sizeof(version_info_block) - sizeof(uint16_t) + sizeof(uint16_t) /* pading */ + + (resource_version_info_reader::version_info_key.length() + 1) * 2 + + sizeof(vs_fixedfileinfo)); + + //If we have any strings values + if(!string_values.empty()) + { + total_version_info_length += sizeof(version_info_block) - sizeof(uint16_t); //StringFileInfo block + total_version_info_length += SizeofStringFileInfo; //Name of block (key) + + //Add required size for version strings + for(lang_string_values_map::const_iterator table_it = string_values.begin(); table_it != string_values.end(); ++table_it) + { + total_version_info_length += pe_utils::align_up(static_cast<uint32_t>(sizeof(uint16_t) * 3 + ((*table_it).first.length() + 1) * 2), sizeof(uint32_t)); //Name of child block and block size (key of string table block) + + const string_values_map& values = (*table_it).second; + for(string_values_map::const_iterator it = values.begin(); it != values.end(); ++it) + { + total_version_info_length += pe_utils::align_up(static_cast<uint32_t>(sizeof(uint16_t) * 3 + ((*it).first.length() + 1) * 2), sizeof(uint32_t)); + total_version_info_length += pe_utils::align_up(static_cast<uint32_t>(((*it).second.length() + 1) * 2), sizeof(uint32_t)); + } + } + } + + //If we have translations + if(!translations.empty()) + { + total_version_info_length += (sizeof(version_info_block) - sizeof(uint16_t)) * 2; //VarFileInfo and Translation blocks + total_version_info_length += SizeofVarFileInfoAligned; //DWORD-aligned VarFileInfo block name + total_version_info_length += SizeofTranslationAligned; //DWORD-aligned Translation block name + total_version_info_length += static_cast<uint32_t>(translations.size() * sizeof(uint16_t) * 2); + } + + //Resize version data buffer + version_data.resize(total_version_info_length); + + //Create root version block + version_info_block root_block = {0}; + root_block.ValueLength = sizeof(vs_fixedfileinfo); + root_block.Length = static_cast<uint16_t>(total_version_info_length); + + //Fill fixed file info + vs_fixedfileinfo fixed_info = {0}; + fixed_info.dwFileDateLS = file_info.get_file_date_ls(); + fixed_info.dwFileDateMS = file_info.get_file_date_ms(); + fixed_info.dwFileFlags = file_info.get_file_flags(); + fixed_info.dwFileFlagsMask = vs_ffi_fileflagsmask; + fixed_info.dwFileOS = file_info.get_file_os_raw(); + fixed_info.dwFileSubtype = file_info.get_file_subtype(); + fixed_info.dwFileType = file_info.get_file_type_raw(); + fixed_info.dwFileVersionLS = file_info.get_file_version_ls(); + fixed_info.dwFileVersionMS = file_info.get_file_version_ms(); + fixed_info.dwSignature = vs_ffi_signature; + fixed_info.dwStrucVersion = vs_ffi_strucversion; + fixed_info.dwProductVersionLS = file_info.get_product_version_ls(); + fixed_info.dwProductVersionMS = file_info.get_product_version_ms(); + + //Write root block and fixed file info to buffer + uint32_t data_ptr = 0; + memcpy(&version_data[data_ptr], &root_block, sizeof(version_info_block) - sizeof(uint16_t)); + data_ptr += sizeof(version_info_block) - sizeof(uint16_t); + memcpy(&version_data[data_ptr], resource_version_info_reader::version_info_key.c_str(), (resource_version_info_reader::version_info_key.length() + 1) * sizeof(uint16_t)); + data_ptr += static_cast<uint32_t>((resource_version_info_reader::version_info_key.length() + 1) * sizeof(uint16_t)); + memset(&version_data[data_ptr], 0, sizeof(uint16_t)); + data_ptr += sizeof(uint16_t); + memcpy(&version_data[data_ptr], &fixed_info, sizeof(fixed_info)); + data_ptr += sizeof(fixed_info); + + //Write string values, if any + if(!string_values.empty()) + { + //Create string file info root block + version_info_block string_file_info_block = {0}; + string_file_info_block.Type = 1; //Block type is string + memcpy(&version_data[data_ptr], &string_file_info_block, sizeof(version_info_block) - sizeof(uint16_t)); + //We will calculate its length later + version_info_block* string_file_info_block_ptr = reinterpret_cast<version_info_block*>(&version_data[data_ptr]); + data_ptr += sizeof(version_info_block) - sizeof(uint16_t); + + uint32_t old_ptr1 = data_ptr; //Used to calculate string file info block length later + memcpy(&version_data[data_ptr], StringFileInfo, SizeofStringFileInfo); //Write block name + data_ptr += SizeofStringFileInfo; + + //Create string table root block (child of string file info) + version_info_block string_table_block = {0}; + string_table_block.Type = 1; //Block type is string + + for(lang_string_values_map::const_iterator table_it = string_values.begin(); table_it != string_values.end(); ++table_it) + { + const string_values_map& values = (*table_it).second; + + memcpy(&version_data[data_ptr], &string_table_block, sizeof(version_info_block) - sizeof(uint16_t)); + //We will calculate its length later + version_info_block* string_table_block_ptr = reinterpret_cast<version_info_block*>(&version_data[data_ptr]); + data_ptr += sizeof(version_info_block) - sizeof(uint16_t); + + uint32_t old_ptr2 = data_ptr; //Used to calculate string table block length later + uint32_t lang_key_length = static_cast<uint32_t>(((*table_it).first.length() + 1) * sizeof(uint16_t)); + +#ifdef PE_BLISS_WINDOWS + memcpy(&version_data[data_ptr], (*table_it).first.c_str(), lang_key_length); //Write block key +#else + { + u16string str(pe_utils::to_ucs2((*table_it).first)); + memcpy(&version_data[data_ptr], str.c_str(), lang_key_length); //Write block key + } +#endif + + data_ptr += lang_key_length; + //Align key if necessary + if((sizeof(uint16_t) * 3 + lang_key_length) % sizeof(uint32_t)) + { + memset(&version_data[data_ptr], 0, sizeof(uint16_t)); + data_ptr += sizeof(uint16_t); + } + + //Create string block (child of string table block) + version_info_block string_block = {0}; + string_block.Type = 1; //Block type is string + for(string_values_map::const_iterator it = values.begin(); it != values.end(); ++it) + { + //Calculate value length and key length of string block + string_block.ValueLength = static_cast<uint16_t>((*it).second.length() + 1); + uint32_t key_length = static_cast<uint32_t>(((*it).first.length() + 1) * sizeof(uint16_t)); + //Calculate length of block + string_block.Length = static_cast<uint16_t>(pe_utils::align_up(sizeof(uint16_t) * 3 + key_length, sizeof(uint32_t)) + string_block.ValueLength * sizeof(uint16_t)); + + //Write string block + memcpy(&version_data[data_ptr], &string_block, sizeof(version_info_block) - sizeof(uint16_t)); + data_ptr += sizeof(version_info_block) - sizeof(uint16_t); + +#ifdef PE_BLISS_WINDOWS + memcpy(&version_data[data_ptr], (*it).first.c_str(), key_length); //Write block key +#else + { + u16string str(pe_utils::to_ucs2((*it).first)); + memcpy(&version_data[data_ptr], str.c_str(), key_length); //Write block key + } +#endif + + data_ptr += key_length; + //Align key if necessary + if((sizeof(uint16_t) * 3 + key_length) % sizeof(uint32_t)) + { + memset(&version_data[data_ptr], 0, sizeof(uint16_t)); + data_ptr += sizeof(uint16_t); + } + + //Write block data (value) +#ifdef PE_BLISS_WINDOWS + memcpy(&version_data[data_ptr], (*it).second.c_str(), string_block.ValueLength * sizeof(uint16_t)); +#else + { + u16string str(pe_utils::to_ucs2((*it).second)); + memcpy(&version_data[data_ptr], str.c_str(), string_block.ValueLength * sizeof(uint16_t)); + } +#endif + + data_ptr += string_block.ValueLength * 2; + //Align data if necessary + if((string_block.ValueLength * 2) % sizeof(uint32_t)) + { + memset(&version_data[data_ptr], 0, sizeof(uint16_t)); + data_ptr += sizeof(uint16_t); + } + } + + //Calculate string table and string file info blocks lengths + string_table_block_ptr->Length = static_cast<uint16_t>(data_ptr - old_ptr2 + sizeof(uint16_t) * 3); + } + + string_file_info_block_ptr->Length = static_cast<uint16_t>(data_ptr - old_ptr1 + sizeof(uint16_t) * 3); + } + + //If we have transactions + if(!translations.empty()) + { + //Create root var file info block + version_info_block var_file_info_block = {0}; + var_file_info_block.Type = 1; //Type of block is string + //Write block header + memcpy(&version_data[data_ptr], &var_file_info_block, sizeof(version_info_block) - sizeof(uint16_t)); + //We will calculate its length later + version_info_block* var_file_info_block_ptr = reinterpret_cast<version_info_block*>(&version_data[data_ptr]); + data_ptr += sizeof(version_info_block) - sizeof(uint16_t); + + uint32_t old_ptr1 = data_ptr; //Used to calculate var file info block length later + memcpy(&version_data[data_ptr], VarFileInfoAligned, SizeofVarFileInfoAligned); //Write block key (aligned) + data_ptr += SizeofVarFileInfoAligned; + + //Create root translation block (child of var file info block) + version_info_block translation_block = {0}; + //Write block header + memcpy(&version_data[data_ptr], &translation_block, sizeof(version_info_block) - sizeof(uint16_t)); + //We will calculate its length later + version_info_block* translation_block_ptr = reinterpret_cast<version_info_block*>(&version_data[data_ptr]); + data_ptr += sizeof(version_info_block) - sizeof(uint16_t); + + uint32_t old_ptr2 = data_ptr; //Used to calculate var file info block length later + memcpy(&version_data[data_ptr], TranslationAligned, SizeofTranslationAligned); //Write block key (aligned) + data_ptr += SizeofTranslationAligned; + + //Calculate translation block value length + translation_block_ptr->ValueLength = static_cast<uint16_t>(sizeof(uint16_t) * 2 * translations.size()); + + //Write translation values to block + for(translation_values_map::const_iterator it = translations.begin(); it != translations.end(); ++it) + { + uint16_t lang_id = (*it).first; //Language ID + uint16_t codepage_id = (*it).second; //Codepage ID + memcpy(&version_data[data_ptr], &lang_id, sizeof(lang_id)); + data_ptr += sizeof(lang_id); + memcpy(&version_data[data_ptr], &codepage_id, sizeof(codepage_id)); + data_ptr += sizeof(codepage_id); + } + + //Calculate Translation and VarFileInfo blocks lengths + translation_block_ptr->Length = static_cast<uint16_t>(data_ptr - old_ptr2 + sizeof(uint16_t) * 3); + var_file_info_block_ptr->Length = static_cast<uint16_t>(data_ptr - old_ptr1 + sizeof(uint16_t) * 3); + } + + //Add/replace version info resource + res_.add_resource(version_data, pe_resource_viewer::resource_version, 1, language, codepage, timestamp); +} + +//Removes version info by language (ID = 1) +bool resource_version_info_writer::remove_version_info(uint32_t language) +{ + return res_.remove_resource(pe_resource_viewer::resource_version, 1, language); +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/resource_version_info_writer.h b/irdb-lib/pebliss/trunk/pe_lib/resource_version_info_writer.h new file mode 100644 index 0000000000000000000000000000000000000000..8f65c5dd2bc7d0b05e2edc8bf33f0937aca04ed4 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/resource_version_info_writer.h @@ -0,0 +1,34 @@ +#ifndef pebliss_resource_version_info_writer_h +#define pebliss_resource_version_info_writer_h +#pragma once +#include "version_info_types.h" +#include "file_version_info.h" + +namespace pe_bliss +{ +class pe_resource_manager; + +class resource_version_info_writer +{ +public: + resource_version_info_writer(pe_resource_manager& res); + + //Sets/replaces full version information: + //file_version_info: versions and file info + //lang_string_values_map: map of version info strings with encodings + //translation_values_map: map of translations + void set_version_info(const file_version_info& file_info, + const lang_string_values_map& string_values, + const translation_values_map& translations, + uint32_t language, + uint32_t codepage = 0, + uint32_t timestamp = 0); + + //Removes version info by language (ID = 1) + bool remove_version_info(uint32_t language); + +private: + pe_resource_manager& res_; +}; +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/stdint_defs.h b/irdb-lib/pebliss/trunk/pe_lib/stdint_defs.h new file mode 100644 index 0000000000000000000000000000000000000000..51b25f743a63e710af959fed9bb8f2b9e59eba01 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/stdint_defs.h @@ -0,0 +1,27 @@ +#ifndef pebliss_stdint_defs_h +#define pebliss_stdint_defs_h +#pragma once +#ifdef _MSC_VER +#if _MSC_VER < 1600 +namespace pe_bliss +{ + //stdint.h definitions for MSVC 2008 and earlier, as + //it doesn't have them + typedef signed char int8_t; + typedef short int16_t; + typedef int int32_t; + + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; + + typedef long long int64_t; + typedef unsigned long long uint64_t; +} +#else +#include <stdint.h> +#endif +#else +#include <stdint.h> +#endif +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/utils.cpp b/irdb-lib/pebliss/trunk/pe_lib/utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..917184d8170a8e61466fc44f20f5768621dffa6f --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/utils.cpp @@ -0,0 +1,87 @@ +#include <string.h> +#include "utils.h" +#include "pe_exception.h" + +#ifndef PE_BLISS_WINDOWS +#include <iconv.h> +#endif + +namespace pe_bliss +{ +const double pe_utils::log_2 = 1.44269504088896340736; //instead of using M_LOG2E + +//Returns stream size +std::streamoff pe_utils::get_file_size(std::istream& file) +{ + //Get old istream offset + std::streamoff old_offset = file.tellg(); + file.seekg(0, std::ios::end); + std::streamoff filesize = file.tellg(); + //Set old istream offset + file.seekg(old_offset); + return filesize; +} + +#ifndef PE_BLISS_WINDOWS +const u16string pe_utils::to_ucs2(const std::wstring& str) +{ + u16string ret; + if(str.empty()) + return ret; + + ret.resize(str.length()); + + iconv_t conv = iconv_open("UCS-2", "WCHAR_T"); + if(conv == reinterpret_cast<iconv_t>(-1)) + throw pe_exception("Error opening iconv", pe_exception::encoding_convertion_error); + + size_t inbytesleft = str.length() * sizeof(wchar_t); + size_t outbytesleft = ret.length() * sizeof(unicode16_t); + const wchar_t* in_pos = str.c_str(); + unicode16_t* out_pos = &ret[0]; + + size_t result = iconv(conv, const_cast<char**>(reinterpret_cast<const char**>(&in_pos)), &inbytesleft, reinterpret_cast<char**>(&out_pos), &outbytesleft); + + iconv_close(conv); + + if(result == static_cast<size_t>(-1)) + throw pe_exception("Iconv error", pe_exception::encoding_convertion_error); + + return ret; +} + +const std::wstring pe_utils::from_ucs2(const u16string& str) +{ + std::wstring ret; + if(str.empty()) + return ret; + + ret.resize(str.length()); + + iconv_t conv = iconv_open("WCHAR_T", "UCS-2"); + if(conv == reinterpret_cast<iconv_t>(-1)) + throw pe_exception("Error opening iconv", pe_exception::encoding_convertion_error); + + size_t inbytesleft = str.length() * sizeof(unicode16_t); + size_t outbytesleft = ret.length() * sizeof(wchar_t); + const unicode16_t* in_pos = str.c_str(); + wchar_t* out_pos = &ret[0]; + + size_t result = iconv(conv, const_cast<char**>(reinterpret_cast<const char**>(&in_pos)), &inbytesleft, reinterpret_cast<char**>(&out_pos), &outbytesleft); + iconv_close(conv); + + if(result == static_cast<size_t>(-1)) + throw pe_exception("Iconv error", pe_exception::encoding_convertion_error); + + return ret; +} +#endif + +bool operator==(const pe_win::guid& guid1, const pe_win::guid& guid2) +{ + return guid1.Data1 == guid2.Data1 + && guid1.Data2 == guid2.Data2 + && guid1.Data3 == guid2.Data3 + && !memcmp(guid1.Data4, guid2.Data4, sizeof(guid1.Data4)); +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/utils.h b/irdb-lib/pebliss/trunk/pe_lib/utils.h new file mode 100644 index 0000000000000000000000000000000000000000..7249b83cec76a05cb19ceb7ba69f69738e70a9b3 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/utils.h @@ -0,0 +1,88 @@ +#ifndef pebliss_utils_h +#define pebliss_utils_h +#pragma once + +#include <istream> +#include <string> +#include "stdint_defs.h" +#include "pe_structures.h" + +namespace pe_bliss +{ +class pe_utils +{ +public: + //Returns true if string "data" with maximum length "raw_length" is null-terminated + template<typename T> + static bool is_null_terminated(const T* data, size_t raw_length) + { + raw_length /= sizeof(T); + for(size_t l = 0; l < raw_length; l++) + { + if(data[l] == static_cast<T>(L'\0')) + return true; + } + + return false; + } + + //Helper template function to strip nullbytes in the end of string + template<typename T> + static void strip_nullbytes(std::basic_string<T>& str) + { + while(!*(str.end() - 1) && !str.empty()) + str.erase(str.length() - 1); + } + + //Helper function to determine if number is power of 2 + template<typename T> + static inline bool is_power_of_2(T x) + { + return !(x & (x - 1)); + } + + //Helper function to align number down + template<typename T> + static inline T align_down(T x, uint32_t align) + { + return x & ~(static_cast<T>(align) - 1); + } + + //Helper function to align number up + template<typename T> + static inline T align_up(T x, uint32_t align) + { + return (x & static_cast<T>(align - 1)) ? align_down(x, align) + static_cast<T>(align) : x; + } + + //Returns true if sum of two unsigned integers is safe (no overflow occurs) + static inline bool is_sum_safe(uint32_t a, uint32_t b) + { + return a <= static_cast<uint32_t>(-1) - b; + } + + //Two gigabytes value in bytes + static const uint32_t two_gb = 0x80000000; + static const uint32_t max_dword = 0xFFFFFFFF; + static const uint32_t max_word = 0x0000FFFF; + static const double log_2; //instead of using M_LOG2E + + //Returns stream size + static std::streamoff get_file_size(std::istream& file); + +#ifndef PE_BLISS_WINDOWS +public: + static const u16string to_ucs2(const std::wstring& str); + static const std::wstring from_ucs2(const u16string& str); +#endif + +private: + pe_utils(); + pe_utils(pe_utils&); + pe_utils& operator=(const pe_utils&); +}; + +//Windows GUID comparison +bool operator==(const pe_win::guid& guid1, const pe_win::guid& guid2); +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/version_info_editor.cpp b/irdb-lib/pebliss/trunk/pe_lib/version_info_editor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9e5c9b7a1c1be96122d62ad9304774ad175978f3 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/version_info_editor.cpp @@ -0,0 +1,163 @@ +#include <sstream> +#include <iomanip> +#include "version_info_types.h" +#include "version_info_editor.h" +#include "version_info_viewer.h" + +namespace pe_bliss +{ +//Default constructor +//strings - version info strings with charsets +//translations - version info translations map +version_info_editor::version_info_editor(lang_string_values_map& strings, translation_values_map& translations) + :version_info_viewer(strings, translations), + strings_edit_(strings), + translations_edit_(translations) +{} + +//Below functions have parameter translation +//If it's empty, the default language translation will be taken +//If there's no default language translation, the first one will be taken + +//Sets company name +void version_info_editor::set_company_name(const std::wstring& value, const std::wstring& translation) +{ + set_property(L"CompanyName", value, translation); +} + +//Sets file description +void version_info_editor::set_file_description(const std::wstring& value, const std::wstring& translation) +{ + set_property(L"FileDescription", value, translation); +} + +//Sets file version +void version_info_editor::set_file_version(const std::wstring& value, const std::wstring& translation) +{ + set_property(L"FileVersion", value, translation); +} + +//Sets internal file name +void version_info_editor::set_internal_name(const std::wstring& value, const std::wstring& translation) +{ + set_property(L"InternalName", value, translation); +} + +//Sets legal copyright +void version_info_editor::set_legal_copyright(const std::wstring& value, const std::wstring& translation) +{ + set_property(L"LegalCopyright", value, translation); +} + +//Sets original file name +void version_info_editor::set_original_filename(const std::wstring& value, const std::wstring& translation) +{ + set_property(L"OriginalFilename", value, translation); +} + +//Sets product name +void version_info_editor::set_product_name(const std::wstring& value, const std::wstring& translation) +{ + set_property(L"ProductName", value, translation); +} + +//Sets product version +void version_info_editor::set_product_version(const std::wstring& value, const std::wstring& translation) +{ + set_property(L"ProductVersion", value, translation); +} + +//Sets version info property value +//property_name - property name +//value - property value +//If translation does not exist, it will be added +//If property does not exist, it will be added +void version_info_editor::set_property(const std::wstring& property_name, const std::wstring& value, const std::wstring& translation) +{ + lang_string_values_map::iterator it = strings_edit_.begin(); + + if(translation.empty()) + { + //If no translation was specified + it = strings_edit_.find(default_language_translation); //Find default translation table + if(it == strings_edit_.end()) //If there's no default translation table, take the first one + { + it = strings_edit_.begin(); + if(it == strings_edit_.end()) //If there's no any translation table, add default one + { + it = strings_edit_.insert(std::make_pair(default_language_translation, string_values_map())).first; + //Also add it to translations list + add_translation(default_language_translation); + } + } + } + else + { + it = strings_edit_.find(translation); //Find specified translation table + if(it == strings_edit_.end()) //If there's no translation, add it + { + it = strings_edit_.insert(std::make_pair(translation, string_values_map())).first; + //Also add it to translations list + add_translation(translation); + } + } + + //Change value of the required property + ((*it).second)[property_name] = value; +} + +//Adds translation to translation list +void version_info_editor::add_translation(const std::wstring& translation) +{ + std::pair<uint16_t, uint16_t> translation_ids(translation_from_string(translation)); + add_translation(translation_ids.first, translation_ids.second); +} + +void version_info_editor::add_translation(uint16_t language_id, uint16_t codepage_id) +{ + std::pair<translation_values_map::const_iterator, translation_values_map::const_iterator> + range(translations_edit_.equal_range(language_id)); + + //If translation already exists + for(translation_values_map::const_iterator it = range.first; it != range.second; ++it) + { + if((*it).second == codepage_id) + return; + } + + translations_edit_.insert(std::make_pair(language_id, codepage_id)); +} + +//Removes translation from translations and strings lists +void version_info_editor::remove_translation(const std::wstring& translation) +{ + std::pair<uint16_t, uint16_t> translation_ids(translation_from_string(translation)); + remove_translation(translation_ids.first, translation_ids.second); +} + +void version_info_editor::remove_translation(uint16_t language_id, uint16_t codepage_id) +{ + { + //Erase string table (if exists) + std::wstringstream ss; + ss << std::hex + << std::setw(4) << std::setfill(L'0') << language_id + << std::setw(4) << std::setfill(L'0') << codepage_id; + + strings_edit_.erase(ss.str()); + } + + //Find and erase translation from translations table + std::pair<translation_values_map::iterator, translation_values_map::iterator> + it_pair = translations_edit_.equal_range(language_id); + + for(translation_values_map::iterator it = it_pair.first; it != it_pair.second; ++it) + { + if((*it).second == codepage_id) + { + translations_edit_.erase(it); + break; + } + } +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/version_info_editor.h b/irdb-lib/pebliss/trunk/pe_lib/version_info_editor.h new file mode 100644 index 0000000000000000000000000000000000000000..2e27d3b28968f044b82da78a62212afb2855bb52 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/version_info_editor.h @@ -0,0 +1,61 @@ +#ifndef pebliss_version_info_editor_h +#define pebliss_version_info_editor_h +#pragma once +#include "version_info_types.h" +#include "version_info_viewer.h" + +namespace pe_bliss +{ + //Helper class to read and edit version information + //lang_string_values_map: map of version info strings with encodings + //translation_values_map: map of translations + class version_info_editor : public version_info_viewer + { + public: + //Default constructor + //strings - version info strings with charsets + //translations - version info translations map + version_info_editor(lang_string_values_map& strings, translation_values_map& translations); + + //Below functions have parameter translation + //If it's empty, the default language translation will be taken + //If there's no default language translation, the first one will be taken + + //Sets company name + void set_company_name(const std::wstring& value, const std::wstring& translation = std::wstring()); + //Sets file description + void set_file_description(const std::wstring& value, const std::wstring& translation = std::wstring()); + //Sets file version + void set_file_version(const std::wstring& value, const std::wstring& translation = std::wstring()); + //Sets internal file name + void set_internal_name(const std::wstring& value, const std::wstring& translation = std::wstring()); + //Sets legal copyright + void set_legal_copyright(const std::wstring& value, const std::wstring& translation = std::wstring()); + //Sets original file name + void set_original_filename(const std::wstring& value, const std::wstring& translation = std::wstring()); + //Sets product name + void set_product_name(const std::wstring& value, const std::wstring& translation = std::wstring()); + //Sets product version + void set_product_version(const std::wstring& value, const std::wstring& translation = std::wstring()); + + //Sets version info property value + //property_name - property name + //value - property value + //If translation does not exist, it will be added to strings and translations lists + //If property does not exist, it will be added + void set_property(const std::wstring& property_name, const std::wstring& value, const std::wstring& translation = std::wstring()); + + //Adds translation to translation list + void add_translation(const std::wstring& translation); + void add_translation(uint16_t language_id, uint16_t codepage_id); + + //Removes translation from translations and strings lists + void remove_translation(const std::wstring& translation); + void remove_translation(uint16_t language_id, uint16_t codepage_id); + + private: + lang_string_values_map& strings_edit_; + translation_values_map& translations_edit_; + }; +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/version_info_types.h b/irdb-lib/pebliss/trunk/pe_lib/version_info_types.h new file mode 100644 index 0000000000000000000000000000000000000000..1525bcf13a4c82f9915eca4abc9770dfd4a7ff4b --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/version_info_types.h @@ -0,0 +1,20 @@ +#ifndef pebliss_version_info_types_h +#define pebliss_version_info_types_h +#pragma once +#include <map> +#include <string> +#include "stdint_defs.h" + +namespace pe_bliss +{ + //Typedef for version info functions: Name - Value + typedef std::map<std::wstring, std::wstring> string_values_map; + //Typedef for version info functions: Language string - String Values Map + //Language String consists of LangID and CharsetID + //E.g. 041904b0 for Russian UNICODE, 040004b0 for Process Default Language UNICODE + typedef std::map<std::wstring, string_values_map> lang_string_values_map; + + //Typedef for version info functions: Language - Character Set + typedef std::multimap<uint16_t, uint16_t> translation_values_map; +} +#endif diff --git a/irdb-lib/pebliss/trunk/pe_lib/version_info_viewer.cpp b/irdb-lib/pebliss/trunk/pe_lib/version_info_viewer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3f6a2573b6b45a85ba28a73c07a954e52f50475d --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/version_info_viewer.cpp @@ -0,0 +1,159 @@ +#include <iomanip> +#include <sstream> +#include "pe_exception.h" +#include "version_info_viewer.h" + +namespace pe_bliss +{ +//Default process language, UNICODE +const std::wstring version_info_viewer::default_language_translation(L"041904b0"); + +//Default constructor +//strings - version info strings with charsets +//translations - version info translations map +version_info_viewer::version_info_viewer(const lang_string_values_map& strings, const translation_values_map& translations) + :strings_(strings), translations_(translations) +{} + +//Below functions have parameter translation +//If it's empty, the default language translation will be taken +//If there's no default language translation, the first one will be taken + +//Returns company name +const std::wstring version_info_viewer::get_company_name(const std::wstring& translation) const +{ + return get_property(L"CompanyName", translation); +} + +//Returns file description +const std::wstring version_info_viewer::get_file_description(const std::wstring& translation) const +{ + return get_property(L"FileDescription", translation); +} + +//Returns file version +const std::wstring version_info_viewer::get_file_version(const std::wstring& translation) const +{ + return get_property(L"FileVersion", translation); +} + +//Returns internal file name +const std::wstring version_info_viewer::get_internal_name(const std::wstring& translation) const +{ + return get_property(L"InternalName", translation); +} + +//Returns legal copyright +const std::wstring version_info_viewer::get_legal_copyright(const std::wstring& translation) const +{ + return get_property(L"LegalCopyright", translation); +} + +//Returns original file name +const std::wstring version_info_viewer::get_original_filename(const std::wstring& translation) const +{ + return get_property(L"OriginalFilename", translation); +} + +//Returns product name +const std::wstring version_info_viewer::get_product_name(const std::wstring& translation) const +{ + return get_property(L"ProductName", translation); +} + +//Returns product version +const std::wstring version_info_viewer::get_product_version(const std::wstring& translation) const +{ + return get_property(L"ProductVersion", translation); +} + +//Returns list of translations in string representation +const version_info_viewer::translation_list version_info_viewer::get_translation_list() const +{ + translation_list ret; + + //Enumerate all translations + for(translation_values_map::const_iterator it = translations_.begin(); it != translations_.end(); ++it) + { + //Create string representation of translation value + std::wstringstream ss; + ss << std::hex + << std::setw(4) << std::setfill(L'0') << (*it).first + << std::setw(4) << std::setfill(L'0') << (*it).second; + + //Save it + ret.push_back(ss.str()); + } + + return ret; +} + +//Returns version info property value +//property_name - required property name +//If throw_if_absent = true, will throw exception if property does not exist +//If throw_if_absent = false, will return empty string if property does not exist +const std::wstring version_info_viewer::get_property(const std::wstring& property_name, const std::wstring& translation, bool throw_if_absent) const +{ + std::wstring ret; + + //If there're no strings + if(strings_.empty()) + { + if(throw_if_absent) + throw pe_exception("Version info string does not exist", pe_exception::version_info_string_does_not_exist); + + return ret; + } + + lang_string_values_map::const_iterator it = strings_.begin(); + + if(translation.empty()) + { + //If no translation was specified + it = strings_.find(default_language_translation); //Find default translation table + if(it == strings_.end()) //If there's no default translation table, take the first one + it = strings_.begin(); + } + else + { + it = strings_.find(translation); //Find specified translation table + if(it == strings_.end()) + { + if(throw_if_absent) + throw pe_exception("Version info string does not exist", pe_exception::version_info_string_does_not_exist); + + return ret; + } + } + + //Find value of the required property + string_values_map::const_iterator str_it = (*it).second.find(property_name); + + if(str_it == (*it).second.end()) + { + if(throw_if_absent) + throw pe_exception("Version info string does not exist", pe_exception::version_info_string_does_not_exist); + + return ret; + } + + ret = (*str_it).second; + + return ret; +} + +//Converts translation HEX-string to pair of language ID and codepage ID +const version_info_viewer::translation_pair version_info_viewer::translation_from_string(const std::wstring& translation) +{ + uint32_t translation_id = 0; + + { + //Convert string to DWORD + std::wstringstream ss; + ss << std::hex << translation; + ss >> translation_id; + } + + return std::make_pair(static_cast<uint16_t>(translation_id >> 16), static_cast<uint16_t>(translation_id & 0xFFFF)); +} +} diff --git a/irdb-lib/pebliss/trunk/pe_lib/version_info_viewer.h b/irdb-lib/pebliss/trunk/pe_lib/version_info_viewer.h new file mode 100644 index 0000000000000000000000000000000000000000..c859d49b83fef7bac5e4a918a1fcc9945925c127 --- /dev/null +++ b/irdb-lib/pebliss/trunk/pe_lib/version_info_viewer.h @@ -0,0 +1,71 @@ +#ifndef pebliss_version_info_viewer_h +#define pebliss_version_info_viewer_h +#pragma once +#include <map> +#include <vector> +#include <string> +#include "pe_resource_viewer.h" +#include "pe_structures.h" +#include "version_info_types.h" + +namespace pe_bliss +{ +//Helper class to read version information +//lang_string_values_map: map of version info strings with encodings +//translation_values_map: map of translations +class version_info_viewer +{ +public: + //Useful typedefs + typedef std::pair<uint16_t, uint16_t> translation_pair; + typedef std::vector<std::wstring> translation_list; + +public: + //Default constructor + //strings - version info strings with charsets + //translations - version info translations map + version_info_viewer(const lang_string_values_map& strings, const translation_values_map& translations); + + //Below functions have parameter translation + //If it's empty, the default language translation will be taken + //If there's no default language translation, the first one will be taken + + //Returns company name + const std::wstring get_company_name(const std::wstring& translation = std::wstring()) const; + //Returns file description + const std::wstring get_file_description(const std::wstring& translation = std::wstring()) const; + //Returns file version + const std::wstring get_file_version(const std::wstring& translation = std::wstring()) const; + //Returns internal file name + const std::wstring get_internal_name(const std::wstring& translation = std::wstring()) const; + //Returns legal copyright + const std::wstring get_legal_copyright(const std::wstring& translation = std::wstring()) const; + //Returns original file name + const std::wstring get_original_filename(const std::wstring& translation = std::wstring()) const; + //Returns product name + const std::wstring get_product_name(const std::wstring& translation = std::wstring()) const; + //Returns product version + const std::wstring get_product_version(const std::wstring& translation = std::wstring()) const; + + //Returns list of translations in string representation + const translation_list get_translation_list() const; + + //Returns version info property value + //property_name - required property name + //If throw_if_absent = true, will throw exception if property does not exist + //If throw_if_absent = false, will return empty string if property does not exist + const std::wstring get_property(const std::wstring& property_name, const std::wstring& translation = std::wstring(), bool throw_if_absent = false) const; + + //Converts translation HEX-string to pair of language ID and codepage ID + static const translation_pair translation_from_string(const std::wstring& translation); + +public: + //Default process language, UNICODE + static const std::wstring default_language_translation; + +private: + const lang_string_values_map& strings_; + const translation_values_map& translations_; +}; +} +#endif diff --git a/irdb-lib/pebliss/trunk/samples/Makefile b/irdb-lib/pebliss/trunk/samples/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..c2502b105bb9f924f017e2fce514bc0b2ca526e6 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/Makefile @@ -0,0 +1,18 @@ +SAMPLES = address_convertions basic_dotnet_viewer basic_info_viewer bound_import_reader debug_info_reader entropy_calculator exception_dir_reader export_adder exports_reader full_pe_rebuilder image_config_editor import_adder imports_reader pe_config_reader pe_realigner pe_rebaser pe_sections_reader pe_stripper relocation_adder relocations_reader resource_editor resource_viewer rich_overlay_stub_reader section_adder sections_and_addresses tls_editor tls_reader +OUTDIR = ./out/ +LIBPATH = ../lib/libpebliss.a +TARGETS = $(foreach sample,$(SAMPLES),$(sample)_sample) +TARGETS_CLEAN = $(foreach sample,$(SAMPLES),$(sample)_clean) + +all: $(TARGETS) + +clean: $(TARGETS_CLEAN) + +$(OUTDIR): + mkdir -p $(OUTDIR) + +%_sample: $(OUTDIR) $(LIBPATH) + $(MAKE) PE_DEBUG=$(PE_DEBUG) -C ./$* + +%_clean: + $(MAKE) -C ./$* clean diff --git a/irdb-lib/pebliss/trunk/samples/address_convertions/Makefile b/irdb-lib/pebliss/trunk/samples/address_convertions/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/address_convertions/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/address_convertions/address_convertions.vcproj b/irdb-lib/pebliss/trunk/samples/address_convertions/address_convertions.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..146d0a5779034cdaadf7f7c73e621ee9c7d761e2 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/address_convertions/address_convertions.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="address_convertions" + ProjectGUID="{642392B3-C763-44C8-91F4-EA90C3651608}" + RootNamespace="address_convertions" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/address_convertions/address_convertions.vcxproj b/irdb-lib/pebliss/trunk/samples/address_convertions/address_convertions.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..4ad28fd6f65da9a4e4b346838ca6dd99f05c2683 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/address_convertions/address_convertions.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{2754B0D6-4A8B-49F4-AB9E-E7306D0DAB32}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>address_convertions</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/address_convertions/address_convertions.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/address_convertions/address_convertions.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/address_convertions/address_convertions.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/address_convertions/main.cpp b/irdb-lib/pebliss/trunk/samples/address_convertions/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cd2f88781121ee8fdd528e7697507dba509f5865 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/address_convertions/main.cpp @@ -0,0 +1,55 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как конвертировать адреÑа Ð´Ð»Ñ PE-файла +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: address_convertions.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + //Получаем ÑпиÑок Ñекций + std::cout << "Reading PE sections..." << std::hex << std::showbase << std::endl << std::endl; + const section_list sections = image.get_image_sections(); + + //ПеречиÑлÑем Ñекции и выводим информацию о них + for(section_list::const_iterator it = sections.begin(); it != sections.end(); ++it) + { + const section& s = *it; //Ð¡ÐµÐºÑ†Ð¸Ñ + std::cout << "Section [" << s.get_name() << "]" << std::endl //Ð˜Ð¼Ñ Ñекции + << " -> RVA: " << s.get_virtual_address() << std::endl //Виртуальный Ð°Ð´Ñ€ÐµÑ (RVA) + << " -> VA: " << image.rva_to_va_64(s.get_virtual_address()) << std::endl //Виртуальный Ð°Ð´Ñ€ÐµÑ (VA) + << " -> File offset: " << image.rva_to_file_offset(s.get_virtual_address()) //Файловое Ñмещение Ñекции, вычиÑленное из ее RVA + << std::endl << std::endl; + } + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/basic_dotnet_viewer/Makefile b/irdb-lib/pebliss/trunk/samples/basic_dotnet_viewer/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/basic_dotnet_viewer/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/basic_dotnet_viewer/basic_dotnet_viewer.vcproj b/irdb-lib/pebliss/trunk/samples/basic_dotnet_viewer/basic_dotnet_viewer.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..7cee484943d3aeea8e07aea492a9e18fb2424ac8 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/basic_dotnet_viewer/basic_dotnet_viewer.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="basic_dotnet_viewer" + ProjectGUID="{DE053D44-F9BD-4C1A-B44B-3157BE27AD02}" + RootNamespace="basic_dotnet_viewer" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/basic_dotnet_viewer/basic_dotnet_viewer.vcxproj b/irdb-lib/pebliss/trunk/samples/basic_dotnet_viewer/basic_dotnet_viewer.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..7e0c09fa7c3d3b7539b92a7527f62e86f5a3e18d --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/basic_dotnet_viewer/basic_dotnet_viewer.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{5E2C4403-4C8B-4773-89A6-61547756ABDC}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>basic_dotnet_viewer</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/basic_dotnet_viewer/basic_dotnet_viewer.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/basic_dotnet_viewer/basic_dotnet_viewer.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/basic_dotnet_viewer/basic_dotnet_viewer.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/basic_dotnet_viewer/main.cpp b/irdb-lib/pebliss/trunk/samples/basic_dotnet_viewer/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..20ddd66a61a45461b76db3477a5e17dd442f7243 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/basic_dotnet_viewer/main.cpp @@ -0,0 +1,69 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как получить базовую информацию о .NET PE-файле +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: basic_dotnet_viewer.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + //ЕÑли образ не .NET, выходим + if(!image.is_dotnet()) + { + std::cout << "Image is not .NET" << std::endl; + return 0; + } + + std::cout << "Reading basic dotnet info..." << std::hex << std::showbase << std::endl << std::endl; + + //Получаем .NET-заголовок PE-файла + const basic_dotnet_info info(get_basic_dotnet_info(image)); + + //Выводим некоторую информацию + std::cout << "Major runtime version: " << info.get_major_runtime_version() << std::endl //ВерÑÐ¸Ñ Ñ€Ð°Ð½Ñ‚Ð°Ð¹Ð¼Ð° + << "Minor runtime version: " << info.get_minor_runtime_version() << std::endl + << "Flags: " << info.get_flags() << std::endl //Флаги + << "RVA of resources: " << info.get_rva_of_resources() << std::endl //RVA реÑурÑов + << "RVA of metadata: " << info.get_rva_of_metadata() << std::endl //RVA метаданных + << "Size of resources: " << info.get_size_of_resources() << std::endl //Размер реÑурÑов + << "Size of metadata: " << info.get_size_of_metadata() << std::endl; //Размер метаданных + + //Определим точку входа .NET + if(info.is_native_entry_point()) + std::cout << "Entry point RVA: "; + else + std::cout << "Entry point token: "; + + std::cout << info.get_entry_point_rva_or_token() << std::endl; + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/basic_info_viewer/Makefile b/irdb-lib/pebliss/trunk/samples/basic_info_viewer/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/basic_info_viewer/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/basic_info_viewer/basic_info_viewer.vcproj b/irdb-lib/pebliss/trunk/samples/basic_info_viewer/basic_info_viewer.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..6cb615b2bee59d71cc0987adfb3f105b7209c3c5 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/basic_info_viewer/basic_info_viewer.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="basic_info_viewer" + ProjectGUID="{7AF45D7B-8341-42CF-B382-B67E1399D8B1}" + RootNamespace="basic_info_viewer" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/basic_info_viewer/basic_info_viewer.vcxproj b/irdb-lib/pebliss/trunk/samples/basic_info_viewer/basic_info_viewer.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..77e9a7d80f1353050946bc819b4b4aacf65d7c18 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/basic_info_viewer/basic_info_viewer.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{71707667-1A10-4B53-AC02-E4AD898AC6E7}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>basic_info_viewer</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/basic_info_viewer/basic_info_viewer.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/basic_info_viewer/basic_info_viewer.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/basic_info_viewer/basic_info_viewer.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/basic_info_viewer/main.cpp b/irdb-lib/pebliss/trunk/samples/basic_info_viewer/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..32573d922ada6a9f5108c1b7203b39240d27aeb3 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/basic_info_viewer/main.cpp @@ -0,0 +1,82 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как получить базовую информацию о PE-файле +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: basic_info_viewer.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + //Фабрика автоматичеÑки получает тип PE-файла и Ñоздает ÑкземплÑÑ€ нужного клаÑÑа, + //но можно получить тип PE-файла и вручную, воÑпользовавшиÑÑŒ одной из перегрузок функции get_pe_type + //ЗдеÑÑŒ мы проÑто выведем уже извеÑтный тип PE-файла: + std::cout << "PE file type: " << (image.get_pe_type() == pe_type_32 ? "PE32 (PE)" : "PE64 (PE+)") << std::endl; + + //ВычиÑлим контрольную Ñумму PE-файла + std::cout << "Calculated checksum: "<< std::hex << std::showbase << calculate_checksum(pe_file) << std::endl; + //Выведем контрольную Ñумму из заголовка файла (Ð´Ð»Ñ Ð½Ðµ-драйверов она обычно равна 0) + std::cout << "Stored checksum: " << image.get_checksum() << std::endl; + + //Выведем характериÑтики PE-файла + std::cout << "Characteristics: " << image.get_characteristics() << std::endl; + + //Выведем Ð°Ð´Ñ€ÐµÑ Ñ‚Ð¾Ñ‡ÐºÐ¸ входа + std::cout << "Entry point: " << image.get_ep() << std::endl; + + //Выведем выравнивание + std::cout << "File alignment: " << image.get_file_alignment() << std::endl; + std::cout << "Section alignment: " << image.get_section_alignment() << std::endl; + + //Выведем базу образа в 64-битном виде (универÑально Ð´Ð»Ñ PE и PE+) + std::cout << "Image base: " << image.get_image_base_64() << std::endl; + + //Выведем подÑиÑтему + std::cout << "Subsystem: " << image.get_subsystem() << std::endl; + std::cout << "Is console: " << (image.is_console() ? "YES" : "NO") << std::endl; + std::cout << "Is windows GUI: " << (image.is_gui() ? "YES" : "NO") << std::endl; + + //Выведем, какие директории еÑÑ‚ÑŒ у файла + std::cout << "Has bound import: " << (image.has_bound_import() ? "YES" : "NO") << std::endl; + std::cout << "Has config: " << (image.has_config() ? "YES" : "NO") << std::endl; + std::cout << "Has debug: " << (image.has_debug() ? "YES" : "NO") << std::endl; + std::cout << "Has delay import: " << (image.has_delay_import() ? "YES" : "NO") << std::endl; + std::cout << "Has exception directory: " << (image.has_exception_directory() ? "YES" : "NO") << std::endl; + std::cout << "Has exports: " << (image.has_exports() ? "YES" : "NO") << std::endl; + std::cout << "Has imports: " << (image.has_imports() ? "YES" : "NO") << std::endl; + std::cout << "Has reloc: " << (image.has_reloc() ? "YES" : "NO") << std::endl; + std::cout << "Has resources: " << (image.has_resources() ? "YES" : "NO") << std::endl; + std::cout << "Has security: " << (image.has_security() ? "YES" : "NO") << std::endl; + std::cout << "Has tls: " << (image.has_tls() ? "YES" : "NO") << std::endl; + std::cout << "Is .NET: " << (image.is_dotnet() ? "YES" : "NO") << std::endl; + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/bound_import_reader/Makefile b/irdb-lib/pebliss/trunk/samples/bound_import_reader/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/bound_import_reader/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/bound_import_reader/bound_import_reader.vcproj b/irdb-lib/pebliss/trunk/samples/bound_import_reader/bound_import_reader.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..b50c696393be17a9fea98657979f338173fb26a4 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/bound_import_reader/bound_import_reader.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="bound_import_reader" + ProjectGUID="{65229ACC-5C9B-429C-B9DA-4710697637EB}" + RootNamespace="bound_import_reader" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/bound_import_reader/bound_import_reader.vcxproj b/irdb-lib/pebliss/trunk/samples/bound_import_reader/bound_import_reader.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..9ab4f6be16a61802a71e3c9d1affd0cb4cb5fed1 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/bound_import_reader/bound_import_reader.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{EFC31F33-D5E4-4356-A892-18CADABCFCCF}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>bound_import_reader</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/bound_import_reader/bound_import_reader.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/bound_import_reader/bound_import_reader.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/bound_import_reader/bound_import_reader.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/bound_import_reader/main.cpp b/irdb-lib/pebliss/trunk/samples/bound_import_reader/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bdd119de7d4bc77c0c977471e378b5f32ecb4b54 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/bound_import_reader/main.cpp @@ -0,0 +1,68 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как Ñчитать и получить информацию о привÑзанном импорте PE-файла +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: bound_import_reader.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + //Проверим, еÑÑ‚ÑŒ ли привÑзанный импорт у PE-файла + if(!image.has_bound_import()) + { + std::cout << "Image has no bound import" << std::endl; + return 0; + } + + std::cout << "Reading PE bound import..." << std::hex << std::showbase << std::endl << std::endl; + + //Получаем информацию о привÑзанном импорте + const bound_import_module_list modules(get_bound_import_module_list(image)); + + //Выведем импортируемые модули и форварды + for(bound_import_module_list::const_iterator it = modules.begin(); it != modules.end(); ++it) + { + const bound_import& import = *it; //Ð˜Ð¼Ð¿Ð¾Ñ€Ñ‚Ð¸Ñ€ÑƒÐµÐ¼Ð°Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñ‚ÐµÐºÐ° + std::cout << "Module: " << import.get_module_name() << std::endl //Ð˜Ð¼Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñ + << "Timestamp: " << import.get_timestamp() << std::endl; //Ð’Ñ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð¼ÐµÑ‚ÐºÐ° + + //ПеречиÑлим форварды Ð´Ð»Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñ - модули, на которые ÑÑылаетÑÑ Ñтот: + const bound_import::ref_list& refs = import.get_module_ref_list(); + for(bound_import::ref_list::const_iterator ref_it = refs.begin(); ref_it != refs.end(); ++ref_it) + { + std::cout << " -> Module: " << (*ref_it).get_module_name() << std::endl //Ð˜Ð¼Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñ, на который ÑÑылаетÑÑ Ñ€Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÑкий модуль + << " -> Timestamp: " << (*ref_it).get_timestamp() << std::endl; //Ð’Ñ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð¼ÐµÑ‚ÐºÐ° + } + } + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/debug_info_reader/Makefile b/irdb-lib/pebliss/trunk/samples/debug_info_reader/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/debug_info_reader/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/debug_info_reader/debug_info_reader.vcproj b/irdb-lib/pebliss/trunk/samples/debug_info_reader/debug_info_reader.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..4a462be617a8eec5d3819e0a759f4a9519fdf2cd --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/debug_info_reader/debug_info_reader.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="debug_info_reader" + ProjectGUID="{218033A7-A6D0-45B4-88F6-F4FF5DD25207}" + RootNamespace="debug_info_reader" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/debug_info_reader/debug_info_reader.vcxproj b/irdb-lib/pebliss/trunk/samples/debug_info_reader/debug_info_reader.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..391d23d4e814531e3ace2a8617effd8877361baf --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/debug_info_reader/debug_info_reader.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{332A1418-E89B-4658-9F7F-8D219ED776EA}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>debug_info_reader</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/debug_info_reader/debug_info_reader.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/debug_info_reader/debug_info_reader.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/debug_info_reader/debug_info_reader.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/debug_info_reader/main.cpp b/irdb-lib/pebliss/trunk/samples/debug_info_reader/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a157f0ad06964f84b4bad7b1b9b65f27aa86c554 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/debug_info_reader/main.cpp @@ -0,0 +1,191 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как Ñчитать и обработать отладочную информацию PE или PE+ файла +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: debug_info_reader.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + //Проверим, еÑÑ‚ÑŒ ли Ð¾Ñ‚Ð»Ð°Ð´Ð¾Ñ‡Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ñƒ файла + if(!image.has_debug()) + { + std::cout << "Image has no debug information" << std::endl; + return 0; + } + + std::cout << "Reading PE debug information..." << std::hex << std::showbase << std::endl << std::endl; + + //Получаем отладочную информацию, находÑщуюÑÑ Ð² PE-файле + const debug_info_list info_list(get_debug_information(image)); + + //ПеречиÑолÑем вÑе отладочные запиÑи + for(debug_info_list::const_iterator it = info_list.begin(); it != info_list.end(); ++it) + { + const debug_info& info = *it; + + //Выведем тип отладочной информации + std::cout << "Debug info type: "; + switch(info.get_type()) + { + case debug_info::debug_type_borland: + std::cout << "Borland"; + break; + + case debug_info::debug_type_clsid: + std::cout << "CLSID"; + break; + + case debug_info::debug_type_codeview: + std::cout << "CodeView"; + break; + + case debug_info::debug_type_coff: + std::cout << "COFF"; + break; + + case debug_info::debug_type_exception: + std::cout << "Exception"; + break; + + case debug_info::debug_type_fixup: + std::cout << "Fixup"; + break; + + case debug_info::debug_type_fpo: + std::cout << "FPO"; + break; + + case debug_info::debug_type_misc: + std::cout << "Misc"; + break; + + case debug_info::debug_type_omap_from_src: + std::cout << "OMAP from src"; + break; + + case debug_info::debug_type_omap_to_src: + std::cout << "OMAP to src"; + break; + + default: + std::cout << "Unknown"; + } + + std::cout << std::endl; + + std::cout << "Timestamp: " << info.get_time_stamp() << std::endl << std::endl; //Ð’Ñ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð¼ÐµÑ‚ÐºÐ° + + //Получим дополнительную информацию, еÑли Ñ‚Ð°ÐºÐ¾Ð²Ð°Ñ Ð¸Ð¼ÐµÐµÑ‚ÑÑ + switch(info.get_advanced_info_type()) + { + case debug_info::advanced_info_pdb_7_0: + { + std::cout << "Advanced info - PDB 7.0" << std::endl; //PDB 7.0 + pdb_7_0_info advanced = info.get_advanced_debug_info<pdb_7_0_info>(); + std::cout << "PDB file name: " << advanced.get_pdb_file_name() << std::endl; //Ð˜Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° PDB + std::cout << "Age: " << advanced.get_age() << std::endl; //ВозраÑÑ‚ (билд) + } + break; + + case debug_info::advanced_info_pdb_2_0: + { + std::cout << "Advanced info - PDB 2.0" << std::endl; //PDB 2.0 + pdb_2_0_info advanced = info.get_advanced_debug_info<pdb_2_0_info>(); + std::cout << "PDB file name: " << advanced.get_pdb_file_name() << std::endl; //Ð˜Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° PDB + std::cout << "Age: " << advanced.get_age() << std::endl; //ВозраÑÑ‚ (билд) + } + break; + + case debug_info::advanced_info_misc: + { + std::cout << "Advanced info - Misc" << std::endl; //Misc + misc_debug_info advanced = info.get_advanced_debug_info<misc_debug_info>(); + std::cout << "Advanced data is EXE name: " << (advanced.is_exe_name() ? "YES" : "NO") << std::endl; //ЕÑли данные в Ñтруктуре - Ð¸Ð¼Ñ EXE-файла + + //Выведем Ñтроковые данные + if(advanced.is_unicode()) + std::wcout << advanced.get_data_unicode() << std::endl; + else + std::cout << advanced.get_data_ansi() << std::endl; + } + break; + + case debug_info::advanced_info_coff: + { + std::cout << "Advanced info - COFF" << std::endl; //COFF + coff_debug_info advanced = info.get_advanced_debug_info<coff_debug_info>(); + std::cout << "LVA to first line number: " << advanced.get_lva_to_first_line_number() << std::endl; //ÐÐ´Ñ€ÐµÑ Ð¿ÐµÑ€Ð²Ð¾Ð³Ð¾ Ñлемента в маÑÑиве номеров Ñтрок + std::cout << "LVA to first symbol: " << advanced.get_lva_to_first_symbol() << std::endl; //ÐÐ´Ñ€ÐµÑ Ð¿ÐµÑ€Ð²Ð¾Ð³Ð¾ Ñлемента в маÑÑиве Ñимволов + std::cout << "Number of line numbers: " << advanced.get_number_of_line_numbers() << std::endl; //КоличеÑтво номеров Ñтрок + std::cout << "Number of symbols: " << advanced.get_number_of_symbols() << std::endl; //КоличеÑтво номеров Ñтрок + std::cout << "RVA of first byte of code: " << advanced.get_rva_to_first_byte_of_code() << std::endl; //RVA первого байта кода + std::cout << "RVA of first byte of data: " << advanced.get_rva_to_first_byte_of_data() << std::endl; //RVA первого байта данных + std::cout << "RVA of last byte of code " << advanced.get_rva_to_last_byte_of_code() << std::endl; //RVA поÑледнего байта кода + std::cout << "RVA of last byte of data: " << advanced.get_rva_to_last_byte_of_data() << std::endl; //RVA поÑледнего байта данных + + std::cout << std::endl << "Symbol list:" << std::endl; + + //Получим ÑпиÑок Ñимволов + const coff_debug_info::coff_symbols_list& symbols = advanced.get_symbols(); + for(coff_debug_info::coff_symbols_list::const_iterator symbol_it = symbols.begin(); symbol_it != symbols.end(); ++symbol_it) + { + //Выведем информацию об отладочных Ñимволах + const coff_debug_info::coff_symbol& symbol = *symbol_it; //Отладочный Ñимвол + std::cout << "Index: " << symbol.get_index() << std::endl + << "RVA: " << symbol.get_rva() << std::endl + << "Section number: " << symbol.get_section_number() << std::endl + << "Storage class: " << symbol.get_storage_class() << std::endl + << "Type: " << symbol.get_type() << std::endl + << "Is file: " << (symbol.is_file() ? "YES" : "NO") << std::endl + << "Symbol: " << symbol.get_symbol() << std::endl << std::endl; + } + } + break; + + case debug_info::advanced_info_codeview_4_0: + std::cout << "Advanced info - CodeView 4.0" << std::endl; //CodeView 4.0 + break; + + case debug_info::advanced_info_codeview_5_0: + std::cout << "Advanced info - CodeView 5.0" << std::endl; //CodeView 5.0 + break; + + default: + break; + } + + std::cout << std::endl << "==========" << std::endl << std::endl; + } + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/entropy_calculator/Makefile b/irdb-lib/pebliss/trunk/samples/entropy_calculator/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/entropy_calculator/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/entropy_calculator/entropy_calculator.vcproj b/irdb-lib/pebliss/trunk/samples/entropy_calculator/entropy_calculator.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..aad775d02469766280cf65203586b1bd181361d0 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/entropy_calculator/entropy_calculator.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="entropy_calculator" + ProjectGUID="{111344DB-1F0B-460E-91DD-9DD36D2238A4}" + RootNamespace="entropy_calculator" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/entropy_calculator/entropy_calculator.vcxproj b/irdb-lib/pebliss/trunk/samples/entropy_calculator/entropy_calculator.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..2fe9def4e9fe6a88fe2877254a00eecabb9ea4b7 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/entropy_calculator/entropy_calculator.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{48879460-0DF8-491E-BD1D-A489C8D92746}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>entropy_calculator</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/entropy_calculator/entropy_calculator.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/entropy_calculator/entropy_calculator.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/entropy_calculator/entropy_calculator.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/entropy_calculator/main.cpp b/irdb-lib/pebliss/trunk/samples/entropy_calculator/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3f7a1660f5fc2e7827bf9db44e65758e321aa7c6 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/entropy_calculator/main.cpp @@ -0,0 +1,54 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как поÑчитать Ñнтропию файла и Ñекций PE +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: entropy_calculator.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + + try + { + //Считаем Ñнтропию файла + std::cout << "File entropy: " << entropy_calculator::calculate_entropy(pe_file) << std::endl; + + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + std::cout << "Sections entropy: " << entropy_calculator::calculate_entropy(image) << std::endl; //Считаем Ñнтропию вÑех Ñекций + + //ПеречиÑлÑем Ñекции и Ñчитаем их Ñнтропию по отдельноÑти + const section_list sections = image.get_image_sections(); + for(section_list::const_iterator it = sections.begin(); it != sections.end(); ++it) + { + if(!(*it).empty()) //ЕÑли ÑÐµÐºÑ†Ð¸Ñ Ð½Ðµ пуÑта - поÑчитаем ее Ñнтропию + std::cout << "Section [" << (*it).get_name() << "] entropy: " << entropy_calculator::calculate_entropy(*it) << std::endl; + } + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/exception_dir_reader/Makefile b/irdb-lib/pebliss/trunk/samples/exception_dir_reader/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/exception_dir_reader/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/exception_dir_reader/exception_dir_reader.vcproj b/irdb-lib/pebliss/trunk/samples/exception_dir_reader/exception_dir_reader.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..28f0fd5487e7993ceff6850a62b4eeaedfe8ddf1 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/exception_dir_reader/exception_dir_reader.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="exception_dir_reader" + ProjectGUID="{D8E2714A-11A7-478D-A966-EF6968FFB766}" + RootNamespace="exception_dir_reader" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/exception_dir_reader/exception_dir_reader.vcxproj b/irdb-lib/pebliss/trunk/samples/exception_dir_reader/exception_dir_reader.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..b1f0c53dd6e885ca0405bd10d29c39d0c672aff4 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/exception_dir_reader/exception_dir_reader.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{EFAF41AB-C77D-4819-996E-4F6C305553A5}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>exception_dir_reader</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/exception_dir_reader/exception_dir_reader.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/exception_dir_reader/exception_dir_reader.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/exception_dir_reader/exception_dir_reader.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/exception_dir_reader/main.cpp b/irdb-lib/pebliss/trunk/samples/exception_dir_reader/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8a29d35cad0276532f2dc4197c8b981c1ff6e67a --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/exception_dir_reader/main.cpp @@ -0,0 +1,71 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как Ñчитать и получить информацию о директории иÑключений +//Она ÑущеÑтвует только Ð´Ð»Ñ 64-разрÑдных PE-файлов (PE+) +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: exception_dir_reader.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + //Проверим, еÑÑ‚ÑŒ ли Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ð¸ об иÑключениÑÑ… у PE-файла + if(!image.has_exception_directory()) + { + std::cout << "Image has no exception directory" << std::endl; + return 0; + } + + std::cout << "Reading exception directory..." << std::hex << std::showbase << std::endl << std::endl; + + //Получаем информацию из exception directory + const exception_entry_list info(get_exception_directory_data(image)); + + //Выведем запиÑи из exception directory + //Подробное опиÑание вÑех Ñтих Ñтруктур еÑÑ‚ÑŒ в MSDN + for(exception_entry_list::const_iterator it = info.begin(); it != info.end(); ++it) + { + const exception_entry& entry = *it; //ЗапиÑÑŒ из таблицы + + //Выведем информацию + std::cout << "Addresses: [" << entry.get_begin_address() << ":" << entry.get_end_address() << "]:" << std::endl + << "Flags: " << static_cast<unsigned long>(entry.get_flags()) << std::endl + << "Frame pointer register number: " << static_cast<unsigned long>(entry.get_frame_pointer_register_number()) << std::endl + << "Number of unwind slots: " << static_cast<unsigned long>(entry.get_number_of_unwind_slots()) << std::endl + << "Scaled RSP offset: " << static_cast<unsigned long>(entry.get_scaled_rsp_offset()) << std::endl + << "Size of prolog: " << static_cast<unsigned long>(entry.get_size_of_prolog()) << std::endl + << "Unwind info address: " << entry.get_unwind_info_address() << std::endl + << "Unwind info version: " << static_cast<unsigned long>(entry.get_unwind_info_version()) << std::endl + << std::endl; + } + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/export_adder/Makefile b/irdb-lib/pebliss/trunk/samples/export_adder/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/export_adder/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/export_adder/export_adder.vcproj b/irdb-lib/pebliss/trunk/samples/export_adder/export_adder.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..2579b13f22c32669107a2c2131a1499ba1da1d01 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/export_adder/export_adder.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="export_adder" + ProjectGUID="{4459EB9F-0332-46C4-BF60-6CECA73C7D17}" + RootNamespace="export_adder" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/export_adder/export_adder.vcxproj b/irdb-lib/pebliss/trunk/samples/export_adder/export_adder.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..6cec6d1b85e2bc7da79c99adf4db88483645def7 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/export_adder/export_adder.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{17C01A93-C7F0-49EB-A9A0-81F5E06779C3}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>export_adder</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/export_adder/export_adder.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/export_adder/export_adder.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/export_adder/export_adder.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/export_adder/main.cpp b/irdb-lib/pebliss/trunk/samples/export_adder/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c7aacbff57a9d166945df209795d86eb69481248 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/export_adder/main.cpp @@ -0,0 +1,101 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как добавить новый ÑкÑпорт в таблицу ÑкÑпорта PE-файла +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: export_adder.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + //Получим ÑпиÑок ÑкÑпортируемых функций и информацию об ÑкÑпорте + export_info info; + exported_functions_list exports; + + //ЕÑли ÑкÑпортов у файла нет, Ñтот вызов броÑит иÑключение, но Ñто не значит, что мы + //не можем Ñоздать таблицу ÑкÑпортов Ñ Ð½ÑƒÐ»Ñ + try + { + exports = get_exported_functions(image, info); + } + catch(const pe_exception&) + { + //Ðет таблицы ÑкÑпортов, или она ÐºÑ€Ð¸Ð²Ð°Ñ + //Создадим информацию об ÑкÑпортах вручную + info.set_name("MySuperLib.dll"); + info.set_ordinal_base(5); + } + + //Создаем новую ÑкÑпортируемую функцию + exported_function func; + func.set_name("SuperKernelCall"); //Ð˜Ð¼Ñ ÑкÑпортируемой функции + func.set_rva(0x123); //ОтноÑительный Ð°Ð´Ñ€ÐµÑ Ñ‚Ð¾Ñ‡ÐºÐ¸ входа ÑкÑпортируемой функции (некорректный, чиÑто Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð¼ÐµÑ€Ð°) + + //Ðеобходимо вычиÑлить ординал функции, которую мы добавлÑем, чтобы не было повторных + //Ð”Ð»Ñ Ñтого еÑÑ‚ÑŒ вÑÐ¿Ð¾Ð¼Ð¾Ð³Ð°Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ + func.set_ordinal(get_export_ordinal_limits(exports).second + 1); //Сделаем наш ординал = макÑимальный ординал Ñреди ÑущеÑтвующих ÑкÑпортов + 1 + exports.push_back(func); //Добавим функцию к ÑкÑпортам + + //Можно редактировать и ÑущеÑтвующие ÑкÑпорты + //или изменить информацию об ÑкÑпортах (info) + //Ðо мы проÑто переÑоберем таблицу ÑкÑпортов + //Она будет иметь больший размер, чем до нашего редактированиÑ, + //поÑтому запишем ее в новую Ñекцию, чтобы вÑе помеÑтилоÑÑŒ + //(мы не можем раÑширÑÑ‚ÑŒ ÑущеÑтвующие Ñекции, еÑли только ÑÐµÐºÑ†Ð¸Ñ Ð½Ðµ в Ñамом конце файла) + section new_exports; + new_exports.get_raw_data().resize(1); //Мы не можем добавлÑÑ‚ÑŒ пуÑтые Ñекции, поÑтому пуÑÑ‚ÑŒ у нее будет начальный размер данных 1 + new_exports.set_name("new_exp"); //Ð˜Ð¼Ñ Ñекции + new_exports.readable(true); //ДоÑтупна на чтение + section& attached_section = image.add_section(new_exports); //Добавим Ñекцию и получим ÑÑылку на добавленную Ñекцию Ñ Ð¿Ñ€Ð¾Ñчитанными размерами + + rebuild_exports(image, info, exports, attached_section); //ПереÑобираем ÑкÑпорты, раÑположив их Ñ Ð½Ð°Ñ‡Ð°Ð»Ð° новой Ñекции и запиÑав новые данные таблиц ÑкÑпорта в PE-заголовок + + //Создаем новый PE-файл + std::string base_file_name(argv[1]); + std::string::size_type slash_pos; + if((slash_pos = base_file_name.find_last_of("/\\")) != std::string::npos) + base_file_name = base_file_name.substr(slash_pos + 1); + + base_file_name = "new_" + base_file_name; + std::ofstream new_pe_file(base_file_name.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); + if(!new_pe_file) + { + std::cout << "Cannot create " << base_file_name << std::endl; + return -1; + } + + //ПереÑобираем PE-файл + rebuild_pe(image, new_pe_file); + + std::cout << "PE was rebuilt and saved to " << base_file_name << std::endl; + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/exports_reader/Makefile b/irdb-lib/pebliss/trunk/samples/exports_reader/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/exports_reader/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/exports_reader/exports_reader.vcproj b/irdb-lib/pebliss/trunk/samples/exports_reader/exports_reader.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..c82d6c85b739f63c7f68cc5241b77f48c3e72265 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/exports_reader/exports_reader.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="exports_reader" + ProjectGUID="{AC7C3A84-2F81-4B22-B27E-50A9D4C750E2}" + RootNamespace="exports_reader" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/exports_reader/exports_reader.vcxproj b/irdb-lib/pebliss/trunk/samples/exports_reader/exports_reader.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..bce82ae68f41755162866d417c2516c6679abc17 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/exports_reader/exports_reader.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{32ABD41F-7BCE-43E0-853E-21E16260EDB7}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>exports_reader</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/exports_reader/exports_reader.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/exports_reader/exports_reader.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/exports_reader/exports_reader.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/exports_reader/main.cpp b/irdb-lib/pebliss/trunk/samples/exports_reader/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dba289971a0eda42342b16c34e6b2a5af0cfbcb7 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/exports_reader/main.cpp @@ -0,0 +1,78 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как Ñчитать и получить информацию об ÑкÑпортах PE или PE+ файла +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: exports_reader.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + //Проверим, еÑÑ‚ÑŒ ли ÑкÑпорты у PE-файла + if(!image.has_exports()) + { + std::cout << "Image has no exports" << std::endl; + return 0; + } + + std::cout << "Reading PE exports..." << std::hex << std::showbase << std::endl << std::endl; + + //Получаем полную информацию об ÑкÑпортах и ÑпиÑок ÑкÑпортируемых функций + export_info info; + const exported_functions_list exports = get_exported_functions(image, info); + + //Выведем некоторую информацию об ÑкÑпорте: + std::cout << "Export info" << std::endl + << "Library name: " << info.get_name() << std::endl //Ð˜Ð¼Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñ‚ÐµÐºÐ¸ + << "Timestamp: " << info.get_timestamp() << std::endl //Ð’Ñ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð¼ÐµÑ‚ÐºÐ° + << "Ordinal base: " << info.get_ordinal_base() << std::endl //База ординалов + << std::endl; + + //ПеречиÑлÑем Ñекции и выводим информацию о них + for(exported_functions_list::const_iterator it = exports.begin(); it != exports.end(); ++it) + { + const exported_function& func = *it; //ÐкÑÐ¿Ð¾Ñ€Ñ‚Ð¸Ñ€ÑƒÐµÐ¼Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ + std::cout << "[+] "; + if(func.has_name()) //ЕÑли Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¸Ð¼ÐµÐµÑ‚ имÑ, выведем его и ординал имени + std::cout << func.get_name() << ", name ordinal: " << func.get_name_ordinal() << " "; + + //Ординал функции + std::cout << "ORD: " << func.get_ordinal(); + + //ЕÑли Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ - форвард (переадреÑÐ°Ñ†Ð¸Ñ Ð² другую DLL), выведем Ð¸Ð¼Ñ Ñ„Ð¾Ñ€Ð²Ð°Ñ€Ð´Ð° + if(func.is_forwarded()) + std::cout << std::endl << " -> " << func.get_forwarded_name(); + + std::cout << std::endl; + } + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/full_pe_rebuilder/Makefile b/irdb-lib/pebliss/trunk/samples/full_pe_rebuilder/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/full_pe_rebuilder/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/full_pe_rebuilder/full_pe_rebuilder.vcproj b/irdb-lib/pebliss/trunk/samples/full_pe_rebuilder/full_pe_rebuilder.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..5ea82bbe961a33d0f052ff9a02b03c77c3ea41c1 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/full_pe_rebuilder/full_pe_rebuilder.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="full_pe_rebuilder" + ProjectGUID="{F61AB18A-8E8B-43D1-91B2-D6A2A297FDD6}" + RootNamespace="full_pe_rebuilder" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/full_pe_rebuilder/full_pe_rebuilder.vcxproj b/irdb-lib/pebliss/trunk/samples/full_pe_rebuilder/full_pe_rebuilder.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..06536189d4688632d5889ea505eca9eda76a7f36 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/full_pe_rebuilder/full_pe_rebuilder.vcxproj @@ -0,0 +1,154 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{D7F6EE93-F88A-4B66-8761-87EC844E20C5}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>full_pe_rebuilder</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/full_pe_rebuilder/full_pe_rebuilder.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/full_pe_rebuilder/full_pe_rebuilder.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/full_pe_rebuilder/full_pe_rebuilder.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/full_pe_rebuilder/main.cpp b/irdb-lib/pebliss/trunk/samples/full_pe_rebuilder/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b5922babe4904a2fc7f84af9ed04d53bc214206a --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/full_pe_rebuilder/main.cpp @@ -0,0 +1,109 @@ +#include <iostream> +#include <fstream> +#include <sstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как Ñ Ð½ÑƒÐ»Ñ Ñоздать PE-файл +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: full_pe_rebuilder.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Ðовый образ, который мы Ñоздадим из открытого Ñ Ð½ÑƒÐ»Ñ + std::auto_ptr<pe_base> new_image; + + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + //Создаем новый пуÑтой образ + new_image.reset(image.get_pe_type() == pe_type_32 + ? static_cast<pe_base*>(new pe_base(pe_properties_32(), image.get_section_alignment())) + : static_cast<pe_base*>(new pe_base(pe_properties_64(), image.get_section_alignment()))); + + //Копируем важные параметры Ñтарого образа в новый + new_image->set_characteristics(image.get_characteristics()); + new_image->set_dll_characteristics(image.get_dll_characteristics()); + new_image->set_file_alignment(image.get_file_alignment()); + new_image->set_heap_size_commit(image.get_heap_size_commit_64()); + new_image->set_heap_size_reserve(image.get_heap_size_reserve_64()); + new_image->set_stack_size_commit(image.get_stack_size_commit_64()); + new_image->set_stack_size_reserve(image.get_stack_size_reserve_64()); + new_image->set_image_base_64(image.get_image_base_64()); + new_image->set_ep(image.get_ep()); + new_image->set_number_of_rvas_and_sizes(new_image->get_number_of_rvas_and_sizes()); + new_image->set_subsystem(image.get_subsystem()); + + //Копируем вÑе ÑущеÑтвующие директории + for(unsigned long i = 0; i < image.get_number_of_rvas_and_sizes(); ++i) + { + new_image->set_directory_rva(i, image.get_directory_rva(i)); + new_image->set_directory_size(i, image.get_directory_size(i)); + } + + //Копируем данные Ñекций + { + const section_list& pe_sections = image.get_image_sections(); + for(section_list::const_iterator it = pe_sections.begin(); it != pe_sections.end(); ++it) + new_image->set_section_virtual_size(new_image->add_section(*it), (*it).get_virtual_size()); + } + } + + + //ПроÑчитаем контрольную Ñумму нового PE-файла + //и Ñохраним ее (Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð¼ÐµÑ€Ð°) + { + std::stringstream temp_pe(std::ios::out | std::ios::in | std::ios::binary); + rebuild_pe(*new_image, temp_pe); + new_image->set_checksum(calculate_checksum(temp_pe)); + } + + + //Создаем новый PE-файл + std::string base_file_name(argv[1]); + std::string::size_type slash_pos; + if((slash_pos = base_file_name.find_last_of("/\\")) != std::string::npos) + base_file_name = base_file_name.substr(slash_pos + 1); + + base_file_name = "new_" + base_file_name; + std::ofstream new_pe_file(base_file_name.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); + if(!new_pe_file) + { + std::cout << "Cannot create " << base_file_name << std::endl; + return -1; + } + + new_image->set_stub_overlay("alalalalala alalalala!!! alalalala alalalalalala!!!!!!"); + + //ПереÑобираем PE-файл из нового обраща + rebuild_pe(*new_image, new_pe_file); + + std::cout << "PE was rebuilt and saved to " << base_file_name << std::endl; + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/image_config_editor/Makefile b/irdb-lib/pebliss/trunk/samples/image_config_editor/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/image_config_editor/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/image_config_editor/image_config_editor.vcproj b/irdb-lib/pebliss/trunk/samples/image_config_editor/image_config_editor.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..7296d74716c1e587dd38cda99b2fc44bc682feec --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/image_config_editor/image_config_editor.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="image_config_editor" + ProjectGUID="{22788F46-AB6B-4278-B1C0-ED220AE85F4A}" + RootNamespace="image_config_editor" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/image_config_editor/image_config_editor.vcxproj b/irdb-lib/pebliss/trunk/samples/image_config_editor/image_config_editor.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..777d961c811f663da3f0e0331a646c501a44844b --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/image_config_editor/image_config_editor.vcxproj @@ -0,0 +1,154 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{48B99169-44E6-41E5-A681-78243B885E86}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>image_config_editor</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/image_config_editor/image_config_editor.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/image_config_editor/image_config_editor.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/image_config_editor/image_config_editor.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/image_config_editor/main.cpp b/irdb-lib/pebliss/trunk/samples/image_config_editor/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..09cf4187d5a4b2b15a609e9f961825a0287026b3 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/image_config_editor/main.cpp @@ -0,0 +1,82 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как переÑобрать директорию Load Config у PE-файла +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: image_config_editor.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + //Получим информацию о директории Load Config + image_config_info info(get_image_config(image)); + + //Ðо переÑоберем Ñту директорию, раÑположив ее в новой Ñекции + section load_config; + load_config.get_raw_data().resize(1); //Мы не можем добавлÑÑ‚ÑŒ пуÑтые Ñекции, поÑтому пуÑÑ‚ÑŒ у нее будет начальный размер данных 1 + load_config.set_name("load_cfg"); //Ð˜Ð¼Ñ Ñекции + load_config.readable(true).writeable(true); //ДоÑтупна на чтение и запиÑÑŒ + section& attached_section = image.add_section(load_config); //Добавим Ñекцию и получим ÑÑылку на добавленную Ñекцию Ñ Ð¿Ñ€Ð¾Ñчитанными размерами + + //ЕÑли у файла была таблица SE Handler'ов + if(info.get_se_handler_table_va()) + info.add_se_handler_rva(0x7777); //Добавим новый SE Handler в таблицу (проÑто Ð´Ð»Ñ Ñ‚ÐµÑта) + + //ЕÑли у файла не ÑущеÑтвовало таблицы Lock-префикÑов, добавим ее + //(также Ð´Ð»Ñ Ñ‚ÐµÑта) + if(!info.get_lock_prefix_table_va()) + info.add_lock_prefix_rva(0x9999); + + //ПереÑобираем директорию Image Load Config, переÑобираем таблицу Lock-префикÑов, еÑли она имелаÑÑŒ, а также + //таблицу SE Handler'ов, еÑли она еÑÑ‚ÑŒ + rebuild_image_config(image, info, attached_section, 1); + + //Создаем новый PE-файл + std::string base_file_name(argv[1]); + std::string::size_type slash_pos; + if((slash_pos = base_file_name.find_last_of("/\\")) != std::string::npos) + base_file_name = base_file_name.substr(slash_pos + 1); + + base_file_name = "new_" + base_file_name; + std::ofstream new_pe_file(base_file_name.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); + if(!new_pe_file) + { + std::cout << "Cannot create " << base_file_name << std::endl; + return -1; + } + + //ПереÑобираем PE-файл + rebuild_pe(image, new_pe_file); + + std::cout << "PE was rebuilt and saved to " << base_file_name << std::endl; + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/import_adder/Makefile b/irdb-lib/pebliss/trunk/samples/import_adder/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/import_adder/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/import_adder/import_adder.vcproj b/irdb-lib/pebliss/trunk/samples/import_adder/import_adder.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..b7a6aebc3a98ea66a3f1f952700aabde3c591a91 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/import_adder/import_adder.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="import_adder" + ProjectGUID="{5303D6F1-D667-4E92-A501-8B396252156F}" + RootNamespace="import_adder" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/import_adder/import_adder.vcxproj b/irdb-lib/pebliss/trunk/samples/import_adder/import_adder.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..2cad57a3e6b0a64c722168f196a8c867489bedff --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/import_adder/import_adder.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{EE56AFB0-A1C4-4F6D-8F90-0DB5A17C5C59}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>import_adder</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/import_adder/import_adder.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/import_adder/import_adder.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/import_adder/import_adder.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/import_adder/main.cpp b/irdb-lib/pebliss/trunk/samples/import_adder/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6e57d66557eccf8b9aea51315b9a90ea01820466 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/import_adder/main.cpp @@ -0,0 +1,100 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как добавить новый импорт в таблицу импорта PE-файла +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: import_adder.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + //Получим ÑпиÑок импортируемых библиотек и функций + imported_functions_list imports(get_imported_functions(image)); + + //Создадим новую библиотеку, из которой будем импортировать функции + import_library new_lib; + new_lib.set_name("kaimi_dx.dll"); //ПуÑÑ‚ÑŒ Ñто будет kaimi_dx.dll + + //Добавим к ней пару импортов функций + imported_function func; + func.set_name("Tralala"); //Один импорт - по имени Tralala + func.set_iat_va(0x1); //Запишем ненулевой абÑолютный Ð°Ð´Ñ€ÐµÑ Ð² import address table + + imported_function func2; + func2.set_ordinal(5); //Другой импорт - по ординалу 5 + func2.set_iat_va(0x2); //Запишем ненулевой абÑолютный Ð°Ð´Ñ€ÐµÑ Ð² import address table + + //Мы указали некорректное Ñодержимое (0x1 и 0x2) Ð´Ð»Ñ Ñчеек, в которые будут запиÑаны адреÑа импортируемых функций + //Ðто не имеет Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð² общем Ñлучае, потому что Ñти Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð²Ñегда перепиÑываютÑÑ Ð·Ð°Ð³Ñ€ÑƒÐ·Ñ‡Ð¸ÐºÐ¾Ð¼ + //Ðти адреÑа важны только в том Ñлучае, еÑли exe-файл имеет привÑзанный импорт + + //Добавим импорты + new_lib.add_import(func); + new_lib.add_import(func2); + imports.push_back(new_lib); //Добавим импортированную библиотеку к импортам + + //Можно редактировать и ÑущеÑтвующие импорты + + //Ðо мы проÑто переÑоберем таблицу импортов + //Она будет иметь больший размер, чем до нашего редактированиÑ, + //поÑтому запишем ее в новую Ñекцию, чтобы вÑе помеÑтилоÑÑŒ + //(мы не можем раÑширÑÑ‚ÑŒ ÑущеÑтвующие Ñекции, еÑли только ÑÐµÐºÑ†Ð¸Ñ Ð½Ðµ в Ñамом конце файла) + section new_imports; + new_imports.get_raw_data().resize(1); //Мы не можем добавлÑÑ‚ÑŒ пуÑтые Ñекции, поÑтому пуÑÑ‚ÑŒ у нее будет начальный размер данных 1 + new_imports.set_name("new_imp"); //Ð˜Ð¼Ñ Ñекции + new_imports.readable(true).writeable(true); //ДоÑтупна на чтение и запиÑÑŒ + section& attached_section = image.add_section(new_imports); //Добавим Ñекцию и получим ÑÑылку на добавленную Ñекцию Ñ Ð¿Ñ€Ð¾Ñчитанными размерами + + //Структура, Ð¾Ñ‚Ð²ÐµÑ‡Ð°ÑŽÑ‰Ð°Ñ Ð·Ð° наÑтройки переÑборщика импортов + import_rebuilder_settings settings(true, false); //Модифицируем заголовок PE и не очищаем поле IMAGE_DIRECTORY_ENTRY_IAT + rebuild_imports(image, imports, attached_section, settings); //ПереÑобираем импорты + + //Создаем новый PE-файл + std::string base_file_name(argv[1]); + std::string::size_type slash_pos; + if((slash_pos = base_file_name.find_last_of("/\\")) != std::string::npos) + base_file_name = base_file_name.substr(slash_pos + 1); + + base_file_name = "new_" + base_file_name; + std::ofstream new_pe_file(base_file_name.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); + if(!new_pe_file) + { + std::cout << "Cannot create " << base_file_name << std::endl; + return -1; + } + + //ПереÑобираем PE-файл + rebuild_pe(image, new_pe_file); + + std::cout << "PE was rebuilt and saved to " << base_file_name << std::endl; + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/imports_reader/Makefile b/irdb-lib/pebliss/trunk/samples/imports_reader/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/imports_reader/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/imports_reader/imports_reader.vcproj b/irdb-lib/pebliss/trunk/samples/imports_reader/imports_reader.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..a89cc345bb2b49c2530e52acd52911a00f51d7f6 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/imports_reader/imports_reader.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="imports_reader" + ProjectGUID="{15AFEB1D-4EF8-4AF0-88C8-9FCA879F8AE2}" + RootNamespace="imports_reader" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/imports_reader/imports_reader.vcxproj b/irdb-lib/pebliss/trunk/samples/imports_reader/imports_reader.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..36480ff1e64b8a109620cb827f605f156a6189d2 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/imports_reader/imports_reader.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{752670B7-53AA-46CF-B3C5-D3FABBDC027D}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>imports_reader</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/imports_reader/imports_reader.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/imports_reader/imports_reader.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/imports_reader/imports_reader.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/imports_reader/main.cpp b/irdb-lib/pebliss/trunk/samples/imports_reader/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8111fbba8f0cc82d8076e94841abf4d119f9c7f9 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/imports_reader/main.cpp @@ -0,0 +1,79 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как Ñчитать и получить информацию об импортах PE или PE+ файла +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: imports_reader.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + //Проверим, еÑÑ‚ÑŒ ли импорты у файла + if(!image.has_imports()) + { + std::cout << "Image has no imports" << std::endl; + return 0; + } + + std::cout << "Reading PE imports..." << std::hex << std::showbase << std::endl << std::endl; + + //Получаем ÑпиÑок импортируемых библиотек Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñми + const imported_functions_list imports = get_imported_functions(image); + + //ПеречиÑлÑем импортированные библиотеки и выводим информацию о них + for(imported_functions_list::const_iterator it = imports.begin(); it != imports.end(); ++it) + { + const import_library& lib = *it; //Ð˜Ð¼Ð¿Ð¾Ñ€Ñ‚Ð¸Ñ€ÑƒÐµÐ¼Ð°Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñ‚ÐµÐºÐ° + std::cout << "Library [" << lib.get_name() << "]" << std::endl //Ð˜Ð¼Ñ + << "Timestamp: " << lib.get_timestamp() << std::endl //Ð’Ñ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð¼ÐµÑ‚ÐºÐ° + << "RVA to IAT: " << lib.get_rva_to_iat() << std::endl //ОтноÑительный Ð°Ð´Ñ€ÐµÑ Ðº import address table + << "========" << std::endl; + + //ПеречиÑлÑем импортированные функции Ð´Ð»Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñ‚ÐµÐºÐ¸ + const import_library::imported_list& functions = lib.get_imported_functions(); + for(import_library::imported_list::const_iterator func_it = functions.begin(); func_it != functions.end(); ++func_it) + { + const imported_function& func = *func_it; //Ð˜Ð¼Ð¿Ð¾Ñ€Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ + std::cout << "[+] "; + if(func.has_name()) //ЕÑли Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¸Ð¼ÐµÐµÑ‚ Ð¸Ð¼Ñ - выведем его + std::cout << func.get_name(); + else + std::cout << "#" << func.get_ordinal(); //Иначе она импортирована по ординалу + + //Хинт + std::cout << " hint: " << func.get_hint() << std::endl; + } + + std::cout << std::endl; + } + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/lib.h b/irdb-lib/pebliss/trunk/samples/lib.h new file mode 100644 index 0000000000000000000000000000000000000000..27d33526d5ecbf057866415831032aede4ce6cb9 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/lib.h @@ -0,0 +1,14 @@ +#pragma once +#ifndef _M_X64 +#ifdef _DEBUG +#pragma comment(lib, "../../Debug/pe_bliss.lib") +#else +#pragma comment(lib, "../../Release/pe_bliss.lib") +#endif +#else +#ifdef _DEBUG +#pragma comment(lib, "../../x64/Debug/pe_bliss.lib") +#else +#pragma comment(lib, "../../x64/Release/pe_bliss.lib") +#endif +#endif diff --git a/irdb-lib/pebliss/trunk/samples/pe_config_reader/Makefile b/irdb-lib/pebliss/trunk/samples/pe_config_reader/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_config_reader/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/pe_config_reader/main.cpp b/irdb-lib/pebliss/trunk/samples/pe_config_reader/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e190aa2a6ba1effd789d4ec80f6b76eb6b2af6f1 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_config_reader/main.cpp @@ -0,0 +1,67 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как Ñчитать и получить информацию о Image Config (ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð¸ÑполнÑемого файла) PE или PE+ +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: pe_config_reader.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + std::cout << "Reading PE image config info..." << std::hex << std::showbase << std::endl << std::endl; + + //Получаем конфигурацию + const image_config_info info(get_image_config(image)); + + //Выводим данные конфигурации + //Подробнее о полÑÑ… - в MSDN + std::cout << "Critical section default timeout: " << info.get_critical_section_default_timeout() << std::endl + << "Decommit free block threshold: " << info.get_decommit_free_block_threshold() << std::endl + << "Decommit total free threshold: " << info.get_decommit_total_free_threshold() << std::endl + << "Global flags clear: " << info.get_global_flags_clear() << std::endl + << "Global flags set: " << info.get_global_flags_set() << std::endl + << "VA of lock table prefix: " << info.get_lock_prefix_table_va() << std::endl + << "Max allocation size: " << info.get_max_allocation_size() << std::endl + << "Process affinity mask: " << info.get_process_affinity_mask() << std::endl + << "Process heap flags: " << info.get_process_heap_flags() << std::endl + << "Security cookie VA: " << info.get_security_cookie_va() << std::endl + << "CSDVersion: " << info.get_service_pack_version() << std::endl + << "Timestamp: " << info.get_time_stamp() << std::endl + << "Virtual memory threshold: " << info.get_virtual_memory_threshold() << std::endl + << std::endl; + + //Выведем адреÑа SE-хендлеров + const image_config_info::se_handler_list& se_handlers = info.get_se_handler_rvas(); + for(image_config_info::se_handler_list::const_iterator it = se_handlers.begin(); it != se_handlers.end(); ++it) + std::cout << "SE Handler: " << (*it) << std::endl; + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/pe_config_reader/pe_config_reader.vcproj b/irdb-lib/pebliss/trunk/samples/pe_config_reader/pe_config_reader.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..ea301cc36615b76ba8fe20d7ad0d47a5343d2c88 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_config_reader/pe_config_reader.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="pe_config_reader" + ProjectGUID="{1F7B06CA-5529-4A3D-89CE-15161D4A01D9}" + RootNamespace="pe_config_reader" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/pe_config_reader/pe_config_reader.vcxproj b/irdb-lib/pebliss/trunk/samples/pe_config_reader/pe_config_reader.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..815c460db6fe82c24f1c0f24ee582b1aa07e0a63 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_config_reader/pe_config_reader.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{4F642892-D07F-4A96-82E4-36E2966D222D}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>pe_config_reader</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/pe_config_reader/pe_config_reader.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/pe_config_reader/pe_config_reader.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_config_reader/pe_config_reader.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/pe_realigner/Makefile b/irdb-lib/pebliss/trunk/samples/pe_realigner/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_realigner/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/pe_realigner/main.cpp b/irdb-lib/pebliss/trunk/samples/pe_realigner/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..849d07ce069257f2e88e9cb7d3cd814a61b696d9 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_realigner/main.cpp @@ -0,0 +1,84 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как изменить файловое выравнивание PE-файлов +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: pe_realigner.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + //Выведем темущий file alignment + std::cout << "File alignment: " << image.get_file_alignment() << std::endl; + + //Предложим выбрать новое выравнивание + unsigned int new_alignment_index = static_cast<unsigned int>(-1); + + while(new_alignment_index > 3) + { + if(std::cin.fail()) + { + //Ðа Ñлучай, еÑли пользователь ввел что-то некорректное + std::cin.clear(); + std::cin.ignore(static_cast<std::streamsize>(-1), '\n'); + } + + std::cout << "Choose new file alignment" << std::endl; + std::cout << "(0 = 512, 1 = 1024, 2 = 2048, 3 = 4096): "; + std::cin >> new_alignment_index; + } + + unsigned int available_aligns[] = {512, 1024, 2048, 4096}; + + //Изменим выравнивание на то, которое указал пользователь + image.realign_file(available_aligns[new_alignment_index]); + + //Создаем новый PE-файл + std::string base_file_name(argv[1]); + std::string::size_type slash_pos; + if((slash_pos = base_file_name.find_last_of("/\\")) != std::string::npos) + base_file_name = base_file_name.substr(slash_pos + 1); + + base_file_name = "new_" + base_file_name; + std::ofstream new_pe_file(base_file_name.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); + if(!new_pe_file) + { + std::cout << "Cannot create " << base_file_name << std::endl; + return -1; + } + + //ПереÑобираем PE-файл + rebuild_pe(image, new_pe_file); + + std::cout << "PE was rebuilt and saved to " << base_file_name << std::endl; + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/pe_realigner/pe_realigner.vcproj b/irdb-lib/pebliss/trunk/samples/pe_realigner/pe_realigner.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..9b9a452f4b74edaa99d22b854ba37ae182b2a13a --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_realigner/pe_realigner.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="pe_realigner" + ProjectGUID="{36EB9E03-E155-4487-AB1B-0B1B862B0155}" + RootNamespace="pe_realigner" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/pe_realigner/pe_realigner.vcxproj b/irdb-lib/pebliss/trunk/samples/pe_realigner/pe_realigner.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..0668df485234300905acc268d201f91415ba4221 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_realigner/pe_realigner.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{F40CE9C6-5E3F-445A-8EA4-ED819E608024}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>pe_realigner</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/pe_realigner/pe_realigner.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/pe_realigner/pe_realigner.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_realigner/pe_realigner.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/pe_rebaser/Makefile b/irdb-lib/pebliss/trunk/samples/pe_rebaser/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_rebaser/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/pe_rebaser/main.cpp b/irdb-lib/pebliss/trunk/samples/pe_rebaser/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6a79856505461720817b857f3eab0c2690b6ac99 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_rebaser/main.cpp @@ -0,0 +1,73 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как изменить базовый Ð°Ð´Ñ€ÐµÑ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ PE-файла при уÑловии Ð½Ð°Ð»Ð¸Ñ‡Ð¸Ñ Ñ€ÐµÐ»Ð¾ÐºÐ°Ñ†Ð¸Ð¹ +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: pe_rebaser.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + //Проверим, еÑÑ‚ÑŒ ли релокации у образа + if(!image.has_reloc()) + { + std::cout << "Image has no relocations, rebase is not possible" << std::endl; + return 0; + } + + //Получим значение базового адреÑа загрузки образа (64-бита, универÑально Ð´Ð»Ñ PE и PE+) + uint64_t base = image.get_image_base_64(); + base += 0x100000; //Изменим базовый Ð°Ð´Ñ€ÐµÑ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ + + //Произведем переÑчет необходимых адреÑов + rebase_image(image, get_relocations(image), base); + + //Создаем новый PE-файл + std::string base_file_name(argv[1]); + std::string::size_type slash_pos; + if((slash_pos = base_file_name.find_last_of("/\\")) != std::string::npos) + base_file_name = base_file_name.substr(slash_pos + 1); + + base_file_name = "new_" + base_file_name; + std::ofstream new_pe_file(base_file_name.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); + if(!new_pe_file) + { + std::cout << "Cannot create " << base_file_name << std::endl; + return -1; + } + + //ПереÑобираем PE-файл + rebuild_pe(image, new_pe_file); + + std::cout << "PE was rebuilt and saved to " << base_file_name << std::endl; + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/pe_rebaser/pe_rebaser.vcproj b/irdb-lib/pebliss/trunk/samples/pe_rebaser/pe_rebaser.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..04dfbb53d324d1ee38112a63c8240296326b90f1 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_rebaser/pe_rebaser.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="pe_rebaser" + ProjectGUID="{0F52C42C-EEDA-4031-B0A0-F6CD53C81465}" + RootNamespace="pe_rebaser" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/pe_rebaser/pe_rebaser.vcxproj b/irdb-lib/pebliss/trunk/samples/pe_rebaser/pe_rebaser.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..a019cde1f0e65e41691fc2ba50a6747a6e965a9e --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_rebaser/pe_rebaser.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{46FD39E7-B16C-4F73-B2F0-F1B570464C6E}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>pe_rebaser</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/pe_rebaser/pe_rebaser.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/pe_rebaser/pe_rebaser.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_rebaser/pe_rebaser.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/pe_sections_reader/Makefile b/irdb-lib/pebliss/trunk/samples/pe_sections_reader/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_sections_reader/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/pe_sections_reader/main.cpp b/irdb-lib/pebliss/trunk/samples/pe_sections_reader/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1d5c9ecb91b7d5609b1ba1c17e652c558df7a13d --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_sections_reader/main.cpp @@ -0,0 +1,56 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как Ñчитать и получить информацию о ÑекциÑÑ… PE или PE+ файла +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: pe_sections_reader.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + //Получаем ÑпиÑок Ñекций + std::cout << "Reading PE sections..." << std::hex << std::showbase << std::endl << std::endl; + const section_list sections(image.get_image_sections()); + + //ПеречиÑлÑем Ñекции и выводим информацию о них + for(section_list::const_iterator it = sections.begin(); it != sections.end(); ++it) + { + const section& s = *it; //Ð¡ÐµÐºÑ†Ð¸Ñ + std::cout << "Section [" << s.get_name() << "]" << std::endl //Ð˜Ð¼Ñ Ñекции + << "Characteristics: " << s.get_characteristics() << std::endl //ХарактериÑтики + << "Size of raw data: " << s.get_size_of_raw_data() << std::endl //Размер данных в файле + << "Virtual address: " << s.get_virtual_address() << std::endl //Виртуальный Ð°Ð´Ñ€ÐµÑ + << "Virtual size: " << s.get_virtual_size() << std::endl //Виртуальный размер + << std::endl; + } + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/pe_sections_reader/pe_sections_reader.vcproj b/irdb-lib/pebliss/trunk/samples/pe_sections_reader/pe_sections_reader.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..5d9eb5c447d110caba4f0d7928897cc466d4b838 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_sections_reader/pe_sections_reader.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="pe_sections_reader" + ProjectGUID="{0A06D231-FC40-4EC9-B0FC-F0D08270384E}" + RootNamespace="pe_sections_reader" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/pe_sections_reader/pe_sections_reader.vcxproj b/irdb-lib/pebliss/trunk/samples/pe_sections_reader/pe_sections_reader.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..119584e311d17139c1b56040cb00fb7ee520ba91 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_sections_reader/pe_sections_reader.vcxproj @@ -0,0 +1,162 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{F154B72B-22DD-493A-B5D5-CDCD8914DA28}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>pe_sections_reader</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/pe_sections_reader/pe_sections_reader.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/pe_sections_reader/pe_sections_reader.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_sections_reader/pe_sections_reader.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/pe_stripper/Makefile b/irdb-lib/pebliss/trunk/samples/pe_stripper/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_stripper/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/pe_stripper/main.cpp b/irdb-lib/pebliss/trunk/samples/pe_stripper/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ecc147ea00b6a072dce574de35d43fca2518106d --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_stripper/main.cpp @@ -0,0 +1,69 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как вырезать ненужные данные из PE-файла и переÑобрать его +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: pe_stripper.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + //Удалим DOS stub и rich overlay + image.strip_stub_overlay(); + + //Удалим ненужные DATA_DIRECTORY (нулевые) + //Очень малое количеÑтво линкеров умеют Ñто делать + image.strip_data_directories(0); + + //Создаем новый PE-файл + std::string base_file_name(argv[1]); + std::string::size_type slash_pos; + if((slash_pos = base_file_name.find_last_of("/\\")) != std::string::npos) + base_file_name = base_file_name.substr(slash_pos + 1); + + base_file_name = "new_" + base_file_name; + std::ofstream new_pe_file(base_file_name.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); + if(!new_pe_file) + { + std::cout << "Cannot create " << base_file_name << std::endl; + return -1; + } + + //ПереÑобираем PE-файл Ñ Ð¾Ð¿Ñ†Ð¸ÐµÐ¹ ÑÐ¶Ð°Ñ‚Ð¸Ñ DOS-header + //Ð£Ð¼ÐµÐ½ÑŒÑˆÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€Ð° Ñто не дает, но упаковывает NT-заголовки в DOS-заголовок + //При переÑборке автоматичеÑки убираютÑÑ Ð½ÐµÐ½ÑƒÐ¶Ð½Ñ‹Ðµ нулевые байты в Ñамом конце образа, + //в результате чего размер образа ÑтановитÑÑ Ð½ÐµÐ¼Ð½Ð¾Ð³Ð¾ меньше + rebuild_pe(image, new_pe_file, true); + + std::cout << "PE was rebuilt and saved to " << base_file_name << std::endl; + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/pe_stripper/pe_stripper.vcproj b/irdb-lib/pebliss/trunk/samples/pe_stripper/pe_stripper.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..a649e2e22ddba9b0098ab7818c78298cc148339d --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_stripper/pe_stripper.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="pe_stripper" + ProjectGUID="{9E09B1EB-D3F3-4C38-B87F-AE642F509D04}" + RootNamespace="pe_stripper" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/pe_stripper/pe_stripper.vcxproj b/irdb-lib/pebliss/trunk/samples/pe_stripper/pe_stripper.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..dab516938a65d8cc43421100dcc03f7ce83ad15f --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_stripper/pe_stripper.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{B32991F6-CD2C-48FE-A2AE-BDE8A4AC847D}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>pe_stripper</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/pe_stripper/pe_stripper.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/pe_stripper/pe_stripper.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/pe_stripper/pe_stripper.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/relocation_adder/Makefile b/irdb-lib/pebliss/trunk/samples/relocation_adder/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/relocation_adder/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/relocation_adder/main.cpp b/irdb-lib/pebliss/trunk/samples/relocation_adder/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b5f6965ea1688763dada1ca1f0e14c6fcc76cb8b --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/relocation_adder/main.cpp @@ -0,0 +1,87 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как добавить новую релокацию в таблицы релокаций PE-файла +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: relocation_adder.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + //ПеречиÑлим и получим вÑе запиÑи из таблиц релокаций в PE-файле, кроме абÑолютных + //Можно было бы включить в ÑпиÑок и абÑолютные запиÑи (ABSOLUTE), передав в вызов true + //Ðти запиÑи не нужны при переÑборке релокаций, они иÑпользуютÑÑ Ð´Ð»Ñ Ð²Ñ‹Ñ€Ð°Ð²Ð½Ð¸Ð²Ð°Ð½Ð¸Ñ + //и будут добавлены автоматичеÑки переÑборщиком + relocation_table_list tables(get_relocations(image)); + + //Создаем новую таблицу релокаций + relocation_table new_table; + new_table.set_rva(0x5678); //ОтноÑительный Ð°Ð´Ñ€ÐµÑ Ñ€ÐµÐ»Ð¾ÐºÐ°Ñ†Ð¸Ð¹ в таблице - он некорректен, Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð¼ÐµÑ€Ð°, поÑтому получившийÑÑ PE Ñкорее вÑего не загрузитÑÑ + //Добавим в таблицу новую релокацию + new_table.add_relocation(relocation_entry(10, 3)); //Тип 3 - HIGHLOW-релокациÑ, RRVA = 10, Ñ‚.е. RVA = 0x5678 + 10 + //ДобавлÑем таблицу + tables.push_back(new_table); + + //Можно редактировать и ÑущеÑтвующие релокации, но делать Ñтого не Ñтоит, так как файл не загрузитÑÑ, еÑли что-то в них поменÑÑ‚ÑŒ + //ЕÑли их удалить у EXE-файла полноÑтью, то вÑе будет нормально, у DLL Ñтого делать не Ñтоит + //Мы проÑто переÑоберем релокации + //Они будет иметь больший размер, чем до нашего редактированиÑ, + //поÑтому запишем их в новую Ñекцию, чтобы вÑе помеÑтилоÑÑŒ + //(мы не можем раÑширÑÑ‚ÑŒ ÑущеÑтвующие Ñекции, еÑли только ÑÐµÐºÑ†Ð¸Ñ Ð½Ðµ в Ñамом конце файла) + section new_relocs; + new_relocs.get_raw_data().resize(1); //Мы не можем добавлÑÑ‚ÑŒ пуÑтые Ñекции, поÑтому пуÑÑ‚ÑŒ у нее будет начальный размер данных 1 + new_relocs.set_name("new_rel"); //Ð˜Ð¼Ñ Ñекции + new_relocs.readable(true); //ДоÑтупна на чтение + section& attached_section = image.add_section(new_relocs); //Добавим Ñекцию и получим ÑÑылку на добавленную Ñекцию Ñ Ð¿Ñ€Ð¾Ñчитанными размерами + + rebuild_relocations(image, tables, attached_section); //ПереÑобираем ÑкÑпорты, раÑположив их Ñ Ð½Ð°Ñ‡Ð°Ð»Ð° новой Ñекции и запиÑав новые данные таблиц релокаций в PE-заголовок + + //Создаем новый PE-файл + std::string base_file_name(argv[1]); + std::string::size_type slash_pos; + if((slash_pos = base_file_name.find_last_of("/\\")) != std::string::npos) + base_file_name = base_file_name.substr(slash_pos + 1); + + base_file_name = "new_" + base_file_name; + std::ofstream new_pe_file(base_file_name.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); + if(!new_pe_file) + { + std::cout << "Cannot create " << base_file_name << std::endl; + return -1; + } + + //ПереÑобираем PE-файл + rebuild_pe(image, new_pe_file); + + std::cout << "PE was rebuilt and saved to " << base_file_name << std::endl; + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/relocation_adder/relocation_adder.vcproj b/irdb-lib/pebliss/trunk/samples/relocation_adder/relocation_adder.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..e7d84353096c58082ed579784c3d1d5f24cfd151 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/relocation_adder/relocation_adder.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="relocation_adder" + ProjectGUID="{9E7C038E-470E-4DF8-A887-3E1B8A02B78C}" + RootNamespace="relocation_adder" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/relocation_adder/relocation_adder.vcxproj b/irdb-lib/pebliss/trunk/samples/relocation_adder/relocation_adder.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..df1f34f6bc61f9a31a146bfaf5f24051741c45c1 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/relocation_adder/relocation_adder.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{7375047B-90D7-4564-BA84-7E5C638C7CCE}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>relocation_adder</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/relocation_adder/relocation_adder.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/relocation_adder/relocation_adder.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/relocation_adder/relocation_adder.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/relocations_reader/Makefile b/irdb-lib/pebliss/trunk/samples/relocations_reader/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/relocations_reader/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/relocations_reader/main.cpp b/irdb-lib/pebliss/trunk/samples/relocations_reader/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..989f5ff8483eaba0bb4cc85c5d72a1ac8199ec6b --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/relocations_reader/main.cpp @@ -0,0 +1,70 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как Ñчитать и получить информацию о релокациÑÑ… PE или PE+ файла +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: relocations_reader.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + //Проверим, еÑÑ‚ÑŒ ли релокации у файла + if(!image.has_reloc()) + { + std::cout << "Image has no relocations" << std::endl; + return 0; + } + + std::cout << "Reading PE relocations..." << std::hex << std::showbase << std::endl << std::endl; + + //Получаем ÑпиÑок таблиц релокаций + const relocation_table_list tables(get_relocations(image)); + + //ПеречиÑлÑем таблицы релокаций и выводим информацию о них + for(relocation_table_list::const_iterator it = tables.begin(); it != tables.end(); ++it) + { + const relocation_table& table = *it; //Таблица релокаций + std::cout << "RVA [" << table.get_rva() << "]" << std::endl //ОтноÑительный Ð°Ð´Ñ€ÐµÑ + << "==========" + << std::endl; + + //ПеречиÑлим вÑе релокации + const relocation_table::relocation_list& relocs = table.get_relocations(); + for(relocation_table::relocation_list::const_iterator reloc_it = relocs.begin(); reloc_it != relocs.end(); ++reloc_it) + { + std::cout << "[+] " << (*reloc_it).get_item() << std::endl; + } + + std::cout << std::endl; + } + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/relocations_reader/relocations_reader.vcproj b/irdb-lib/pebliss/trunk/samples/relocations_reader/relocations_reader.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..5a18e10eb94cf4280d3adb74fe5e3f6e79ae72be --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/relocations_reader/relocations_reader.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="relocations_reader" + ProjectGUID="{3EDCB092-C785-41EB-8A83-C5B37A2FF310}" + RootNamespace="relocations_reader" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/relocations_reader/relocations_reader.vcxproj b/irdb-lib/pebliss/trunk/samples/relocations_reader/relocations_reader.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..5f17bca9921d9aa81f5d69ea6aa1fb14fc1fb14a --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/relocations_reader/relocations_reader.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{A188C743-EA65-4D18-8964-18EAE61ACAC2}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>relocations_reader</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/relocations_reader/relocations_reader.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/relocations_reader/relocations_reader.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/relocations_reader/relocations_reader.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/resource_editor/Makefile b/irdb-lib/pebliss/trunk/samples/resource_editor/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/resource_editor/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/resource_editor/main.cpp b/irdb-lib/pebliss/trunk/samples/resource_editor/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..935fc712bd5a87af14d02b574c73f5c5ed7a15ee --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/resource_editor/main.cpp @@ -0,0 +1,175 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#include <pe_bliss_resources.h> +#ifdef PE_BLISS_WINDOWS +#include "resource.h" +#include "lib.h" +#else +#define IDR_CUSTOM1 100 +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как редактировать реÑурÑÑ‹ PE-файла +//Ð”Ð»Ñ Ð½Ð°Ñ‡Ð°Ð»Ð° рекомендуетÑÑ Ð¾Ð·Ð½Ð°ÐºÐ¾Ð¼Ð¸Ñ‚ÑŒÑÑ Ñ Ð¿Ñ€Ð¸Ð¼ÐµÑ€Ð¾Ð¼ resource_viewer +//Обратите внимание, что пример корректно отработает и в x86, и в x64 варианте +int main(int argc, char* argv[]) +{ + std::string pe_filename; + +#ifdef PE_BLISS_WINDOWS + //Открываем файл (Ñами ÑебÑ) + pe_filename = argv[0]; +#else + std::cout << "This sample needs itself to be compiled on Windows" + << std::endl << "Enter its filename: "; + + std::cin >> pe_filename; +#endif + + std::ifstream pe_file(pe_filename.c_str(), std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << pe_filename << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + //Суть примера будет ÑоÑтоÑÑ‚ÑŒ в Ñледующем: + //Ð’ Ñам пример вкомпиливаетÑÑ Ð¸ÐºÐ¾Ð½ÐºÐ° в директорию Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ CUSTOM + //Иконка ÑоÑтоит из трех картинок разных разрешений + //Ðаша задача - Ñчитать иконку из директории CUSTOM и уÑтановить ее как главную иконку exe-файла + //Далее - удалить директорию CUSTOM + //Ðаконец, добавить какую-нибудь информацию о верÑии к файлу + + //Проверим, еÑÑ‚ÑŒ ли реÑурÑÑ‹ у файла + if(!image.has_resources()) + { + std::cout << "Image has no resources" << std::endl; + return 0; + } + + //Получаем корневую директорию реÑурÑов + std::cout << "Reading PE resources..." << std::hex << std::showbase << std::endl << std::endl; + resource_directory root(get_resources(image)); + + //Ð”Ð»Ñ Ð¾Ð±Ð»ÐµÐ³Ñ‡ÐµÐ½Ð¸Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñ Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñми и запиÑÑми реÑурÑов Ñозданы вÑпомогательные клаÑÑÑ‹ + //Ðтот клаÑÑ Ð¿Ð¾Ð·Ð²Ð¾Ð»Ñет извлекать из PE-файлов любые реÑурÑÑ‹ и перезапиÑывать их + //и предоÑтавлÑет выÑокоуровневые функции Ð´Ð»Ñ Ð¸Ð·Ð²ÐµÑ‡ÐµÐ½Ð¸Ñ Ð¸ÐºÐ¾Ð½Ð¾Ðº, курÑоров, картинкок, Ñтроковых таблиц + //и таблиц Ñообщений, а также информации о верÑии + //и Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸ÐºÐ¾Ð½Ð¾Ðº, курÑоров, картинок и информации о верÑии + pe_resource_manager res(root); + + //Ð”Ð»Ñ Ð½Ð°Ñ‡Ð°Ð»Ð° убедимÑÑ, что Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ CUSTOM еÑÑ‚ÑŒ + if(!res.resource_exists(L"CUSTOM")) + { + std::cout << "\"CUSTOM\" resource directory does not exist" << std::endl; + return -1; + } + + //Получим нашу иконку из Ñтой директории: мы знаем, что ее ID=100 и она одна в директории имен, поÑтому делаем так + //Получаем ее по нулевому индекÑу (можно было получить по Ñзыку, но Ñто незачем, Ñ‚.к. она единÑтвеннаÑ) + const resource_data_info data = res.get_resource_data_by_id(L"CUSTOM", IDR_CUSTOM1); + + //Ðеобходимо теперь добавить ее как главную иконку + //Иконка Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ - Ñто иконка из той группы иконок, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ñледует Ñамой первой в ÑпиÑке групп иконок + //Помните, что Ñначала идут именованные реÑурÑÑ‹, а потом реÑурÑÑ‹ Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€Ð°Ð¼Ð¸, и вÑÑ‘ ÑортируетÑÑ + //Создадим группу иконок Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ MAIN_ICON + resource_cursor_icon_writer(res).add_icon(data.get_data(), //Данные файла иконки + L"MAIN_ICON", //Ð˜Ð¼Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ñ‹ иконок (помните, у Ð½Ð°Ñ Ñ‚Ñ€Ð¸ картинки внутри иконки, они будут находитьÑÑ Ð² Ñтой группе) + 0, //Язык - нам неважен + resource_cursor_icon_writer::icon_place_after_max_icon_id, //Вариант раÑÐ¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¸ÐºÐ¾Ð½Ð¾Ðº в ÑущеÑтвующей группе - нам он неважен, так как мы Ñоздаем новую группу + data.get_codepage(), //Сохраним иÑходную Codepage + 0 //Timestamp - неважен + ); + + //Теперь удалим уже ненужный реÑÑƒÑ€Ñ CUSTOM + res.remove_resource(L"CUSTOM"); + + //Теперь Ñоздадим информацию о верÑии + file_version_info file_info; //Ð‘Ð°Ð·Ð¾Ð²Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ файле + file_info.set_special_build(true); //Ðто будет Ñпециальный билд + file_info.set_file_os(file_version_info::file_os_nt_win32); //СиÑтема, на которой работает файл + file_info.set_file_version_ms(0x00010002); //ВерÑÐ¸Ñ Ñ„Ð°Ð¹Ð»Ð° будет 1.2.3.4 + file_info.set_file_version_ls(0x00030004); + + //Теперь Ñоздадим Ñтроки Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸ÐµÐ¹ и транÑлÑции (переводы) + lang_string_values_map strings; + translation_values_map translations; + + //Ð”Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñо Ñтроками и транÑлÑциÑми еÑÑ‚ÑŒ вÑпомогательный клаÑÑ + version_info_editor version(strings, translations); + //Добавим транÑлÑцию - default process language, UNICODE + //Можно указать и конкретный Ñзык и кодировку + version.add_translation(version_info_editor::default_language_translation); + //Строки будут уÑтанавливатьÑÑ Ð´Ð»Ñ Ð´ÐµÑ„Ð¾Ð»Ñ‚Ð½Ð¾Ð¹ кодировки (default_language_translation) + //ЕÑли такой нет, то Ð´Ð»Ñ Ð¿ÐµÑ€Ð²Ð¾Ð¹ найденной + //ЕÑли вообще нет ни одной транÑлÑции, то будет добавлена Ð´ÐµÑ„Ð¾Ð»Ñ‚Ð½Ð°Ñ (default_language_translation) + //Таким образом, предыдущий вызов add_translation можно было бы опуÑтить + //И еще: необÑзательно уÑтанавливать вÑе доÑтупные Ñтроки, как Ñделано ниже + version.set_company_name(L"Kaimi.ru DX"); //Ð˜Ð¼Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ð¸-Ð¿Ñ€Ð¾Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ‚ÐµÐ»Ñ + version.set_file_description(L"Generated file version info"); //ОпиÑание файла + version.set_internal_name(L"Tralala.exe"); //Внутреннее Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° + version.set_legal_copyright(L"(C) DX Portable Executable Library"); //Копирайт + version.set_original_filename(L"resource_editor.exe"); //Оригинальное Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° + version.set_product_name(L"PE Resource Editor Example"); //Ð˜Ð¼Ñ Ð¿Ñ€Ð¾Ð´ÑƒÐºÑ‚Ð° + version.set_product_version(L"x.y.z"); //ВерÑÐ¸Ñ Ð¿Ñ€Ð¾Ð´ÑƒÐºÑ‚Ð° + + //Можно также добавить Ñвою ÑобÑтвенную Ñтроку: она будет хранитьÑÑ Ð² информации о верÑии, + //но Windows Explorer врÑд ли ее отобразит в ÑвойÑтвах файла + version.set_property(L"MyLittleProperty", L"Secret Value"); + + //УÑтановим информацию о верÑии + resource_version_info_writer(res).set_version_info(file_info, strings, translations, 1033); //1033 - руÑÑкий Ñзык + + //ОÑталоÑÑŒ переименовать Ñтарую Ñекцию реÑурÑов + //Она называетÑÑ .rsrc + //Переименование необходимо Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы Windows Explorer Ñмог Ñчитать из новой Ñекции иконку + image.section_from_directory(pe_win::image_directory_entry_resource).set_name("oldres"); + + //ПереÑоберем реÑурÑÑ‹ + //Они будет иметь больший размер, чем до нашего редактированиÑ, + //поÑтому запишем их в новую Ñекцию, чтобы вÑе помеÑтилоÑÑŒ + //(мы не можем раÑширÑÑ‚ÑŒ ÑущеÑтвующие Ñекции, еÑли только ÑÐµÐºÑ†Ð¸Ñ Ð½Ðµ в Ñамом конце файла) + section new_resources; + new_resources.get_raw_data().resize(1); //Мы не можем добавлÑÑ‚ÑŒ пуÑтые Ñекции, поÑтому пуÑÑ‚ÑŒ у нее будет начальный размер данных 1 + new_resources.set_name(".rsrc"); //Ð˜Ð¼Ñ Ñекции + new_resources.readable(true); //ДоÑтупна на чтение + section& attached_section = image.add_section(new_resources); //Добавим Ñекцию и получим ÑÑылку на добавленную Ñекцию Ñ Ð¿Ñ€Ð¾Ñчитанными размерами + + //Теперь переÑоберем реÑурÑÑ‹, раÑположив их в Ñамом начале новой Ñекции и поправив PE-заголовок, запиÑав туда новые параметры директории реÑурÑÑ‹ + rebuild_resources(image, root, attached_section); + + //Создаем новый PE-файл + std::string base_file_name(pe_filename); + std::string::size_type slash_pos; + if((slash_pos = base_file_name.find_last_of("/\\")) != std::string::npos) + base_file_name = base_file_name.substr(slash_pos + 1); + + base_file_name = "new_" + base_file_name; + std::ofstream new_pe_file(base_file_name.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); + if(!new_pe_file) + { + std::cout << "Cannot create " << base_file_name << std::endl; + return -1; + } + + //ПереÑобираем PE-файл + rebuild_pe(image, new_pe_file); + + std::cout << "PE was rebuilt and saved to " << base_file_name << std::endl; + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/resource_editor/resource.h b/irdb-lib/pebliss/trunk/samples/resource_editor/resource.h new file mode 100644 index 0000000000000000000000000000000000000000..ce9e9c169c920c311e809b3d6ff0b25344eee022 Binary files /dev/null and b/irdb-lib/pebliss/trunk/samples/resource_editor/resource.h differ diff --git a/irdb-lib/pebliss/trunk/samples/resource_editor/resource.rc b/irdb-lib/pebliss/trunk/samples/resource_editor/resource.rc new file mode 100644 index 0000000000000000000000000000000000000000..234fa23e3975d323df1492e032039cde9dabc300 Binary files /dev/null and b/irdb-lib/pebliss/trunk/samples/resource_editor/resource.rc differ diff --git a/irdb-lib/pebliss/trunk/samples/resource_editor/resource_editor.vcproj b/irdb-lib/pebliss/trunk/samples/resource_editor/resource_editor.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..260f28dcf15ea543a9c6ff05bd9e7ddc74c1e4c2 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/resource_editor/resource_editor.vcproj @@ -0,0 +1,363 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="resource_editor" + ProjectGUID="{B0D287DB-451D-4005-9CE3-185D7602F0B7}" + RootNamespace="resource_editor" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + <File + RelativePath=".\resource.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + <File + RelativePath=".\resource.rc" + > + </File> + <File + RelativePath=".\wxwin.ico" + > + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/resource_editor/resource_editor.vcxproj b/irdb-lib/pebliss/trunk/samples/resource_editor/resource_editor.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..0812f7422ca1d4b6ac431d98659a39045b5ef845 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/resource_editor/resource_editor.vcxproj @@ -0,0 +1,165 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{B88455A6-C93A-4F17-93A5-FC84B70F9CFE}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>resource_editor</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + <ClInclude Include="resource.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="resource.rc" /> + </ItemGroup> + <ItemGroup> + <None Include="wxwin.ico" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/resource_editor/resource_editor.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/resource_editor/resource_editor.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..97def5d8b734ed771f93724b34503f9d22aaeba9 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/resource_editor/resource_editor.vcxproj.filters @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="resource.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="resource.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> + <ItemGroup> + <None Include="wxwin.ico"> + <Filter>Resource Files</Filter> + </None> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/resource_editor/wxwin.ico b/irdb-lib/pebliss/trunk/samples/resource_editor/wxwin.ico new file mode 100644 index 0000000000000000000000000000000000000000..719de36e163e34eaa4a03665873045b831757c5a Binary files /dev/null and b/irdb-lib/pebliss/trunk/samples/resource_editor/wxwin.ico differ diff --git a/irdb-lib/pebliss/trunk/samples/resource_viewer/Makefile b/irdb-lib/pebliss/trunk/samples/resource_viewer/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/resource_viewer/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/resource_viewer/main.cpp b/irdb-lib/pebliss/trunk/samples/resource_viewer/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..653b143864540acfacfb3390c26f0c05ccef3811 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/resource_viewer/main.cpp @@ -0,0 +1,226 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#include <pe_bliss_resources.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как читать реÑурÑÑ‹ PE-файла +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: resource_viewer.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + //Проверим, еÑÑ‚ÑŒ ли реÑурÑÑ‹ у файла + if(!image.has_resources()) + { + std::cout << "Image has no resources" << std::endl; + return 0; + } + + //Получаем корневую директорию реÑурÑов + std::cout << "Reading PE resources..." << std::hex << std::showbase << std::endl << std::endl; + const resource_directory root(get_resources(image)); + + //Ð”Ð»Ñ Ð¾Ð±Ð»ÐµÐ³Ñ‡ÐµÐ½Ð¸Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñ Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñми и запиÑÑми реÑурÑов Ñозданы вÑпомогательные клаÑÑÑ‹ + //Ðтот клаÑÑ Ð¿Ð¾Ð·Ð²Ð¾Ð»Ñет извлекать из PE-файлов любые реÑурÑÑ‹ + //и предоÑтавлÑет выÑокоуровневые функции Ð´Ð»Ñ Ð¸Ð·Ð²ÐµÑ‡ÐµÐ½Ð¸Ñ Ð¸ÐºÐ¾Ð½Ð¾Ðº, курÑоров, картинкок, Ñтроковых таблиц + //и таблиц Ñообщений, а также информации о верÑии + pe_resource_viewer res(root); + + //Выведем типы реÑурÑов, которые приÑутÑтвуют в PE-файле + pe_resource_viewer::resource_type_list res_types(res.list_resource_types()); + for(pe_resource_viewer::resource_type_list::const_iterator it = res_types.begin(); it != res_types.end(); ++it) + std::cout << "Present resource type: " << (*it) << std::endl; + + std::cout << std::endl; + + //Выведем иофнрмацию о верÑии, еÑли она ÑущеÑтвует + if(res.resource_exists(pe_resource_viewer::resource_version)) + { + lang_string_values_map strings; + translation_values_map translations; + //Получаем ÑпиÑок Ñтрок, переводов и базовую информацию о файле + file_version_info file_info(resource_version_info_reader(res).get_version_info(strings, translations)); + + //Выводить информацию будем в юникодный поток + std::wstringstream version_info; + //Выведем некоторую базовую информацию + version_info << L"Version info: " << std::endl; + version_info << L"File version: " << file_info.get_file_version_string<wchar_t>() << std::endl; //Строка верÑии файла + version_info << L"Debug build: " << (file_info.is_debug() ? L"YES" : L"NO") << std::endl; //Отладочный ли билд + version_info << std::endl; + + //Выведем Ñтроки Ð´Ð»Ñ Ñ€Ð°Ð·Ð½Ñ‹Ñ… транÑлÑций: + for(lang_string_values_map::const_iterator it = strings.begin(); it != strings.end(); ++it) + { + version_info << L"Translation ID: " << (*it).first << std::endl; + + //ПеречиÑлим запиÑи в таблице Ñтрок Ð´Ð»Ñ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ¹ транÑлÑции (перевода) + const string_values_map& string_table = (*it).second; + for(string_values_map::const_iterator str_it = string_table.begin(); str_it != string_table.end(); ++str_it) + version_info << (*str_it).first << L": " << (*str_it).second << std::endl; + + version_info << std::endl; + } + + //Выведем доÑтупные переводы (транÑлÑции): + for(translation_values_map::const_iterator it = translations.begin(); it != translations.end(); ++it) + version_info << L"Translation: language: " << (*it).first << ", codepage: " << (*it).second << std::endl; + + { + //Создаем файл, в который запишем информацию о верÑии + std::ofstream version_info_file("version_info.txt", std::ios::out | std::ios::trunc | std::ios::binary); + if(!version_info_file) + { + std::cout << "Cannot create file version_info.txt" << std::endl; + return -1; + } + + std::wstring version_info_string(version_info.str()); + //Запишем буфер, чтобы не паритьÑÑ Ñ Ð»Ð¾ÐºÐ°Ð»Ñми и запиÑью юникода в файл + version_info_file.write(reinterpret_cast<const char*>(version_info_string.data()), version_info_string.length() * sizeof(wchar_t)); + + std::cout << "version_info.txt created" << std::endl << std::endl; + } + + //Ð”Ð»Ñ Ð¾Ð±Ð»ÐµÐ³Ñ‡ÐµÐ½Ð¸Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ð¸ о верÑии еÑÑ‚ÑŒ Ñпециальный клаÑÑ + version_info_viewer version_viewer(strings, translations); + std::wcout << L"Original filename: " << version_viewer.get_original_filename() << std::endl << std::endl; + } + + { + //Ðайдем, еÑÑ‚ÑŒ ли у Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¸ÐºÐ¾Ð½ÐºÐ° + //Ð”Ð»Ñ Ñтого Ñначала узнаем вÑе имена и идентификаторы групп иконок + //Ð’Ñе реÑурÑÑ‹ в целом организованы в таком виде (дерево): + //тип реÑурÑа + //--> Ð¸Ð¼Ñ Ñ€ÐµÑурÑа + //----> Ñзык рерурÑа + //------> реÑÑƒÑ€Ñ + //----> Ñзык реÑурÑа + //------> реÑÑƒÑ€Ñ + //----> ... + //--> Ð¸Ð¼Ñ Ñ€ÐµÑурÑа + //--> ... + //--> id реÑурÑа + //----> Ñзык рерурÑа + //------> реÑÑƒÑ€Ñ + //----> Ñзык реÑурÑа + //------> реÑÑƒÑ€Ñ + //----> ... + //--> id реÑурÑа + //--> ... + //тип реÑурÑа + //... + pe_resource_viewer::resource_id_list icon_id_list(res.list_resource_ids(pe_resource_viewer::resource_icon_group)); + pe_resource_viewer::resource_name_list icon_name_list(res.list_resource_names(pe_resource_viewer::resource_icon_group)); + std::string main_icon; //Данные иконки Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ + //Сначала вÑегда раÑполагаютÑÑ Ð¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð½Ñ‹Ðµ реÑурÑÑ‹, поÑтому проверим, еÑÑ‚ÑŒ ли они + if(!icon_name_list.empty()) + { + //Получим Ñамую первую иконку Ð´Ð»Ñ Ñамого первого Ñзыка (по индекÑу 0) + //ЕÑли надо было бы перечиÑлить Ñзыки Ð´Ð»Ñ Ð·Ð°Ð´Ð°Ð½Ð½Ð¾Ð¹ иконки, можно было вызвать list_resource_languages + //ЕÑли надо было бы получить иконку Ð´Ð»Ñ ÐºÐ¾Ð½ÐºÑ€ÐµÑ‚Ð½Ð¾Ð³Ð¾ Ñзыка, можно было вызвать get_icon_by_name (перегрузка Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð¸ÐµÐ¼ Ñзыка) + main_icon = resource_cursor_icon_reader(res).get_icon_by_name(icon_name_list[0]); + } + else if(!icon_id_list.empty()) //ЕÑли нет именованных групп иконок, но еÑÑ‚ÑŒ группы Ñ ID + { + //Получим Ñамую первую иконку Ð´Ð»Ñ Ñамого первого Ñзыка (по индекÑу 0) + //ЕÑли надо было бы перечиÑлить Ñзыки Ð´Ð»Ñ Ð·Ð°Ð´Ð°Ð½Ð½Ð¾Ð¹ иконки, можно было вызвать list_resource_languages + //ЕÑли надо было бы получить иконку Ð´Ð»Ñ ÐºÐ¾Ð½ÐºÑ€ÐµÑ‚Ð½Ð¾Ð³Ð¾ Ñзыка, можно было вызвать get_icon_by_id_lang + main_icon = resource_cursor_icon_reader(res).get_icon_by_id(icon_id_list[0]); + } + + //ЕÑли еÑÑ‚ÑŒ иконка... + if(!main_icon.empty()) + { + //Сохраним полученную иконку в файл + std::ofstream app_icon("main_icon.ico", std::ios::out | std::ios::trunc | std::ios::binary); + if(!app_icon) + { + std::cout << "Cannot create file main_icon.ico" << std::endl; + return -1; + } + + app_icon.write(main_icon.data(), main_icon.length()); + + std::cout << "main_icon.ico created" << std::endl; + } + } + + { + //Сдампим Ñтроковые таблицы + //ПеречиÑлим идентификаторы ÑущеÑтвующих Ñтроковых таблиц + pe_resource_viewer::resource_id_list strings_id_list(res.list_resource_ids(pe_resource_viewer::resource_string)); + + //Дампить будем в юникодный поток + std::wstringstream string_data; + + if(!strings_id_list.empty()) //ЕÑли у Ð½Ð°Ñ ÐµÑÑ‚ÑŒ именованные Ñтроковые таблицы, Ñдампим их + { + //Ð’Ñе имена Ñтроковых таблиц + for(pe_resource_viewer::resource_id_list::const_iterator it = strings_id_list.begin(); it != strings_id_list.end(); ++it) + { + string_data << L"String table [" << (*it) << L"]" << std::endl; + + //ПеречиÑлим Ñзыки таблицы + pe_resource_viewer::resource_language_list langs(res.list_resource_languages(pe_resource_viewer::resource_string, *it)); + //Ð”Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ Ñзыка получим таблицу Ñтрок + for(pe_resource_viewer::resource_language_list::const_iterator lang_it = langs.begin(); lang_it != langs.end(); ++lang_it) + { + string_data << L" -> Language = " << *lang_it << std::endl; //Запишем Ñзык + //Таблица Ñтрок + resource_string_list strings(resource_string_table_reader(res).get_string_table_by_id_lang(*lang_it, *it)); + + //Ðаконец, запишем вÑе Ñтроки в поток + for(resource_string_list::const_iterator str_it = strings.begin(); str_it != strings.end(); ++str_it) + string_data << L" --> #" << (*str_it).first << L": " << (*str_it).second << std::endl; //ID Ñтроки: ее значение + } + + string_data << std::endl; + } + + //Запишем полученные Ñтроки в файл + std::ofstream strings_file("strings.txt", std::ios::out | std::ios::trunc | std::ios::binary); + if(!strings_file) + { + std::cout << "Cannot create file strings.txt" << std::endl; + return -1; + } + + std::wstring strings_str(string_data.str()); + //Запишем буфер, чтобы не паритьÑÑ Ñ Ð»Ð¾ÐºÐ°Ð»Ñми и запиÑью юникода в файл + strings_file.write(reinterpret_cast<const char*>(strings_str.data()), strings_str.length() * sizeof(wchar_t)); + + std::cout << "strings.txt created" << std::endl; + } + } + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/resource_viewer/resource_viewer.vcproj b/irdb-lib/pebliss/trunk/samples/resource_viewer/resource_viewer.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..8482c29f6bd78cc83113e87ead0b1ff6cad61770 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/resource_viewer/resource_viewer.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="resource_viewer" + ProjectGUID="{D10B61A9-09FD-4E87-8C66-BE07AE5CC8E9}" + RootNamespace="resource_viewer" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/resource_viewer/resource_viewer.vcxproj b/irdb-lib/pebliss/trunk/samples/resource_viewer/resource_viewer.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..697c1c1f23dc91f73a11d6b2b69682ff35023ba6 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/resource_viewer/resource_viewer.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{BC2D8697-73C1-46B9-AC1C-7777D1A71609}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>resource_viewer</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/resource_viewer/resource_viewer.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/resource_viewer/resource_viewer.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/resource_viewer/resource_viewer.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/rich_overlay_stub_reader/Makefile b/irdb-lib/pebliss/trunk/samples/rich_overlay_stub_reader/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/rich_overlay_stub_reader/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/rich_overlay_stub_reader/main.cpp b/irdb-lib/pebliss/trunk/samples/rich_overlay_stub_reader/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fa7bac5ca451ca68a2f55083fc5929c892fb14c1 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/rich_overlay_stub_reader/main.cpp @@ -0,0 +1,57 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как получить информацию о Ñтабе PE-файла и rich overlay, который добавлÑет при компилÑции MS Visual Studio +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: rich_overlay_stub_reader.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + //Выведем длину DOS stub'а + std::cout << "Image stub length: " << image.get_stub_overlay().length() << std::endl << std::endl; + + //ПеречиÑлÑем вÑе RICH-запиÑи + rich_data_list data = get_rich_data(image); + for(rich_data_list::const_iterator it = data.begin(); it != data.end(); ++it) + { + //Выводим информацию о запиÑи + std::cout << "Number: " << (*it).get_number() << std::endl + << "Times: " << (*it).get_times() << std::endl + << "Version: " << (*it).get_version() << std::endl + << std::endl; + } + + //Отобразим информацию о том, еÑÑ‚ÑŒ ли у файла оверлей в конце (у некоторых инÑталлÑторов, например, еÑÑ‚ÑŒ) + std::cout << "Has overlay in the end: " << (image.has_overlay() ? "YES" : "NO") << std::endl; + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/rich_overlay_stub_reader/rich_overlay_stub_reader.vcproj b/irdb-lib/pebliss/trunk/samples/rich_overlay_stub_reader/rich_overlay_stub_reader.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..ed7648d9106e04d1e8eb244260969f1bb83f24d6 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/rich_overlay_stub_reader/rich_overlay_stub_reader.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="rich_overlay_stub_reader" + ProjectGUID="{33FF435B-A3CF-441E-964E-A7DA8735E7B1}" + RootNamespace="rich_overlay_stub_reader" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/rich_overlay_stub_reader/rich_overlay_stub_reader.vcxproj b/irdb-lib/pebliss/trunk/samples/rich_overlay_stub_reader/rich_overlay_stub_reader.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..16b5b014852a8850a021d9baed0f0a4db160f219 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/rich_overlay_stub_reader/rich_overlay_stub_reader.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{3FDDF315-4CD6-4A21-91CE-F5AFF5BB9667}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>rich_overlay_stub_reader</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/rich_overlay_stub_reader/rich_overlay_stub_reader.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/rich_overlay_stub_reader/rich_overlay_stub_reader.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/rich_overlay_stub_reader/rich_overlay_stub_reader.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/sample.mak b/irdb-lib/pebliss/trunk/samples/sample.mak new file mode 100644 index 0000000000000000000000000000000000000000..688875a862800bc431e876301dc3d4461c40ffb9 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/sample.mak @@ -0,0 +1,24 @@ +PWD=$(shell pwd) +OUTDIR = ../out/ +LIBPATH = ../../lib/libpebliss.a +NAME=$(shell basename $(PWD)) +CXXFLAGS = -Wall -I../../pe_lib + +ifdef PE_DEBUG +CXXFLAGS += -g -O0 +endif + +all: $(OUTDIR)$(NAME) + +clean: + rm -f $(NAME) *.o + rm -f $(OUTDIR)$(NAME) + +$(NAME): main.o + $(CXX) -Wall $^ -lpebliss -L../../lib -o $(NAME) -liconv + +main.o: $(LIBPATH) + +$(OUTDIR)$(NAME): $(NAME) + cp -d $(NAME) $(OUTDIR) + diff --git a/irdb-lib/pebliss/trunk/samples/section_adder/Makefile b/irdb-lib/pebliss/trunk/samples/section_adder/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/section_adder/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/section_adder/main.cpp b/irdb-lib/pebliss/trunk/samples/section_adder/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..227c4fdbdaf7eb3fe6915b0d70363de0d854ccbf --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/section_adder/main.cpp @@ -0,0 +1,74 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как добавить Ñекцию в PE-файл и запиÑать в нее какие-нибудь данные +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: section_adder.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + //Секцию можно добавить только поÑле вÑех ÑущеÑтвующих, чтобы PE-файл не иÑпортилÑÑ + //Создаем новую Ñекцию + section new_section; + new_section.readable(true).writeable(true); //Делаем Ñекцию доÑтупной Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ð¸ запиÑи + new_section.set_name("kaimi.ru"); //Ставим Ð¸Ð¼Ñ Ñекции - макÑимум 8 Ñимволов + new_section.set_raw_data("Tralala"); //УÑтанавливаем данные Ñекции + + //ДобавлÑем Ñекцию. Ð’Ñе адреÑа переÑчитаютÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки + //Вызов вернет ÑÑылку на уже добавленную Ñекцию Ñ Ð¿ÐµÑ€ÐµÑчитанными адреÑами + //СовÑем пуÑтую Ñекцию к образу добавить нельзÑ, у нее должен быть ненулевой размер данных или виртуальный размер + section& added_section = image.add_section(new_section); + + //ЕÑли нужно изменить виртуальный размер Ñекции, то делаетÑÑ Ñто так: + image.set_section_virtual_size(added_section, 0x1000); + + //Создаем новый PE-файл + std::string base_file_name(argv[1]); + std::string::size_type slash_pos; + if((slash_pos = base_file_name.find_last_of("/\\")) != std::string::npos) + base_file_name = base_file_name.substr(slash_pos + 1); + + base_file_name = "new_" + base_file_name; + std::ofstream new_pe_file(base_file_name.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); + if(!new_pe_file) + { + std::cout << "Cannot create " << base_file_name << std::endl; + return -1; + } + + //ПереÑобираем PE-файл + rebuild_pe(image, new_pe_file); + + std::cout << "PE was rebuilt and saved to " << base_file_name << std::endl; + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/section_adder/section_adder.vcproj b/irdb-lib/pebliss/trunk/samples/section_adder/section_adder.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..2011bee8055eccf1baddeca083b8caedd36aa964 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/section_adder/section_adder.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="section_adder" + ProjectGUID="{C3B58F69-FA5D-4E9E-8E21-F6C5EBAC22ED}" + RootNamespace="section_adder" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/section_adder/section_adder.vcxproj b/irdb-lib/pebliss/trunk/samples/section_adder/section_adder.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..85a2e4ddaae2ea8b861624566925c042d4d7f9bf --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/section_adder/section_adder.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{93ABC577-1018-48C2-95C6-39B0B26DD3B0}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>section_adder</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/section_adder/section_adder.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/section_adder/section_adder.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/section_adder/section_adder.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/sections_and_addresses/Makefile b/irdb-lib/pebliss/trunk/samples/sections_and_addresses/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/sections_and_addresses/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/sections_and_addresses/main.cpp b/irdb-lib/pebliss/trunk/samples/sections_and_addresses/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a6d12b8e895e7c3cddf1eb66fa0db7624a2fd7b6 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/sections_and_addresses/main.cpp @@ -0,0 +1,50 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как работать Ñ ÑекциÑми в PE-файле +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: sections_and_addresses.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + //Выведем Ð¸Ð¼Ñ Ñекции, в которой находитÑÑ Ñ‚Ð¾Ñ‡ÐºÐ° входа PE-файла + //Ð’ хитрых PE-файлах точка входа может находитьÑÑ Ð² заголовке, тогда section_from_rva броÑит иÑключение + std::cout << "EP section name: " << image.section_from_rva(image.get_ep()).get_name() << std::endl; + //Длина "Ñырых" (raw) данных Ñекции + std::cout << "EP section data length: " << image.section_data_length_from_rva(image.get_ep()) << std::endl; + + //ЕÑли у PE-файла еÑÑ‚ÑŒ импорты, выведем Ð¸Ð¼Ñ Ñекции, в которой они находÑÑ‚ÑÑ + if(image.has_imports()) + std::cout << "Import section name: " << image.section_from_directory(pe_win::image_directory_entry_import).get_name() << std::endl; + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/sections_and_addresses/sections_and_addresses.vcproj b/irdb-lib/pebliss/trunk/samples/sections_and_addresses/sections_and_addresses.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..e4f12f28aee3e567003892b89c3155ff5ee15625 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/sections_and_addresses/sections_and_addresses.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="sections_and_addresses" + ProjectGUID="{660117AA-6B9E-4C7D-B0BE-DE6BD17DBA1E}" + RootNamespace="sections_and_addresses" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/sections_and_addresses/sections_and_addresses.vcxproj b/irdb-lib/pebliss/trunk/samples/sections_and_addresses/sections_and_addresses.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..684a43f1318c897c3c4ebbbd81a09d1ac9f9a7d4 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/sections_and_addresses/sections_and_addresses.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{99F41F8F-44DB-410E-9883-A6A16E903DF8}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>sections_and_addresses</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/sections_and_addresses/sections_and_addresses.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/sections_and_addresses/sections_and_addresses.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/sections_and_addresses/sections_and_addresses.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/tls_editor/Makefile b/irdb-lib/pebliss/trunk/samples/tls_editor/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/tls_editor/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/tls_editor/main.cpp b/irdb-lib/pebliss/trunk/samples/tls_editor/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..700a9fc481d24743d6f0b7c7754e7f51ae2d769d --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/tls_editor/main.cpp @@ -0,0 +1,88 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как редактировать TLS (Thread Local Storage) у PE-файлов +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: tls_editor.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + //Получим информацию о TLS PE-файла + //ЕÑли TLS нет, Ñтот вызов выброÑит иÑключение + tls_info info(get_tls_info(image)); + + //ПереÑоберем TLS + //Он, вероÑтно, будет иметь больший размер, чем до нашего редактированиÑ, + //поÑтому запишем его в новую Ñекцию, чтобы вÑе помеÑтилоÑÑŒ + //(мы не можем раÑширÑÑ‚ÑŒ ÑущеÑтвующие Ñекции, еÑли только ÑÐµÐºÑ†Ð¸Ñ Ð½Ðµ в Ñамом конце файла) + section new_tls; + new_tls.get_raw_data().resize(1); //Мы не можем добавлÑÑ‚ÑŒ пуÑтые Ñекции, поÑтому пуÑÑ‚ÑŒ у нее будет начальный размер данных 1 + new_tls.set_name("new_tls"); //Ð˜Ð¼Ñ Ñекции + new_tls.readable(true); //ДоÑтупна на чтение + section& attached_section = image.add_section(new_tls); //Добавим Ñекцию и получим ÑÑылку на добавленную Ñекцию Ñ Ð¿Ñ€Ð¾Ñчитанными размерами + + if(info.get_callbacks_rva() != 0) //ЕÑли у TLS еÑÑ‚ÑŒ Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ один коллбек + info.add_tls_callback(0x100); //Добавим новый коллбек в TLS - отноÑительный адреÑ, Ñкорее вÑего, некорректен, поÑтому программа не запуÑтитÑÑ (проÑто Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð¼ÐµÑ€Ð°) + + info.set_raw_data("Hello, world!"); //УÑтановим или заменим "Ñырые" данные TLS + info.set_raw_data_start_rva(image.rva_from_section_offset(attached_section, 0)); //РаÑположим их Ñ Ð½Ð°Ñ‡Ð°Ð»Ð° добавленной Ñекции + info.recalc_raw_data_end_rva(); //ПроÑчитаем новый конечный Ð°Ð´Ñ€ÐµÑ "Ñырых" данных + + //ПереÑобираем TLS, раÑположив их Ñ 50-го байта (будет выровнено, ÑÐµÐºÑ†Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚ автоматичеÑки раÑширена) новой Ñекции и запиÑав новые данные TLS в PE-заголовок + //По умолчанию Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿ÐµÑ€ÐµÑобирает также TLS-коллбеки и "Ñырые" данные TLS, раÑÐ¿Ð¾Ð»Ð°Ð³Ð°Ñ Ð¸Ñ… по указанным в Ñтруктуре info адреÑам + //ÐžÐ¿Ñ†Ð¸Ñ expand позволÑет задать, как должны раÑпологатьÑÑ "Ñырые" данные + //tls_data_expand_raw позволÑет увеличить "Ñырой" размер Ñекции, то еÑÑ‚ÑŒ размер в файле + //tls_data_expand_virtual позволÑет увеличить виртуальный размер Ñекции Ñ Ð´Ð°Ð½Ð½Ñ‹Ð¼Ð¸ TLS + //ЕÑли не хватит меÑта под данные TLS, будет запиÑана только их чаÑÑ‚ÑŒ, или вообще ничего запиÑано не будет + rebuild_tls(image, info, attached_section, 50); + + //Создаем новый PE-файл + std::string base_file_name(argv[1]); + std::string::size_type slash_pos; + if((slash_pos = base_file_name.find_last_of("/\\")) != std::string::npos) + base_file_name = base_file_name.substr(slash_pos + 1); + + base_file_name = "new_" + base_file_name; + std::ofstream new_pe_file(base_file_name.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); + if(!new_pe_file) + { + std::cout << "Cannot create " << base_file_name << std::endl; + return -1; + } + + //ПереÑобираем PE-файл + rebuild_pe(image, new_pe_file); + + std::cout << "PE was rebuilt and saved to " << base_file_name << std::endl; + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/tls_editor/tls_editor.vcproj b/irdb-lib/pebliss/trunk/samples/tls_editor/tls_editor.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..249379c497facc0968f8e49e620a03f8576c94b2 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/tls_editor/tls_editor.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="tls_editor" + ProjectGUID="{781B56DF-15CE-4CBA-A008-0403029E558A}" + RootNamespace="tls_editor" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/tls_editor/tls_editor.vcxproj b/irdb-lib/pebliss/trunk/samples/tls_editor/tls_editor.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..cf2f3b9195050f2519ceb95eb29c2965e2a021c0 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/tls_editor/tls_editor.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{ABA9C7BF-D145-4066-8E0D-41C190BB5C0A}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>tls_editor</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/tls_editor/tls_editor.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/tls_editor/tls_editor.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/tls_editor/tls_editor.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/tls_reader/Makefile b/irdb-lib/pebliss/trunk/samples/tls_reader/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91d2ea5d90ed8ba9bfa09dd3d6ebfdd0934df9df --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/tls_reader/Makefile @@ -0,0 +1 @@ +include ../sample.mak diff --git a/irdb-lib/pebliss/trunk/samples/tls_reader/main.cpp b/irdb-lib/pebliss/trunk/samples/tls_reader/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4f5021ae4107a587d9d0d3ff80f643a05db06aba --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/tls_reader/main.cpp @@ -0,0 +1,58 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +//Пример, показывающий, как Ñчитать и получить информацию о ÑтатичеÑком TLS (Thread Local Storage, Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ð°Ñ Ð¿Ð°Ð¼ÑÑ‚ÑŒ потока) +//PE или PE+ файла +int main(int argc, char* argv[]) +{ + if(argc != 2) + { + std::cout << "Usage: tls_reader.exe PE_FILE" << std::endl; + return 0; + } + + //Открываем файл + std::ifstream pe_file(argv[1], std::ios::in | std::ios::binary); + if(!pe_file) + { + std::cout << "Cannot open " << argv[1] << std::endl; + return -1; + } + + try + { + //Создаем ÑкземплÑÑ€ PE или PE+ клаÑÑа Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ фабрики + pe_base image(pe_factory::create_pe(pe_file)); + + std::cout << "Reading PE TLS info..." << std::hex << std::showbase << std::endl << std::endl; + + //Получаем информацию о TLS + const tls_info info = get_tls_info(image); + + //Выводим информацию о TLS + std::cout << "Callbacks RVA: " << info.get_callbacks_rva() << std::endl + << "Index RVA: " << info.get_index_rva() << std::endl + << "Raw data start RVA: " << info.get_raw_data_start_rva() << std::endl + << "Raw data end RVA: " << info.get_raw_data_end_rva() << std::endl + << "Size of zero fill: " << info.get_size_of_zero_fill() << std::endl; + + //Выведем TLS-коллбеки: + const tls_info::tls_callback_list& tls_callbacks = info.get_tls_callbacks(); + for(tls_info::tls_callback_list::const_iterator it = tls_callbacks.begin(); it != tls_callbacks.end(); ++it) + std::cout << "Callback: " << (*it) << std::endl; + } + catch(const pe_exception& e) + { + //ЕÑли возникла ошибка + std::cout << "Error: " << e.what() << std::endl; + return -1; + } + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/samples/tls_reader/tls_reader.vcproj b/irdb-lib/pebliss/trunk/samples/tls_reader/tls_reader.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..7ff7bf6616ef86271700c149fbf3cee45e2bce29 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/tls_reader/tls_reader.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="tls_reader" + ProjectGUID="{BA36739B-F101-4C91-928D-678AB9521A22}" + RootNamespace="tls_reader" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/samples/tls_reader/tls_reader.vcxproj b/irdb-lib/pebliss/trunk/samples/tls_reader/tls_reader.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..0ab9a5e51f504047aa2d7d2cc75a589fa6aab423 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/tls_reader/tls_reader.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{CFB9A225-E2E5-43BC-898A-6D52357E7F92}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>tls_reader</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <EnablePREfast>false</EnablePREfast> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/samples/tls_reader/tls_reader.vcxproj.filters b/irdb-lib/pebliss/trunk/samples/tls_reader/tls_reader.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..33c9b83ec121a2f99a3c03bf1b76e0fac37d8d64 --- /dev/null +++ b/irdb-lib/pebliss/trunk/samples/tls_reader/tls_reader.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/Makefile b/irdb-lib/pebliss/trunk/tests/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..ab12c166d274c2c4d3ee5b268c9966a691e2b2d7 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/Makefile @@ -0,0 +1,21 @@ +TESTS = tests_utils tests_basic test_rich_data test_entropy test_runner test_checksum test_tls test_relocations test_load_config test_exception_directory test_imports test_exports test_resources test_bound_import test_resource_viewer test_dotnet test_debug test_resource_manager test_resource_bitmap test_resource_icon_cursor test_resource_string_table test_resource_message_table test_resource_version_info +OUTDIR = ./bin/ +LIBPATH = ../lib/libpebliss.a +TARGETS = $(foreach test,$(TESTS),$(test)_test) +TARGETS_CLEAN = $(foreach test,$(TESTS),$(test)_clean) + +all: $(TARGETS) run_all_tests + +clean: $(TARGETS_CLEAN) + +$(OUTDIR): + mkdir -p $(OUTDIR) + +%_test: $(OUTDIR) $(LIBPATH) + $(MAKE) PE_DEBUG=$(PE_DEBUG) -C ./$* + +%_clean: + $(MAKE) -C ./$* clean + +run_all_tests: + ./bin/test_runner diff --git a/irdb-lib/pebliss/trunk/tests/lib.h b/irdb-lib/pebliss/trunk/tests/lib.h new file mode 100644 index 0000000000000000000000000000000000000000..27d33526d5ecbf057866415831032aede4ce6cb9 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/lib.h @@ -0,0 +1,14 @@ +#pragma once +#ifndef _M_X64 +#ifdef _DEBUG +#pragma comment(lib, "../../Debug/pe_bliss.lib") +#else +#pragma comment(lib, "../../Release/pe_bliss.lib") +#endif +#else +#ifdef _DEBUG +#pragma comment(lib, "../../x64/Debug/pe_bliss.lib") +#else +#pragma comment(lib, "../../x64/Release/pe_bliss.lib") +#endif +#endif diff --git a/irdb-lib/pebliss/trunk/tests/pe_files/TestApp.exe b/irdb-lib/pebliss/trunk/tests/pe_files/TestApp.exe new file mode 100644 index 0000000000000000000000000000000000000000..c9487ab657b050ec13d66137ebb4894f7ca74b17 Binary files /dev/null and b/irdb-lib/pebliss/trunk/tests/pe_files/TestApp.exe differ diff --git a/irdb-lib/pebliss/trunk/tests/pe_files/bound32.exe b/irdb-lib/pebliss/trunk/tests/pe_files/bound32.exe new file mode 100644 index 0000000000000000000000000000000000000000..1d593d3e0384afd81e78c64c24eaf5ba13f0eec6 Binary files /dev/null and b/irdb-lib/pebliss/trunk/tests/pe_files/bound32.exe differ diff --git a/irdb-lib/pebliss/trunk/tests/pe_files/bound64.exe b/irdb-lib/pebliss/trunk/tests/pe_files/bound64.exe new file mode 100644 index 0000000000000000000000000000000000000000..e288befc9b9f38bf8854a8c4ad36c5958700139f Binary files /dev/null and b/irdb-lib/pebliss/trunk/tests/pe_files/bound64.exe differ diff --git a/irdb-lib/pebliss/trunk/tests/pe_files/debug_test.exe b/irdb-lib/pebliss/trunk/tests/pe_files/debug_test.exe new file mode 100644 index 0000000000000000000000000000000000000000..0dd38a057d04a80045bd0c89041b9dbbfb281d0b Binary files /dev/null and b/irdb-lib/pebliss/trunk/tests/pe_files/debug_test.exe differ diff --git a/irdb-lib/pebliss/trunk/tests/pe_files/image32.exe b/irdb-lib/pebliss/trunk/tests/pe_files/image32.exe new file mode 100644 index 0000000000000000000000000000000000000000..fab6f99f62f9e3733f3c7150d9125738062f8880 Binary files /dev/null and b/irdb-lib/pebliss/trunk/tests/pe_files/image32.exe differ diff --git a/irdb-lib/pebliss/trunk/tests/pe_files/image64.exe b/irdb-lib/pebliss/trunk/tests/pe_files/image64.exe new file mode 100644 index 0000000000000000000000000000000000000000..5f426f7f26598bff141eecdb5a2ed43313d47643 Binary files /dev/null and b/irdb-lib/pebliss/trunk/tests/pe_files/image64.exe differ diff --git a/irdb-lib/pebliss/trunk/tests/pe_files/message_table_resource.exe b/irdb-lib/pebliss/trunk/tests/pe_files/message_table_resource.exe new file mode 100644 index 0000000000000000000000000000000000000000..b28bd212a1a89e01445db69d7ef9ad94943b8cb4 Binary files /dev/null and b/irdb-lib/pebliss/trunk/tests/pe_files/message_table_resource.exe differ diff --git a/irdb-lib/pebliss/trunk/tests/pe_files/test_dll_32.dll b/irdb-lib/pebliss/trunk/tests/pe_files/test_dll_32.dll new file mode 100644 index 0000000000000000000000000000000000000000..5f9a485e00e147d79bd505020578dccac1f29e41 Binary files /dev/null and b/irdb-lib/pebliss/trunk/tests/pe_files/test_dll_32.dll differ diff --git a/irdb-lib/pebliss/trunk/tests/pe_files/test_dll_64.dll b/irdb-lib/pebliss/trunk/tests/pe_files/test_dll_64.dll new file mode 100644 index 0000000000000000000000000000000000000000..2bbcfcc401474468ee0ec92c8d187da60c0887af Binary files /dev/null and b/irdb-lib/pebliss/trunk/tests/pe_files/test_dll_64.dll differ diff --git a/irdb-lib/pebliss/trunk/tests/test.h b/irdb-lib/pebliss/trunk/tests/test.h new file mode 100644 index 0000000000000000000000000000000000000000..032214812ab04d1c736ff04254f62eac944cd414 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test.h @@ -0,0 +1,124 @@ +#pragma once +#include <string> +#include <iostream> +#include <typeinfo> +#include <exception> +#include <stdlib.h> + +enum test_level +{ + test_level_normal, + test_level_critical +}; + +static void pe_test_print_error(const std::string& test_name, + test_level level, + const std::string& expression, + const std::string& file, size_t line) +{ + std::cerr << test_name << " - FAIL!" << std::endl + << "File: " << file << ", line: " << line << std::endl + << "Expression: " << expression << std::endl << std::endl; + + if(level == test_level_critical) + exit(EXIT_FAILURE); +} + +static void pe_test(bool result, + const std::string& test_name, test_level level, + const std::string& expression, + const std::string& file, size_t line) +{ + if(result) + std::cout << test_name << " - OK" << std::endl; + else + pe_test_print_error(test_name, level, expression, file, line); +} + +static void pe_test_error(const std::exception& e, + const std::string& test_name, test_level level, + const std::string& expression, + const std::string& file, size_t line) +{ + std::cerr << test_name << " FAIL!" << std::endl + << "File: " << file << ", line: " << line << std::endl + << "Expression: " << expression << std::endl + << "Exception occured: " << e.what() << std::endl + << "Exception type: " << typeid(e).name() << std::endl << std::endl; + + if(level == test_level_critical) + exit(EXIT_FAILURE); +} + +#define PE_TEST_TO_STRING(expression) #expression + +//Checks the result of expression (true) +#define PE_TEST(expression, test_name, level) \ + try \ + { \ + pe_test((expression), test_name, level, PE_TEST_TO_STRING(expression), __FILE__, __LINE__); \ + } \ + catch(const std::exception& e) \ + { \ + pe_test_error(e, test_name, level, PE_TEST_TO_STRING(expression), __FILE__, __LINE__); \ + } + +//Runs expression and checks for exceptions +#define PE_TEST_EXCEPTION(expression, test_name, level) \ + try \ + { \ + (expression); \ + std::cout << test_name << " - OK" << std::endl; \ + } \ + catch(const std::exception& e) \ + { \ + pe_test_error(e, test_name, level, PE_TEST_TO_STRING(expression), __FILE__, __LINE__); \ + } + +//Awaits exception from expression +#define PE_TEST_EXPECT_EXCEPTION(expression, pe_exception_code, test_name, level) \ + try \ + { \ + (expression); \ + std::cerr << "Expected exception: " << PE_TEST_TO_STRING(pe_exception_code) << std::endl; \ + pe_test_print_error(test_name, level, PE_TEST_TO_STRING(expression), __FILE__, __LINE__); \ + } \ + catch(const pe_exception& e) \ + { \ + if(e.get_id() == pe_exception_code) \ + std::cout << test_name << " - OK" << std::endl; \ + else \ + pe_test_error(e, test_name, level, PE_TEST_TO_STRING(expression), __FILE__, __LINE__); \ + } + + +#ifndef PE_FILES_UNUSED +static bool open_pe_file(int argc, char* argv[], std::auto_ptr<std::ifstream>& pe_file) +{ + if(argc != 2) + { + std::cerr << "Usage: test.exe PE_FILE" << std::endl; + return false; + } + + pe_file.reset(new std::ifstream(argv[1], std::ios::in | std::ios::binary)); + if(!*pe_file) + { + std::cerr << "Cannot open " << argv[1] << std::endl; + return false; + } + + return true; +} +#endif + +#define PE_TEST_START \ + try \ + { + + +#define PE_TEST_END } \ + catch(const std::exception& e) \ + { \ + pe_test_error(e, "Global Test", test_level_critical, "global test exception handler", __FILE__, __LINE__); \ + } diff --git a/irdb-lib/pebliss/trunk/tests/test_bound_import/Makefile b/irdb-lib/pebliss/trunk/tests/test_bound_import/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..422827f1e3ba0c0d1373f3dcd0b7219c702e806e --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_bound_import/Makefile @@ -0,0 +1 @@ +include ../tests.mak diff --git a/irdb-lib/pebliss/trunk/tests/test_bound_import/main.cpp b/irdb-lib/pebliss/trunk/tests/test_bound_import/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..69b9cb937292c66e151cc5e4776d41702f59a162 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_bound_import/main.cpp @@ -0,0 +1,83 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#include "test.h" +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +void test_bound_imports(const pe_base& image) +{ + bound_import_module_list imports; + PE_TEST_EXCEPTION(imports = get_bound_import_module_list(image), "Bound Import Parser test", test_level_critical); + PE_TEST(imports.size() == 2, "Bound Import test 1", test_level_critical); + PE_TEST(imports[0].get_module_name() == "USER32.dll" + && imports[1].get_module_name() == "KERNEL32.dll", "Bound Import test 2", test_level_normal); + + if(image.get_pe_type() == pe_type_32) + { + PE_TEST(imports[0].get_timestamp() == 0x4a5bdb3c + && imports[1].get_timestamp() == 0x4afc68c0, "Bound Import test 3", test_level_normal); + } + else + { + PE_TEST(imports[0].get_timestamp() == 0x4a5bdb3c + && imports[1].get_timestamp() == 0, "Bound Import test 3", test_level_normal); + } + + PE_TEST(imports[0].get_module_ref_count() == 0 + && imports[1].get_module_ref_count() == 1, "Bound Import test 4", test_level_critical); + PE_TEST(imports[1].get_module_ref_list()[0].get_module_name() == "NTDLL.DLL" + && imports[1].get_module_ref_list()[0].get_timestamp() == 0x4afc681b, "Bound Import test 5", test_level_normal); +} + +int main(int argc, char* argv[]) +{ + PE_TEST_START + + std::auto_ptr<std::ifstream> pe_file; + if(!open_pe_file(argc, argv, pe_file)) + return -1; + + pe_base image(pe_factory::create_pe(*pe_file)); + test_bound_imports(image); + + { + std::stringstream new_pe(std::ios::in | std::ios::out | std::ios::binary); + PE_TEST_EXCEPTION(rebuild_pe(image, new_pe, false, true, true), "Bound Rebuild PE test 1", test_level_critical); + PE_TEST_EXCEPTION(image = pe_factory::create_pe(new_pe), "Bound Rebuild PE test 2", test_level_critical); + test_bound_imports(image); + + new_pe.str(""); + PE_TEST_EXCEPTION(rebuild_pe(image, new_pe, true, true, true), "Bound Rebuild PE test 3", test_level_critical); + PE_TEST_EXCEPTION(image = pe_factory::create_pe(new_pe), "Bound Rebuild PE test 4", test_level_critical); + test_bound_imports(image); + } + + + section s; + s.get_raw_data().resize(1); + s.set_name("newbound"); + s.readable(true); + section& new_bound_import_section = image.add_section(s); + bound_import_module_list imports; + PE_TEST_EXCEPTION(imports = get_bound_import_module_list(image), "Bound Import Parser test", test_level_critical); + + uint32_t old_bound_import_rva = image.get_directory_rva(pe_win::image_directory_entry_bound_import); + PE_TEST_EXCEPTION(rebuild_bound_imports(image, imports, new_bound_import_section, 0, true, true), "Bound Import Rebuilder test 1", test_level_critical); + PE_TEST(old_bound_import_rva != image.get_directory_rva(pe_win::image_directory_entry_bound_import), "Bound Import Directory test", test_level_normal); + test_bound_imports(image); + + new_bound_import_section.set_raw_data("111"); + old_bound_import_rva = image.get_directory_rva(pe_win::image_directory_entry_bound_import); + PE_TEST_EXCEPTION(rebuild_bound_imports(image, imports, new_bound_import_section, 3, true, true), "Bound Import Rebuilder test 2", test_level_critical); + PE_TEST(new_bound_import_section.get_raw_data().substr(0, 3) == "111", "Bound Import Rebuilder Offset test", test_level_normal); + PE_TEST(old_bound_import_rva != image.get_directory_rva(pe_win::image_directory_entry_bound_import), "Bound Import Directory test 2", test_level_normal); + test_bound_imports(image); + + PE_TEST_END + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/tests/test_bound_import/test_bound_import.vcproj b/irdb-lib/pebliss/trunk/tests/test_bound_import/test_bound_import.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..d3b1e34b2757741ccfd3eb5c9f6a095b0941179f --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_bound_import/test_bound_import.vcproj @@ -0,0 +1,359 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="test_bound_import" + ProjectGUID="{6EBEAFA6-7489-4026-83D1-CAF67D243119}" + RootNamespace="test_bound_import" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + <File + RelativePath="..\test.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/tests/test_bound_import/test_bound_import.vcxproj b/irdb-lib/pebliss/trunk/tests/test_bound_import/test_bound_import.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..1016788db89add3aaa45d3f4556860ee95eaf3d8 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_bound_import/test_bound_import.vcxproj @@ -0,0 +1,163 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{DA8A8F03-E719-45EF-A376-766A18772FA5}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>test_bound_import</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_bound_import/test_bound_import.vcxproj.filters b/irdb-lib/pebliss/trunk/tests/test_bound_import/test_bound_import.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..8755a3a0268981c2f6fee186ee23f9488c6d781c --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_bound_import/test_bound_import.vcxproj.filters @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_checksum/Makefile b/irdb-lib/pebliss/trunk/tests/test_checksum/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..422827f1e3ba0c0d1373f3dcd0b7219c702e806e --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_checksum/Makefile @@ -0,0 +1 @@ +include ../tests.mak diff --git a/irdb-lib/pebliss/trunk/tests/test_checksum/main.cpp b/irdb-lib/pebliss/trunk/tests/test_checksum/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6fc33b1f8bdd6e101db36a982edb2e0b76020306 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_checksum/main.cpp @@ -0,0 +1,28 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#include "test.h" +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +int main(int argc, char* argv[]) +{ + PE_TEST_START + + std::auto_ptr<std::ifstream> pe_file; + if(!open_pe_file(argc, argv, pe_file)) + return -1; + + pe_base image(pe_factory::create_pe(*pe_file)); + + uint32_t checksum = -1; + PE_TEST_EXCEPTION(checksum = calculate_checksum(*pe_file), "Checksum test 1", test_level_normal); + PE_TEST(image.get_checksum() == checksum, "Checksum test 2", test_level_normal); + + PE_TEST_END + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/tests/test_checksum/test_checksum.vcproj b/irdb-lib/pebliss/trunk/tests/test_checksum/test_checksum.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..b40b3542d35f4c506a79c9c4cd2b9f225648d3d1 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_checksum/test_checksum.vcproj @@ -0,0 +1,359 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="test_checksum" + ProjectGUID="{7F95DC75-2CFA-4D0D-BD43-1BF6749F16EE}" + RootNamespace="test_checksum" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + <File + RelativePath="..\test.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/tests/test_checksum/test_checksum.vcxproj b/irdb-lib/pebliss/trunk/tests/test_checksum/test_checksum.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..00822bc45c6dc5ab71855f9207c1927241d5bc48 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_checksum/test_checksum.vcxproj @@ -0,0 +1,168 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{7B7AEAB2-7755-409D-A6C9-D5FFB7D1A95A}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>test_other</RootNamespace> + <ProjectName>test_checksum</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + <ClInclude Include="..\test.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_checksum/test_checksum.vcxproj.filters b/irdb-lib/pebliss/trunk/tests/test_checksum/test_checksum.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..8f0719260417c2cc422a533c4a0c453eb3d84c1a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_checksum/test_checksum.vcxproj.filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\test.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_debug/Makefile b/irdb-lib/pebliss/trunk/tests/test_debug/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..422827f1e3ba0c0d1373f3dcd0b7219c702e806e --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_debug/Makefile @@ -0,0 +1 @@ +include ../tests.mak diff --git a/irdb-lib/pebliss/trunk/tests/test_debug/main.cpp b/irdb-lib/pebliss/trunk/tests/test_debug/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..77f010dc76115884b5ba8f6a041cdf0cb3e70441 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_debug/main.cpp @@ -0,0 +1,122 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#include "test.h" +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +void debug_test(const debug_info& dbg) +{ + PE_TEST(dbg.get_characteristics() == 0 + && dbg.get_time_stamp() == 0x50757757 + && dbg.get_major_version() == 0 + && dbg.get_minor_version() == 0 + && dbg.get_rva_of_raw_data() == 0, + "Debug Basic Info test", test_level_normal); +} + +int main(int argc, char* argv[]) +{ + PE_TEST_START + + std::auto_ptr<std::ifstream> pe_file; + if(!open_pe_file(argc, argv, pe_file)) + return -1; + + pe_base image(pe_factory::create_pe(*pe_file)); + + debug_info_list info; + PE_TEST_EXCEPTION(info = get_debug_information(image), "Debug Info Parser test", test_level_critical); + + if(image.get_pe_type() == pe_type_32) + { + { + PE_TEST(info.size() == 3, "Debug Info test 1", test_level_critical); + debug_info& dbg = info[0]; + debug_test(dbg); + PE_TEST(dbg.get_size_of_data() == 0x00008CB1, "Debug Info test 2", test_level_normal); + + PE_TEST(dbg.get_type() == debug_info::debug_type_coff + && dbg.get_advanced_info_type() == debug_info::advanced_info_coff, "Debug Info test 3", test_level_critical); + + coff_debug_info advanced; + PE_TEST_EXCEPTION(advanced = dbg.get_advanced_debug_info<coff_debug_info>(), "Debug COFF Info Parser test", test_level_critical); + PE_TEST(advanced.get_number_of_line_numbers() == 0 + && advanced.get_number_of_symbols() == 0x4E9, "Debug Info test 4", test_level_critical); + PE_TEST(advanced.get_lva_to_first_line_number() == 0 + && advanced.get_lva_to_first_symbol() == 0x20 + && advanced.get_rva_to_first_byte_of_code() == 0x1000 + && advanced.get_rva_to_first_byte_of_data() == 0xE000 + && advanced.get_rva_to_last_byte_of_code() == 0xE000 + && advanced.get_rva_to_last_byte_of_data() == 0x7000, "Debug Info test 5", test_level_normal); + + const coff_debug_info::coff_symbol& sym = advanced.get_symbols()[1]; + PE_TEST(sym.get_index() == 0x55 && sym.get_rva() == 0xCD1C + && sym.get_section_number() == 1 + && sym.get_storage_class() == 3 + && sym.get_type() == 0 + && !sym.is_file() + && sym.get_symbol() == "UnwindUpVec", "Debug Info test 6", test_level_normal); + } + + { + debug_info& dbg = info[1]; + debug_test(dbg); + PE_TEST(dbg.get_size_of_data() == 0x110, "Debug Info test 7", test_level_normal); + + PE_TEST(dbg.get_type() == debug_info::debug_type_misc + && dbg.get_advanced_info_type() == debug_info::advanced_info_misc, "Debug Info test 8", test_level_critical); + + misc_debug_info advanced; + PE_TEST_EXCEPTION(advanced = dbg.get_advanced_debug_info<misc_debug_info>(), "Debug MISC Info Parser test", test_level_critical); + PE_TEST(advanced.is_exe_name(), "Debug MISC test 1", test_level_normal); + PE_TEST(!advanced.is_unicode(), "Debug MISC test 2", test_level_normal); + PE_TEST(advanced.get_data_ansi() == "Debug/debugtest.exe", "Debug MISC test 3", test_level_normal); + } + + { + debug_info& dbg = info[2]; + debug_test(dbg); + PE_TEST(dbg.get_size_of_data() == 0x68, "Debug Info test 9", test_level_normal); + + PE_TEST(dbg.get_type() == debug_info::debug_type_codeview + && dbg.get_advanced_info_type() == debug_info::advanced_info_pdb_2_0, "Debug Info test 10", test_level_critical); + + pdb_2_0_info advanced; + PE_TEST_EXCEPTION(advanced = dbg.get_advanced_debug_info<pdb_2_0_info>(), "Debug PDB 2.0 Info Parser test", test_level_critical); + PE_TEST(advanced.get_age() == 1, "Debug PDB 2.0 test 1", test_level_normal); + PE_TEST(advanced.get_signature() == 0x50757757, "Debug PDB 2.0 test 2", test_level_normal); + PE_TEST(advanced.get_pdb_file_name() == "C:\\Program Files (x86)\\Microsoft Visual Studio\\MyProjects\\debugtest\\Debug\\debugtest.pdb", "Debug PDB 2.0 test 3", test_level_normal); + } + } + else + { + PE_TEST(info.size() == 1, "Debug Info test 1", test_level_critical); + debug_info& dbg = info[0]; + PE_TEST(dbg.get_characteristics() == 0 + && dbg.get_time_stamp() == 0x50937d36 + && dbg.get_major_version() == 0 + && dbg.get_minor_version() == 0 + && dbg.get_rva_of_raw_data() == 0x0001F300 + && dbg.get_size_of_data() == 0x0000006F, + "Debug Basic Info test", test_level_normal); + + PE_TEST(dbg.get_type() == debug_info::debug_type_codeview + && dbg.get_advanced_info_type() == debug_info::advanced_info_pdb_7_0, "Debug Info test 2", test_level_critical); + + pdb_7_0_info advanced; + PE_TEST_EXCEPTION(advanced = dbg.get_advanced_debug_info<pdb_7_0_info>(), "Debug PDB 7.0 Info Parser test", test_level_critical); + PE_TEST(advanced.get_age() == 1, "Debug PDB 7.0 test 1", test_level_normal); + + pe_win::guid testguid = {0xCC311030, 0xD245, 0x4FF7, {0x9F, 0x16, 0xB5, 0x6D, 0x8B, 0x11, 0x1F, 0x1A}}; + PE_TEST(advanced.get_guid() == testguid, "Debug PDB 7.0 test 2", test_level_normal); + PE_TEST(advanced.get_pdb_file_name() == "C:\\Users\\Bliss\\Documents\\Visual Studio 2010\\Projects\\hello_world\\x64\\Release\\test1.pdb", "Debug PDB 7.0 test 3", test_level_normal); + } + + PE_TEST_END + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/tests/test_debug/test_debug.vcproj b/irdb-lib/pebliss/trunk/tests/test_debug/test_debug.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..a2aac4b0d0e9f9dcc266f71cb21994a1cc830008 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_debug/test_debug.vcproj @@ -0,0 +1,359 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="test_debug" + ProjectGUID="{42AC1521-0800-4D81-9363-6EF9362F7A4A}" + RootNamespace="test_debug" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + <File + RelativePath="..\test.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/tests/test_debug/test_debug.vcxproj b/irdb-lib/pebliss/trunk/tests/test_debug/test_debug.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..4de2d750a924a36f7b577ca457c567526de7f3ad --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_debug/test_debug.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{B82FC407-B927-49D1-9DEB-0DFC3DC12A9C}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>test_debug</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + <ClInclude Include="..\test.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_debug/test_debug.vcxproj.filters b/irdb-lib/pebliss/trunk/tests/test_debug/test_debug.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..8f0719260417c2cc422a533c4a0c453eb3d84c1a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_debug/test_debug.vcxproj.filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\test.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_dotnet/Makefile b/irdb-lib/pebliss/trunk/tests/test_dotnet/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..422827f1e3ba0c0d1373f3dcd0b7219c702e806e --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_dotnet/Makefile @@ -0,0 +1 @@ +include ../tests.mak diff --git a/irdb-lib/pebliss/trunk/tests/test_dotnet/main.cpp b/irdb-lib/pebliss/trunk/tests/test_dotnet/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d5ec9b37aced4e7f087f7793d9d2550d6099f8eb --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_dotnet/main.cpp @@ -0,0 +1,39 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#include "test.h" +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +int main(int argc, char* argv[]) +{ + PE_TEST_START + + std::auto_ptr<std::ifstream> pe_file; + if(!open_pe_file(argc, argv, pe_file)) + return -1; + + pe_base image(pe_factory::create_pe(*pe_file)); + + basic_dotnet_info info; + PE_TEST_EXCEPTION(info = get_basic_dotnet_info(image), "Basic Dotnet Info Parser test", test_level_critical); + PE_TEST(info.get_flags() == 1, "DotNet test 1", test_level_normal); + PE_TEST(info.get_major_runtime_version() == 2 && info.get_minor_runtime_version() == 5, "DotNet test 2", test_level_normal); + PE_TEST(info.get_rva_of_metadata() == 0x2064 && info.get_size_of_metadata() == 0x598, "DotNet test 3", test_level_normal); + PE_TEST(info.get_rva_of_resources() == 0 && info.get_size_of_resources() == 0, "DotNet test 4", test_level_normal); + PE_TEST(info.get_rva_of_strong_name_signature() == 0 && info.get_size_of_strong_name_signature() == 0, "DotNet test 5", test_level_normal); + PE_TEST(info.get_rva_of_code_manager_table() == 0 && info.get_size_of_code_manager_table() == 0, "DotNet test 6", test_level_normal); + PE_TEST(info.get_rva_of_vtable_fixups() == 0 && info.get_size_of_vtable_fixups() == 0, "DotNet test 7", test_level_normal); + PE_TEST(info.get_rva_of_export_address_table_jumps() == 0 && info.get_size_of_export_address_table_jumps() == 0, "DotNet test 8", test_level_normal); + PE_TEST(info.get_rva_of_managed_native_header() == 0 && info.get_size_of_managed_native_header() == 0, "DotNet test 9", test_level_normal); + PE_TEST(info.get_entry_point_rva_or_token() == 0x06000001, "DotNet test 10", test_level_normal); + PE_TEST(!info.is_native_entry_point(), "DotNet test 11", test_level_normal); + PE_TEST(!info.is_32bit_required(), "DotNet test 12", test_level_normal); + + PE_TEST_END + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/tests/test_dotnet/test_dotnet.vcproj b/irdb-lib/pebliss/trunk/tests/test_dotnet/test_dotnet.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..40fcfc8f824b3347217698567822fccd119ba210 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_dotnet/test_dotnet.vcproj @@ -0,0 +1,359 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="test_dotnet" + ProjectGUID="{094A7331-54E1-4034-BD1E-BE2F974B0142}" + RootNamespace="test_dotnet" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + <File + RelativePath="..\test.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/tests/test_dotnet/test_dotnet.vcxproj b/irdb-lib/pebliss/trunk/tests/test_dotnet/test_dotnet.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..41ff9fca4dead700260d0f59da90b074f0b52083 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_dotnet/test_dotnet.vcxproj @@ -0,0 +1,168 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{F8A9C956-AA19-4AEF-B1B7-E7C392E437FE}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>test_dotner</RootNamespace> + <ProjectName>test_dotnet</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + <ClInclude Include="..\test.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_dotnet/test_dotnet.vcxproj.filters b/irdb-lib/pebliss/trunk/tests/test_dotnet/test_dotnet.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..8f0719260417c2cc422a533c4a0c453eb3d84c1a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_dotnet/test_dotnet.vcxproj.filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\test.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_entropy/Makefile b/irdb-lib/pebliss/trunk/tests/test_entropy/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..422827f1e3ba0c0d1373f3dcd0b7219c702e806e --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_entropy/Makefile @@ -0,0 +1 @@ +include ../tests.mak diff --git a/irdb-lib/pebliss/trunk/tests/test_entropy/main.cpp b/irdb-lib/pebliss/trunk/tests/test_entropy/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3bb6d116e6f7694cc9bf48f1b335b738c7e7a9b2 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_entropy/main.cpp @@ -0,0 +1,34 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#include "test.h" +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +int main(int argc, char* argv[]) +{ + PE_TEST_START + + std::auto_ptr<std::ifstream> pe_file; + if(!open_pe_file(argc, argv, pe_file)) + return -1; + + pe_base image(pe_factory::create_pe(*pe_file)); + + PE_TEST(entropy_calculator::calculate_entropy(image) > 3.0, "Entropy test 1", test_level_normal); + PE_TEST(entropy_calculator::calculate_entropy(*pe_file) > 3.0, "Entropy test 2", test_level_normal); + PE_TEST(entropy_calculator::calculate_entropy(image.get_image_sections().at(0)) > 3.0, "Entropy test 3", test_level_normal); + + const char data[] = "123456789"; + PE_TEST(entropy_calculator::calculate_entropy(data, sizeof(data) - 1) > 3.0, "Entropy test 4", test_level_normal); + + PE_TEST_EXPECT_EXCEPTION(entropy_calculator::calculate_entropy("", 0), pe_exception::data_is_empty, "Entropy test 5", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(entropy_calculator::calculate_entropy(section()), pe_exception::section_is_empty, "Entropy test 6", test_level_normal); + + PE_TEST_END + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/tests/test_entropy/test_entropy.vcproj b/irdb-lib/pebliss/trunk/tests/test_entropy/test_entropy.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..1b1287445d4b3d4a0d278979af3cdfb4655a6442 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_entropy/test_entropy.vcproj @@ -0,0 +1,359 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="test_entropy" + ProjectGUID="{D3FAD2A8-FF48-4E59-A347-C54AD9DB6AC4}" + RootNamespace="test_entropy" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + <File + RelativePath="..\test.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/tests/test_entropy/test_entropy.vcxproj b/irdb-lib/pebliss/trunk/tests/test_entropy/test_entropy.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..8cfdcdb616bb75e08075f973b1e95c810e4d3e22 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_entropy/test_entropy.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{853CFFF4-1FAB-48EB-81A9-CC35F9FB3F80}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>test_entropy</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + <ClInclude Include="..\test.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_entropy/test_entropy.vcxproj.filters b/irdb-lib/pebliss/trunk/tests/test_entropy/test_entropy.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..8f0719260417c2cc422a533c4a0c453eb3d84c1a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_entropy/test_entropy.vcxproj.filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\test.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_exception_directory/Makefile b/irdb-lib/pebliss/trunk/tests/test_exception_directory/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..422827f1e3ba0c0d1373f3dcd0b7219c702e806e --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_exception_directory/Makefile @@ -0,0 +1 @@ +include ../tests.mak diff --git a/irdb-lib/pebliss/trunk/tests/test_exception_directory/main.cpp b/irdb-lib/pebliss/trunk/tests/test_exception_directory/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f8521eaed3517175822d595cc444a2c7c9d6c681 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_exception_directory/main.cpp @@ -0,0 +1,40 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#include "test.h" +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +int main(int argc, char* argv[]) +{ + PE_TEST_START + + std::auto_ptr<std::ifstream> pe_file; + if(!open_pe_file(argc, argv, pe_file)) + return -1; + + pe_base image(pe_factory::create_pe(*pe_file)); + + if(image.get_pe_type() == pe_type_64) + { + exception_entry_list info; + PE_TEST_EXCEPTION(info = get_exception_directory_data(image), "Exception directory parser test", test_level_critical); + PE_TEST(info.size() == 0x1C6, "Exception directory test 1", test_level_normal); + PE_TEST(info[5].get_begin_address() == 0x000011D5 + && info[5].get_end_address() == 0x00001220, "Exception directory test 2", test_level_normal); + PE_TEST(info[5].get_flags() == 4, "Exception directory test 3", test_level_normal); + PE_TEST(info[5].get_unwind_info_address() == 0x21528, "Exception directory test 4", test_level_normal); + PE_TEST(info[5].get_unwind_info_version() == 1, "Exception directory test 5", test_level_normal); + PE_TEST(info[5].get_size_of_prolog() == 0x5, "Exception directory test 6", test_level_normal); + PE_TEST(info[5].get_number_of_unwind_slots() == 2, "Exception directory test 7", test_level_normal); + PE_TEST(info[5].get_frame_pointer_register_number() == 0, "Exception directory test 8", test_level_normal); + PE_TEST(info[5].get_scaled_rsp_offset() == 0, "Exception directory test 9", test_level_normal); + } + + PE_TEST_END + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/tests/test_exception_directory/test_exception_directory.vcproj b/irdb-lib/pebliss/trunk/tests/test_exception_directory/test_exception_directory.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..91d5bde30c1de0690215a6400087bf12ffdf35cf --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_exception_directory/test_exception_directory.vcproj @@ -0,0 +1,359 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="test_exception_directory" + ProjectGUID="{1C36ED94-CBE5-4107-83B6-9C37F3A4041C}" + RootNamespace="test_exception_directory" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + <File + RelativePath="..\test.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/tests/test_exception_directory/test_exception_directory.vcxproj b/irdb-lib/pebliss/trunk/tests/test_exception_directory/test_exception_directory.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..03fcdf08b808ea474b6b57257c798fa1304ed66c --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_exception_directory/test_exception_directory.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{B6A37BAA-484D-4175-BEA2-62892A12E8F5}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>test_exception_directory</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + <ClInclude Include="..\test.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_exception_directory/test_exception_directory.vcxproj.filters b/irdb-lib/pebliss/trunk/tests/test_exception_directory/test_exception_directory.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..8f0719260417c2cc422a533c4a0c453eb3d84c1a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_exception_directory/test_exception_directory.vcxproj.filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\test.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_exports/Makefile b/irdb-lib/pebliss/trunk/tests/test_exports/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..422827f1e3ba0c0d1373f3dcd0b7219c702e806e --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_exports/Makefile @@ -0,0 +1 @@ +include ../tests.mak diff --git a/irdb-lib/pebliss/trunk/tests/test_exports/main.cpp b/irdb-lib/pebliss/trunk/tests/test_exports/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..23965cf09c89cca67ce425b9d31c2dbcd5bf62df --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_exports/main.cpp @@ -0,0 +1,147 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#include "test.h" +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +void test_exports(const export_info& info, const exported_functions_list& exports, const pe_base& image, bool test_rvas = true) +{ + PE_TEST(info.get_characteristics() == 0 + && info.get_major_version() == 0 + && info.get_minor_version() == 0 + && info.get_ordinal_base() == 5 + && info.get_name() == "test_dll.dll" + && info.get_number_of_functions() == 6 + && info.get_number_of_names() == 3, "Exports test 1", test_level_normal); + + if(test_rvas) + { + if(image.get_pe_type() == pe_type_32) + { + PE_TEST(info.get_timestamp() == 0x509103D8 + && info.get_rva_of_functions() == 0x00002588 + && info.get_rva_of_names() == 0x000025A0 + && info.get_rva_of_name_ordinals() == 0x000025AC, "Exports test 2", test_level_normal); + } + else + { + PE_TEST(info.get_timestamp() == 0x509103D3 + && info.get_rva_of_functions() == 0x00002718 + && info.get_rva_of_names() == 0x00002730 + && info.get_rva_of_name_ordinals() == 0x0000273C, "Exports test 2", test_level_normal); + } + } + + PE_TEST(exports.size() == 4, "Exports test 3", test_level_critical); + + PE_TEST(exports[0].has_name() && exports[0].get_name() == "dll_func1", "Exports test 4", test_level_normal); + PE_TEST(!exports[0].is_forwarded(), "Exports test 5", test_level_normal); + PE_TEST(exports[0].get_name_ordinal() == 0 && exports[0].get_ordinal() == 5, "Exports test 6", test_level_normal); + PE_TEST(exports[0].get_rva() == 0x00001000, "Exports test 7", test_level_normal); + + PE_TEST(exports[2].has_name() && exports[2].get_name() == "MsgBoxA", "Exports test 8", test_level_normal); + PE_TEST(exports[2].is_forwarded() && exports[2].get_forwarded_name() == "USER32.MessageBoxA", "Exports test 9", test_level_normal); + PE_TEST(exports[2].get_name_ordinal() == 2 && exports[2].get_ordinal() == 7, "Exports test 10", test_level_normal); + + if(test_rvas) + { + if(image.get_pe_type() == pe_type_32) + { + PE_TEST(exports[2].get_rva() == 0x000025DB, "Exports test 11", test_level_normal); + } + else + { + PE_TEST(exports[2].get_rva() == 0x0000276B, "Exports test 11", test_level_normal); + } + } + + PE_TEST(!exports[3].has_name() && exports[3].get_ordinal() == 0xA, "Exports test 12", test_level_normal); + PE_TEST(!exports[3].is_forwarded(), "Exports test 13", test_level_normal); + PE_TEST(exports[3].get_rva() == 0x00001020, "Exports test 14", test_level_normal); + + std::pair<uint16_t, uint16_t> limits; + PE_TEST_EXCEPTION(limits = get_export_ordinal_limits(exports), "get_export_ordinal_limits test 1", test_level_normal); + PE_TEST(limits.first == info.get_ordinal_base() && limits.second == 0xA, "get_export_ordinal_limits test 2", test_level_normal); + + PE_TEST(exported_name_exists("MsgBoxA", exports), "exported_name_exists test 1", test_level_normal); + PE_TEST(exported_name_exists("dll_func1", exports), "exported_name_exists test 2", test_level_normal); + PE_TEST(!exported_name_exists("dll_func2", exports), "exported_name_exists test 3", test_level_normal); + PE_TEST(!exported_name_exists("USER32.MessageBoxA", exports), "exported_name_exists test 4", test_level_normal); + + PE_TEST(exported_ordinal_exists(0x5, exports), "exported_ordinal_exists test 1", test_level_normal); + PE_TEST(exported_ordinal_exists(0xA, exports), "exported_ordinal_exists test 2", test_level_normal); + PE_TEST(!exported_ordinal_exists(0x1, exports), "exported_ordinal_exists test 3", test_level_normal); + PE_TEST(!exported_ordinal_exists(0x9, exports), "exported_ordinal_exists test 4", test_level_normal); +} + +int main(int argc, char* argv[]) +{ + PE_TEST_START + + std::auto_ptr<std::ifstream> pe_file; + if(!open_pe_file(argc, argv, pe_file)) + return -1; + + pe_base image(pe_factory::create_pe(*pe_file)); + + exported_functions_list exports; + export_info info; + PE_TEST_EXCEPTION(exports = get_exported_functions(image, info), "Exports Parser test 1", test_level_critical); + test_exports(info, exports, image); + + PE_TEST_EXCEPTION(rebuild_exports(image, info, exports, image.section_from_directory(pe_win::image_directory_entry_export), 0, true, true), "Exports Rebuilder test 1", test_level_critical); + PE_TEST_EXCEPTION(exports = get_exported_functions(image, info), "Exports Parser test 2", test_level_critical); + test_exports(info, exports, image, false); + + section s; + s.get_raw_data().resize(1); + s.set_name("newexp"); + section& new_export_section = image.add_section(s); + uint32_t old_export_rva = image.get_directory_rva(pe_win::image_directory_entry_export); + PE_TEST_EXCEPTION(rebuild_exports(image, info, exports, new_export_section, 0, true, true), "Exports Rebuilder test 2", test_level_critical); + PE_TEST(old_export_rva != image.get_directory_rva(pe_win::image_directory_entry_export), "Exports Rebuilder test 3", test_level_normal); + PE_TEST_EXCEPTION(exports = get_exported_functions(image, info), "Exports Parser test 3", test_level_critical); + test_exports(info, exports, image, false); + + new_export_section.set_raw_data("111"); + PE_TEST_EXCEPTION(rebuild_exports(image, info, exports, new_export_section, 3, true, true), "Exports Rebuilder test 4", test_level_critical); + PE_TEST(new_export_section.get_raw_data().substr(0, 3) == "111", "Exports Rebuilder offset test 1", test_level_normal); + PE_TEST_EXCEPTION(exports = get_exported_functions(image, info), "Exports Parser test 4", test_level_critical); + test_exports(info, exports, image, false); + + new_export_section.set_raw_data("111111111111"); + PE_TEST_EXCEPTION(rebuild_exports(image, info, exports, new_export_section, 12, true, true), "Exports Rebuilder test 5", test_level_critical); + PE_TEST(new_export_section.get_raw_data().substr(0, 12) == "111111111111", "Exports Rebuilder offset test 2", test_level_normal); + PE_TEST_EXCEPTION(exports = get_exported_functions(image, info), "Exports Parser test 5", test_level_critical); + test_exports(info, exports, image, false); + + exported_function func; + func.set_ordinal(0xA); + func.set_name("DuplicatedOrdinal"); + func.set_rva(0x1000); + exports.push_back(func); + PE_TEST_EXPECT_EXCEPTION(rebuild_exports(image, info, exports, new_export_section, 12, true, true), pe_exception::duplicate_exported_function_ordinal, "Exports Rebuilder test 6", test_level_normal); + + exports.back().set_ordinal(0xC); + exports.back().set_name("MsgBoxA"); //Duplicate name + PE_TEST_EXPECT_EXCEPTION(rebuild_exports(image, info, exports, new_export_section, 12, true, true), pe_exception::duplicate_exported_function_name, "Exports Rebuilder test 7", test_level_normal); + + exports.back().set_ordinal(0xC); + exports.back().set_name("ANewFunction"); + exports.back().set_ordinal(0xF); + PE_TEST_EXCEPTION(rebuild_exports(image, info, exports, new_export_section, 12, true, true), "Exports Rebuilder test 8", test_level_normal); + PE_TEST_EXCEPTION(exports = get_exported_functions(image, info), "Exports Parser test 6", test_level_critical); + + PE_TEST(exports.size() == 5, "New Exported Function test 1", test_level_critical); + PE_TEST(exports[4].has_name() && exports[4].get_name() == "ANewFunction", "New Exported Function test 2", test_level_normal); + PE_TEST(!exports[4].is_forwarded(), "New Exported Function test 3", test_level_normal); + PE_TEST(exports[4].get_rva() == 0x00001000, "New Exported Function test 4", test_level_normal); + + PE_TEST_END + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/tests/test_exports/test_exports.vcproj b/irdb-lib/pebliss/trunk/tests/test_exports/test_exports.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..af99cbe4cfb8108b675c2c924c03d805a8e494a9 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_exports/test_exports.vcproj @@ -0,0 +1,359 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="test_exports" + ProjectGUID="{E126644C-38FF-41EF-9EAF-ED8C9FCF62EF}" + RootNamespace="test_exports" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + <File + RelativePath="..\test.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/tests/test_exports/test_exports.vcxproj b/irdb-lib/pebliss/trunk/tests/test_exports/test_exports.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..d40a35cb422b0704ee279bf2c1b90a4ba4c24c51 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_exports/test_exports.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{82EAF17E-9618-4BD7-AE50-0C325591B585}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>test_exports</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + <ClInclude Include="..\test.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_exports/test_exports.vcxproj.filters b/irdb-lib/pebliss/trunk/tests/test_exports/test_exports.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..8f0719260417c2cc422a533c4a0c453eb3d84c1a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_exports/test_exports.vcxproj.filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\test.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_imports/Makefile b/irdb-lib/pebliss/trunk/tests/test_imports/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..422827f1e3ba0c0d1373f3dcd0b7219c702e806e --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_imports/Makefile @@ -0,0 +1 @@ +include ../tests.mak diff --git a/irdb-lib/pebliss/trunk/tests/test_imports/main.cpp b/irdb-lib/pebliss/trunk/tests/test_imports/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..242eb7c67835fd6cd5de70cd8d95ef90a73cc72c --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_imports/main.cpp @@ -0,0 +1,192 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#include "test.h" +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +void compare_imports(const imported_functions_list& imports, const imported_functions_list& new_imports, bool compare_original_iat = true) +{ + PE_TEST(imports.size() == new_imports.size(), "Import compare test (libraries)", test_level_critical); + for(size_t i = 0; i != imports.size(); ++i) + { + std::cout << "Library iteration = " << i << std::endl; + const import_library::imported_list& funcs = imports[i].get_imported_functions(); + const import_library::imported_list& new_funcs = new_imports[i].get_imported_functions(); + + PE_TEST(imports[i].get_name() == new_imports[i].get_name() + && imports[i].get_rva_to_iat() == new_imports[i].get_rva_to_iat() + && imports[i].get_timestamp() == new_imports[i].get_timestamp(), + "Import compare test (library properties)", test_level_normal); + + if(compare_original_iat) + { + PE_TEST(imports[i].get_rva_to_original_iat() == new_imports[i].get_rva_to_original_iat(), "Import compare test (library properties)", test_level_normal); + } + + PE_TEST(funcs.size() == new_funcs.size(), "Import compare test (function count)", test_level_critical); + for(size_t j = 0; j != new_funcs.size(); ++j) + { + std::cout << "Function iteration = " << j << std::endl; + PE_TEST(funcs[i].has_name() == new_funcs[i].has_name(), "Import compare test (function properties)", test_level_normal); + + if(compare_original_iat) + { + PE_TEST(funcs[i].get_iat_va() == new_funcs[i].get_iat_va(), "Import compare test (function properties)", test_level_normal); + } + + if(funcs[i].has_name()) + { + PE_TEST(funcs[i].get_name() == new_funcs[i].get_name() && funcs[i].get_hint() == new_funcs[i].get_hint(), "Import compare test (function properties)", test_level_normal); + } + else + { + PE_TEST(funcs[i].get_ordinal() == new_funcs[i].get_ordinal(), "Import compare test (function properties)", test_level_normal); + } + } + } +} + +int main(int argc, char* argv[]) +{ + PE_TEST_START + + std::auto_ptr<std::ifstream> pe_file; + if(!open_pe_file(argc, argv, pe_file)) + return -1; + + pe_base image(pe_factory::create_pe(*pe_file)); + + imported_functions_list imports; + PE_TEST_EXCEPTION(imports = get_imported_functions(image), "get_imported_functions test", test_level_critical); + PE_TEST(imports.size() == 2, "Imports test 1", test_level_normal); + PE_TEST(imports.at(0).get_name() == "USER32.dll", "Imports test 2", test_level_normal); + PE_TEST(imports.at(1).get_name() == "KERNEL32.dll", "Imports test 3", test_level_normal); + + import_library& user32 = imports.at(0); + import_library& kernel32 = imports.at(1); + + PE_TEST(user32.get_imported_functions().at(0).has_name() && user32.get_imported_functions().at(0).get_name() == "MessageBoxW", "Imports test 4", test_level_normal); + PE_TEST(kernel32.get_timestamp() == 0, "Imports test 5", test_level_normal); + + if(image.get_pe_type() == pe_type_32) + { + PE_TEST(kernel32.get_rva_to_iat() == 0x00018000, "Imports test 6", test_level_normal); + PE_TEST(kernel32.get_rva_to_original_iat() == 0x0001CA20, "Imports test 7", test_level_normal); + PE_TEST(user32.get_imported_functions().at(0).get_hint() == 0x215, "Imports test 8", test_level_normal); + } + else + { + PE_TEST(kernel32.get_rva_to_iat() == 0x0001B000, "Imports test 6", test_level_normal); + PE_TEST(kernel32.get_rva_to_original_iat() == 0x00022428, "Imports test 7", test_level_normal); + PE_TEST(user32.get_imported_functions().at(0).get_hint() == 0x219, "Imports test 8", test_level_normal); + } + + + imported_functions_list new_imports; + + section s; + s.get_raw_data().resize(1); + section& import_section = image.add_section(s); + + import_rebuilder_settings settings(true, false); + settings.build_original_iat(true); + settings.enable_auto_strip_last_section(true); + settings.fill_missing_original_iats(false); + settings.save_iat_and_original_iat_rvas(true, false); + settings.set_offset_from_section_start(0); + + image_directory import_dir; + PE_TEST_EXCEPTION(import_dir = rebuild_imports(image, imports, import_section, settings), "Import rebuilder test 1", test_level_critical); + PE_TEST_EXCEPTION(new_imports = get_imported_functions(image), "get_imported_functions test 2", test_level_critical); + PE_TEST(import_dir.get_rva() == image.get_directory_rva(pe_win::image_directory_entry_import) + && import_dir.get_size() == image.get_directory_size(pe_win::image_directory_entry_import), "Import directory test 1", test_level_critical); + PE_TEST(image.get_directory_rva(pe_win::image_directory_entry_iat) && image.get_directory_size(pe_win::image_directory_entry_iat), "Import directory test 2", test_level_critical); + + compare_imports(imports, new_imports); + + settings.zero_directory_entry_iat(true); + settings.set_offset_from_section_start(1); + import_section.get_raw_data() = "x"; + PE_TEST_EXCEPTION(import_dir = rebuild_imports(image, imports, import_section, settings), "Import rebuilder test 2", test_level_critical); + PE_TEST_EXCEPTION(new_imports = get_imported_functions(image), "get_imported_functions test 3", test_level_critical); + PE_TEST(import_section.get_raw_data().substr(0, 1) == "x", "Import offset test 1", test_level_critical); + PE_TEST(!image.get_directory_rva(pe_win::image_directory_entry_iat) && !image.get_directory_size(pe_win::image_directory_entry_iat), "Import directory test 3", test_level_critical); + compare_imports(imports, new_imports); + + settings.set_offset_from_section_start(10); + import_section.get_raw_data() = "0123456789"; + PE_TEST_EXCEPTION(import_dir = rebuild_imports(image, imports, import_section, settings), "Import rebuilder test 3", test_level_critical); + PE_TEST_EXCEPTION(new_imports = get_imported_functions(image), "get_imported_functions test 4", test_level_critical); + PE_TEST(import_section.get_raw_data().substr(0, 10) == "0123456789", "Import offset test 2", test_level_critical); + compare_imports(imports, new_imports); + + settings.save_iat_and_original_iat_rvas(true, true); + PE_TEST_EXCEPTION(import_dir = rebuild_imports(image, imports, import_section, settings), "Import rebuilder test 4", test_level_critical); + PE_TEST_EXCEPTION(new_imports = get_imported_functions(image), "get_imported_functions test 5", test_level_critical); + compare_imports(imports, new_imports); + + settings.build_original_iat(false); + PE_TEST_EXCEPTION(import_dir = rebuild_imports(image, imports, import_section, settings), "Import rebuilder test 5", test_level_critical); + PE_TEST_EXCEPTION(new_imports = get_imported_functions(image), "get_imported_functions test 6", test_level_critical); + PE_TEST(!new_imports[0].get_rva_to_original_iat() && !new_imports[1].get_rva_to_original_iat(), "Import original IAT test", test_level_normal); + compare_imports(imports, new_imports, false); + + settings.build_original_iat(true); + PE_TEST_EXCEPTION(import_dir = rebuild_imports(image, imports, import_section, settings), "Import rebuilder test 6", test_level_critical); + PE_TEST_EXCEPTION(new_imports = get_imported_functions(image), "get_imported_functions test 7", test_level_critical); + PE_TEST(new_imports[0].get_rva_to_original_iat() && new_imports[1].get_rva_to_original_iat(), "Import original IAT test 2", test_level_normal); + compare_imports(imports, new_imports, false); + + settings.fill_missing_original_iats(true); + settings.build_original_iat(false); + PE_TEST_EXCEPTION(import_dir = rebuild_imports(image, imports, import_section, settings), "Import rebuilder test 7", test_level_critical); + PE_TEST_EXCEPTION(new_imports = get_imported_functions(image), "get_imported_functions test 8", test_level_critical); + compare_imports(imports, new_imports, false); + + settings.save_iat_and_original_iat_rvas(false); + PE_TEST_EXCEPTION(import_dir = rebuild_imports(image, imports, import_section, settings), "Import rebuilder test 8", test_level_critical); + PE_TEST_EXCEPTION(new_imports = get_imported_functions(image), "get_imported_functions test 9", test_level_critical); + PE_TEST(imports[0].get_rva_to_iat() != new_imports[0].get_rva_to_iat() + && imports[1].get_rva_to_iat() != new_imports[1].get_rva_to_iat(), "IAT rebuilder test", test_level_normal); + + + import_library lib; + lib.set_name("TEST.DLL"); + lib.set_timestamp(0x12345); + imported_function func; + func.set_name("TestFunc"); + func.set_iat_va(1); + lib.add_import(func); + func.set_name("AFunc"); + lib.add_import(func); + + func.set_name(""); + func.set_ordinal(123); + lib.add_import(func); + + func.set_name("BFunc"); + lib.add_import(func); + + imports.push_back(lib); + + import_rebuilder_settings new_settings; + new_settings.save_iat_and_original_iat_rvas(false); + + PE_TEST_EXCEPTION(import_dir = rebuild_imports(image, imports, import_section, new_settings), "Import rebuilder test 9", test_level_critical); + PE_TEST_EXCEPTION(new_imports = get_imported_functions(image), "get_imported_functions test 10", test_level_critical); + + PE_TEST(new_imports.size() == 3 && new_imports[2].get_name() == "TEST.DLL", "Added import test", test_level_normal); + PE_TEST(new_imports[2].get_imported_functions().size() == 4, "Added import function test 1", test_level_normal); + PE_TEST(new_imports[2].get_imported_functions()[1].get_name() == "AFunc", "Added import function test 2", test_level_normal); + PE_TEST(new_imports[2].get_imported_functions()[3].get_iat_va() == 1, "Added import function test 3", test_level_normal); + PE_TEST(new_imports[2].get_imported_functions()[2].has_name() == false, "Added import function test 4", test_level_normal); + PE_TEST(new_imports[2].get_imported_functions()[2].get_ordinal() == 123, "Added import function test 5", test_level_normal); + + PE_TEST_END + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/tests/test_imports/test_imports.vcproj b/irdb-lib/pebliss/trunk/tests/test_imports/test_imports.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..b701bb76369aa6b514bdd8f29efb8cc6b2e6a34f --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_imports/test_imports.vcproj @@ -0,0 +1,359 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="test_imports" + ProjectGUID="{BD969F96-E5A5-47B2-B5EF-B7999A441CE5}" + RootNamespace="test_imports" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + <File + RelativePath="..\test.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/tests/test_imports/test_imports.vcxproj b/irdb-lib/pebliss/trunk/tests/test_imports/test_imports.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..b8793c39efca0c40470cf743a12d383500684561 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_imports/test_imports.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{CE1D0620-BC75-456F-914B-3BEBF5444B4C}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>test_imports</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + <ClInclude Include="..\test.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_imports/test_imports.vcxproj.filters b/irdb-lib/pebliss/trunk/tests/test_imports/test_imports.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..8f0719260417c2cc422a533c4a0c453eb3d84c1a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_imports/test_imports.vcxproj.filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\test.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_load_config/Makefile b/irdb-lib/pebliss/trunk/tests/test_load_config/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..422827f1e3ba0c0d1373f3dcd0b7219c702e806e --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_load_config/Makefile @@ -0,0 +1 @@ +include ../tests.mak diff --git a/irdb-lib/pebliss/trunk/tests/test_load_config/main.cpp b/irdb-lib/pebliss/trunk/tests/test_load_config/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eb62d59ba38a427120c772b96d0036f1f9bea23a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_load_config/main.cpp @@ -0,0 +1,83 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#include "test.h" +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +void check_load_config(const image_config_info& info) +{ + PE_TEST(info.get_security_cookie_va() == 0x41E7F4, "Load Config Values test 1", test_level_normal); + PE_TEST(info.get_se_handler_count() == 0x20, "Load Config Values test 2", test_level_critical); + PE_TEST(info.get_time_stamp() == 0, "Load Config Values test 3", test_level_normal); + PE_TEST(info.get_se_handler_rvas()[1] == 0x731a, "Load Config Values test 4", test_level_normal); +} + +int main(int argc, char* argv[]) +{ + PE_TEST_START + + std::auto_ptr<std::ifstream> pe_file; + if(!open_pe_file(argc, argv, pe_file)) + return -1; + + pe_base image(pe_factory::create_pe(*pe_file)); + + if(image.get_pe_type() == pe_type_32) + { + image_config_info info; + PE_TEST_EXCEPTION(info = get_image_config(image), "Load Config Parser test 1", test_level_critical); + check_load_config(info); + + section s; + s.get_raw_data().resize(1); + s.set_name("newcfg"); + section& new_config_section = image.add_section(s); + + uint32_t old_dir_rva = image.get_directory_rva(pe_win::image_directory_entry_load_config); + + PE_TEST_EXCEPTION(rebuild_image_config(image, info, new_config_section, 0, false, false, true, true), "Load Config Rebuilder test 1", test_level_critical); + PE_TEST(old_dir_rva != image.get_directory_rva(pe_win::image_directory_entry_load_config), "Load Config test 5", test_level_normal); + + uint64_t old_se_handler_table_va = info.get_se_handler_table_va(); + PE_TEST_EXCEPTION(info = get_image_config(image), "Load Config Parser test 2", test_level_critical); + PE_TEST(old_se_handler_table_va == info.get_se_handler_table_va(), "Load Config test 5", test_level_normal); + check_load_config(info); + + PE_TEST_EXCEPTION(rebuild_image_config(image, info, new_config_section, 0, true, false, true, true), "Load Config Rebuilder test 2", test_level_critical); + PE_TEST_EXCEPTION(info = get_image_config(image), "Load Config Parser test 3", test_level_critical); + PE_TEST(old_se_handler_table_va != info.get_se_handler_table_va(), "Load Config test 6", test_level_normal); + check_load_config(info); + + info.add_lock_prefix_rva(0x123); + info.add_lock_prefix_rva(0x456); + info.add_lock_prefix_rva(0x789); + + PE_TEST_EXCEPTION(rebuild_image_config(image, info, new_config_section, 0, true, true, true, true), "Load Config Rebuilder test 3", test_level_critical); + PE_TEST_EXCEPTION(info = get_image_config(image), "Load Config Parser test 4", test_level_critical); + check_load_config(info); + PE_TEST(info.get_lock_prefix_rvas().size() == 3, "Load Config Lock Prefix test 1", test_level_normal); + PE_TEST(info.get_lock_prefix_rvas()[2] == 0x789, "Load Config Lock Prefix test 2", test_level_normal); + + PE_TEST_EXCEPTION(rebuild_image_config(image, info, new_config_section, 1, true, true, true, true), "Load Config Rebuilder test 4", test_level_critical); + PE_TEST_EXCEPTION(info = get_image_config(image), "Load Config Parser test 5", test_level_critical); + check_load_config(info); + PE_TEST_EXCEPTION(rebuild_image_config(image, info, new_config_section, 12, true, true, true, true), "Load Config Rebuilder test 5", test_level_critical); + PE_TEST_EXCEPTION(info = get_image_config(image), "Load Config Parser test 6", test_level_critical); + check_load_config(info); + + info.add_se_handler_rva(0x001); //Check sorting + info.set_lock_prefix_table_va(0); + PE_TEST_EXCEPTION(rebuild_image_config(image, info, new_config_section, 0, true, false, true, true), "Load Config Rebuilder test 5", test_level_critical); + PE_TEST_EXCEPTION(info = get_image_config(image), "Load Config Parser test 6", test_level_critical); + PE_TEST(info.get_se_handler_count() == 0x21, "Load Config Values test 5", test_level_critical); + PE_TEST(info.get_se_handler_rvas()[0] == 0x001, "Load Config Values test 6", test_level_normal); //Checks if list is sorted + } + + PE_TEST_END + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/tests/test_load_config/test_load_config.vcproj b/irdb-lib/pebliss/trunk/tests/test_load_config/test_load_config.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..e66c33ab9271bbb6fa40d123a2f1ab13a6327b1a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_load_config/test_load_config.vcproj @@ -0,0 +1,359 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="test_load_config" + ProjectGUID="{089E9482-33DD-4C64-84A1-C9B5F10F802A}" + RootNamespace="test_load_config" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + <File + RelativePath="..\test.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/tests/test_load_config/test_load_config.vcxproj b/irdb-lib/pebliss/trunk/tests/test_load_config/test_load_config.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..5083d79429e7eebdc3bee24a0a4459d43420a511 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_load_config/test_load_config.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{FAD361E1-1FD7-4993-BD20-7450026E51CC}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>test_load_config</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + <ClInclude Include="..\test.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_load_config/test_load_config.vcxproj.filters b/irdb-lib/pebliss/trunk/tests/test_load_config/test_load_config.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..8f0719260417c2cc422a533c4a0c453eb3d84c1a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_load_config/test_load_config.vcxproj.filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\test.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_relocations/Makefile b/irdb-lib/pebliss/trunk/tests/test_relocations/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..422827f1e3ba0c0d1373f3dcd0b7219c702e806e --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_relocations/Makefile @@ -0,0 +1 @@ +include ../tests.mak diff --git a/irdb-lib/pebliss/trunk/tests/test_relocations/main.cpp b/irdb-lib/pebliss/trunk/tests/test_relocations/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..12e166210f43cd373a6457deb58d6f163f939473 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_relocations/main.cpp @@ -0,0 +1,100 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#include "test.h" +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +void test_relocations(const pe_base& image, const relocation_table_list& tables, bool read_absolute_entries) +{ + if(image.get_pe_type() == pe_type_32) + { + PE_TEST(tables.size() == 30, "Relocation test 1", test_level_critical); + PE_TEST(tables[1].get_rva() == 0x2000, "Relocation test 2", test_level_normal); + PE_TEST(tables[1].get_relocations().size() == (read_absolute_entries ? 22 : 21), "Relocation test 3", test_level_critical); + PE_TEST(tables[1].get_relocations()[1].get_rva() == 0x54, "Relocation test 4", test_level_normal); + PE_TEST(tables[1].get_relocations()[1].get_type() == pe_win::image_rel_based_highlow, "Relocation test 5", test_level_normal); + } + else + { + PE_TEST(tables.size() == 7, "Relocation test 1", test_level_critical); + PE_TEST(tables[1].get_rva() == 0x1C000, "Relocation test 2", test_level_normal); + PE_TEST(tables[4].get_relocations().size() == (read_absolute_entries ? 6 : 5), "Relocation test 3", test_level_critical); + PE_TEST(tables[1].get_relocations()[1].get_rva() == 0x4E8, "Relocation test 4", test_level_normal); + PE_TEST(tables[1].get_relocations()[1].get_type() == pe_win::image_rel_based_dir64, "Relocation test 5", test_level_normal); + } +} + +int main(int argc, char* argv[]) +{ + PE_TEST_START + + std::auto_ptr<std::ifstream> pe_file; + if(!open_pe_file(argc, argv, pe_file)) + return -1; + + pe_base image(pe_factory::create_pe(*pe_file)); + + relocation_table_list tables; + PE_TEST_EXCEPTION(tables = get_relocations(image, true), "Relocation parser test 1", test_level_critical); + test_relocations(image, tables, true); + + tables.clear(); + PE_TEST_EXCEPTION(tables = get_relocations(image, false), "Relocation parser test 2", test_level_critical); + test_relocations(image, tables, false); + + section& reloc_section = image.section_from_directory(pe_win::image_directory_entry_basereloc); + PE_TEST_EXCEPTION(rebuild_relocations(image, tables, reloc_section, 0, true, true), "Relocation Rebuilder test 1", test_level_critical); + PE_TEST_EXCEPTION(tables = get_relocations(image, true), "Relocation parser test 3", test_level_critical); + test_relocations(image, tables, true); + + PE_TEST_EXCEPTION(rebuild_relocations(image, tables, reloc_section, 0, true, true), "Relocation Rebuilder test 2", test_level_critical); + PE_TEST_EXCEPTION(tables = get_relocations(image, true), "Relocation parser test 4", test_level_critical); + test_relocations(image, tables, true); + + section s; + s.get_raw_data().resize(1); + s.set_name("newreloc"); + section& new_reloc_section = image.add_section(s); + + uint32_t old_reloc_rva = image.get_directory_rva(pe_win::image_directory_entry_basereloc); + + PE_TEST_EXCEPTION(rebuild_relocations(image, tables, new_reloc_section, 0, true, true), "Relocation Rebuilder test 3", test_level_critical); + PE_TEST(old_reloc_rva != image.get_directory_rva(pe_win::image_directory_entry_basereloc), "Relocation Rebuilder test 4", test_level_normal); + + old_reloc_rva = image.get_directory_rva(pe_win::image_directory_entry_basereloc); + + PE_TEST_EXCEPTION(tables = get_relocations(image, false), "Relocation parser test 5", test_level_critical); + test_relocations(image, tables, false); + + new_reloc_section.set_raw_data("111"); + PE_TEST_EXCEPTION(rebuild_relocations(image, tables, new_reloc_section, 3, true, true), "Relocation Rebuilder test 4", test_level_critical); + PE_TEST(new_reloc_section.get_raw_data().substr(0, 3) == "111", "Relocation Rebuilder offset test", test_level_normal); + PE_TEST(old_reloc_rva != image.get_directory_rva(pe_win::image_directory_entry_basereloc), "Relocation Rebuilder test 5", test_level_normal); + + PE_TEST_EXCEPTION(tables = get_relocations(image, false), "Relocation parser test 6", test_level_critical); + test_relocations(image, tables, false); + + relocation_table_list full_tables; //With absolute entries + PE_TEST_EXCEPTION(full_tables = get_relocations(image, true), "Relocation parser test 7", test_level_critical); + test_relocations(image, full_tables, true); + + pe_base old_image(image); + + PE_TEST_EXCEPTION(rebase_image(image, tables, image.get_image_base_64() + 0x10000), "PE Rebaser test 1", test_level_critical); + PE_TEST_EXCEPTION(rebase_image(image, full_tables, image.get_image_base_64() - 0x10000), "PE Rebaser test 2", test_level_critical); //Check that rebaser skips absolute entries + + uint16_t section_count = image.get_number_of_sections(); + for(uint16_t i = 0; i != section_count; ++i) + { + std::cout << "Rebaser control test iteration: " << i << std::endl; + PE_TEST(image.get_image_sections().at(i).get_raw_data() == old_image.get_image_sections().at(i).get_raw_data(), "Rebaser control test", test_level_normal); + } + + PE_TEST_END + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/tests/test_relocations/test_relocations.vcproj b/irdb-lib/pebliss/trunk/tests/test_relocations/test_relocations.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..8256125da44c2088c0c89f37256381bcb7e2cd70 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_relocations/test_relocations.vcproj @@ -0,0 +1,359 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="test_relocations" + ProjectGUID="{997A89F0-372D-4306-AE4D-7438D93273C3}" + RootNamespace="test_relocations" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + <File + RelativePath="..\test.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/tests/test_relocations/test_relocations.vcxproj b/irdb-lib/pebliss/trunk/tests/test_relocations/test_relocations.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..83fbafdfc54bb9fb8678dd2758a7228564ba3309 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_relocations/test_relocations.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{709B0E41-9792-4A0A-B28B-CBD06CE441B9}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>test_relocations</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + <ClInclude Include="..\test.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_relocations/test_relocations.vcxproj.filters b/irdb-lib/pebliss/trunk/tests/test_relocations/test_relocations.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..12409d248c06566328fc21348384c0e1e43e7cd9 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_relocations/test_relocations.vcxproj.filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\test.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_bitmap/Makefile b/irdb-lib/pebliss/trunk/tests/test_resource_bitmap/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..422827f1e3ba0c0d1373f3dcd0b7219c702e806e --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_bitmap/Makefile @@ -0,0 +1 @@ +include ../tests.mak diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_bitmap/main.cpp b/irdb-lib/pebliss/trunk/tests/test_resource_bitmap/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1640bfd45c4521c7a1dc43607c5b4eb7b4202751 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_bitmap/main.cpp @@ -0,0 +1,59 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#include <pe_bliss_resources.h> +#include "test.h" +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +int main(int argc, char* argv[]) +{ + PE_TEST_START + + std::auto_ptr<std::ifstream> pe_file; + if(!open_pe_file(argc, argv, pe_file)) + return -1; + + pe_base image(pe_factory::create_pe(*pe_file)); + + resource_directory root(get_resources(image)); + + pe_resource_manager res(root); + resource_bitmap_reader bmp_read(res); + resource_bitmap_writer bmp_write(res); + + PE_TEST_EXPECT_EXCEPTION(bmp_read.get_bitmap_by_name(L"TEST"), pe_exception::resource_directory_entry_not_found, "Bitmap Reader test 1", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(bmp_read.get_bitmap_by_name(123, L"TEST"), pe_exception::resource_directory_entry_not_found, "Bitmap Reader test 2", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(bmp_read.get_bitmap_by_id(123), pe_exception::resource_directory_entry_not_found, "Bitmap Reader test 3", test_level_normal); + + std::string bitmap; + PE_TEST_EXCEPTION(bitmap = bmp_read.get_bitmap_by_id(102), "Bitmap Reader test 4", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(bmp_read.get_bitmap_by_id(102, 1), pe_exception::resource_data_entry_not_found, "Bitmap Reader test 5", test_level_normal); + PE_TEST_EXCEPTION(bmp_write.add_bitmap(bitmap, L"TEST", 1049, 1234, 5678), "Bitmap Writer test 1", test_level_normal); + + std::string bitmap2; + PE_TEST_EXCEPTION(bitmap2 = bmp_read.get_bitmap_by_name(1049, L"TEST"), "Bitmap Reader test 6", test_level_critical); + PE_TEST(bitmap == bitmap2, "Bitmap Reader test 7", test_level_normal); + + PE_TEST_EXCEPTION(bmp_write.add_bitmap(bitmap, 9000, 1049, 1234, 5678), "Bitmap Writer test 2", test_level_critical); + PE_TEST_EXCEPTION(bitmap2 = bmp_read.get_bitmap_by_id(9000), "Bitmap Reader test 8", test_level_normal); + PE_TEST(bitmap == bitmap2, "Bitmap Reader test 9", test_level_normal); + + PE_TEST_EXCEPTION(bitmap = bmp_read.get_bitmap_by_id(103), "Bitmap Reader test 10", test_level_normal); + PE_TEST_EXCEPTION(bmp_write.add_bitmap(bitmap, 9000, 1049, 1234, 5678), "Bitmap Writer test 3 (bitmap replace test)", test_level_critical); + PE_TEST_EXCEPTION(bitmap2 = bmp_read.get_bitmap_by_id(9000), "Bitmap Reader test 11", test_level_normal); + PE_TEST(bitmap == bitmap2, "Bitmap Reader test 12", test_level_normal); + + PE_TEST_EXCEPTION(bmp_write.remove_bitmap(9000, 1049), "Bitmap Writer test 4", test_level_critical); + PE_TEST_EXPECT_EXCEPTION(bmp_read.get_bitmap_by_id(9000), pe_exception::resource_directory_entry_not_found, "Bitmap Reader test 13", test_level_normal); + + PE_TEST_EXCEPTION(bmp_write.remove_bitmap(L"TEST", 1049), "Bitmap Writer test 5", test_level_critical); + PE_TEST_EXPECT_EXCEPTION(bmp_read.get_bitmap_by_name(L"TEST"), pe_exception::resource_directory_entry_not_found, "Bitmap Reader test 14", test_level_normal); + + PE_TEST_END + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_bitmap/test_resource_bitmap.vcproj b/irdb-lib/pebliss/trunk/tests/test_resource_bitmap/test_resource_bitmap.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..ffb4ba74866c76c5209b436e98b704661859376e --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_bitmap/test_resource_bitmap.vcproj @@ -0,0 +1,359 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="test_resource_bitmap" + ProjectGUID="{1B337DC2-628E-4DA4-8C0F-A6880289C6E2}" + RootNamespace="test_resource_bitmap" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + <File + RelativePath="..\test.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_bitmap/test_resource_bitmap.vcxproj b/irdb-lib/pebliss/trunk/tests/test_resource_bitmap/test_resource_bitmap.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..85f748a41507f5bd3a80ff6ee2418b02172b639b --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_bitmap/test_resource_bitmap.vcxproj @@ -0,0 +1,168 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{F401B9A2-B8CB-477A-A515-F029D0AA5553}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>test_bitmap_reader</RootNamespace> + <ProjectName>test_resource_bitmap</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + <ClInclude Include="..\test.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_bitmap/test_resource_bitmap.vcxproj.filters b/irdb-lib/pebliss/trunk/tests/test_resource_bitmap/test_resource_bitmap.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..8f0719260417c2cc422a533c4a0c453eb3d84c1a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_bitmap/test_resource_bitmap.vcxproj.filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\test.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_icon_cursor/Makefile b/irdb-lib/pebliss/trunk/tests/test_resource_icon_cursor/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..422827f1e3ba0c0d1373f3dcd0b7219c702e806e --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_icon_cursor/Makefile @@ -0,0 +1 @@ +include ../tests.mak diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_icon_cursor/main.cpp b/irdb-lib/pebliss/trunk/tests/test_resource_icon_cursor/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0e373e66fb30a5ebd85f699b6b0c62dd1455d824 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_icon_cursor/main.cpp @@ -0,0 +1,120 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#include <pe_bliss_resources.h> +#include "test.h" +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +int main(int argc, char* argv[]) +{ + PE_TEST_START + + std::auto_ptr<std::ifstream> pe_file; + if(!open_pe_file(argc, argv, pe_file)) + return -1; + + pe_base image(pe_factory::create_pe(*pe_file)); + + resource_directory root(get_resources(image)); + + pe_resource_manager res(root); + resource_cursor_icon_reader ico_read(res); + resource_cursor_icon_writer ico_write(res); + + std::string icon, icon2; + + //Named icon groups tests + PE_TEST_EXCEPTION(icon = ico_read.get_single_icon_by_id(5), "Icon Reader test 1", test_level_normal); + PE_TEST_EXCEPTION(ico_write.add_icon(icon, L"NEW_GROUP", 1033, resource_cursor_icon_writer::icon_place_free_ids, 1234, 5678), "Icon Writer test 1", test_level_critical); + PE_TEST_EXCEPTION(icon2 = ico_read.get_icon_by_name(1033, L"NEW_GROUP"), "Icon Reader test 2", test_level_normal); //This group contains single icon + PE_TEST(icon == icon2, "Icon Reader test 3", test_level_normal); + PE_TEST_EXCEPTION(ico_read.get_single_icon_by_id(1), "Icon Reader test 4", test_level_normal); //icon_place_free_ids - the first free id was 1 + + PE_TEST_EXCEPTION(ico_write.remove_icon_group(L"NEW_GROUP", 1033), "Icon Writer test 2", test_level_critical); + PE_TEST_EXPECT_EXCEPTION(ico_read.get_icon_by_name(1033, L"NEW_GROUP"), pe_exception::resource_directory_entry_not_found, "Icon Reader test 5", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(ico_read.get_single_icon_by_id(1), pe_exception::resource_directory_entry_not_found, "Icon Reader test 6", test_level_normal); + + PE_TEST_EXCEPTION(icon = ico_read.get_icon_by_name(1049, L"MAIN_ICON"), "Icon Reader test 7", test_level_normal); + + PE_TEST_EXCEPTION(ico_write.add_icon(icon, L"NEW_GROUP", 1033, resource_cursor_icon_writer::icon_place_after_max_icon_id, 1234, 5678), "Icon Writer test 3", test_level_critical); + PE_TEST_EXCEPTION(icon2 = ico_read.get_icon_by_name(1033, L"NEW_GROUP"), "Icon Reader test 8", test_level_normal); //This group contains single icon + PE_TEST(icon == icon2, "Icon Reader test 9", test_level_normal); + PE_TEST_EXCEPTION(ico_read.get_single_icon_by_id(18), "Icon Reader test 10", test_level_normal); //icon_place_after_max_icon_id - the last free id was 17, and MAIN_ICON contains more than one icon + PE_TEST_EXCEPTION(ico_read.get_single_icon_by_id(19), "Icon Reader test 11", test_level_normal); + + PE_TEST_EXCEPTION(ico_write.remove_icon_group(L"NEW_GROUP", 1033), "Icon Writer test 4", test_level_critical); + + + //ID icon groups tests + PE_TEST_EXCEPTION(icon = ico_read.get_single_icon_by_id(5), "Icon Reader test 12", test_level_normal); + PE_TEST_EXCEPTION(ico_write.add_icon(icon, 777, 1033, resource_cursor_icon_writer::icon_place_free_ids, 1234, 5678), "Icon Writer test 5", test_level_critical); + PE_TEST_EXCEPTION(icon2 = ico_read.get_icon_by_id_lang(1033, 777), "Icon Reader test 13", test_level_normal); //This group contains single icon + PE_TEST(icon == icon2, "Icon Reader test 14", test_level_normal); + PE_TEST_EXCEPTION(ico_read.get_single_icon_by_id(1), "Icon Reader test 15", test_level_normal); //icon_place_free_ids - the first free id was 1 + + PE_TEST_EXCEPTION(ico_write.remove_icon_group(777, 1033), "Icon Writer test 6", test_level_critical); + PE_TEST_EXPECT_EXCEPTION(ico_read.get_icon_by_id_lang(1033, 777), pe_exception::resource_directory_entry_not_found, "Icon Reader test 16", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(ico_read.get_single_icon_by_id(1), pe_exception::resource_directory_entry_not_found, "Icon Reader test 17", test_level_normal); + + PE_TEST_EXCEPTION(icon = ico_read.get_icon_by_name(1049, L"MAIN_ICON"), "Icon Reader test 18", test_level_normal); + + PE_TEST_EXCEPTION(ico_write.add_icon(icon, 777, 1033, resource_cursor_icon_writer::icon_place_after_max_icon_id, 1234, 5678), "Icon Writer test 7", test_level_critical); + PE_TEST_EXCEPTION(icon2 = ico_read.get_icon_by_id_lang(1033, 777), "Icon Reader test 19", test_level_normal); //This group contains single icon + PE_TEST(icon == icon2, "Icon Reader test 20", test_level_normal); + PE_TEST_EXCEPTION(ico_read.get_single_icon_by_id(18), "Icon Reader test 21", test_level_normal); //icon_place_after_max_icon_id - the last free id was 17, and MAIN_ICON contains more than one icon + PE_TEST_EXCEPTION(ico_read.get_single_icon_by_id(19), "Icon Reader test 22", test_level_normal); + + PE_TEST_EXCEPTION(ico_write.remove_icon_group(777, 1033), "Icon Writer test 8", test_level_critical); + + + //Named cursor groups tests + PE_TEST_EXCEPTION(icon = ico_read.get_single_cursor_by_id(3), "Cursor Reader test 1", test_level_normal); + PE_TEST_EXCEPTION(ico_write.add_cursor(icon, L"NEW_GROUP", 1033, resource_cursor_icon_writer::icon_place_free_ids, 1234, 5678), "Cursor Writer test 1", test_level_critical); + PE_TEST_EXCEPTION(icon2 = ico_read.get_cursor_by_name(1033, L"NEW_GROUP"), "Cursor Reader test 2", test_level_normal); //This group contains single cursor + PE_TEST(icon == icon2, "Cursor Reader test 3", test_level_normal); + PE_TEST_EXCEPTION(ico_read.get_single_cursor_by_id(4), "Cursor Reader test 4", test_level_normal); //icon_place_free_ids - the first free id was 4 + + PE_TEST_EXCEPTION(ico_write.remove_cursor_group(L"NEW_GROUP", 1033), "Cursor Writer test 2", test_level_critical); + PE_TEST_EXPECT_EXCEPTION(ico_read.get_cursor_by_name(1033, L"NEW_GROUP"), pe_exception::resource_directory_entry_not_found, "Cursor Reader test 5", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(ico_read.get_single_cursor_by_id(4), pe_exception::resource_directory_entry_not_found, "Cursor Reader test 6", test_level_normal); + + PE_TEST_EXCEPTION(icon = ico_read.get_cursor_by_id_lang(1049, 105), "Cursor Reader test 7", test_level_normal); + + PE_TEST_EXCEPTION(ico_write.add_cursor(icon, L"NEW_GROUP", 1033, resource_cursor_icon_writer::icon_place_after_max_icon_id, 1234, 5678), "Cursor Writer test 3", test_level_critical); + PE_TEST_EXCEPTION(icon2 = ico_read.get_cursor_by_name(1033, L"NEW_GROUP"), "Cursor Reader test 8", test_level_normal); //This group contains single cursor + PE_TEST(icon == icon2, "Cursor Reader test 9", test_level_normal); + PE_TEST_EXCEPTION(ico_read.get_single_cursor_by_id(4), "Cursor Reader test 10", test_level_normal); //icon_place_after_max_icon_id - the last free id was 4, and cursor group "105" contains more than one cursor + PE_TEST_EXCEPTION(ico_read.get_single_cursor_by_id(5), "Cursor Reader test 11", test_level_normal); + + PE_TEST_EXCEPTION(ico_write.remove_cursor_group(L"NEW_GROUP", 1033), "Cursor Writer test 4", test_level_critical); + + + //ID cursor groups tests + PE_TEST_EXCEPTION(icon = ico_read.get_single_cursor_by_id(3), "Cursor Reader test 12", test_level_normal); + PE_TEST_EXCEPTION(ico_write.add_cursor(icon, 777, 1033, resource_cursor_icon_writer::icon_place_free_ids, 1234, 5678), "Cursor Writer test 5", test_level_critical); + PE_TEST_EXCEPTION(icon2 = ico_read.get_cursor_by_id_lang(1033, 777), "Cursor Reader test 13", test_level_normal); //This group contains single cursor + PE_TEST(icon == icon2, "Cursor Reader test 14", test_level_normal); + PE_TEST_EXCEPTION(ico_read.get_single_cursor_by_id(4), "Cursor Reader test 15", test_level_normal); //icon_place_free_ids - the first free id was 4 + + PE_TEST_EXCEPTION(ico_write.remove_cursor_group(777, 1033), "Cursor Writer test 6", test_level_critical); + PE_TEST_EXPECT_EXCEPTION(ico_read.get_cursor_by_id_lang(1033, 777), pe_exception::resource_directory_entry_not_found, "Cursor Reader test 16", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(ico_read.get_single_cursor_by_id(4), pe_exception::resource_directory_entry_not_found, "Cursor Reader test 17", test_level_normal); + + PE_TEST_EXCEPTION(icon = ico_read.get_cursor_by_id_lang(1049, 105), "Cursor Reader test 18", test_level_normal); + + PE_TEST_EXCEPTION(ico_write.add_cursor(icon, 777, 1033, resource_cursor_icon_writer::icon_place_after_max_icon_id, 1234, 5678), "Cursor Writer test 7", test_level_critical); + PE_TEST_EXCEPTION(icon2 = ico_read.get_cursor_by_id_lang(1033, 777), "Cursor Reader test 19", test_level_normal); //This group contains single cursor + PE_TEST(icon == icon2, "Cursor Reader test 20", test_level_normal); + PE_TEST_EXCEPTION(ico_read.get_single_cursor_by_id(4), "Cursor Reader test 21", test_level_normal); //icon_place_after_max_icon_id - the last free id was 4, and cursor group "105" contains more than one cursor + PE_TEST_EXCEPTION(ico_read.get_single_cursor_by_id(5), "Cursor Reader test 22", test_level_normal); + + PE_TEST_EXCEPTION(ico_write.remove_cursor_group(777, 1033), "Cursor Writer test 8", test_level_critical); + + PE_TEST_END + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_icon_cursor/test_resource_icon_cursor.vcproj b/irdb-lib/pebliss/trunk/tests/test_resource_icon_cursor/test_resource_icon_cursor.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..217078c56a1894244bc20aa9eb830e5c3ca5d170 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_icon_cursor/test_resource_icon_cursor.vcproj @@ -0,0 +1,359 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="test_resource_icon_cursor" + ProjectGUID="{1E59538C-2C78-4D35-8639-568890543A4A}" + RootNamespace="test_resource_icon_cursor" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + <File + RelativePath="..\test.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_icon_cursor/test_resource_icon_cursor.vcxproj b/irdb-lib/pebliss/trunk/tests/test_resource_icon_cursor/test_resource_icon_cursor.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..bd7fbead1d50a9f209feffeee37ef0713a26606a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_icon_cursor/test_resource_icon_cursor.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{D9AC6F2E-3FE9-4D64-BEAA-C7104A0397B2}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>test_resource_icon_cursor</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + <ClInclude Include="..\test.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_icon_cursor/test_resource_icon_cursor.vcxproj.filters b/irdb-lib/pebliss/trunk/tests/test_resource_icon_cursor/test_resource_icon_cursor.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..8f0719260417c2cc422a533c4a0c453eb3d84c1a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_icon_cursor/test_resource_icon_cursor.vcxproj.filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\test.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_manager/Makefile b/irdb-lib/pebliss/trunk/tests/test_resource_manager/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..422827f1e3ba0c0d1373f3dcd0b7219c702e806e --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_manager/Makefile @@ -0,0 +1 @@ +include ../tests.mak diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_manager/main.cpp b/irdb-lib/pebliss/trunk/tests/test_resource_manager/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c69b45c481073cabfa10cc3cee10c07285362a67 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_manager/main.cpp @@ -0,0 +1,68 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#include <pe_bliss_resources.h> +#include "test.h" +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +int main(int argc, char* argv[]) +{ + PE_TEST_START + + std::auto_ptr<std::ifstream> pe_file; + if(!open_pe_file(argc, argv, pe_file)) + return -1; + + pe_base image(pe_factory::create_pe(*pe_file)); + + resource_directory root(get_resources(image)); + + pe_resource_manager res(root); + + PE_TEST(res.remove_resource_type(pe_resource_viewer::resource_bitmap) == true, "Resource Manager test 1", test_level_normal); + PE_TEST(res.remove_resource_type(pe_resource_viewer::resource_bitmap) == false, "Resource Manager test 2", test_level_normal); + PE_TEST(res.remove_resource(L"DOESNOT_EXIST") == false, "Resource Manager test 3", test_level_normal); + + PE_TEST(res.remove_resource(pe_resource_viewer::resource_icon_group, 107) == true, "Resource Manager test 4", test_level_normal); + PE_TEST(res.remove_resource(pe_resource_viewer::resource_icon_group, 107) == false, "Resource Manager test 5", test_level_normal); + PE_TEST(res.remove_resource(pe_resource_viewer::resource_icon_group, L"MAIN_ICON") == true, "Resource Manager test 6", test_level_normal); + PE_TEST(res.remove_resource(pe_resource_viewer::resource_icon_group, L"MAIN_ICON") == false, "Resource Manager test 7", test_level_normal); + PE_TEST(res.remove_resource(pe_resource_viewer::resource_bitmap, 101) == false, "Resource Manager test 8", test_level_normal); + PE_TEST(res.remove_resource(pe_resource_viewer::resource_bitmap, L"TEST") == false, "Resource Manager test 9", test_level_normal); + PE_TEST(res.remove_resource(L"TEST", 1) == false, "Resource Manager test 10", test_level_normal); + PE_TEST(res.remove_resource(L"TEST", L"TEST") == false, "Resource Manager test 11", test_level_normal); + + PE_TEST(res.remove_resource(pe_resource_viewer::resource_cursor_group, 104, 1047) == false, "Resource Manager test 12", test_level_normal); + PE_TEST(res.remove_resource(pe_resource_viewer::resource_cursor_group, 104, 1049) == true, "Resource Manager test 13", test_level_normal); + PE_TEST(res.remove_resource(pe_resource_viewer::resource_cursor_group, 104, 1049) == false, "Resource Manager test 14", test_level_normal); + PE_TEST(res.remove_resource(L"TEST", 100, 1049) == false, "Resource Manager test 15", test_level_normal); + PE_TEST(res.remove_resource(L"TEST", L"TEST", 1049) == false, "Resource Manager test 16", test_level_normal); + PE_TEST(res.remove_resource(pe_resource_viewer::resource_cursor_group, L"TEST", 1049) == false, "Resource Manager test 17", test_level_normal); + + PE_TEST_EXCEPTION(res.add_resource("res data", pe_resource_viewer::resource_rcdata, L"TESTNAME", 1049, 123, 12345), "Resource Manager test 18", test_level_normal); + PE_TEST(res.get_resource_data_by_name(1049, pe_resource_viewer::resource_rcdata, L"TESTNAME").get_data() == "res data", "Resource Manager test 19", test_level_normal); + PE_TEST(res.get_resource_data_by_name(1049, pe_resource_viewer::resource_rcdata, L"TESTNAME").get_codepage() == 123, "Resource Manager test 20", test_level_normal); + + PE_TEST_EXCEPTION(res.add_resource("res data 2", L"ROOT", L"TESTNAME", 1049, 456, 12345), "Resource Manager test 21", test_level_normal); + PE_TEST(res.get_resource_data_by_name(1049, L"ROOT", L"TESTNAME").get_data() == "res data 2", "Resource Manager test 22", test_level_normal); + PE_TEST(res.get_resource_data_by_name(1049, L"ROOT", L"TESTNAME").get_codepage() == 456, "Resource Manager test 23", test_level_normal); + + PE_TEST_EXCEPTION(res.add_resource("res data", pe_resource_viewer::resource_rcdata, 12345, 1049, 123, 12345), "Resource Manager test 24", test_level_normal); + PE_TEST(res.get_resource_data_by_id(1049, pe_resource_viewer::resource_rcdata, 12345).get_data() == "res data", "Resource Manager test 25", test_level_normal); + PE_TEST(res.get_resource_data_by_id(1049, pe_resource_viewer::resource_rcdata, 12345).get_codepage() == 123, "Resource Manager test 26", test_level_normal); + + PE_TEST_EXCEPTION(res.add_resource("res data 2", L"ROOT", 12345, 1049, 456, 12345), "Resource Manager test 27", test_level_normal); + PE_TEST(res.get_resource_data_by_id(1049, L"ROOT", 12345).get_data() == "res data 2", "Resource Manager test 28", test_level_normal); + PE_TEST(res.get_resource_data_by_id(1049, L"ROOT", 12345).get_codepage() == 456, "Resource Manager test 29", test_level_normal); + + PE_TEST_EXCEPTION(res.add_resource("res data 3", L"ROOT", 12345, 1049, 456, 12345), "Resource Manager test 30", test_level_normal); + PE_TEST(res.get_resource_data_by_id(1049, L"ROOT", 12345).get_data() == "res data 3", "Resource Manager test 31", test_level_normal); + + PE_TEST_END + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_manager/test_resource_manager.vcproj b/irdb-lib/pebliss/trunk/tests/test_resource_manager/test_resource_manager.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..9dc242cbf0aa8d4a59460d940cb28074723ac739 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_manager/test_resource_manager.vcproj @@ -0,0 +1,359 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="test_resource_manager" + ProjectGUID="{39E1826B-5436-47D3-9B95-D3C667691461}" + RootNamespace="test_resource_manager" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + <File + RelativePath="..\test.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_manager/test_resource_manager.vcxproj b/irdb-lib/pebliss/trunk/tests/test_resource_manager/test_resource_manager.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..b41c9f6fb5effa780d3a204c1cbe824803619f54 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_manager/test_resource_manager.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{415A9FD5-59F6-4B1B-8EB8-EBD87E37EEA4}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>test_resource_manager</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + <ClInclude Include="..\test.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_manager/test_resource_manager.vcxproj.filters b/irdb-lib/pebliss/trunk/tests/test_resource_manager/test_resource_manager.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..8f0719260417c2cc422a533c4a0c453eb3d84c1a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_manager/test_resource_manager.vcxproj.filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\test.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_message_table/Makefile b/irdb-lib/pebliss/trunk/tests/test_resource_message_table/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..422827f1e3ba0c0d1373f3dcd0b7219c702e806e --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_message_table/Makefile @@ -0,0 +1 @@ +include ../tests.mak diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_message_table/main.cpp b/irdb-lib/pebliss/trunk/tests/test_resource_message_table/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..60d598820b42710837d23ea70f04d4c7f1ce6bd5 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_message_table/main.cpp @@ -0,0 +1,62 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#include <pe_bliss_resources.h> +#include "test.h" +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +int main(int argc, char* argv[]) +{ + PE_TEST_START + + std::auto_ptr<std::ifstream> pe_file; + if(!open_pe_file(argc, argv, pe_file)) + return -1; + + pe_base image(pe_factory::create_pe(*pe_file)); + + resource_directory root(get_resources(image)); + + pe_resource_manager res(root); + resource_message_list_reader msg(res); + + resource_message_list messages; + + //Unicode tests + PE_TEST_EXCEPTION(messages = msg.get_message_table_by_id_lang(1049, 1), "Message Table Parser test 1", test_level_critical); + PE_TEST(messages.size() == 2, "Message Table Parser test 2", test_level_critical); + PE_TEST(messages.find(0x01000000) != messages.end() + && messages.find(0xC1000001) != messages.end(), "Message Table Parser test 3", test_level_critical); + PE_TEST(messages[0xC1000001].is_unicode(), "Message Table Parser test 4", test_level_normal); + PE_TEST(messages[0xC1000001].get_unicode_string() == L"Ошибка!\r\n", "Message Table Parser test 5", test_level_normal); + + PE_TEST_EXCEPTION(messages = msg.get_message_table_by_id_lang(1033, 1), "Message Table Parser test 6", test_level_critical); + PE_TEST(messages.size() == 2, "Message Table Parser test 7", test_level_critical); + PE_TEST(messages.find(0x01000000) != messages.end() + && messages.find(0xC1000001) != messages.end(), "Message Table Parser test 8", test_level_critical); + PE_TEST(messages[0xC1000001].is_unicode(), "Message Table Parser test 9", test_level_normal); + PE_TEST(messages[0xC1000001].get_unicode_string() == L"Error!\r\n", "Message Table Parser test 10", test_level_normal); + + //ANSI Tests + PE_TEST_EXCEPTION(messages = msg.get_message_table_by_id_lang(1049, 2), "Message Table Parser test 11", test_level_critical); + PE_TEST(messages.size() == 2, "Message Table Parser test 12", test_level_critical); + PE_TEST(messages.find(0x01000000) != messages.end() + && messages.find(0xC1000001) != messages.end(), "Message Table Parser test 13", test_level_critical); + PE_TEST(!messages[0xC1000001].is_unicode(), "Message Table Parser test 14", test_level_normal); + PE_TEST(messages[0xC1000001].get_ansi_string() == "\xCE\xF8\xE8\xE1\xEA\xE0!\r\n", "Message Table Parser test 15", test_level_normal); //"Ошибка!\r\n" + + PE_TEST_EXCEPTION(messages = msg.get_message_table_by_id_lang(1033, 2), "Message Table Parser test 16", test_level_critical); + PE_TEST(messages.size() == 2, "Message Table Parser test 17", test_level_critical); + PE_TEST(messages.find(0x01000000) != messages.end() + && messages.find(0xC1000001) != messages.end(), "Message Table Parser test 18", test_level_critical); + PE_TEST(!messages[0xC1000001].is_unicode(), "Message Table Parser test 19", test_level_normal); + PE_TEST(messages[0xC1000001].get_ansi_string() == "Error!\r\n", "Message Table Parser test 20", test_level_normal); + + PE_TEST_END + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_message_table/test_resource_message_table.vcproj b/irdb-lib/pebliss/trunk/tests/test_resource_message_table/test_resource_message_table.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..deb049798a35b072f235fb2655b9b375ff01f544 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_message_table/test_resource_message_table.vcproj @@ -0,0 +1,359 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="test_resource_message_table" + ProjectGUID="{57EFEFC9-E2D9-418E-9F05-3FD0D9921251}" + RootNamespace="test_resource_message_table" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + <File + RelativePath="..\test.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_message_table/test_resource_message_table.vcxproj b/irdb-lib/pebliss/trunk/tests/test_resource_message_table/test_resource_message_table.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..5edc5ca5ebc6e0d7e3bca4352151e5331935cc37 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_message_table/test_resource_message_table.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{6CBACE55-8DDC-4EAE-A23A-DF412265D30C}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>test_resource_message_table</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + <ClInclude Include="..\test.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_message_table/test_resource_message_table.vcxproj.filters b/irdb-lib/pebliss/trunk/tests/test_resource_message_table/test_resource_message_table.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..8f0719260417c2cc422a533c4a0c453eb3d84c1a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_message_table/test_resource_message_table.vcxproj.filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\test.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_string_table/Makefile b/irdb-lib/pebliss/trunk/tests/test_resource_string_table/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..422827f1e3ba0c0d1373f3dcd0b7219c702e806e --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_string_table/Makefile @@ -0,0 +1 @@ +include ../tests.mak diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_string_table/main.cpp b/irdb-lib/pebliss/trunk/tests/test_resource_string_table/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..72e54de944c963841eaeb044320be6caee392559 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_string_table/main.cpp @@ -0,0 +1,41 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#include <pe_bliss_resources.h> +#include "test.h" +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +int main(int argc, char* argv[]) +{ + PE_TEST_START + + std::auto_ptr<std::ifstream> pe_file; + if(!open_pe_file(argc, argv, pe_file)) + return -1; + + pe_base image(pe_factory::create_pe(*pe_file)); + + resource_directory root(get_resources(image)); + + pe_resource_manager res(root); + resource_string_table_reader str(res); + + resource_string_list strings; + PE_TEST_EXCEPTION(strings = str.get_string_table_by_id_lang(1049, 7), "String List Parser test 1", test_level_critical); + PE_TEST(strings.size() == 4, "String List Parser test 2", test_level_critical); + PE_TEST(strings.find(111) != strings.end(), "String List Parser test 3", test_level_critical); + PE_TEST(strings[111] == L"Test String 4", "String List Parser test 4", test_level_normal); + + std::wstring str_111; + PE_TEST_EXCEPTION(str_111 = str.get_string_by_id(111), "String List Parser test 5", test_level_normal); + PE_TEST(str_111 == L"Test String 4", "String List Parser test 6", test_level_normal); + PE_TEST(str_111 == str.get_string_by_id_lang(1049, 111), "String List Parser test 7", test_level_normal); + + PE_TEST_END + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_string_table/test_resource_string_table.vcproj b/irdb-lib/pebliss/trunk/tests/test_resource_string_table/test_resource_string_table.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..bab4cc87ab7a7e49325d6a20fa3d416a7a6c2754 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_string_table/test_resource_string_table.vcproj @@ -0,0 +1,359 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="test_resource_string_table" + ProjectGUID="{C68A466D-0C1B-40BC-9AB1-49B582958524}" + RootNamespace="test_resource_string_table" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + <File + RelativePath="..\test.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_string_table/test_resource_string_table.vcxproj b/irdb-lib/pebliss/trunk/tests/test_resource_string_table/test_resource_string_table.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..5973303e806a0b2fa1b7c51feb9453b46668b993 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_string_table/test_resource_string_table.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{5E32A144-2F2D-4BB1-BBEF-13BE94414E99}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>test_resource_string_table</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + <ClInclude Include="..\test.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_string_table/test_resource_string_table.vcxproj.filters b/irdb-lib/pebliss/trunk/tests/test_resource_string_table/test_resource_string_table.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..8f0719260417c2cc422a533c4a0c453eb3d84c1a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_string_table/test_resource_string_table.vcxproj.filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\test.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_version_info/Makefile b/irdb-lib/pebliss/trunk/tests/test_resource_version_info/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..422827f1e3ba0c0d1373f3dcd0b7219c702e806e --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_version_info/Makefile @@ -0,0 +1 @@ +include ../tests.mak diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_version_info/main.cpp b/irdb-lib/pebliss/trunk/tests/test_resource_version_info/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..24757f90a52c21b02a49b6131e6590a362e3c4b6 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_version_info/main.cpp @@ -0,0 +1,97 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#include <pe_bliss_resources.h> +#include "test.h" +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +void test_version(const resource_version_info_reader& ver_reader, file_version_info& file_info, lang_string_values_map& strings, translation_values_map& translations) +{ + strings.clear(); + translations.clear(); + + PE_TEST_EXCEPTION(file_info = ver_reader.get_version_info(strings, translations), "Version Info Parser test 1", test_level_critical); + PE_TEST(strings.size() == 2 && translations.size() == 2, "Version Info Parser test 2", test_level_critical); + PE_TEST(strings.find(L"040004b0") != strings.end() && strings.find(L"041904b0") != strings.end(), "Version Info Parser test 3", test_level_critical); + PE_TEST(translations.find(0x0400) != translations.end() && translations.find(0x0419) != translations.end(), "Version Info Parser test 4", test_level_critical); + PE_TEST(strings[L"040004b0"][L"FileDescription"] == L"PE Bliss Test PE File", "Version Info Parser test 5", test_level_normal); + PE_TEST(strings[L"041904b0"][L"FileDescription"] == L"PE Bliss - ТеÑтовый PE-файл", "Version Info Parser test 6", test_level_normal); + PE_TEST((*translations.find(0x0400)).second == 0x4b0 && (*translations.find(0x0419)).second == 0x4b0, "Version Info Parser test 7", test_level_normal); + PE_TEST(file_info.get_file_date_ls() == 0 && file_info.get_file_date_ms() == 0 + && file_info.get_file_flags() == 0 && file_info.get_file_os() == file_version_info::file_os_nt_win32 + && file_info.get_file_subtype() == 0 && file_info.get_file_type() == file_version_info::file_type_application + && file_info.get_file_version_ls() == 0x00020001 && file_info.get_file_version_ms() == 0x00040003 + && file_info.get_product_version_ls() == 0x00070008 && file_info.get_product_version_ms() == 0x00050006 + && file_info.get_file_version_string<char>() == "4.3.2.1" + && file_info.get_product_version_string<wchar_t>() == L"5.6.7.8", "File Version Info Parser test", test_level_normal); + + version_info_viewer ver_view(strings, translations); + version_info_editor ver_edit(strings, translations); + + PE_TEST(version_info_viewer::translation_from_string(L"041904b0").first == 0x0419 + && version_info_viewer::translation_from_string(L"041904b0").second == 0x04b0, "translation_from_string test", test_level_normal); + + PE_TEST(ver_view.get_company_name() == L"PE Bliss", "Version Info Viewer test 1", test_level_normal); + PE_TEST(ver_view.get_company_name(L"040004b0") == L"PE Bliss", "Version Info Viewer test 2", test_level_normal); + PE_TEST(ver_view.get_file_description() == L"PE Bliss - ТеÑтовый PE-файл", "Version Info Viewer test 3", test_level_normal); + PE_TEST(ver_view.get_file_description(L"040004b0") == L"PE Bliss Test PE File", "Version Info Viewer test 4", test_level_normal); + PE_TEST(ver_view.get_file_version() == L"4.3.2.1", "Version Info Viewer test 5", test_level_normal); + PE_TEST(ver_view.get_file_version(L"040004b0") == L"4.3.2.1", "Version Info Viewer test 6", test_level_normal); + PE_TEST(ver_view.get_internal_name() == L"test.exe", "Version Info Viewer test 7", test_level_normal); + PE_TEST(ver_view.get_internal_name(L"040004b0") == L"test.exe", "Version Info Viewer test 8", test_level_normal); + PE_TEST(ver_view.get_legal_copyright() == L"(C) dx", "Version Info Viewer test 9", test_level_normal); + PE_TEST(ver_view.get_legal_copyright(L"040004b0") == L"(C) dx", "Version Info Viewer test 10", test_level_normal); + PE_TEST(ver_view.get_original_filename() == L"original.exe", "Version Info Viewer test 11", test_level_normal); + PE_TEST(ver_view.get_original_filename(L"040004b0") == L"original.exe", "Version Info Viewer test 12", test_level_normal); + PE_TEST(ver_view.get_product_name() == L"PE Bliss - ТеÑÑ‚Ñ‹", "Version Info Viewer test 13", test_level_normal); + PE_TEST(ver_view.get_product_name(L"040004b0") == L"PE Bliss Test", "Version Info Viewer test 14", test_level_normal); + PE_TEST(ver_view.get_product_version() == L"5.6.7.8", "Version Info Viewer test 15", test_level_normal); + PE_TEST(ver_view.get_product_version(L"040004b0") == L"5.6.7.8", "Version Info Viewer test 16", test_level_normal); + PE_TEST(ver_view.get_property(L"CompanyName", L"", false) == L"PE Bliss", "Version Info Viewer test 17", test_level_normal); + PE_TEST(ver_view.get_property(L"CompanyName", L"040004b0", false) == L"PE Bliss", "Version Info Viewer test 18", test_level_normal); + PE_TEST(ver_view.get_property(L"TestProperty", L"", false) == L"", "Version Info Viewer test 19", test_level_normal); + PE_TEST(ver_view.get_property(L"TestProperty", L"040004b0", false) == L"", "Version Info Viewer test 20", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(ver_view.get_property(L"TestProperty", L"", true) == L"", pe_exception::version_info_string_does_not_exist, "Version Info Viewer test 21", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(ver_view.get_property(L"TestProperty", L"040004b0", true) == L"", pe_exception::version_info_string_does_not_exist, "Version Info Viewer test 22", test_level_normal); + PE_TEST(ver_view.get_translation_list().size() == 2, "Version Info Viewer test 23", test_level_critical); + PE_TEST(ver_view.get_translation_list().at(1) == L"041904b0", "Version Info Viewer test 24", test_level_critical); +} + +int main(int argc, char* argv[]) +{ + PE_TEST_START + + std::auto_ptr<std::ifstream> pe_file; + if(!open_pe_file(argc, argv, pe_file)) + return -1; + + pe_base image(pe_factory::create_pe(*pe_file)); + + resource_directory root(get_resources(image)); + + pe_resource_manager res(root); + resource_version_info_reader ver_reader(res); + resource_version_info_writer ver_writer(res); + + file_version_info file_info; + lang_string_values_map strings; + translation_values_map translations; + test_version(ver_reader, file_info, strings, translations); + + PE_TEST(ver_writer.remove_version_info(1049) == true, "Version Info Writer test 1", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(ver_reader.get_version_info(strings, translations), pe_exception::resource_directory_entry_not_found, "Version Info Parser test", test_level_critical); + + PE_TEST_EXCEPTION(ver_writer.set_version_info(file_info, strings, translations, 12345, 678, 123), "Version Info Writer test 2", test_level_critical); + test_version(ver_reader, file_info, strings, translations); + + + + + PE_TEST_END + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_version_info/test_resource_version_info.vcproj b/irdb-lib/pebliss/trunk/tests/test_resource_version_info/test_resource_version_info.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..9f043e4d185140d40f07aa4539244ee315ff14c5 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_version_info/test_resource_version_info.vcproj @@ -0,0 +1,359 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="test_resource_version_info" + ProjectGUID="{C30B270A-4C93-44A3-AABE-633713D0F1D7}" + RootNamespace="test_resource_version_info" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + <File + RelativePath="..\test.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_version_info/test_resource_version_info.vcxproj b/irdb-lib/pebliss/trunk/tests/test_resource_version_info/test_resource_version_info.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..a8415847759f9271d1c17db2eb32377c305fbd65 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_version_info/test_resource_version_info.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{5C2B081E-5414-437B-86EB-B2695AEDF3F0}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>test_resource_version_info</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + <ClInclude Include="..\test.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_version_info/test_resource_version_info.vcxproj.filters b/irdb-lib/pebliss/trunk/tests/test_resource_version_info/test_resource_version_info.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..8f0719260417c2cc422a533c4a0c453eb3d84c1a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_version_info/test_resource_version_info.vcxproj.filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\test.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_viewer/Makefile b/irdb-lib/pebliss/trunk/tests/test_resource_viewer/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..422827f1e3ba0c0d1373f3dcd0b7219c702e806e --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_viewer/Makefile @@ -0,0 +1 @@ +include ../tests.mak diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_viewer/main.cpp b/irdb-lib/pebliss/trunk/tests/test_resource_viewer/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..510313e8ea59cc6fd774e57de2bde70bca69a8fd --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_viewer/main.cpp @@ -0,0 +1,89 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#include <pe_bliss_resources.h> +#include "test.h" +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +int main(int argc, char* argv[]) +{ + PE_TEST_START + + std::auto_ptr<std::ifstream> pe_file; + if(!open_pe_file(argc, argv, pe_file)) + return -1; + + pe_base image(pe_factory::create_pe(*pe_file)); + + resource_directory root(get_resources(image)); + + pe_resource_viewer res(root); + + PE_TEST_EXPECT_EXCEPTION(res.get_resource_count(L"NoName") == 0, pe_exception::resource_directory_entry_not_found, "Resource viewer test 1", test_level_normal); + PE_TEST(res.get_resource_count(pe_resource_viewer::resource_cursor) == 3, "Resource viewer test 2", test_level_normal); + + PE_TEST_EXPECT_EXCEPTION(res.get_language_count(L"NoName", 123) == 0, pe_exception::resource_directory_entry_not_found, "Resource viewer test 3", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(res.get_language_count(pe_resource_viewer::resource_accelerator, 123), pe_exception::resource_directory_entry_not_found, "Resource viewer test 4", test_level_normal); + + PE_TEST_EXPECT_EXCEPTION(res.get_language_count(pe_resource_viewer::resource_cursor, 5) == 0, pe_exception::resource_directory_entry_not_found, "Resource viewer test 5", test_level_normal); + PE_TEST(res.get_language_count(pe_resource_viewer::resource_cursor, 2) == 1, "Resource viewer test 6", test_level_normal); + + PE_TEST_EXPECT_EXCEPTION(res.get_language_count(pe_resource_viewer::resource_cursor, 5) == 0, pe_exception::resource_directory_entry_not_found, "Resource viewer test 7", test_level_normal); + PE_TEST(res.get_language_count(pe_resource_viewer::resource_cursor, 2) == 1, "Resource viewer test 8", test_level_normal); + + PE_TEST(res.get_language_count(pe_resource_viewer::resource_icon_group, L"MAIN_ICON") == 1, "Resource viewer test 9", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(res.get_language_count(pe_resource_viewer::resource_icon_group, L"DOESNT_EXIST") == 1, pe_exception::resource_directory_entry_not_found, "Resource viewer test 10", test_level_normal); + + PE_TEST_EXPECT_EXCEPTION(res.get_language_count(L"NONAME", L"DOESNT_EXIST") == 1, pe_exception::resource_directory_entry_not_found, "Resource viewer test 11", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(res.get_language_count(L"NONAME", 123) == 1, pe_exception::resource_directory_entry_not_found, "Resource viewer test 12", test_level_normal); + + PE_TEST(!res.resource_exists(L"NOT_EXISTENT"), "Resource viewer test 13", test_level_normal); + PE_TEST(res.resource_exists(pe_resource_viewer::resource_bitmap), "Resource viewer test 14", test_level_normal); + + PE_TEST(res.list_resource_types().size() == 8, "Resource viewer test 15", test_level_critical); + PE_TEST(res.list_resource_types()[7] == pe_resource_viewer::resource_manifest, "Resource viewer test 16", test_level_normal); + + PE_TEST(res.list_resource_names(pe_resource_viewer::resource_bitmap).size() == 0, "Resource viewer test 17", test_level_critical); + PE_TEST(res.list_resource_ids(pe_resource_viewer::resource_bitmap).size() == 3, "Resource viewer test 18", test_level_critical); + + PE_TEST_EXPECT_EXCEPTION(res.list_resource_names(L"DOESNOT_EXIST"), pe_exception::resource_directory_entry_not_found, "Resource viewer test 19", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(res.list_resource_ids(L"DOESNOT_EXIST"), pe_exception::resource_directory_entry_not_found, "Resource viewer test 20", test_level_normal); + + PE_TEST(res.list_resource_ids(pe_resource_viewer::resource_bitmap).at(2) == 103, "Resource viewer test 21", test_level_normal); + PE_TEST(res.list_resource_names(pe_resource_viewer::resource_icon_group).size() == 1, "Resource viewer test 22", test_level_critical); + PE_TEST(res.list_resource_names(pe_resource_viewer::resource_icon_group).at(0) == L"MAIN_ICON", "Resource viewer test 23", test_level_normal); + + PE_TEST(res.list_resource_languages(pe_resource_viewer::resource_icon_group, 107).size() == 1, "Resource viewer test 24", test_level_critical); + PE_TEST(res.list_resource_languages(pe_resource_viewer::resource_icon_group, 107).at(0) == 1049, "Resource viewer test 25", test_level_normal); + + PE_TEST(res.list_resource_languages(pe_resource_viewer::resource_icon_group, L"MAIN_ICON").size() == 1, "Resource viewer test 26", test_level_critical); + PE_TEST(res.list_resource_languages(pe_resource_viewer::resource_icon_group, L"MAIN_ICON").at(0) == 1049, "Resource viewer test 27", test_level_critical); + + PE_TEST_EXPECT_EXCEPTION(res.list_resource_languages(L"UNEXISTENT", L"MAIN_ICON"), pe_exception::resource_directory_entry_not_found, "Resource viewer test 28", test_level_critical); + PE_TEST_EXPECT_EXCEPTION(res.list_resource_languages(L"UNEXISTENT", 123), pe_exception::resource_directory_entry_not_found, "Resource viewer test 29", test_level_critical); + + PE_TEST(res.get_resource_data_by_id(pe_resource_viewer::resource_manifest, 1).get_codepage() == 0x4E4, "Resource viewer test 30", test_level_normal); + PE_TEST(res.get_resource_data_by_id(pe_resource_viewer::resource_manifest, 1).get_data().substr(0, 15) == "<assembly xmlns", "Resource viewer test 31", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(res.get_resource_data_by_id(pe_resource_viewer::resource_manifest, 1, 1), pe_exception::resource_data_entry_not_found, "Resource viewer test 32", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(res.get_resource_data_by_id(L"NONAME", 1), pe_exception::resource_directory_entry_not_found, "Resource viewer test 33", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(res.get_resource_data_by_id(1049, L"NONAME", 123), pe_exception::resource_directory_entry_not_found, "Resource viewer test 34", test_level_normal); + PE_TEST(res.get_resource_data_by_id(1033, pe_resource_viewer::resource_manifest, 1).get_codepage() == 0x4E4, "Resource viewer test 35", test_level_normal); + + PE_TEST(res.get_resource_data_by_name(pe_resource_viewer::resource_icon_group, L"MAIN_ICON").get_codepage() == 0x4E4, "Resource viewer test 36", test_level_normal); + PE_TEST(res.get_resource_data_by_name(pe_resource_viewer::resource_icon_group, L"MAIN_ICON").get_data().substr(0, 5) == std::string("\0\0\1\0\x0d", 5), "Resource viewer test 37", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(res.get_resource_data_by_name(pe_resource_viewer::resource_icon_group, L"MAIN_ICON", 1), pe_exception::resource_data_entry_not_found, "Resource viewer test 38", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(res.get_resource_data_by_name(L"NONAME", L"NONAME2"), pe_exception::resource_directory_entry_not_found, "Resource viewer test 39", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(res.get_resource_data_by_name(1049, L"QWERTY", L"QWERTY"), pe_exception::resource_directory_entry_not_found, "Resource viewer test 40", test_level_normal); + PE_TEST(res.get_resource_data_by_name(1049, pe_resource_viewer::resource_icon_group, L"MAIN_ICON").get_codepage() == 0x4E4, "Resource viewer test 41", test_level_normal); + + PE_TEST_EXPECT_EXCEPTION(res.get_resource_data_by_id(1032, pe_resource_viewer::resource_manifest, 1), pe_exception::resource_directory_entry_not_found, "Resource viewer test 42", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(res.get_resource_data_by_name(1050, pe_resource_viewer::resource_icon_group, L"MAIN_ICON"), pe_exception::resource_directory_entry_not_found, "Resource viewer test 43", test_level_normal); + + PE_TEST_END + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_viewer/test_resource_viewer.vcproj b/irdb-lib/pebliss/trunk/tests/test_resource_viewer/test_resource_viewer.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..31ea0ba0136a91c5e11b0bb8cb1fbd6987851540 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_viewer/test_resource_viewer.vcproj @@ -0,0 +1,359 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="test_resource_viewer" + ProjectGUID="{DD6C58C3-6DD5-43B2-A9ED-760E5F5830AA}" + RootNamespace="test_resource_viewer" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + <File + RelativePath="..\test.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_viewer/test_resource_viewer.vcxproj b/irdb-lib/pebliss/trunk/tests/test_resource_viewer/test_resource_viewer.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..ba74aff11534d22ff31eb72ebff31f9972703f6b --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_viewer/test_resource_viewer.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{1FC3537C-EC13-4877-A06C-42DD8B81CBF3}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>test_resource_viewer</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + <ClInclude Include="..\test.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_resource_viewer/test_resource_viewer.vcxproj.filters b/irdb-lib/pebliss/trunk/tests/test_resource_viewer/test_resource_viewer.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..8f0719260417c2cc422a533c4a0c453eb3d84c1a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resource_viewer/test_resource_viewer.vcxproj.filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\test.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_resources/Makefile b/irdb-lib/pebliss/trunk/tests/test_resources/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..422827f1e3ba0c0d1373f3dcd0b7219c702e806e --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resources/Makefile @@ -0,0 +1 @@ +include ../tests.mak diff --git a/irdb-lib/pebliss/trunk/tests/test_resources/main.cpp b/irdb-lib/pebliss/trunk/tests/test_resources/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a84fb940cc2b3044bc919f863a573c3b582dbf3a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resources/main.cpp @@ -0,0 +1,89 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#include <pe_bliss_resources.h> +#include "test.h" +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +void test_resources(const resource_directory& root) +{ + PE_TEST(root.get_entry_list().size() == 8, "Resource test 1", test_level_critical); + PE_TEST(root.get_characteristics() == 0 && root.get_timestamp() == 0, "Resource test 2", test_level_normal); + PE_TEST(root.get_minor_version() == 0 && root.get_major_version() == 4, "Resource test 3", test_level_normal); + PE_TEST(root.get_number_of_named_entries() == 0 && root.get_number_of_id_entries() == 8, "Resource test 4", test_level_normal); + PE_TEST(!root.get_entry_list()[1].is_named() && root.get_entry_list()[1].get_id() == pe_resource_viewer::resource_bitmap, "Resource test 5", test_level_normal); + PE_TEST(!root.get_entry_list()[1].includes_data(), "Resource test 6", test_level_critical); + + const resource_directory& bitmap_root = root.get_entry_list()[1].get_resource_directory(); + PE_TEST(bitmap_root.get_number_of_named_entries() == 0 && bitmap_root.get_number_of_id_entries() == 3, "Resource test 7", test_level_critical); + PE_TEST(!bitmap_root.get_entry_list()[1].is_named() && bitmap_root.get_entry_list()[1].get_id() == 102, "Resource test 8", test_level_normal); + PE_TEST(!bitmap_root.get_entry_list()[1].includes_data(), "Resource test 9", test_level_critical); + + const resource_directory& bitmap_102_root = bitmap_root.get_entry_list()[1].get_resource_directory(); + PE_TEST(bitmap_102_root.get_number_of_named_entries() == 0 && bitmap_102_root.get_number_of_id_entries() == 1, "Resource test 10", test_level_critical); + PE_TEST(!bitmap_102_root.get_entry_list()[0].is_named() && bitmap_102_root.get_entry_list()[0].get_id() == 1049, "Resource test 11", test_level_normal); + PE_TEST(bitmap_102_root.get_entry_list()[0].includes_data(), "Resource test 12", test_level_critical); + + const resource_data_entry& bitmap_data = bitmap_102_root.get_entry_list()[0].get_data_entry(); + PE_TEST(bitmap_data.get_codepage() == 0x4E4, "Resource test 13", test_level_normal); + PE_TEST(bitmap_data.get_data().substr(0, 5) == std::string("\x28\0\0\0\x4f", 5) && bitmap_data.get_data().size() == 0x4EE8, "Resource test 14", test_level_normal); +} + +int main(int argc, char* argv[]) +{ + PE_TEST_START + + std::auto_ptr<std::ifstream> pe_file; + if(!open_pe_file(argc, argv, pe_file)) + return -1; + + pe_base image(pe_factory::create_pe(*pe_file)); + + resource_directory root; + + PE_TEST_EXCEPTION(root = get_resources(image), "Resource Directory Parser test 1", test_level_critical); + test_resources(root); + + section s; + s.get_raw_data().resize(1); + s.set_name("newrsrc"); + section& new_resource_section = image.add_section(s); + uint32_t old_resources_rva = image.get_directory_rva(pe_win::image_directory_entry_resource); + PE_TEST_EXCEPTION(rebuild_resources(image, root, new_resource_section, 0, true, true), "Resource Rebuilder test 1", test_level_critical); + PE_TEST_EXCEPTION(root = get_resources(image), "Resource Directory Parser test 2", test_level_critical); + PE_TEST(old_resources_rva != image.get_directory_rva(pe_win::image_directory_entry_resource), "Relocation Directory test", test_level_normal); + test_resources(root); + + new_resource_section.set_raw_data("111"); + PE_TEST_EXCEPTION(rebuild_resources(image, root, new_resource_section, 3, true, true), "Resource Rebuilder test 2", test_level_critical); + PE_TEST(new_resource_section.get_raw_data().substr(0, 3) == "111", "Resource Rebuilder Offset test", test_level_normal); + PE_TEST_EXCEPTION(root = get_resources(image), "Resource Directory Parser test 3", test_level_critical); + test_resources(root); + + PE_TEST_EXCEPTION(rebuild_resources(image, root, new_resource_section, 12, true, true), "Resource Rebuilder test 3", test_level_critical); + PE_TEST_EXCEPTION(root = get_resources(image), "Resource Directory Parser test 4", test_level_critical); + test_resources(root); + + { + resource_directory& cursor_root = root.get_entry_list()[0].get_resource_directory(); + resource_directory_entry named_entry; + named_entry.set_name(L"test entry"); + named_entry.add_data_entry(resource_data_entry("alala", 123)); + cursor_root.add_resource_directory_entry(named_entry); + } + + PE_TEST_EXCEPTION(rebuild_resources(image, root, new_resource_section, 12, true, true), "Resource Rebuilder test 4", test_level_critical); + PE_TEST_EXCEPTION(root = get_resources(image), "Resource Directory Parser test 5", test_level_critical); + test_resources(root); + + resource_directory& cursor_root = root.get_entry_list()[0].get_resource_directory(); + PE_TEST(cursor_root.entry_by_name(L"test entry").get_data_entry().get_data() == "alala", "Resource named entry test", test_level_normal); + + PE_TEST_END + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/tests/test_resources/test_resources.vcproj b/irdb-lib/pebliss/trunk/tests/test_resources/test_resources.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..bb6f122160579d7dc67d9c8cf97dba7ced3f9705 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resources/test_resources.vcproj @@ -0,0 +1,359 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="test_resources" + ProjectGUID="{7E3867A9-59BC-4441-A74E-F4ABFFEE231C}" + RootNamespace="test_resources" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + <File + RelativePath="..\test.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/tests/test_resources/test_resources.vcxproj b/irdb-lib/pebliss/trunk/tests/test_resources/test_resources.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..43718c2ff54122831509770ec3de63635b66b598 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resources/test_resources.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{8ECEF4F9-1461-4FCB-87D9-C871C71B01B7}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>test_resources</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + <ClInclude Include="..\test.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_resources/test_resources.vcxproj.filters b/irdb-lib/pebliss/trunk/tests/test_resources/test_resources.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..8f0719260417c2cc422a533c4a0c453eb3d84c1a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_resources/test_resources.vcxproj.filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\test.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_rich_data/Makefile b/irdb-lib/pebliss/trunk/tests/test_rich_data/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..422827f1e3ba0c0d1373f3dcd0b7219c702e806e --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_rich_data/Makefile @@ -0,0 +1 @@ +include ../tests.mak diff --git a/irdb-lib/pebliss/trunk/tests/test_rich_data/main.cpp b/irdb-lib/pebliss/trunk/tests/test_rich_data/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..51027ada7074aa177e1944d53ba51809f495d486 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_rich_data/main.cpp @@ -0,0 +1,40 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#include "test.h" +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +int main(int argc, char* argv[]) +{ + PE_TEST_START + + std::auto_ptr<std::ifstream> pe_file; + if(!open_pe_file(argc, argv, pe_file)) + return -1; + + pe_base image(pe_factory::create_pe(*pe_file)); + + rich_data_list data; + PE_TEST_EXCEPTION(data = get_rich_data(image), "Rich Data test 1", test_level_critical); + PE_TEST(data.size() == 8, "Rich Data test 2", test_level_normal); + PE_TEST(data[0].get_number() == 158, "Rich Data test 3", test_level_normal); + + if(image.get_pe_type() == pe_type_32) + { + PE_TEST(data[1].get_times() == 47, "Rich Data test 4", test_level_normal); + } + else + { + PE_TEST(data[1].get_times() == 48, "Rich Data test 4", test_level_normal); + } + + PE_TEST(data[2].get_version() == 40219, "Rich Data test 5", test_level_normal); + + PE_TEST_END + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/tests/test_rich_data/test_rich_data.vcproj b/irdb-lib/pebliss/trunk/tests/test_rich_data/test_rich_data.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..ce50d48e7d4e688ca5fde7c5c87324109e923ef2 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_rich_data/test_rich_data.vcproj @@ -0,0 +1,359 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="test_rich_data" + ProjectGUID="{1F877026-3D94-41BF-B392-06DFAF67AE34}" + RootNamespace="test_rich_data" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + <File + RelativePath="..\test.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/tests/test_rich_data/test_rich_data.vcxproj b/irdb-lib/pebliss/trunk/tests/test_rich_data/test_rich_data.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..a51b0c5ac51028e02b474bfac66088657a408dd0 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_rich_data/test_rich_data.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{114AC59B-BC28-40DB-8380-67C422D0C81B}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>test_rich_data</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + <ClInclude Include="..\test.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_rich_data/test_rich_data.vcxproj.filters b/irdb-lib/pebliss/trunk/tests/test_rich_data/test_rich_data.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..8f0719260417c2cc422a533c4a0c453eb3d84c1a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_rich_data/test_rich_data.vcxproj.filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\test.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_runner/Makefile b/irdb-lib/pebliss/trunk/tests/test_runner/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..422827f1e3ba0c0d1373f3dcd0b7219c702e806e --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_runner/Makefile @@ -0,0 +1 @@ +include ../tests.mak diff --git a/irdb-lib/pebliss/trunk/tests/test_runner/main.cpp b/irdb-lib/pebliss/trunk/tests/test_runner/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..69839e67332604516f5b8b98812a6884ea13f6f1 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_runner/main.cpp @@ -0,0 +1,212 @@ +#include <iostream> +#include <map> +#include <string> +#include <stdio.h> +#include <pe_bliss.h> +#ifndef PE_BLISS_WINDOWS +#include <sys/wait.h> +#endif + +#define PE_TEST_32 "../pe_files/image32.exe" +#define PE_TEST_64 "../pe_files/image64.exe" +#define PE_TEST_DOTNET "../pe_files/TestApp.exe" +#define PE_TEST_DEBUG "../pe_files/debug_test.exe" +#define PE_DLL_TEST_32 "../pe_files/test_dll_32.dll" +#define PE_DLL_TEST_64 "../pe_files/test_dll_64.dll" +#define PE_BOUND_IMPORT_TEST_32 "../pe_files/bound32.exe" +#define PE_BOUND_IMPORT_TEST_64 "../pe_files/bound64.exe" +#define PE_TEST_MESSAGE_TABLE "../pe_files/message_table_resource.exe" + +class testcase +{ +public: + testcase(const std::string& binary_name, const std::string& testcase_name, const std::vector<std::string>& command_lines = std::vector<std::string>()) + :binary_name_(binary_name), testcase_name_(testcase_name), command_lines_(command_lines) + {} + + const std::string get_binary_name() const + { +#ifdef PE_BLISS_WINDOWS + return binary_name_ + ".exe"; +#else + return binary_name_; +#endif + } + + const std::string& get_testcase_name() const + { + return testcase_name_; + } + + const std::vector<std::string>& get_command_lines() const + { + return command_lines_; + } + +private: + std::string binary_name_; + std::string testcase_name_; + std::vector<std::string> command_lines_; +}; + +#ifdef PE_BLISS_WINDOWS +#define POPEN _popen +#define PCLOSE _pclose +#define DEV_NULL " 1> nul" +#else +#define POPEN popen +#define PCLOSE pclose +#define DEV_NULL " 1> /dev/null" +#endif + +bool run_test(const std::string& path, const std::string& test, bool& warnings_occured, const std::string& cmd = "") +{ + FILE* bin; +#ifdef PE_BLISS_WINDOWS + bin = POPEN(("\"\"" + path + test + "\" \"" + path + cmd + "\"\" 2>&1" + DEV_NULL).c_str(), "r"); +#else + bin = POPEN(("\"" + path + test + "\" \"" + path + cmd + "\" 2>&1" + DEV_NULL).c_str(), "r"); +#endif + + if(bin == NULL) + { + std::cerr << "Cannot execute testsuite" << std::endl; + return false; + } + + char buf[256]; + while(fgets(buf, sizeof(buf), bin) != NULL) + { + warnings_occured = true; + std::cerr << buf; + } + +#ifdef PE_BLISS_WINDOWS + return PCLOSE(bin) == 0; +#else + int stat; + int wstat = WEXITSTATUS(stat = PCLOSE(bin)); + if(stat < 0 || (wstat != 0 && wstat != 128 + SIGPIPE)) + return false; + else + return true; +#endif +} + +const std::string get_full_path(const std::string& full_name) +{ + std::string::size_type slash_pos = full_name.find_last_of("/\\"); + if(slash_pos != std::string::npos) + return full_name.substr(0, slash_pos + 1); + + return ""; +} + +int main(int argc, char* argv[]) +{ + bool warnings_occured = false; + + typedef std::vector<testcase> test_list; + + test_list tests; + + { + std::vector<std::string> command_line; + command_line.push_back(PE_TEST_32); + command_line.push_back(PE_TEST_64); + tests.push_back(testcase("tests_utils", "PE Utils tests")); + tests.push_back(testcase("tests_basic", "Basic PE tests", command_line)); + tests.push_back(testcase("test_checksum", "PE Checksum tests", command_line)); + tests.push_back(testcase("test_entropy", "PE Entropy tests", command_line)); + tests.push_back(testcase("test_rich_data", "PE Rich Data tests", command_line)); + tests.push_back(testcase("test_imports", "PE Imports tests", command_line)); + tests.push_back(testcase("test_relocations", "PE Relocations tests", command_line)); + tests.push_back(testcase("test_load_config", "PE Load Configuration tests", command_line)); + tests.push_back(testcase("test_exception_directory", "PE Exception Directory tests", command_line)); + tests.push_back(testcase("test_tls", "PE Thread Local Storage tests", command_line)); + tests.push_back(testcase("test_resources", "PE Resource Directory tests", command_line)); + + command_line.pop_back(); + //These binaries work with resource classes, which are not dependent on PE format + //So PE32 is enough to test them + tests.push_back(testcase("test_resource_viewer", "PE Resource Viewer tests", command_line)); + tests.push_back(testcase("test_resource_manager", "PE Resource Manager tests", command_line)); + tests.push_back(testcase("test_resource_bitmap", "PE Resource Bitmap Read & Write tests", command_line)); + tests.push_back(testcase("test_resource_icon_cursor", "PE Resource Icon/Cursor Read & Write tests", command_line)); + tests.push_back(testcase("test_resource_string_table", "PE Resource String Table Parser tests", command_line)); + tests.push_back(testcase("test_resource_version_info", "PE Resource Version Info & Write tests", command_line)); + } + + { + std::vector<std::string> message_table_command_line; + message_table_command_line.push_back(PE_TEST_MESSAGE_TABLE); + tests.push_back(testcase("test_resource_message_table", "Pe Resource Message Table Parser tests", message_table_command_line)); + } + + { + std::vector<std::string> dotnet_command_line; + dotnet_command_line.push_back(PE_TEST_DOTNET); + tests.push_back(testcase("test_dotnet", "PE Basic .NET tests", dotnet_command_line)); + } + + { + std::vector<std::string> debug_command_line; + debug_command_line.push_back(PE_TEST_DEBUG); + debug_command_line.push_back(PE_TEST_64); + tests.push_back(testcase("test_debug", "PE Debug Info tests", debug_command_line)); + } + + { + std::vector<std::string> dll_command_line; + dll_command_line.push_back(PE_DLL_TEST_32); + dll_command_line.push_back(PE_DLL_TEST_64); + tests.push_back(testcase("test_exports", "PE Exports tests", dll_command_line)); + } + + { + std::vector<std::string> bound_import_command_line; + bound_import_command_line.push_back(PE_BOUND_IMPORT_TEST_32); + bound_import_command_line.push_back(PE_BOUND_IMPORT_TEST_64); + tests.push_back(testcase("test_bound_import", "PE Bound Import tests", bound_import_command_line)); + } + + std::string runner_path(get_full_path(argv[0])); + + for(test_list::const_iterator it = tests.begin(); it != tests.end(); ++it) + { + const testcase& t = *it; + bool result = true; + if(!t.get_command_lines().empty()) + { + const std::vector<std::string>& cmd_lines = t.get_command_lines(); + for(std::vector<std::string>::const_iterator cmd = cmd_lines.begin(); cmd != cmd_lines.end(); ++cmd) + { + std::cout << "Running " << t.get_testcase_name() << " with \"" << (*cmd) << "\"" << std::endl; + result = run_test(runner_path, t.get_binary_name(), warnings_occured, *cmd); + if(!result) + break; + } + } + else + { + std::cout << "Running " << t.get_testcase_name() << std::endl; + result = run_test(runner_path, t.get_binary_name(), warnings_occured); + } + + if(!result) + { + std::cerr << "Some tests hard-failed in this testsuite, exiting..." << std::endl; + return -1; + } + + std::cout << std::endl; + } + + if(warnings_occured) + std::cout << "Some tests failed, check the log!" << std::endl; + else + std::cout << "Everything went just fine!" << std::endl; + + std::cout << "Finished." << std::endl; + return 0; +} diff --git a/irdb-lib/pebliss/trunk/tests/test_runner/test_runner.vcproj b/irdb-lib/pebliss/trunk/tests/test_runner/test_runner.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..73c1ed9f48b62d67173fa2e4fd858ad870cc363b --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_runner/test_runner.vcproj @@ -0,0 +1,351 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="test_runner" + ProjectGUID="{31843E48-DC9A-4887-BD97-328079D78C88}" + RootNamespace="test_runner" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/tests/test_runner/test_runner.vcxproj b/irdb-lib/pebliss/trunk/tests/test_runner/test_runner.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..9b86e96c00b09ccbe0f4071fbb10c5b2d85a813c --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_runner/test_runner.vcxproj @@ -0,0 +1,163 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{132DFCC9-13EF-4178-9772-1C467FB296D6}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>test_runner</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_runner/test_runner.vcxproj.filters b/irdb-lib/pebliss/trunk/tests/test_runner/test_runner.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..8755a3a0268981c2f6fee186ee23f9488c6d781c --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_runner/test_runner.vcxproj.filters @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_tls/Makefile b/irdb-lib/pebliss/trunk/tests/test_tls/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..422827f1e3ba0c0d1373f3dcd0b7219c702e806e --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_tls/Makefile @@ -0,0 +1 @@ +include ../tests.mak diff --git a/irdb-lib/pebliss/trunk/tests/test_tls/main.cpp b/irdb-lib/pebliss/trunk/tests/test_tls/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..802147c793a352143b02cf40663c7a256a2aba6a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_tls/main.cpp @@ -0,0 +1,101 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#include "test.h" +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +void test_tls(const tls_info& info, const pe_base& image, bool check_callbacks = true) +{ + PE_TEST(info.get_characteristics() == 0, "TLS test 1", test_level_normal); + PE_TEST(info.get_size_of_zero_fill() == 0, "TLS test 2", test_level_normal); + PE_TEST(info.get_raw_data_end_rva() - info.get_raw_data_start_rva() == 8, "TLS test 3", test_level_normal); + PE_TEST(info.get_raw_data() == std::string("\0\0\0\0\x37\x02\0\0", 8), "TLS test 4", test_level_normal); + + if(check_callbacks) + { + PE_TEST(info.get_tls_callbacks().empty(), "TLS test 5", test_level_normal); + } + + if(image.get_pe_type() == pe_type_32) + { + PE_TEST(info.get_index_rva() == 0x420738 - image.get_image_base_32(), "TLS test 6", test_level_normal); + + if(check_callbacks) + { + PE_TEST(info.get_callbacks_rva() == 0x418188 - image.get_image_base_32(), "TLS test 7", test_level_normal); + } + } + else + { + PE_TEST(info.get_index_rva() == 0x14002647Cull - image.get_image_base_64(), "TLS test 6", test_level_normal); + + if(check_callbacks) + { + PE_TEST(info.get_callbacks_rva() == 0x14001B310ull - image.get_image_base_64(), "TLS test 7", test_level_normal); + } + } +} + +int main(int argc, char* argv[]) +{ + PE_TEST_START + + std::auto_ptr<std::ifstream> pe_file; + if(!open_pe_file(argc, argv, pe_file)) + return -1; + + pe_base image(pe_factory::create_pe(*pe_file)); + + tls_info info; + PE_TEST_EXCEPTION(info = get_tls_info(image), "TLS Parser test 1", test_level_critical); + test_tls(info, image); + + section s; + s.get_raw_data().resize(1); + s.set_name("newtls"); + section& new_tls_section = image.add_section(s); + uint32_t old_tls_rva = image.get_directory_rva(pe_win::image_directory_entry_tls); + PE_TEST_EXCEPTION(rebuild_tls(image, info, new_tls_section, 0, false, false, tls_data_expand_raw, true, true), "TLS Rebuilder test 1", test_level_critical); + PE_TEST(old_tls_rva != image.get_directory_rva(pe_win::image_directory_entry_tls), "TLS directory test", test_level_normal); + + PE_TEST_EXCEPTION(info = get_tls_info(image), "TLS Parser test 2", test_level_critical); + test_tls(info, image); + + new_tls_section.set_raw_data("111"); + PE_TEST_EXCEPTION(rebuild_tls(image, info, new_tls_section, 3, false, false, tls_data_expand_raw, true, true), "TLS Rebuilder test 2", test_level_critical); + PE_TEST_EXCEPTION(info = get_tls_info(image), "TLS Parser test 3", test_level_critical); + PE_TEST(new_tls_section.get_raw_data().substr(0, 3) == "111", "TLS Rebuilder offset test", test_level_normal); + test_tls(info, image); + + PE_TEST_EXCEPTION(rebuild_tls(image, info, new_tls_section, 12, false, false, tls_data_expand_raw, true, true), "TLS Rebuilder test 3", test_level_critical); + PE_TEST_EXCEPTION(info = get_tls_info(image), "TLS Parser test 4", test_level_critical); + test_tls(info, image); + + image.set_section_virtual_size(new_tls_section, 0x2000); + info.set_raw_data_start_rva(image.rva_from_section_offset(new_tls_section, 0x1000)); + info.recalc_raw_data_end_rva(); + PE_TEST_EXCEPTION(rebuild_tls(image, info, new_tls_section, 12, false, true, tls_data_expand_raw, true, true), "TLS Rebuilder test 4", test_level_critical); + PE_TEST_EXCEPTION(info = get_tls_info(image), "TLS Parser test 5", test_level_critical); + test_tls(info, image); + + info.add_tls_callback(0x111); + info.add_tls_callback(0x222); + info.add_tls_callback(0x333); + info.add_tls_callback(0x444); + info.add_tls_callback(0x555); + info.set_callbacks_rva(image.rva_from_section_offset(new_tls_section, 0x1500)); + + PE_TEST_EXCEPTION(rebuild_tls(image, info, new_tls_section, 12, true, true, tls_data_expand_raw, true, true), "TLS Rebuilder test 5", test_level_critical); + PE_TEST_EXCEPTION(info = get_tls_info(image), "TLS Parser test 6", test_level_critical); + test_tls(info, image, false); + PE_TEST(info.get_tls_callbacks().size() == 5, "TLS test 7", test_level_normal); + PE_TEST(info.get_tls_callbacks()[2] == 0x333, "TLS test 8", test_level_normal); + + PE_TEST_END + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/tests/test_tls/test_tls.vcproj b/irdb-lib/pebliss/trunk/tests/test_tls/test_tls.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..457589e1d7f8aefc2f77069fd8da5d46e4238c9f --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_tls/test_tls.vcproj @@ -0,0 +1,359 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="test_tls" + ProjectGUID="{63D80BC8-EB14-4698-A391-4A41AC15E8D1}" + RootNamespace="test_tls" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + <File + RelativePath="..\test.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/tests/test_tls/test_tls.vcxproj b/irdb-lib/pebliss/trunk/tests/test_tls/test_tls.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..d7e555f9074f52d8aeb79ce1a7655648319cdce5 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_tls/test_tls.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{CFC22F11-2C5F-46F3-9C51-ED8C3E5EFA89}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>test_tls</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + <ClInclude Include="..\test.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/test_tls/test_tls.vcxproj.filters b/irdb-lib/pebliss/trunk/tests/test_tls/test_tls.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..8f0719260417c2cc422a533c4a0c453eb3d84c1a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/test_tls/test_tls.vcxproj.filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\test.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/tests.mak b/irdb-lib/pebliss/trunk/tests/tests.mak new file mode 100644 index 0000000000000000000000000000000000000000..430bcdcc1db27a9a81c90f1e425807ccd8591f19 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/tests.mak @@ -0,0 +1,23 @@ +PWD=$(shell pwd) +OUTDIR = ../bin/ +LIBPATH = ../../lib/libpebliss.a +NAME=$(shell basename $(PWD)) +CXXFLAGS = -O2 -Wall -I../../pe_lib -I../ + +ifdef PE_DEBUG +CXXFLAGS += -g -O0 +endif + +all: $(OUTDIR)$(NAME) + +clean: + rm -f $(NAME) *.o + rm -f $(OUTDIR)$(NAME) + +$(NAME): main.o + $(CXX) -Wall $^ -lpebliss -L../../lib -o $(NAME) -liconv + +main.o: $(LIBPATH) + +$(OUTDIR)$(NAME): $(NAME) + cp -d $(NAME) $(OUTDIR) diff --git a/irdb-lib/pebliss/trunk/tests/tests_basic/Makefile b/irdb-lib/pebliss/trunk/tests/tests_basic/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..422827f1e3ba0c0d1373f3dcd0b7219c702e806e --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/tests_basic/Makefile @@ -0,0 +1 @@ +include ../tests.mak diff --git a/irdb-lib/pebliss/trunk/tests/tests_basic/main.cpp b/irdb-lib/pebliss/trunk/tests/tests_basic/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..487ceda9dc04dc8545a66685d35edf61aa6d53e6 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/tests_basic/main.cpp @@ -0,0 +1,496 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#include "test.h" +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +int main(int argc, char* argv[]) +{ + PE_TEST_START + + std::auto_ptr<std::ifstream> pe_file; + if(!open_pe_file(argc, argv, pe_file)) + return -1; + + std::auto_ptr<pe_base> image; + PE_TEST_EXCEPTION(image.reset(new pe_base(pe_factory::create_pe(*pe_file))), "Creation, type detection and copying test", test_level_critical); + + PE_TEST(!image->has_overlay(), "Overlay test", test_level_normal); + PE_TEST(image->get_stub_overlay()[1] == 0x1F, "Stub test 1", test_level_normal); + PE_TEST_EXCEPTION(image->fill_stub_overlay(0x11), "Stub test 2", test_level_normal); + PE_TEST(image->get_stub_overlay()[1] == 0x11, "Stub test 3", test_level_normal); + PE_TEST_EXCEPTION(image->strip_stub_overlay(), "Stub test 4", test_level_normal); + PE_TEST(image->get_stub_overlay().empty(), "Stub test 5", test_level_normal); + + std::cout << "PE Header tests..." << std::endl; + + PE_TEST(!image->directory_exists(pe_win::image_directory_entry_com_descriptor), "Directory test 1", test_level_normal); + PE_TEST(image->directory_exists(pe_win::image_directory_entry_import), "Directory test 2", test_level_normal); + PE_TEST(image->has_imports(), "Directory test 3", test_level_normal); + PE_TEST(!image->has_exports(), "Directory test 4", test_level_normal); + + PE_TEST(image->get_subsystem() == pe_win::image_subsystem_windows_cui, "Subsystem test 1", test_level_normal); + PE_TEST(image->is_console(), "Subsystem test 2", test_level_normal); + PE_TEST(!image->is_gui(), "Subsystem test 3", test_level_normal); + + image->set_subsystem(pe_win::image_subsystem_native_windows); + PE_TEST(image->get_subsystem() == pe_win::image_subsystem_native_windows, "Subsystem test 4", test_level_normal); + + PE_TEST(image->get_pe_signature() == 0x4550, "PE Signature test", test_level_normal); + + PE_TEST(image->get_file_alignment() == 0x200, "File Alignment test 1", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(image->set_file_alignment(123), pe_exception::incorrect_file_alignment, "File Alignment test 2", test_level_normal); + PE_TEST_EXCEPTION(image->set_file_alignment(0x1000), "File Alignment test 3", test_level_normal); + PE_TEST(image->get_file_alignment() == 0x1000, "File Alignment test 4", test_level_normal); + + PE_TEST(image->get_section_alignment() == 0x1000, "Section Alignment test", test_level_normal); + + PE_TEST(image->get_number_of_rvas_and_sizes() == 0x10, "Data directories test", test_level_normal); + + PE_TEST(image->check_characteristics_flag(pe_win::image_file_executable_image), "Image Characteristics test 1", test_level_normal); + PE_TEST(!image->check_characteristics_flag(pe_win::image_file_dll), "Image Characteristics test 2", test_level_normal); + + PE_TEST(image->get_size_of_headers() == 0x400, "Size of headers test", test_level_normal); + + PE_TEST(image->get_dll_characteristics() == 0x8140, "Image DLL Characteristics test", test_level_normal); + + if(image->get_pe_type() == pe_type_32) + { + PE_TEST(image->get_directory_rva(pe_win::image_directory_entry_import) == 0x1C9E4, "Directory RVA test 1", test_level_normal); + PE_TEST(image->get_directory_size(pe_win::image_directory_entry_import) == 0x3C, "Directory size test 1", test_level_normal); + + PE_TEST(image->get_minor_os_version() == 1 && image->get_major_os_version() == 5, "OS Version test", test_level_normal); + PE_TEST(image->get_minor_subsystem_version() == 1 && image->get_major_subsystem_version() == 5, "Subsystem Version test", test_level_normal); + + PE_TEST(image->get_pe_header_start() == 0xE0, "e_lfanew test", test_level_normal); + + PE_TEST(image->get_size_of_image() == 0x41000, "Size of Image test", test_level_normal); + PE_TEST(image->get_ep() == 0x6851, "Entry Point test", test_level_normal); + + PE_TEST(image->get_characteristics() == 0x102, "Image Characteristics test 3", test_level_normal); + + PE_TEST(image->get_size_of_optional_header() == 0xE0, "Size of optional header test", test_level_normal); + + PE_TEST(image->get_magic() == 0x10B, "PE Magic test", test_level_normal); + + PE_TEST(image->get_image_base_32() == 0x400000, "Image Base test 1", test_level_normal); + + { + uint32_t image_base; + image->get_image_base(image_base); + PE_TEST(image_base == 0x400000, "Image Base test 2", test_level_normal); + } + + PE_TEST(image->get_heap_size_commit_32() == 0x1000, "Heap Size Commit test 1", test_level_normal); + PE_TEST(image->get_heap_size_reserve_32() == 0x100000, "Heap Size Reserve test 1", test_level_normal); + PE_TEST(image->get_stack_size_commit_32() == 0x1000, "Stack Size Commit test 1", test_level_normal); + PE_TEST(image->get_stack_size_reserve_32() == 0x100000, "Stack Size Reserve test 1", test_level_normal); + + { + uint32_t size; + image->get_heap_size_commit(size); + PE_TEST(size == 0x1000, "Heap Size Commit test 2", test_level_normal); + image->get_heap_size_reserve(size); + PE_TEST(size == 0x100000, "Heap Size Reserve test 2", test_level_normal); + image->get_stack_size_commit(size); + PE_TEST(size == 0x1000, "Stack Size Commit test 2", test_level_normal); + image->get_stack_size_reserve(size); + PE_TEST(size == 0x100000, "Stack Size Reserve test 2", test_level_normal); + } + + PE_TEST(image->get_time_date_stamp() == 0x508E65A3, "TimeStamp test", test_level_normal); + PE_TEST(image->get_machine() == 0x014C, "Machine test", test_level_normal); + } + else + { + PE_TEST(image->get_directory_rva(pe_win::image_directory_entry_import) == 0x223EC, "Directory RVA test", test_level_normal); + PE_TEST(image->get_directory_size(pe_win::image_directory_entry_import) == 0x3C, "Directory size test", test_level_normal); + + PE_TEST(image->get_pe_header_start() == 0xF0, "e_lfanew test", test_level_normal); + + PE_TEST(image->get_minor_os_version() == 2 && image->get_major_os_version() == 5, "OS Version test", test_level_normal); + PE_TEST(image->get_minor_subsystem_version() == 2 && image->get_major_subsystem_version() == 5, "Subsystem Version test", test_level_normal); + + PE_TEST(image->get_size_of_image() == 0x48000, "Size of Image test", test_level_normal); + PE_TEST(image->get_ep() == 0x7A64, "Entry Point test", test_level_normal); + + PE_TEST(image->get_characteristics() == 0x22, "Image Characteristics test 3", test_level_normal); + + PE_TEST(image->get_size_of_optional_header() == 0xF0, "Size of optional header test", test_level_normal); + + PE_TEST(image->get_magic() == 0x20B, "PE Magic test", test_level_normal); + + PE_TEST(image->get_image_base_64() == 0x0000000140000000ull, "Image Base test 1", test_level_normal); + + { + uint64_t image_base; + image->get_image_base(image_base); + PE_TEST(image_base == 0x0000000140000000ull, "Image Base test 2", test_level_normal); + } + + PE_TEST(image->get_heap_size_commit_64() == 0x1000, "Heap Size Commit test 1", test_level_normal); + PE_TEST(image->get_heap_size_reserve_64() == 0x100000, "Heap Size Reserve test 1", test_level_normal); + PE_TEST(image->get_stack_size_commit_64() == 0x1000, "Stack Size Commit test 1", test_level_normal); + PE_TEST(image->get_stack_size_reserve_64() == 0x100000, "Stack Size Reserve test 1", test_level_normal); + + { + uint64_t size; + image->get_heap_size_commit(size); + PE_TEST(size == 0x1000, "Heap Size Commit test 2", test_level_normal); + image->get_heap_size_reserve(size); + PE_TEST(size == 0x100000, "Heap Size Reserve test 2", test_level_normal); + image->get_stack_size_commit(size); + PE_TEST(size == 0x1000, "Stack Size Commit test 2", test_level_normal); + image->get_stack_size_reserve(size); + PE_TEST(size == 0x100000, "Stack Size Reserve test 2", test_level_normal); + } + + PE_TEST(image->get_time_date_stamp() == 0x508E65B2, "TimeStamp test", test_level_normal); + PE_TEST(image->get_machine() == 0x8664, "Machine test", test_level_normal); + } + + image->set_directory_rva(pe_win::image_directory_entry_architecture, 0x1000); + image->set_directory_size(pe_win::image_directory_entry_architecture, 0x2000); + PE_TEST(image->get_directory_rva(pe_win::image_directory_entry_architecture) == 0x1000, "Directory RVA test 2", test_level_normal); + PE_TEST(image->get_directory_size(pe_win::image_directory_entry_architecture) == 0x2000, "Directory size test 2", test_level_normal); + + image->remove_directory(pe_win::image_directory_entry_architecture); + PE_TEST(image->get_directory_rva(pe_win::image_directory_entry_architecture) == 0, "Directory RVA test 3", test_level_normal); + PE_TEST(image->get_directory_size(pe_win::image_directory_entry_architecture) == 0, "Directory size test 3", test_level_normal); + + PE_TEST(image->strip_data_directories(0, false) == 0x10 - 3, "Data directories strip test 1", test_level_normal); + PE_TEST(image->get_number_of_rvas_and_sizes() == 0x10 - 3, "Data directories strip test 2", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(image->get_directory_rva(pe_win::image_directory_entry_com_descriptor) == 0, pe_exception::directory_does_not_exist, "Directory RVA test 4", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(image->get_directory_size(pe_win::image_directory_entry_com_descriptor) == 0, pe_exception::directory_does_not_exist, "Directory size test 4", test_level_normal); + + if(image->get_pe_type() == pe_type_32) + { + PE_TEST(image->strip_data_directories(0, true) == 0x10 - 5, "Data directories strip test 3", test_level_normal); + } + else + { + PE_TEST(image->strip_data_directories(0, true) == 0x10 - 6, "Data directories strip test 3", test_level_normal); + } + + std::cout << "Address tests..." << std::endl; + + if(image->get_pe_type() == pe_type_32) + { + PE_TEST(image->va_to_rva(image->get_image_base_32() + 1) == 1, "Address conversion test 1", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(image->va_to_rva(image->get_image_base_32() - 1), pe_exception::incorrect_address_conversion, "Address conversion test 2", test_level_normal); + PE_TEST(image->rva_to_va_32(1) == image->get_image_base_32() + 1, "Address conversion test 3", test_level_normal); + + { + uint32_t va; + image->rva_to_va(1, va); + PE_TEST(va == image->get_image_base_32() + 1, "Address conversion test 4", test_level_normal); + } + } + else + { + PE_TEST(image->va_to_rva(image->get_image_base_64() + 1) == 1, "Address conversion test 1", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(image->va_to_rva(image->get_image_base_64() - 1), pe_exception::incorrect_address_conversion, "Address conversion test 2", test_level_normal); + PE_TEST(image->rva_to_va_64(1) == image->get_image_base_64() + 1, "Address conversion test 3", test_level_normal); + + { + uint64_t va; + image->rva_to_va(1, va); + PE_TEST(va == image->get_image_base_64() + 1, "Address conversion test 4", test_level_normal); + } + } + + PE_TEST(image->rva_to_file_offset(0x1001) == 0x401, "Address conversion test 5", test_level_normal); + PE_TEST(image->file_offset_to_rva(0x401) == 0x1001, "Address conversion test 6", test_level_normal); + PE_TEST(image->file_offset_to_rva(0x1) == 0x1, "Address conversion test 7", test_level_normal); + PE_TEST(image->rva_to_file_offset(0x1) == 0x1, "Address conversion test 8", test_level_normal); + + + std::cout << "Section tests..." << std::endl; + if(image->get_pe_type() == pe_type_32) + { + PE_TEST(image->get_number_of_sections() == 0x6, "Section number test 1", test_level_normal); + } + else + { + PE_TEST(image->get_number_of_sections() == 0x7, "Section number test 1", test_level_normal); + } + + PE_TEST(image->get_image_sections().size() == image->get_number_of_sections(), "Section number test 2", test_level_critical); + + PE_TEST(image->get_image_sections().at(0).get_name() == ".text", "Section name test 1", test_level_normal); + PE_TEST(image->get_image_sections().at(1).get_name() == ".rdata", "Section name test 2", test_level_normal); + + PE_TEST(image->section_from_directory(pe_win::image_directory_entry_import).get_name() == ".rdata", "Section test 1", test_level_normal); + PE_TEST(image->section_from_rva(0x1000).get_name() == ".text", "Section test 2", test_level_normal); + PE_TEST(image->section_from_va(image->get_image_base_64() + 0x1000).get_name() == ".text", "Section test 3", test_level_normal); + PE_TEST(image->section_from_file_offset(0x401).get_name() == ".text", "Section test 4", test_level_normal); + PE_TEST(image->rva_from_section_offset(image->get_image_sections().at(0), 0x5) == 0x1005, "Section test 5", test_level_normal); + + { + const section& s = image->get_image_sections().at(0); + PE_TEST(image->section_data_length_from_rva(s.get_virtual_address() + 123, section_data_raw, false) == s.get_raw_data().size(), "Section test 6", test_level_normal); + PE_TEST(image->section_data_length_from_rva(s, s.get_virtual_address() + 123, section_data_raw) == s.get_raw_data().size() - 123, "Section test 7", test_level_normal); + PE_TEST(image->section_data_length_from_rva(s.get_virtual_address() + 123, s.get_virtual_address() + 123, section_data_raw, false) == s.get_raw_data().size() - 123, "Section test 8", test_level_normal); + + PE_TEST_EXPECT_EXCEPTION(image->section_data_length_from_rva(s, s.get_virtual_address() - 1, section_data_raw), pe_exception::rva_not_exists, "Section test 9", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(image->section_data_length_from_rva(s.get_virtual_address() + 123, s.get_virtual_address() - 1, section_data_raw, false), pe_exception::rva_not_exists, "Section test 10", test_level_normal); + + PE_TEST(image->section_data_length_from_rva(s.get_virtual_address() + 123, section_data_virtual, false) == s.get_aligned_virtual_size(image->get_section_alignment()), "Section test 11", test_level_normal); + PE_TEST(image->section_data_length_from_rva(s, s.get_virtual_address() + 123, section_data_virtual) == s.get_aligned_virtual_size(image->get_section_alignment()) - 123, "Section test 12", test_level_normal); + PE_TEST(image->section_data_length_from_rva(s.get_virtual_address() + 123, s.get_virtual_address() + 123, section_data_virtual, false) == s.get_aligned_virtual_size(image->get_section_alignment()) - 123, "Section test 13", test_level_normal); + + PE_TEST_EXPECT_EXCEPTION(image->section_data_length_from_rva(s, s.get_virtual_address() - 1, section_data_virtual), pe_exception::rva_not_exists, "Section test 14", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(image->section_data_length_from_rva(s.get_virtual_address() + 123, s.get_virtual_address() - 1, section_data_virtual, false), pe_exception::rva_not_exists, "Section test 15", test_level_normal); + + if(image->get_pe_type() == pe_type_32) + { + uint32_t base = image->get_image_base_32(); + PE_TEST(image->section_data_length_from_va(base + s.get_virtual_address() + 123, section_data_raw, false) == s.get_raw_data().size(), "Section test 16", test_level_normal); + PE_TEST(image->section_data_length_from_va(s, base + s.get_virtual_address() + 123, section_data_raw) == s.get_raw_data().size() - 123, "Section test 17", test_level_normal); + PE_TEST(image->section_data_length_from_va(base + s.get_virtual_address() + 123, base + s.get_virtual_address() + 123, section_data_raw, false) == s.get_raw_data().size() - 123, "Section test 18", test_level_normal); + + PE_TEST_EXPECT_EXCEPTION(image->section_data_length_from_va(s, base + s.get_virtual_address() - 1, section_data_raw), pe_exception::rva_not_exists, "Section test 19", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(image->section_data_length_from_va(base + s.get_virtual_address() + 123, base + s.get_virtual_address() - 1, section_data_raw, false), pe_exception::rva_not_exists, "Section test 20", test_level_normal); + + PE_TEST(image->section_data_length_from_va(base + s.get_virtual_address() + 123, section_data_virtual, false) == s.get_aligned_virtual_size(image->get_section_alignment()), "Section test 21", test_level_normal); + PE_TEST(image->section_data_length_from_va(s, base + s.get_virtual_address() + 123, section_data_virtual) == s.get_aligned_virtual_size(image->get_section_alignment()) - 123, "Section test 22", test_level_normal); + PE_TEST(image->section_data_length_from_va(base + s.get_virtual_address() + 123, base + s.get_virtual_address() + 123, section_data_virtual, false) == s.get_aligned_virtual_size(image->get_section_alignment()) - 123, "Section test 23", test_level_normal); + + PE_TEST_EXPECT_EXCEPTION(image->section_data_length_from_va(s, base + s.get_virtual_address() - 1, section_data_virtual), pe_exception::rva_not_exists, "Section test 24", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(image->section_data_length_from_va(base + s.get_virtual_address() + 123, base + s.get_virtual_address() - 1, section_data_virtual, false), pe_exception::rva_not_exists, "Section test 25", test_level_normal); + + PE_TEST(image->section_data_from_rva<uint32_t>(0x1005, section_data_raw, false) == 0x505BE900, "Section data test 1", test_level_normal); + PE_TEST(image->section_data_from_rva<uint32_t>(s, 0x1005, section_data_raw) == 0x505BE900, "Section data test 2", test_level_normal); + + PE_TEST(image->section_data_from_va<uint32_t>(base + 0x1005, section_data_raw, false) == 0x505BE900, "Section data test 3", test_level_normal); + PE_TEST(image->section_data_from_va<uint32_t>(s, base + 0x1005, section_data_raw) == 0x505BE900, "Section data test 4", test_level_normal); + + PE_TEST(image->section_data_from_rva<uint32_t>(0x1005, section_data_virtual, false) == 0x505BE900, "Section data test 5", test_level_normal); + PE_TEST(image->section_data_from_rva<uint32_t>(s, 0x1005, section_data_virtual) == 0x505BE900, "Section data test 6", test_level_normal); + + PE_TEST(image->section_data_from_va<uint32_t>(base + 0x1005, section_data_virtual, false) == 0x505BE900, "Section data test 7", test_level_normal); + PE_TEST(image->section_data_from_va<uint32_t>(s, base + 0x1005, section_data_virtual) == 0x505BE900, "Section data test 8", test_level_normal); + + PE_TEST(image->section_data_from_rva<uint32_t>(0x1, section_data_raw, true) == 0x0300905A, "Section data test 9", test_level_normal); + PE_TEST(image->section_data_from_va<uint32_t>(base + 0x1, section_data_raw, true) == 0x0300905A, "Section data test 10", test_level_normal); + + PE_TEST(*image->section_data_from_rva(0x1005, section_data_raw, false) == 0x00, "Section data test 11", test_level_normal); + PE_TEST(*image->section_data_from_rva(s, 0x1005, section_data_raw) == 0x00, "Section data test 12", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(image->section_data_from_rva(s, 0x999, section_data_raw), pe_exception::rva_not_exists, "Section data test 13", test_level_normal); + + PE_TEST(*image->section_data_from_va(base + 0x1005, section_data_raw, false) == 0x00, "Section data test 14", test_level_normal); + PE_TEST(*image->section_data_from_va(s, base + 0x1005, section_data_raw) == 0x00, "Section data test 15", test_level_normal); + + PE_TEST(*image->section_data_from_rva(0x1E000 + 0x388C, section_data_virtual, false) == 0x00, "Section data test 16", test_level_normal); + } + else + { + uint64_t base = image->get_image_base_64(); + PE_TEST(image->section_data_length_from_va(base + s.get_virtual_address() + 123, section_data_raw, false) == s.get_raw_data().size(), "Section test 16", test_level_normal); + PE_TEST(image->section_data_length_from_va(s, base + s.get_virtual_address() + 123, section_data_raw) == s.get_raw_data().size() - 123, "Section test 17", test_level_normal); + PE_TEST(image->section_data_length_from_va(base + s.get_virtual_address() + 123, base + s.get_virtual_address() + 123, section_data_raw, false) == s.get_raw_data().size() - 123, "Section test 18", test_level_normal); + + PE_TEST_EXPECT_EXCEPTION(image->section_data_length_from_va(s, base + s.get_virtual_address() - 1, section_data_raw), pe_exception::rva_not_exists, "Section test 19", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(image->section_data_length_from_va(base + s.get_virtual_address() + 123, base + s.get_virtual_address() - 1, section_data_raw, false), pe_exception::rva_not_exists, "Section test 20", test_level_normal); + + PE_TEST(image->section_data_length_from_va(base + s.get_virtual_address() + 123, section_data_virtual, false) == s.get_aligned_virtual_size(image->get_section_alignment()), "Section test 21", test_level_normal); + PE_TEST(image->section_data_length_from_va(s, base + s.get_virtual_address() + 123, section_data_virtual) == s.get_aligned_virtual_size(image->get_section_alignment()) - 123, "Section test 22", test_level_normal); + PE_TEST(image->section_data_length_from_va(base + s.get_virtual_address() + 123, base + s.get_virtual_address() + 123, section_data_virtual, false) == s.get_aligned_virtual_size(image->get_section_alignment()) - 123, "Section test 23", test_level_normal); + + PE_TEST_EXPECT_EXCEPTION(image->section_data_length_from_va(s, base + s.get_virtual_address() - 1, section_data_virtual), pe_exception::rva_not_exists, "Section test 24", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(image->section_data_length_from_va(base + s.get_virtual_address() + 123, base + s.get_virtual_address() - 1, section_data_virtual, false), pe_exception::rva_not_exists, "Section test 25", test_level_normal); + + PE_TEST(image->section_data_from_rva<uint32_t>(0x1005, section_data_raw, false) == 0x89480001, "Section data test 1", test_level_normal); + PE_TEST(image->section_data_from_rva<uint32_t>(s, 0x1005, section_data_raw) == 0x89480001, "Section data test 2", test_level_normal); + + PE_TEST(image->section_data_from_va<uint32_t>(base + 0x1005, section_data_raw, false) == 0x89480001, "Section data test 3", test_level_normal); + PE_TEST(image->section_data_from_va<uint32_t>(s, base + 0x1005, section_data_raw) == 0x89480001, "Section data test 4", test_level_normal); + + PE_TEST(image->section_data_from_rva<uint32_t>(0x1005, section_data_virtual, false) == 0x89480001, "Section data test 5", test_level_normal); + PE_TEST(image->section_data_from_rva<uint32_t>(s, 0x1005, section_data_virtual) == 0x89480001, "Section data test 6", test_level_normal); + + PE_TEST(image->section_data_from_va<uint32_t>(base + 0x1005, section_data_virtual, false) == 0x89480001, "Section data test 7", test_level_normal); + PE_TEST(image->section_data_from_va<uint32_t>(s, base + 0x1005, section_data_virtual) == 0x89480001, "Section data test 8", test_level_normal); + + PE_TEST(image->section_data_from_rva<uint32_t>(0x1, section_data_raw, true) == 0x0300905A, "Section data test 9", test_level_normal); + PE_TEST(image->section_data_from_va<uint32_t>(base + 0x1, section_data_raw, true) == 0x0300905A, "Section data test 10", test_level_normal); + + PE_TEST(*image->section_data_from_rva(0x1005, section_data_raw, false) == 0x01, "Section data test 11", test_level_normal); + PE_TEST(*image->section_data_from_rva(s, 0x1005, section_data_raw) == 0x01, "Section data test 12", test_level_normal); + PE_TEST_EXPECT_EXCEPTION(image->section_data_from_rva(s, 0x999, section_data_raw), pe_exception::rva_not_exists, "Section data test 13", test_level_normal); + + PE_TEST(*image->section_data_from_va(base + 0x1005, section_data_raw, false) == 0x01, "Section data test 14", test_level_normal); + PE_TEST(*image->section_data_from_va(s, base + 0x1005, section_data_raw) == 0x01, "Section data test 15", test_level_normal); + + PE_TEST(*image->section_data_from_rva(0x23000 + 0x46F0, section_data_virtual, false) == 0x00, "Section data test 16", test_level_normal); + } + } + + PE_TEST(image->section_and_offset_from_rva(0x1005).first == 5, "Section data test 17", test_level_normal); + PE_TEST(image->section_and_offset_from_rva(0x1005).second->get_name() == ".text", "Section data test 18", test_level_normal); + + PE_TEST(image->section_data_length_from_rva(1, section_data_raw, true) == image->get_size_of_headers(), "Section test 26", test_level_normal); + PE_TEST(image->section_data_length_from_rva(1, 1, section_data_raw, true) == image->get_size_of_headers() - 1, "Section test 27", test_level_normal); + + if(image->get_pe_type() == pe_type_32) + { + uint32_t base = image->get_image_base_32(); + PE_TEST(image->section_data_length_from_va(base + 1, section_data_raw, true) == image->get_size_of_headers(), "Section test 28", test_level_normal); + PE_TEST(image->section_data_length_from_va(base + 1, base + 1, section_data_raw, true) == image->get_size_of_headers() - 1, "Section test 29", test_level_normal); + } + else + { + uint64_t base = image->get_image_base_64(); + PE_TEST(image->section_data_length_from_va(base + 1, section_data_raw, true) == image->get_size_of_headers(), "Section test 28", test_level_normal); + PE_TEST(image->section_data_length_from_va(base + 1, base + 1, section_data_raw, true) == image->get_size_of_headers() - 1, "Section test 29", test_level_normal); + } + + PE_TEST(image->section_attached(image->get_image_sections().at(0)), "Section data test 30", test_level_normal); + PE_TEST(!image->section_attached(section()), "Section data test 31", test_level_normal); + + + { + const section& s = image->get_image_sections().at(0); + PE_TEST(s.get_characteristics() == 0x60000020, "Section class test 1", test_level_normal); + PE_TEST(s.get_name() == ".text", "Section class test 2", test_level_normal); + PE_TEST(s.get_pointer_to_raw_data() == 0x400, "Section class test 3", test_level_normal); + PE_TEST(s.get_virtual_address() == 0x1000, "Section class test 4", test_level_normal); + + if(image->get_pe_type() == pe_type_32) + { + PE_TEST(s.get_size_of_raw_data() == 0x16E00, "Section class test 5", test_level_normal); + PE_TEST(s.get_virtual_size() == 0x16C0D, "Section class test 6", test_level_normal); + } + else + { + PE_TEST(s.get_size_of_raw_data() == 0x19400, "Section class test 5", test_level_normal); + PE_TEST(s.get_virtual_size() == 0x1923E, "Section class test 6", test_level_normal); + } + + PE_TEST(s.readable(), "Section class test 7", test_level_normal); + PE_TEST(s.executable(), "Section class test 8", test_level_normal); + PE_TEST(!s.writeable(), "Section class test 9", test_level_normal); + PE_TEST(!s.shared(), "Section class test 10", test_level_normal); + PE_TEST(!s.discardable(), "Section class test 11", test_level_normal); + PE_TEST(!s.empty(), "Section class test 12", test_level_normal); + } + + { + section s; + PE_TEST_EXPECT_EXCEPTION(image->prepare_section(s), pe_exception::zero_section_sizes, "Prepare Section test 1", test_level_normal); + } + + { + section s; + s.set_raw_data("123"); + PE_TEST_EXCEPTION(image->prepare_section(s), "Prepare Section test 2", test_level_normal); + PE_TEST(s.get_virtual_size() == pe_utils::align_up(s.get_size_of_raw_data(), image->get_file_alignment()), "Prepare Section test 3", test_level_normal); + + uint16_t old_sections_count = image->get_number_of_sections(); + uint16_t old_size_of_image = image->get_size_of_image(); + PE_TEST_EXCEPTION(image->add_section(s), "Add section test 1", test_level_normal); + PE_TEST(image->get_number_of_sections() == old_sections_count + 1, "Add section test 2", test_level_normal); + PE_TEST(image->get_image_sections().back().get_raw_data() == "123", "Add section test 3", test_level_normal); + PE_TEST(image->get_size_of_image() > old_size_of_image, "Add section test 4", test_level_normal); + } + + { + section s; + s.set_raw_data(std::string("123\0\0\0", 6)); + PE_TEST_EXCEPTION(image->recalculate_section_sizes(s, true), "recalculate_section_sizes test 1", test_level_normal); + PE_TEST(s.get_raw_data() == "123", "recalculate_section_sizes test 2", test_level_normal); + } + + PE_TEST_EXPECT_EXCEPTION(image->set_section_virtual_size(image->get_image_sections().at(0), 0x100), pe_exception::error_changing_section_virtual_size, "set_section_virtual_size test 1", test_level_normal); + + { + section s; + PE_TEST_EXPECT_EXCEPTION(image->set_section_virtual_size(s, 0), pe_exception::error_changing_section_virtual_size, "set_section_virtual_size test 2", test_level_normal); + } + + PE_TEST_EXCEPTION(image->set_section_virtual_size(image->get_image_sections().back(), 0x1000), "set_section_virtual_size test 3", test_level_normal); + PE_TEST(image->get_image_sections().back().get_virtual_size() == 0x1000, "set_section_virtual_size test 4", test_level_normal); + + image->set_file_alignment(0x1000); + PE_TEST_EXCEPTION(image->realign_all_sections(), "Section realigning test", test_level_normal); + PE_TEST_EXCEPTION(image->realign_file(0x200), "File realigning test", test_level_normal); + + { + section& s = image->get_image_sections().back(); + PE_TEST_EXPECT_EXCEPTION(image->expand_section(s, s.get_virtual_address() + 0x5000, 0x1000, pe_base::expand_section_raw), pe_exception::rva_not_exists, "Section expand test 1", test_level_normal); + PE_TEST(image->expand_section(s, s.get_virtual_address() + 0x100, 0x1000, pe_base::expand_section_raw) == true, "Section expand test 2", test_level_normal); + PE_TEST(s.get_virtual_size() >= 0x100 + 0x1000, "Section expand test 3", test_level_normal); + PE_TEST(s.get_size_of_raw_data() >= 0x100 + 0x1000, "Section expand test 4", test_level_normal); + + uint32_t old_raw_size = s.get_size_of_raw_data(); + PE_TEST(image->expand_section(s, s.get_virtual_address() + 0x100, 0x5000, pe_base::expand_section_virtual) == true, "Section expand test 5", test_level_normal); + PE_TEST(s.get_virtual_size() >= 0x100 + 0x5000, "Section expand test 6", test_level_normal); + PE_TEST(old_raw_size == s.get_size_of_raw_data(), "Section expand test 7", test_level_normal); + PE_TEST(image->expand_section(s, s.get_virtual_address() + 0x100, 0x1000, pe_base::expand_section_raw) == false, "Section expand test 8", test_level_normal); + PE_TEST(image->expand_section(s, s.get_virtual_address() + 0x100, 0x5000, pe_base::expand_section_virtual) == false, "Section expand test 9", test_level_normal); + } + + { + image->get_image_sections().pop_back(); + + std::stringstream new_pe(std::ios::in | std::ios::out | std::ios::binary); + PE_TEST_EXCEPTION(rebuild_pe(*image, new_pe, false, true, true), "Rebuild PE test 1", test_level_critical); + + std::auto_ptr<pe_base> new_image; + PE_TEST_EXCEPTION(new_image.reset(new pe_base(pe_factory::create_pe(new_pe))), "Creation, type detection and copying test 2", test_level_critical); + + section_list& sections = image->get_image_sections(); + section_list& new_sections = new_image->get_image_sections(); + PE_TEST(sections.size() == new_sections.size(), "Rebuild PE test 2", test_level_normal); + + for(uint32_t i = 0; i != sections.size(); ++i) + { + std::string raw_data_old(sections[i].get_raw_data()); + std::string raw_data_new(new_sections[i].get_raw_data()); + pe_utils::strip_nullbytes(raw_data_old); + pe_utils::strip_nullbytes(raw_data_new); + + std::cout << "Rebuilt PE test iteration " << i << std::endl; + PE_TEST(raw_data_old == raw_data_new, "Rebuild PE test (section raw data compare)", test_level_normal); + PE_TEST(sections[i].get_virtual_address() == new_sections[i].get_virtual_address(), "Rebuild PE test (section virtual addresses compare)", test_level_normal); + PE_TEST(sections[i].get_aligned_virtual_size(image->get_section_alignment()) == new_sections[i].get_aligned_virtual_size(new_image->get_section_alignment()), "Rebuild PE test (section virtual sizes compare)", test_level_normal); + } + + + new_pe.str(""); + PE_TEST_EXCEPTION(rebuild_pe(*image, new_pe, true, true, true), "Rebuild PE test 3", test_level_critical); + PE_TEST_EXCEPTION(new_image.reset(new pe_base(pe_factory::create_pe(new_pe))), "Creation, type detection and copying test 3", test_level_critical); + + image->set_stub_overlay("123"); + new_pe.str(""); + PE_TEST_EXCEPTION(rebuild_pe(*image, new_pe, false, true, true), "Rebuild PE test 4", test_level_critical); + PE_TEST_EXCEPTION(new_image.reset(new pe_base(pe_factory::create_pe(new_pe))), "Creation, type detection and copying test 4", test_level_critical); + new_pe.str(""); + PE_TEST_EXCEPTION(rebuild_pe(*image, new_pe, true, true, true), "Rebuild PE test 5", test_level_critical); + PE_TEST_EXCEPTION(new_image.reset(new pe_base(pe_factory::create_pe(new_pe))), "Creation, type detection and copying test 5", test_level_critical); + } + + + { + pe_base new_pe(pe_properties_32(), 0x1000, false, pe_win::image_subsystem_windows_cui); + PE_TEST(new_pe.get_section_alignment() == 0x1000, "Empty PE Creation test 1", test_level_normal); + PE_TEST(new_pe.get_subsystem() == pe_win::image_subsystem_windows_cui, "Empty PE Creation test 2", test_level_normal); + PE_TEST(!new_pe.check_characteristics_flag(pe_win::image_file_dll), "Empty PE Creation test 3", test_level_normal); + + std::stringstream new_pe_data(std::ios::in | std::ios::out | std::ios::binary); + PE_TEST_EXCEPTION(rebuild_pe(new_pe, new_pe_data, false, true), "Rebuild PE test 3", test_level_critical); + + std::auto_ptr<pe_base> new_pe_after_rebuild; + PE_TEST_EXCEPTION(new_pe_after_rebuild.reset(new pe_base(pe_factory::create_pe(new_pe_data))), "Creation, type detection and copying test 4", test_level_critical); + PE_TEST(new_pe_after_rebuild->get_section_alignment() == 0x1000, "Empty PE Read test 1", test_level_normal); + PE_TEST(new_pe_after_rebuild->get_number_of_sections() == 0, "Empty PE Read test 2", test_level_normal); + } + + PE_TEST_END + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/tests/tests_basic/tests_basic.vcproj b/irdb-lib/pebliss/trunk/tests/tests_basic/tests_basic.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..c69523410d829a54366ea88626ccdddbf86d874a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/tests_basic/tests_basic.vcproj @@ -0,0 +1,359 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="tests_basic" + ProjectGUID="{3451AE03-3363-445B-8DA8-94B197563D59}" + RootNamespace="tests_basic" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + <File + RelativePath="..\test.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/tests/tests_basic/tests_basic.vcxproj b/irdb-lib/pebliss/trunk/tests/tests_basic/tests_basic.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..70e1846a9dcb28fce91f78e950b2b7bc77f037aa --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/tests_basic/tests_basic.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{7870A9AC-92BB-423B-BC03-FBF7B46CD338}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>tests_basic</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + <ClInclude Include="..\test.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/tests_basic/tests_basic.vcxproj.filters b/irdb-lib/pebliss/trunk/tests/tests_basic/tests_basic.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..8f0719260417c2cc422a533c4a0c453eb3d84c1a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/tests_basic/tests_basic.vcxproj.filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\test.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/tests_utils/Makefile b/irdb-lib/pebliss/trunk/tests/tests_utils/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..422827f1e3ba0c0d1373f3dcd0b7219c702e806e --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/tests_utils/Makefile @@ -0,0 +1 @@ +include ../tests.mak diff --git a/irdb-lib/pebliss/trunk/tests/tests_utils/main.cpp b/irdb-lib/pebliss/trunk/tests/tests_utils/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1db6212f78720cec140f3e13ebac9306d6084bff --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/tests_utils/main.cpp @@ -0,0 +1,52 @@ +#include <iostream> +#include <fstream> +#include <pe_bliss.h> +#define PE_FILES_UNUSED +#include "test.h" +#ifdef PE_BLISS_WINDOWS +#include "lib.h" +#endif + +using namespace pe_bliss; + +int main(int argc, char* argv[]) +{ + PE_TEST_START + + const char data[] = "abcdefgh"; + PE_TEST(pe_utils::is_null_terminated(data, sizeof(data)), "is_null_terminated test 1", test_level_normal); + PE_TEST(!pe_utils::is_null_terminated(data, sizeof(data) - 1), "is_null_terminated test 2", test_level_normal); + + std::string str("test\0\0\0"); + PE_TEST_EXCEPTION(pe_utils::strip_nullbytes(str), "strip_nullbytes test 1", test_level_normal); + PE_TEST(str == "test", "strip_nullbytes test 2", test_level_normal); + + PE_TEST(pe_utils::is_power_of_2(8), "is_power_of_2 test 1", test_level_normal); + PE_TEST(!pe_utils::is_power_of_2(7), "is_power_of_2 test 2", test_level_normal); + + PE_TEST(pe_utils::align_down(99, 4) == 96, "align_down test 1", test_level_normal); + PE_TEST(pe_utils::align_down(100, 4) == 100, "align_down test 2", test_level_normal); + + PE_TEST(pe_utils::align_up(99, 4) == 100, "align_up test 1", test_level_normal); + PE_TEST(pe_utils::align_up(100, 4) == 100, "align_up test 2", test_level_normal); + + PE_TEST(pe_utils::is_sum_safe(100, 100), "is_sum_safe test 1", test_level_normal); + PE_TEST(!pe_utils::is_sum_safe(pe_utils::max_dword - 1, 2), "is_sum_safe test 2", test_level_normal); + + std::ifstream file(argv[0]); + file.seekg(0, std::ios::end); + std::streamoff size = file.tellg(); + file.seekg(123); + + PE_TEST(pe_utils::get_file_size(file) == size, "get_file_size test 1", test_level_normal); + PE_TEST(static_cast<std::streamoff>(file.tellg()) == static_cast<std::streamoff>(123), "get_file_size test 2", test_level_normal); //Restore position test + +#ifndef PE_BLISS_WINDOWS + PE_TEST(pe_utils::from_ucs2(pe_utils::to_ucs2(L"alala")) == L"alala", "to_ucs2 & from_ucs2 test 1", test_level_normal); + PE_TEST(pe_utils::from_ucs2(pe_utils::to_ucs2(L"")) == L"", "to_ucs2 & from_ucs2 test 2", test_level_normal); +#endif + + PE_TEST_END + + return 0; +} diff --git a/irdb-lib/pebliss/trunk/tests/tests_utils/tests_utils.vcproj b/irdb-lib/pebliss/trunk/tests/tests_utils/tests_utils.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..43861cf957ab800fc315a8a157e420b8a07a7bcb --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/tests_utils/tests_utils.vcproj @@ -0,0 +1,359 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="tests_utils" + ProjectGUID="{B0478C25-73AD-4085-BA1A-DDF66431EB6E}" + RootNamespace="tests_utils" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../pe_lib/;../" + PreprocessorDefinitions="_WIN64;NDEBUG;_CONSOLE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\lib.h" + > + </File> + <File + RelativePath="..\test.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/irdb-lib/pebliss/trunk/tests/tests_utils/tests_utils.vcxproj b/irdb-lib/pebliss/trunk/tests/tests_utils/tests_utils.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..2f02942415aaf04fcecae2105d5fb1f2eafc2127 --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/tests_utils/tests_utils.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{50212477-1614-49C9-9791-4AC72025DC76}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>tests_utils</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../pe_lib/;../</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>copy /Y "$(TargetPath)" "$(ProjectDir)..\..\tests\bin\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h" /> + <ClInclude Include="..\test.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/pebliss/trunk/tests/tests_utils/tests_utils.vcxproj.filters b/irdb-lib/pebliss/trunk/tests/tests_utils/tests_utils.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..8f0719260417c2cc422a533c4a0c453eb3d84c1a --- /dev/null +++ b/irdb-lib/pebliss/trunk/tests/tests_utils/tests_utils.vcxproj.filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\lib.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\test.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/irdb-lib/plugins_install/add_confinement_section.sh b/irdb-lib/plugins_install/add_confinement_section.sh new file mode 100755 index 0000000000000000000000000000000000000000..de8ce41834d0859683637a71ac9461c81c57fc83 --- /dev/null +++ b/irdb-lib/plugins_install/add_confinement_section.sh @@ -0,0 +1,4 @@ + +cp a.ncexe a.ncexe.orig +$STRATA_HOME/tools/pc_confinement/add_confinement_section.sh a.ncexe.orig a.ncexe + diff --git a/irdb-lib/plugins_install/assurance_case_evidence.sh b/irdb-lib/plugins_install/assurance_case_evidence.sh new file mode 100755 index 0000000000000000000000000000000000000000..c10f2f7b87cab4eedca72c341bead4a098f1cca1 --- /dev/null +++ b/irdb-lib/plugins_install/assurance_case_evidence.sh @@ -0,0 +1,13 @@ +#!/bin/bash -x + +# check for the logs directory +if [ -d logs ]; then + # Gather the relevant lines and print to stdout + grep -h ATTRIBUTE logs/* | grep :: | sed "s/# ATTRIBUTE//g" + +else + echo "ERROR: assurance_case_evidence: no logs directory." + exit 1 +fi + +exit 0 diff --git a/irdb-lib/plugins_install/cgc_optimize_start.sh b/irdb-lib/plugins_install/cgc_optimize_start.sh new file mode 100755 index 0000000000000000000000000000000000000000..a494580fba3ec1feea6dd690ad0301f71b1eb65b --- /dev/null +++ b/irdb-lib/plugins_install/cgc_optimize_start.sh @@ -0,0 +1,2 @@ + +$DAFFY_HOME/dead_code_ident/optimize_start.sh a.ncexe diff --git a/irdb-lib/plugins_install/concolic.sh b/irdb-lib/plugins_install/concolic.sh new file mode 100755 index 0000000000000000000000000000000000000000..d84f8317ebd85e8e35c2ba04af57b6556935b4e5 --- /dev/null +++ b/irdb-lib/plugins_install/concolic.sh @@ -0,0 +1,4 @@ + + +$PEASOUP_HOME/tools/do_concolic.sh a -z $PEASOUP_UMBRELLA_DIR/grace.conf + diff --git a/irdb-lib/plugins_install/controlled_exit.sh b/irdb-lib/plugins_install/controlled_exit.sh new file mode 100755 index 0000000000000000000000000000000000000000..54f7cd7c035190b2a4e827e5742d8a4ec7a9e4c9 --- /dev/null +++ b/irdb-lib/plugins_install/controlled_exit.sh @@ -0,0 +1,2 @@ + +$PEASOUP_HOME/tools/update_env_var.sh STRATA_CONTROLLED_EXIT 1 diff --git a/irdb-lib/plugins_install/create_binary_script.sh b/irdb-lib/plugins_install/create_binary_script.sh new file mode 100755 index 0000000000000000000000000000000000000000..3b7f2b2b8059c21cb5b02080b933c3580c5a899c --- /dev/null +++ b/irdb-lib/plugins_install/create_binary_script.sh @@ -0,0 +1,3 @@ + +$PEASOUP_HOME/tools/do_makepeasoupbinary2.sh a + diff --git a/irdb-lib/plugins_install/detect_server.sh b/irdb-lib/plugins_install/detect_server.sh new file mode 100755 index 0000000000000000000000000000000000000000..fca1498126f042b90ee83abb83f6927ca58165b6 --- /dev/null +++ b/irdb-lib/plugins_install/detect_server.sh @@ -0,0 +1,2 @@ + +$PEASOUP_HOME/tools/update_env_var.sh STRATA_DETECT_SERVERS 1 diff --git a/irdb-lib/plugins_install/diehard.sh b/irdb-lib/plugins_install/diehard.sh new file mode 100755 index 0000000000000000000000000000000000000000..e052b12c28aa9bf2d8f09e08ce46a106eaecf432 --- /dev/null +++ b/irdb-lib/plugins_install/diehard.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +if [ ! -f $CFAR_HOME/DieHard/src/libdiehard-4k-x64.so ]; then + echo "ERROR: DieHard library not built/found" | tee warning.txt + exit 1 +fi + +$PEASOUP_HOME/tools/update_env_var.sh DO_DIEHARD 1 + +seq="" +while [[ $# -gt 0 ]] +do +key="$1" +case $key in + --structured_heap) + seq="$2" + shift + shift + ;; + *) + shift + ;; +esac +done + +file a.ncexe |grep -q "64-bit" + +if (file a.ncexe |grep -q "64-bit") ; then + echo "Detected 64-bit binary" + ext=x64 +else + echo "Detected 32-bit binary" + ext=x32 +fi + +if [ -z "$seq" ]; then + cp $CFAR_HOME/DieHard/src/libdiehard-32k-$ext.so libheaprand.so +else + if [ ! -f $CFAR_HOME/DieHard/src/libdiehard-4k-$ext.so ]; then + echo "ERROR: DieHard library 4k not built/found" | tee warning.txt + exit 1 + fi + + if [ ! -f $CFAR_HOME/DieHard/src/libdiehard-32k-$ext.so ]; then + echo "ERROR: DieHard library 32k not built/found" | tee warning.txt + exit 1 + fi + + if [ $(expr ${seq} % 2) = 0 ]; then + cp $CFAR_HOME/DieHard/src/libdiehard-32k-$ext.so libheaprand.so + else + cp $CFAR_HOME/DieHard/src/libdiehard-4k-$ext.so libheaprand.so + fi +fi diff --git a/irdb-lib/plugins_install/double_free.sh b/irdb-lib/plugins_install/double_free.sh new file mode 100755 index 0000000000000000000000000000000000000000..fbe81b00919bce5b25d6b74eee5e279acfea1e05 --- /dev/null +++ b/irdb-lib/plugins_install/double_free.sh @@ -0,0 +1,2 @@ + +$PEASOUP_HOME/tools/update_env_var.sh STRATA_DOUBLE_FREE 1 diff --git a/irdb-lib/plugins_install/generate_variant_config.sh b/irdb-lib/plugins_install/generate_variant_config.sh new file mode 100755 index 0000000000000000000000000000000000000000..5b67f9714922fb8b042894dab3c290ce492f1794 --- /dev/null +++ b/irdb-lib/plugins_install/generate_variant_config.sh @@ -0,0 +1,57 @@ +#!/bin/bash -x + +backend="zipr" + +# check if strata was on from it's log. +if [ -f logs/stratafy_with_pc_confine.log ]; then + backend="strata" +fi + +if [ $backend = "zipr" ]; then + echo Found zipr backend. + + template=$PEASOUP_HOME/tools/cfar_configs/zipr_variant.json.template; + + + +elif [ $backend = "strata" ]; then + + echo "Found strata backend." + template=$PEASOUP_HOME/tools/cfar_configs/strata_variant.json.template + +else + echo Unknown backend. + exit 1 +fi + + +# calc stuffs needed. +base_peasoup_dir=$(basename $newdir) +exe=$(basename $protected_exe) + +# get and fill in template. +cp $template variant_config.json +sed -i "s/<<EXE_NAME>>/$exe/g" variant_config.json +sed -i "s|<<PS_DIR>>|$base_peasoup_dir|g" variant_config.json + +# +# note that these are all hard-coded in the config files right now. +# plan: mine these values out of ps_run.sh and replace in config file. +# +#"STRATA_LOG=detectors", +#"PEASOUP_SCHEDULE_PERTURB=0", +#"STRATA_WATCHDOG=0", +#"STRATA_NUM_HANDLE=0", +#"STRATA_DOUBLE_FREE=0", +#"STRATA_HEAPRAND=0", +#"STRATA_SHADOW_STACK=0", +#"STRATA_CONTROLLED_EXIT=0", +#"STRATA_DETECT_SERVERS=0", +#"STRATA_PC_CONFINE=0", +#"STRATA_PC_CONFINE_XOR=0", +#"STRATA_REKEY_AFTER=0", +#"STRATA_PC_CONFINE_XOR_KEY_LENGTH=1024", +#"STRATA_IS_SO=0", +#"STRATA_MAX_WARNINGS=500000" + +exit 0 diff --git a/irdb-lib/plugins_install/heaprand.sh b/irdb-lib/plugins_install/heaprand.sh new file mode 100755 index 0000000000000000000000000000000000000000..31194836964047aa1fc24fe7eaa6aef6b83c0e24 --- /dev/null +++ b/irdb-lib/plugins_install/heaprand.sh @@ -0,0 +1,2 @@ + +$PEASOUP_HOME/tools/update_env_var.sh STRATA_HEAPRAND 1 diff --git a/irdb-lib/plugins_install/ibtl.sh b/irdb-lib/plugins_install/ibtl.sh new file mode 100755 index 0000000000000000000000000000000000000000..4384aa5cba9ed4f5c1a7dec3579fe1d8a59fd8ae --- /dev/null +++ b/irdb-lib/plugins_install/ibtl.sh @@ -0,0 +1,3 @@ + + +$PEASOUP_HOME/tools/update_env_var.sh STRATA_IBTL 1 diff --git a/irdb-lib/plugins_install/is_so.sh b/irdb-lib/plugins_install/is_so.sh new file mode 100755 index 0000000000000000000000000000000000000000..7bd11b2eedef7b9c693d96c31ba7a672a4c40770 --- /dev/null +++ b/irdb-lib/plugins_install/is_so.sh @@ -0,0 +1,4 @@ + + +$PEASOUP_HOME/tools/update_env_var.sh STRATA_IS_SO $($PEASOUP_HOME/tools/is_so.sh a.ncexe) + diff --git a/irdb-lib/plugins_install/isr.sh b/irdb-lib/plugins_install/isr.sh new file mode 100755 index 0000000000000000000000000000000000000000..de35fc27643b8dda22e514929b224e5f566f2a5a --- /dev/null +++ b/irdb-lib/plugins_install/isr.sh @@ -0,0 +1,2 @@ + +$PEASOUP_HOME/tools/update_env_var.sh STRATA_PC_CONFINE_XOR 1 diff --git a/irdb-lib/plugins_install/libtwitcher.sh b/irdb-lib/plugins_install/libtwitcher.sh new file mode 100755 index 0000000000000000000000000000000000000000..cd1743d340905234164ac3ed98d559218a7e4ee0 --- /dev/null +++ b/irdb-lib/plugins_install/libtwitcher.sh @@ -0,0 +1,3 @@ + +cp $GT_COLLAB_HOME/downloads/libtwitcher.so libheaprand.so + diff --git a/irdb-lib/plugins_install/noh.sh b/irdb-lib/plugins_install/noh.sh new file mode 100755 index 0000000000000000000000000000000000000000..c4b8a2ccf2dbd8338469ec32bab0e7f184983a9e --- /dev/null +++ b/irdb-lib/plugins_install/noh.sh @@ -0,0 +1 @@ +cp $CFAR_HOME/non_overlapping_heap/noh.so noh.so diff --git a/irdb-lib/plugins_install/nol.sh b/irdb-lib/plugins_install/nol.sh new file mode 100755 index 0000000000000000000000000000000000000000..797a408cfb45130af91f2f6673f989aba1ddaf9b --- /dev/null +++ b/irdb-lib/plugins_install/nol.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +cp $CFAR_HOME/non_overlapping_libraries/ld-nol.so.ubuntu . || exit 1 +cp $CFAR_HOME/non_overlapping_libraries/ld-nol.so.centos . || exit 1 diff --git a/irdb-lib/plugins_install/output_spec.sh b/irdb-lib/plugins_install/output_spec.sh new file mode 100755 index 0000000000000000000000000000000000000000..d0696a161cc494e3d3e38bfee365dea9791495d1 --- /dev/null +++ b/irdb-lib/plugins_install/output_spec.sh @@ -0,0 +1,35 @@ +#!/bin/bash -x + + +varid="$1" +fileopt="$2" +file="$3" + +usage() +{ + echo " + +Usage: + + output_spec.sh <varid> --file 'file1.attr file2.attr ...' + +" +} + +main() +{ + + if [ "X$fileopt" != "X--file" ]; then + usage + exit 1 + fi + + echo "# ATTRIBUTE backend=$backend" $i > $file + echo "# ATTRIBUTE peasoup_dir=$newdir" $i >> $file + echo "# ATTRIBUTE output_file=$stratafied_exe" $i >> $file + echo "# ATTRIBUTE pwd=$PWD" $i >> $file + + +} + +main "$@" diff --git a/irdb-lib/plugins_install/pc_confine.sh b/irdb-lib/plugins_install/pc_confine.sh new file mode 100755 index 0000000000000000000000000000000000000000..36355db8c0cfc525d7c5b8f95071eabdee05a545 --- /dev/null +++ b/irdb-lib/plugins_install/pc_confine.sh @@ -0,0 +1,2 @@ + +$PEASOUP_HOME/tools/update_env_var.sh STRATA_PC_CONFINE 1 diff --git a/irdb-lib/plugins_install/rekey.sh b/irdb-lib/plugins_install/rekey.sh new file mode 100755 index 0000000000000000000000000000000000000000..bc9e3a83cbb4431b12a32b2f54e38f55c70744ab --- /dev/null +++ b/irdb-lib/plugins_install/rekey.sh @@ -0,0 +1,4 @@ + + +$PEASOUP_HOME/tools/update_env_var.sh STRATA_REKEY_AFTER 5000 + diff --git a/irdb-lib/plugins_install/signconv_func_monitor.sh b/irdb-lib/plugins_install/signconv_func_monitor.sh new file mode 100755 index 0000000000000000000000000000000000000000..9eeaf06b20eba30cbd7612fa28a59199fa0fa293 --- /dev/null +++ b/irdb-lib/plugins_install/signconv_func_monitor.sh @@ -0,0 +1,3 @@ + + +$PEASOUP_HOME/tools/update_env_var.sh STRATA_NUM_HANDLE 1 diff --git a/irdb-lib/plugins_install/stratafy_with_pc_confine.sh b/irdb-lib/plugins_install/stratafy_with_pc_confine.sh new file mode 100755 index 0000000000000000000000000000000000000000..90f2059ccc76debac9b001a5d4af080a04b6a4b2 --- /dev/null +++ b/irdb-lib/plugins_install/stratafy_with_pc_confine.sh @@ -0,0 +1,2 @@ + +sh $STRATA_HOME/tools/pc_confinement/stratafy_with_pc_confine.sh a.ncexe a.stratafied diff --git a/irdb-lib/plugins_install/test.exe b/irdb-lib/plugins_install/test.exe new file mode 100755 index 0000000000000000000000000000000000000000..7daf5cd461c7392b817d6aba7a9cffd577c85412 --- /dev/null +++ b/irdb-lib/plugins_install/test.exe @@ -0,0 +1,3 @@ +#/bin/sh + +echo this is a test of a shell script in plugins_install with args = "$@" diff --git a/irdb-lib/plugins_install/test.sh b/irdb-lib/plugins_install/test.sh new file mode 100755 index 0000000000000000000000000000000000000000..7daf5cd461c7392b817d6aba7a9cffd577c85412 --- /dev/null +++ b/irdb-lib/plugins_install/test.sh @@ -0,0 +1,3 @@ +#/bin/sh + +echo this is a test of a shell script in plugins_install with args = "$@" diff --git a/irdb-lib/plugins_install/watchdog.sh b/irdb-lib/plugins_install/watchdog.sh new file mode 100755 index 0000000000000000000000000000000000000000..ae3002757a9c0712aee3ba5717118c9aaaac455d --- /dev/null +++ b/irdb-lib/plugins_install/watchdog.sh @@ -0,0 +1,3 @@ + +watchdog_val=30 +$PEASOUP_HOME/tools/update_env_var.sh STRATA_WATCHDOG $watchdog_val diff --git a/irdb-lib/plugins_install/zipr.sh b/irdb-lib/plugins_install/zipr.sh new file mode 100755 index 0000000000000000000000000000000000000000..e37c8e25d4b4dc694940221a3cd62ec0f1aa845f --- /dev/null +++ b/irdb-lib/plugins_install/zipr.sh @@ -0,0 +1,7 @@ +#/bin/bash + +cloneid=$1 +shift +other_opts="$@" + +(set -x ; LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ZIPR_INSTALL/lib $ZIPR_INSTALL/bin/zipr.exe --variant $cloneid --zipr:objcopy $PS_OBJCOPY $other_opts) diff --git a/irdb-lib/rida/SConscript b/irdb-lib/rida/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..68e393c43bea056f94b6b613ee43700032cb6b6b --- /dev/null +++ b/irdb-lib/rida/SConscript @@ -0,0 +1,32 @@ +import os + + + +Import('env') +myenv=env.Clone() +myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) + +cpppath=''' + $SECURITY_TRANSFORMS_HOME/include + $SECURITY_TRANSFORMS_HOME/libehp/include + $SECURITY_TRANSFORMS_HOME/libEXEIO/include + $SECURITY_TRANSFORMS_HOME/libcapstone/include + ''' + + +files=Glob( Dir('.').srcnode().abspath+"/*.cpp") + + +pgm="rida.exe" + +LIBPATH=Split(''' + $SECURITY_TRANSFORMS_HOME/lib + $SECURITY_TRANSFORMS_HOME/libcapstone + ''') +LIBS=Split("ehp EXEIO pebliss capstone") +myenv=myenv.Clone(CPPPATH=Split(cpppath)) +pgm=myenv.Program(pgm, files, LIBPATH=LIBPATH, LIBS=LIBS) +install=myenv.Install("$SECURITY_TRANSFORMS_HOME/plugins_install/", pgm) +Default(install) + +Return('install') diff --git a/irdb-lib/rida/SConstruct b/irdb-lib/rida/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..9c9d2a5d563079f60954e46d422025a7c18edb82 --- /dev/null +++ b/irdb-lib/rida/SConstruct @@ -0,0 +1,12 @@ + + + +env=Environment() + +env.Append(CFLAGS=" -g -Wall -Werror -std=c++11 -fmax-errors=2") +env.Append(CXXFLAGS=" -g -Wall -Werror -std=c++11 -fmax-errors=2") +env.Append(LINKFLAGS=" -g -Wall -Werror -std=c++11 -fmax-errors=2") + +Export('env') +install=SConscript("SConscript") +Return('install') diff --git a/irdb-lib/rida/rida.cpp b/irdb-lib/rida/rida.cpp new file mode 100644 index 0000000000000000000000000000000000000000..91833dfb11270b5bd8f1a98f657d3fb5223054bf --- /dev/null +++ b/irdb-lib/rida/rida.cpp @@ -0,0 +1,606 @@ +#include <iostream> +#include <sstream> +#include <assert.h> +#include <set> +#include <algorithm> +#include <getopt.h> +#include <ehp.hpp> +#include <exeio.h> +#include <string> +#include "capstone/capstone.h" +#include <fstream> +#include <elf.h> +#include <functional> + + +using namespace std; +using namespace EHP; +using namespace EXEIO; + +#define ALLOF(a) begin(a),end(a) + +void usage(int argc, char* argv[]) +{ + cout<<"Usage: "<<argv[0]<<" input.exe output.annot>"<<endl; + exit(1); +} + + + +class CreateFunctions_t +{ + private: + shared_ptr<const EHFrameParser_t> ehp; + using Address_t = uint64_t; + class Range_t : public pair<Address_t,Address_t> + { + public: + Range_t(const Address_t &a, const Address_t &b) : pair<Address_t,Address_t>(a,b) { } + bool contains(const Address_t &c) const { return first <= c && c<second; } + + }; + using RangeSet_t = set<Range_t>; + set < RangeSet_t > sccs; + map<RangeSet_t,string> funcNames; + bool verbose; + exeio_t exeio; + csh cshandle; + ofstream outfile; + execlass_t file_class; + MachineType_t machine_type; + friend ostream& operator<<(ostream& os, const CreateFunctions_t::RangeSet_t& rs); + public: + CreateFunctions_t(const string &input_pgm, const string &output_annot, const bool p_verbose) + : + verbose(p_verbose), + exeio(input_pgm), + cshandle(), + file_class(exeio.get_class()), + machine_type(exeio.getMachineType()) + { + outfile.open(output_annot.c_str(), ofstream::out); + if(!outfile.is_open()) + { + cerr<<"Cannot open "<<output_annot<<endl; + exit(1); + } + ehp = EHFrameParser_t::factory(input_pgm); + if(verbose) + ehp->print(); + + if(file_class!=ELF64 && file_class != ELF32) + { + cerr<<"Rida can only process ELF files."<<endl; + exit(1); + } + + const auto cs_mode= + machine_type==mtAarch64 ? CS_MODE_LITTLE_ENDIAN : + file_class==ELF64 ? CS_MODE_64 : + file_class==ELF32 ? CS_MODE_32 : + throw std::runtime_error("Cannot handle ELF class"); + + const auto my_cs_arch = + machine_type == mtX86_64 ? CS_ARCH_X86 : + machine_type == mtI386 ? CS_ARCH_X86 : + machine_type == mtAarch64 ? CS_ARCH_ARM64 : + throw std::runtime_error("Cannot handle architecture"); + + if (cs_open(my_cs_arch, cs_mode , &cshandle) != CS_ERR_OK) + { + cerr<<"Cannot initialize capstone"<<endl; + exit(1); + } + } + virtual ~CreateFunctions_t() + { + cs_close(&cshandle); + } + + + void calculate() + { + + + ehframeToSccs(); + addSectionToSccs(".init"); + addSectionToSccs(".fini"); + + if(file_class==ELF64) + { + class Extracter64 + { + public: + Elf64_Xword elf_r_sym (Elf64_Xword a) { return ELF64_R_SYM (a); } + Elf64_Xword elf_r_type(Elf64_Xword a) { return ELF64_R_TYPE(a); } + unsigned char elf_st_bind(unsigned char a) { return ELF64_ST_BIND(a); } + unsigned char elf_st_type(unsigned char a) { return ELF64_ST_TYPE(a); } + }; + pltSplit<Elf64_Sym, Elf64_Rela, Elf64_Rel, Extracter64>(".plt", ".plt.got"); + nameFunctions<Elf64_Sym, Extracter64>(); + } + else + { + class Extracter32 + { + public: + Elf32_Word elf_r_sym (Elf32_Word a) { return ELF32_R_SYM (a); } + Elf32_Word elf_r_type(Elf32_Word a) { return ELF32_R_TYPE(a); } + unsigned char elf_st_bind(unsigned char a) { return ELF32_ST_BIND(a); } + unsigned char elf_st_type(unsigned char a) { return ELF32_ST_TYPE(a); } + }; + pltSplit<Elf32_Sym, Elf32_Rela, Elf32_Rel, Extracter32>(".plt", ".plt.got"); + nameFunctions<Elf32_Sym, Extracter32>(); + } + + } + + template<class T_Sym, class T_Extracter> + void nameFunctions() + { + // do symbol names. + parseSyms<T_Sym, T_Extracter>(".dynsym", ".dynstr"); + parseSyms<T_Sym, T_Extracter>(".symtab", ".strtab"); + + auto namedFunctions=0U; + auto unnamedFunctions=0U; + auto functions=0U; + + // set default names + for(const auto &func: sccs) + { + assert(func.begin() != func.end()); + const auto first_range=*(func.begin()); + const auto startAddr=first_range.first; + std::stringstream ss; + ss << "sub_" << hex << startAddr; + const auto name = ss.str(); + + functions++; + if(funcNames[func]=="") // destructive test OK, next line sets if empty. + { + unnamedFunctions++; + funcNames[func]=name; + } + else + { + namedFunctions++; + } + + } + + cout<<"#ATTRIBUTE functions="<<dec<<functions<<endl; + cout<<"#ATTRIBUTE named_functions="<<dec<<namedFunctions<<endl; + cout<<"#ATTRIBUTE uunamed_functions="<<dec<<unnamedFunctions<<endl; + + } + + template<class T_Sym, class T_Extracter> + void parseSyms(const string& secName, const string & stringSecName) + { + const auto sec=exeio.sections[secName]; + if(!sec) return; // err check + + const auto stringSec=exeio.sections[stringSecName]; + if(!stringSec) return; // err check + + const auto data=sec->get_data(); + const auto stringData=stringSec->get_data(); + + for(auto i=0U; i+sizeof(T_Sym) <= (size_t)sec->get_size(); i+=sizeof(T_Sym)) + { + const auto sym=reinterpret_cast<const T_Sym *>(data+i); + const auto value=sym->st_value; + if(value==0) + continue; + + // works for both ELF64 and ELF32, macros defined the same. + const auto type=T_Extracter().elf_st_type(sym->st_info); + if(type!=STT_FUNC) + continue; + + + // functions with non-zero address at this point. + const auto name_offset=sym->st_name; + + // sanity check string length + if(name_offset < 0U || name_offset > (size_t)stringSec->get_size()) + continue; + + // get the name + const auto name=string(stringData+name_offset); + + + // find a function + auto func_it=find_if(ALLOF(sccs), [&](const RangeSet_t& s) + { + return s.begin() -> first == value; + }); + if(func_it!=sccs.end()) + { + cout<<"Setting function at "<<hex<<value<<" to name "<<name<<endl; + funcNames[*func_it]=name; + } + + } + } + + void ehframeToSccs() + { + const auto fdes=ehp->getFDEs(); + for(const auto fde : *fdes) + //sccs.insert({ RangeSet_t({fde->getStartAddress(), fde->getEndAddress()})}); + sccs.insert(RangeSet_t({Range_t(fde->getStartAddress(),fde->getEndAddress())})); + + cout<<hex; + if(getenv("SELF_VALIDATE")) + assert(fdes->size()>0); + + for(const auto fde : *fdes) + { + if(verbose) + cout<<"Found FDE at : " << fde->getStartAddress() << "-"<<fde->getEndAddress()<<endl; + auto pair=Range_t(fde->getStartAddress(), fde->getEndAddress()); + const auto lsda=fde->getLSDA(); + assert(lsda); + const auto callsites=lsda->getCallSites(); + assert(callsites); + + for(const auto cs : *callsites) + { + if(verbose) + cout<<"\tCall site (0x"<<cs->getCallSiteAddress()<<"-"<<cs->getCallSiteEndAddress() + <<") with landing pad=0x"<<cs->getLandingPadAddress()<<endl; + if(cs->getLandingPadAddress()==0x0) + continue; + auto set1_it=find_if(ALLOF(sccs), [&](const RangeSet_t& s) { return s.find(pair) != s.end(); } ); + assert(set1_it!=sccs.end()); + + auto set2_it=find_if(ALLOF(sccs), [&](const RangeSet_t& s) + { + return find_if(ALLOF(s), [&](const Range_t& r) { return r.contains(cs->getLandingPadAddress()); }) != s.end(); + }); + assert(set2_it!=sccs.end()); + auto set1=*set1_it; + auto set2=*set2_it; + if(set1!=set2) + { + sccs.erase(set1); + sccs.erase(set2); + auto set3=RangeSet_t(); + if(verbose) + cout<<"\tMerging: set1="<< hex<< set1 << " and set2="<<set2<<dec<<endl; + set_union(ALLOF(set1), ALLOF(set2), inserter(set3, set3.begin())); + sccs.insert(set3); + } + } + } + + + } + + void addSectionToSccs(const string &sec_name) + { + const auto sec=exeio.sections[sec_name]; + if(sec==nullptr) + return; + const auto range=Range_t(sec->get_address(), sec->get_address()+sec->get_size()); + const auto ranges=RangeSet_t({range}); + sccs.insert(ranges); + } + + template<class T_Sym, class T_Rela, class T_Rel, class T_Extracter> + void pltSplit(const string &pltSecName, const string &endSecName) + { + const auto dynsymSec=exeio.sections[".dynsym"]; + const auto dynstrSec=exeio.sections[".dynstr"]; + const auto relapltSec=exeio.sections[".rela.plt"]; + const auto relpltSec=exeio.sections[".rel.plt"]; + const auto relSec=relapltSec ? relapltSec : relpltSec; + const auto relSecEntrySize=relapltSec ? sizeof(T_Rela) : sizeof(T_Rel); + + + const auto addRange=[&](const Address_t s, size_t len) + { + if(verbose) + cout<<"Adding PLT function "<<s<<" "<<len<<endl; + sccs.insert(RangeSet_t({Range_t({s,s+len})})); + }; + + const auto addName=[&](const Address_t addr, uint64_t symIndex) + { + if(!dynsymSec) return; + if(!dynstrSec) return; + if(!relSec) return; + + // get the data out of the plt section. + const auto relData=relSec->get_data(); + if(symIndex*relSecEntrySize >= (size_t)relSec->get_size()) return; + const auto relDataAsSymPtr=reinterpret_cast<const T_Rel *>(relData + symIndex*relSecEntrySize); + const auto &relEntry=*relDataAsSymPtr; + + // calculate index into dynsym, section. + const auto dynsymIndex=T_Extracter().elf_r_sym(relEntry.r_info); + const auto dynsymData=dynsymSec->get_data(); + const auto dynstrData=dynstrSec->get_data(); + + cout<<dec<<"At entry "<<symIndex<<", reloc entry has dynsym index "<<dynsymIndex<<endl; + + // the index into the .dynsym section for the relocation. + const auto dynsymDataAsSymPtr=reinterpret_cast<const T_Sym *>(dynsymData); + if(dynsymIndex*sizeof(T_Sym) >= (size_t)dynsymSec->get_size()) return; + + // get a reference to the dynsym entry. + const auto &dynsymEntry=dynsymDataAsSymPtr[dynsymIndex]; + // extra where in the string table the name is. + const auto name_offset=dynsymEntry.st_name; + + // sanity check string length + if(name_offset < 0U || name_offset > (size_t)dynstrSec->get_size()) + return; + + const auto applyName=[&](const string& part, const Address_t myAddr) + { + // get the name + const auto name=string(dynstrData+name_offset)+part+"@plt"; + + // find a function + auto func_it=find_if(ALLOF(sccs), [&](const RangeSet_t& s) + { + return s.begin() -> first == myAddr; + }); + if(func_it!=sccs.end()) + { + cout<<"Setting function at "<<hex<<myAddr<<" to name "<<name<<endl; + funcNames[*func_it]=name; + } + }; + + applyName("part1", addr); + applyName("part2", addr+6); + }; + + const auto pltSec=exeio.sections[pltSecName]; + if(pltSec==NULL) return; + + const auto startAddr=pltSec->get_address(); + const auto endAddr=pltSec->get_address()+pltSec->get_size(); + + if(verbose) + cout<<"Found plt function range is "<<hex<<startAddr<<"-"<<endAddr<<endl; + + const auto pltRange_it=find_if(ALLOF(sccs), [&](const RangeSet_t& s) + { + return find_if(ALLOF(s), [&](const Range_t& r) { return r.contains(startAddr); }) != s.end(); + }); + // erase startAddr if found. + if(pltRange_it!=sccs.end()) + sccs.erase(pltRange_it); // invalidates all iterators + + auto dynsymEntryIndex=0; + + const auto handle_x86_plt=[&]() + { + const auto plt_skip=16; + const auto plt_header_size=12; + const auto plt_entry_size=16; + const auto plt_entry_size_first_part=6; + + addRange(startAddr,plt_header_size); + for(auto i=startAddr+plt_skip; i<endAddr; i+=plt_skip) + { + addRange(i,plt_entry_size_first_part); + addRange(i+6,plt_entry_size-plt_entry_size_first_part); + addName(i,dynsymEntryIndex++); + } + }; + const auto handle_arm_plt=[&]() + { + const auto plt_entry_size=16; + const auto plt_header_size=8*4; + + addRange(startAddr,plt_header_size); + for(auto i=startAddr+plt_header_size; i<endAddr; i+=plt_entry_size) + { + addRange(i,plt_entry_size); + addName(i,dynsymEntryIndex++); + } + }; + + switch(machine_type) + { + case mtX86_64: + case mtI386: + handle_x86_plt(); + break; + case mtAarch64: + handle_arm_plt(); + break; + default: + assert(0); + + }; + cout<<"#ATTRIBUTE plt_entries="<<dec<<dynsymEntryIndex<<endl; + + + // deal with gotPlt Section. + const auto gotPltSec=exeio.sections[endSecName]; + if(gotPltSec==NULL) + return; + + // both 32- and 64-bit, entries are 6 bytes, with 2 bytes of padding. + const auto gotPltEntrySize=8; + const auto gotPltRangeSize=6; + const auto gotPltStartAddr=gotPltSec->get_address(); + auto gotpltEntries=0U; + + for(auto i=0U; i + gotPltRangeSize < (size_t)gotPltSec->get_size(); i+=gotPltEntrySize) + { + addRange(gotPltStartAddr+i,gotPltRangeSize); + gotpltEntries++; + } + cout<<"#ATTRIBUTE gotplt_entries="<<dec<<gotpltEntries<<endl; + + } + + void doBelongTos(const Range_t &range, const Address_t startAddr) + { + const auto sec=exeio.sections.findByAddress(range.first); + assert(sec); + const auto secEnd=exeio.sections.findByAddress(range.second-1); + assert(sec==secEnd); // same section. + const auto data=sec->get_data(); + const auto secStartAddr=sec->get_address(); + const auto range_len=range.second-range.first; + const auto the_code=(const uint8_t*)(data+(range.first-secStartAddr)); + + auto insn=(cs_insn *)nullptr; + + const auto count = cs_disasm(cshandle, the_code, range_len, range.first, 0, &insn); + if (count > 0) + { + for (auto j = 0U; j < count; j++) + { + outfile<<hex<<"\t"<<insn[j].address<<"\t"<<dec<<insn[j].size<<"\tINSTR BELONGTO\t"<<hex<<startAddr<< "\t; "<<insn[j].mnemonic << " " << insn[j].op_str<<endl; + } + + cs_free(insn, count); + } + else + { + cerr<<"ERROR: Failed to disassemble code at "<<range.first<<"-"<<range.second<<endl; + exit(1); + } + + + } + void doBelongTos(const RangeSet_t &scc) + { + const auto min=*scc.begin(); + const auto startAddr=min.first; + + for(auto range : scc) + doBelongTos(range,startAddr); + + } + + void writeAnnotations() + { + cout<<"The functions are:"<<endl; + auto i=0; + for(const auto &scc : sccs) + { + const auto min=*scc.begin(); + const auto max=*prev(scc.end()); + const auto size=max.second-min.first; + + cout<<"Function "<<dec<<i++<<" (" <<funcNames[scc] << ") is "<<hex<<min.first<<" "<<dec<<max.second-min.first<<endl; + const auto usefp=getUseFp(scc); + + outfile<<hex<<"\t"<<min.first<<"\t"<<dec<<size<<"\tFUNC GLOBAL\t"<<funcNames[scc]<<" "<< usefp << endl; + doBelongTos(scc); + } + if(getenv("SELF_VALIDATE")) + assert(sccs.size()>0); + } + + string getUseFp(const RangeSet_t scc) + { + assert(scc.begin()!=scc.end()); + const auto startAddr=scc.begin()->first; + const auto fde=ehp->findFDE(startAddr); + if(!fde) return "NOFP"; + const auto &ehprogram=fde->getProgram(); + const auto ehprogramInstructions=ehprogram.getInstructions(); + + const auto def_cfa_rbp_it = find_if(ALLOF(*ehprogramInstructions), [&](const shared_ptr<EHProgramInstruction_t> insn) + { + assert(insn); + const auto &insnBytes=insn->getBytes(); + // 0xd, 0x5 is "def_cfa_register ebp" + // 0xd, 0x6 is "def_cfa_register rbp" + const auto reg=file_class==ELF64 ? (uint8_t)0x6 : (uint8_t)0x5; + return insnBytes==EHProgramInstructionByteVector_t({(uint8_t)0xd, reg }); + }); + return def_cfa_rbp_it == ehprogramInstructions->end() ? "NOFP" : "USEFP"; + } + + + +}; + +ostream& operator<<(ostream& os, const CreateFunctions_t::RangeSet_t& rs) +{ + for(const auto r : rs) + { + os<<"("<<r.first<<"-"<<r.second<<"), "; + } + return os; +} + +int main(int argc, char* argv[]) +{ + + if(argc < 3) + { + usage(argc,argv); + exit(1); + } + // Parse some options for the transform + const static struct option long_options[] = { + {"verbose", no_argument, 0, 'v'}, + {"help", no_argument, 0, 'h'}, + {"usage", no_argument, 0, '?'}, + {0,0,0,0} + }; + auto short_opts="vh?"; + auto verbose=false; + auto index = (int)0; + while(1) + { + int c = getopt_long(argc, argv,short_opts, long_options, &index); + if(c == -1) + break; + switch(c) + { + case 0: + break; + case 'v': + verbose=true; + break; + case '?': + case 'h': + usage(argc,argv); + exit(1); + break; + default: + break; + } + } + + + if(optind+2 > argc) + { + usage(argc,argv); + exit(1); + } + + auto input_pgm=string(argv[optind]); + auto output_annot=string(argv[optind+1]); + for(auto i=optind+2 ; i < argc; i++) + { + ofstream out(argv[i]); // touch file + if(!out.is_open()) + { + cerr<<"Cannot touch file "<<argv[i]<<endl; + exit(1); + } + + } + + CreateFunctions_t create_funcs(input_pgm,output_annot,verbose); + create_funcs.calculate(); + create_funcs.writeAnnotations(); + + return 0; +} diff --git a/irdb-lib/thanos/SConscript b/irdb-lib/thanos/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..ed7ad18ccbdec2248fb96d7f5fcef85375cac017 --- /dev/null +++ b/irdb-lib/thanos/SConscript @@ -0,0 +1,32 @@ +import os + + + +Import('env') +myenv=env.Clone() +myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) + +cpppath=''' + $IRDB_SDK/include + $SECURITY_TRANSFORMS_HOME/libIRDB-core/include + ''' + + +files=Glob( Dir('.').srcnode().abspath+"/*.cpp") + +myenv.Append(CXXFLAGS = " -std=c++11 -Wall ") + +pgm="thanos.exe" + +LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" +LIBS=Split( env.subst('$BASE_IRDB_LIBS')+ " irdb-transform dl") +myenv=myenv.Clone(CPPPATH=Split(cpppath)) +pgm=myenv.Program(pgm, files, LIBPATH=LIBPATH, LIBS=LIBS) +install=myenv.Install("$SECURITY_TRANSFORMS_HOME/plugins_install", pgm) +Default(install) + + + + +ret=[]+install +Return('ret') diff --git a/irdb-lib/thanos/SConstruct b/irdb-lib/thanos/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..44d3bd9e81dfb9812806072103183b71c0810436 --- /dev/null +++ b/irdb-lib/thanos/SConstruct @@ -0,0 +1,7 @@ + + + +env=Environment() +Export('env') +ret=SConscript("SConscript") +Return('ret') diff --git a/irdb-lib/thanos/thanos.cpp b/irdb-lib/thanos/thanos.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e336c3307ff9e4ab7a1e3387c74943f9c3fea7fe --- /dev/null +++ b/irdb-lib/thanos/thanos.cpp @@ -0,0 +1,435 @@ +#include <irdb-core> +#include <libIRDB-core.hpp> +#include <dlfcn.h> +#include <vector> +#include <memory> +#include <sstream> +#include <iostream> +#include <iomanip> +#include <unistd.h> +#include <fcntl.h> +#include <fstream> +#include <ctime> +#include <ext/stdio_filebuf.h> + + + +using namespace std; +using namespace IRDB_SDK; + +#define ALLOF(a) begin(a),end(a) + +// global to be used like cout/cerr for writing to the logs +int thanos_log_fd=-1; +ostream *thanos_log; +ostream *real_cout; +ostream *real_cerr; +string thanos_path; +bool redirect_opt=true; +int new_stdout_fd=1; +int new_stderr_fd=2; + +class ThanosPlugin_t +{ + public: + static unique_ptr<ThanosPlugin_t> pluginFactory(const string plugin_details); + static int saveChanges(); + bool isOptional() + { + return step_optional; + } + string getStepName() + { + return step_name; + } + int runPlugin(); + + private: + // methods + ThanosPlugin_t(const string p_step_name, + const bool p_step_optional, + const vector<string> p_step_args + ) + : + step_name(p_step_name), + step_optional(p_step_optional), + step_args(p_step_args) + { + } + void tidyIR(); + int executeStep(TransformStep_t& the_step, const bool are_debugging); + int commitAll(); + + // data + const string step_name; + const bool step_optional; + const vector<string> step_args; + static const unique_ptr<IRDBObjects_t> shared_objects; +}; +// initialize private static data member +const unique_ptr<IRDBObjects_t> ThanosPlugin_t::shared_objects(new libIRDB::IRDBObjects_t()); + +using PluginList_t = vector<unique_ptr<ThanosPlugin_t>>; +PluginList_t getPlugins(const int argc, char const *const argv[]); + +int main(int argc, char* argv[]) +{ + thanos_path=argv[0]; + + new_stdout_fd=dup(STDOUT_FILENO); + new_stderr_fd=dup(STDERR_FILENO); + + __gnu_cxx::stdio_filebuf<char> stdout_filebuf(new_stdout_fd, ios::out); + __gnu_cxx::stdio_filebuf<char> stderr_filebuf(new_stderr_fd, ios::out); + + ostream my_real_cout(&stderr_filebuf); + ostream my_real_cerr(&stdout_filebuf); + real_cout=&my_real_cout; + real_cerr=&my_real_cerr; + + auto thanos_log_fileptr=fopen("logs/thanos.log", "a+"); + if(!thanos_log_fileptr) + { + *real_cerr<<"Cannot open logs/thanos.log"<<endl; + exit(1); + } + thanos_log_fd=fileno(thanos_log_fileptr); + __gnu_cxx::stdio_filebuf<char> thanos_log_filebuf(thanos_log_fd, ios::out); + ostream thanos_log_stream(&thanos_log_filebuf); + thanos_log=&thanos_log_stream; + + // make sure stuff goes to the log unless otherwise indicated by using real_cout + dup2(thanos_log_fd, STDOUT_FILENO); + dup2(thanos_log_fd, STDERR_FILENO); + + // get plugins + auto argv_iter=1; + while (true) + { + if(argv_iter >= argc) + { + break; + } + if(string(argv[argv_iter])=="--no-redirect") + { + redirect_opt=false; + argv_iter++; + } + else + break; + } + const auto plugin_argv_iter=argv_iter; + + auto thanos_plugins = getPlugins(argc-plugin_argv_iter, argv+plugin_argv_iter); + if(thanos_plugins.size() == 0) + { + // for now, usage is pretty strict to enable simple + // parsing, because this program is only used by an + // automated script + *thanos_log << "Syntax error in arguments." << endl; + *thanos_log << "USAGE: <thanos opts> (\"<step name> [-optional] [--step-args [ARGS]]\")+" << endl; + return 1; + } + + for(unsigned int i = 0; i < thanos_plugins.size(); ++i) + { + ThanosPlugin_t* plugin = thanos_plugins[i].get(); + + const int result = plugin->runPlugin(); + // if that returns failure AND the step is not optional + if(result != 0 && !plugin->isOptional()) + { + *thanos_log << "A critical step failed: " << plugin->getStepName() << endl; + *thanos_log << "If DEBUG_STEPS is not on, this failure could " + << "be due to an earlier critical step." << endl; + return 1; // critical step failed, abort + } + } + // write back final changes + const int result = ThanosPlugin_t::saveChanges(); + if(result != 0) + { + *thanos_log << "A critical step failed: " << (thanos_plugins.back())->getStepName() + << endl; + *thanos_log << "If DEBUG_STEPS is not on, this failure could " + << "be due to an earlier critical step." << endl; + return 1; // critical step failed, abort + } + else + { + return 0; // success :) + } +} + + +PluginList_t getPlugins(const int argc, char const *const argv[]) +{ + PluginList_t plugins; + + for(auto i = 0; i < argc; ++i) + { + auto the_plugin = ThanosPlugin_t::pluginFactory(string(argv[i])); + if(the_plugin == nullptr) + return PluginList_t(); + plugins.push_back(move(the_plugin)); + } + return plugins; +} + + +// assumes that tokens are always space-separated +// (cannot be delineated by quotes, for example) +const vector<string> getTokens(const string arg_string) +{ + vector<string> tokens; + istringstream arg_stream(arg_string); + string token; + while (getline(arg_stream, token, ' ')) + { + tokens.push_back(token); + } + return tokens; +} + + +unique_ptr<ThanosPlugin_t> ThanosPlugin_t::pluginFactory(const string plugin_details) +{ + auto tokens = getTokens(plugin_details); + if(tokens.size() < 1) + return unique_ptr<ThanosPlugin_t>(nullptr); + + const auto step_name = tokens[0]; + auto step_optional = false; + vector<string> step_args; + for(unsigned int i = 1; i < tokens.size(); ++i) + { + if(tokens[i] == "--step-args") + { + if(tokens.begin()+i+1 < tokens.end()) + step_args.assign(tokens.begin()+i+1, tokens.end()); + break; + } + else if(tokens[i] == "-optional") + { + step_optional = true; + } + else + { + return unique_ptr<ThanosPlugin_t>(nullptr); + } + } + return unique_ptr<ThanosPlugin_t>(new ThanosPlugin_t(step_name, step_optional, step_args)); +} + + +int ThanosPlugin_t::runPlugin() +{ + static const char *const base_path = getenv("SECURITY_TRANSFORMS_HOME"); + if(base_path == NULL) + { + *thanos_log << "Environment variables not set." << endl; + return -1; + } + static const auto plugin_path (string(base_path).append("/plugins_install/")); + + void *const dlhdl = dlopen((plugin_path+"lib"+step_name+".so").c_str(), RTLD_NOW); + if(dlhdl == NULL) + { + const auto err=dlerror(); + *thanos_log<<"Cannot open "<<step_name<<": "<<err<<endl; + return -1; + } + + const void *const sym = dlsym(dlhdl, "getTransformStep"); + if(sym == NULL) + { + const auto err=dlerror(); + *thanos_log<<"Cannot find getTransformStep in "<<step_name<<": "<<err<<endl; + return -1; + } + + using GetTransformPtr_t = shared_ptr<TransformStep_t> (*)(void); // function pointer, takes void, returns TransformStep_t shared ptr + GetTransformPtr_t func=(GetTransformPtr_t)sym; + shared_ptr<TransformStep_t> the_step = (*func)(); + assert(the_step != NULL); + + static const char *const are_debugging = getenv("DEBUG_STEPS"); + + auto logfile=(FILE*)nullptr; + + auto are_logging = !((bool) are_debugging); + if(are_logging) + { + // setup logging + auto logfile_path = "./logs/"+step_name+".log"; + logfile=fopen(logfile_path.c_str(), "a+"); + if(!logfile) + { + *real_cout<<"Cannot open log file "<<logfile_path<<endl; + exit(1); + } + if(redirect_opt) + { + dup2(fileno(logfile), STDOUT_FILENO); + dup2(fileno(logfile), STDERR_FILENO); + } + else + { + dup2(new_stdout_fd, STDOUT_FILENO); + dup2(new_stderr_fd, STDERR_FILENO); + } + } + + + const auto start_time = clock(); + const auto start_t=time(nullptr); + const auto start_time_str = ctime(&start_t); + + const auto step_result = executeStep(*(the_step.get()), (bool) are_debugging); + + const auto end_time = clock(); + const auto end_t=time(nullptr); + const auto end_time_str = ctime(&end_t); + const auto elapsed_time = (double)(end_time-start_time)/ CLOCKS_PER_SEC; + + cout<< "#ATTRIBUTE start_time=" << start_time_str ; // endl in time_str + cout<< "#ATTRIBUTE end_time=" << end_time_str ; // endl in time_str + cout<< "#ATTRIBUTE elapsed_time=" << elapsed_time<<endl; + cout<< "#ATTRIBUTE step_name=" << step_name<<endl; + cout<< "#ATTRIBUTE step_command= " << thanos_path << " \"" << step_name + << " --step-args "; copy(ALLOF(step_args), ostream_iterator<string>(cout, " ")); cout<<"\""<<endl; + cout<< "#ATTRIBUTE step_exitcode="<<dec<<step_result<<endl; + + + dup2(thanos_log_fd, STDOUT_FILENO); + dup2(thanos_log_fd, STDERR_FILENO); + if(logfile) + fclose(logfile); + + the_step.reset(); // explicitly get rid of the handle to the library so we can close it. + dlclose(dlhdl); + + // return status of execute method + return step_result; +} + + +void ThanosPlugin_t::tidyIR() +{ + optind=1; + shared_objects->tidyIR(); +} + +int ThanosPlugin_t::executeStep(TransformStep_t& the_step, const bool are_debugging) +{ + + *real_cout<<"Performing step "<<the_step.getStepName()<< " [dependencies=unknown] ..."; // no endl intentionally. + flush(*real_cout); + + + tidyIR(); + + const int parse_retval = the_step.parseArgs(step_args); + if(parse_retval != 0) + { + *real_cout<<"Done. Command failed! ***************************************"<<endl; + if(!step_optional) + { + *real_cout<<"ERROR: The "<<the_step.getStepName()<<" step is necessary, but options parsing failed. Exiting early."<<endl; + } + return parse_retval; + } + + pqxxDB_t* pqxx_interface = shared_objects->getDBInterface(); + if(step_optional) + { + const int error = shared_objects->writeBackAll(thanos_log); + if(error) + { + return 1; // the failure must be from a critical step, abort + } + else + { + // commit changes (in case this step fails) and reset interface + pqxx_interface->commit(); + pqxx_interface = shared_objects->resetDBInterface(); + } + } + + const int step_error = the_step.executeStep(shared_objects.get()); + + if(step_error) + { + if(step_optional) + { + + *real_cout<<"Done. Command failed! ***************************************"<<endl; + // delete all shared items without writing + // next step will have to get the last "good" version from DB + shared_objects->deleteAll(); + } + else + { + *real_cout<<"Done. Command failed! ***************************************"<<endl; + *real_cout<<"ERROR: The "<<the_step.getStepName()<<" step is necessary, but failed. Exiting early."<<endl; + return 1; // critical step failed, abort + } + } + else + { + *real_cout<<"Done. Successful."<<endl; + } + + if(step_optional) + { + // write changes to DB to see if it succeeds + const int error = shared_objects->writeBackAll(thanos_log); + if(error) + { + // abort changes by resetting DB interface + pqxx_interface = shared_objects->resetDBInterface(); + } + else if(are_debugging) + { + // commit changes (in case next step fails) and reset interface + pqxx_interface->commit(); + pqxx_interface = shared_objects->resetDBInterface(); + } + } + else if(are_debugging) + { + // write changes to DB in case next step fails + const int error = shared_objects->writeBackAll(thanos_log); + if(error) + { + return 1; // critical step failed, abort + } + else + { + // commit changes (in case next step fails) and reset interface + pqxx_interface->commit(); + pqxx_interface = shared_objects->resetDBInterface(); + } + } + + return step_error; +} + + +int ThanosPlugin_t::saveChanges() +{ + pqxxDB_t* pqxx_interface = shared_objects->getDBInterface(); + const int error = shared_objects->writeBackAll(thanos_log); + if(error) + { + return 1; // critical step failed, abort + } + else + { + // commit changes and reset interface + pqxx_interface->commit(); + pqxx_interface = shared_objects->resetDBInterface(); + return 0; + } +} + diff --git a/irdb-lib/third_party/LICENSE.txt b/irdb-lib/third_party/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..42d3e128c3508710e668d7631a54a5f0bd36fce1 --- /dev/null +++ b/irdb-lib/third_party/LICENSE.txt @@ -0,0 +1 @@ +Software under this directory and sub-directory is subject to its own licensing requirement diff --git a/irdb-lib/xform/SConscript b/irdb-lib/xform/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..e1af37fa9cd25ac1e18962acd38edb281d8f18b1 --- /dev/null +++ b/irdb-lib/xform/SConscript @@ -0,0 +1,39 @@ +import os + +Import('env') +myenv=env.Clone() +myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) + +lib="xform" + +files= ''' + instruction_descriptor.cpp + function_descriptor.cpp + elfreader.cpp + null_transform.cpp + rewriter.cpp + spri_alloc.c + gen_hash.c + constant_hash.c + funclist_hash.c + instrmap_hash.c + framerestore_hash.c + stackref_hash.c + ''' +cpppath=''' + $SECURITY_TRANSFORMS_HOME/libIRDB/include/ + $SECURITY_TRANSFORMS_HOME/libEXEIO/include/ + $SECURITY_TRANSFORMS_HOME/include/ + ''' + +CFLAGS="-fPIC -DUBUNTU" + +myenv=myenv.Clone(CC="$CXX", CPPPATH=Split(cpppath), CFLAGS=CFLAGS) +myenv.Append(CXXFLAGS=" -std=c++11 ") +lib=myenv.SharedLibrary(lib, Split(files), LIBS=Split("IRDB-core EXEIO"), LIBPATH=Split("$SECURITY_TRANSFORMS_HOME/lib")) + +install=myenv.Install("$SECURITY_TRANSFORMS_HOME/lib/", lib) + +Default(install) + +Return('lib') diff --git a/irdb-lib/xform/SConstruct b/irdb-lib/xform/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..e542bcbc14c04dc8cdf8e3535b9585b4ef0cf232 --- /dev/null +++ b/irdb-lib/xform/SConstruct @@ -0,0 +1,7 @@ + + + +env=Environment() +Export('env') +lib=SConscript("SConscript") +Return(lib) diff --git a/libcapstone b/libcapstone new file mode 160000 index 0000000000000000000000000000000000000000..9408c0de4f3a4b2a3cc1cac3f22219301c561400 --- /dev/null +++ b/libcapstone @@ -0,0 +1 @@ +Subproject commit 9408c0de4f3a4b2a3cc1cac3f22219301c561400 diff --git a/libehp b/libehp new file mode 160000 index 0000000000000000000000000000000000000000..cda036f54b68d2eb1bfd0c0d636dad954433a3b7 --- /dev/null +++ b/libehp @@ -0,0 +1 @@ +Subproject commit cda036f54b68d2eb1bfd0c0d636dad954433a3b7 diff --git a/third_party/elfio-code b/third_party/elfio-code new file mode 160000 index 0000000000000000000000000000000000000000..9f9407d3018fb4317e56bb78a74b9cdbf6c96306 --- /dev/null +++ b/third_party/elfio-code @@ -0,0 +1 @@ +Subproject commit 9f9407d3018fb4317e56bb78a74b9cdbf6c96306