diff --git a/.gitattributes b/.gitattributes index 8e948c534a1fd79cf59d786adc75fec0a4d091d7..63270b69bcf9f232e3af412baf2220fd807214dc 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,8 @@ * text=auto !eol +/Makefile.in -text +/SConscript -text +/SConstruct -text +/configure.in -text +/install-sh -text +/push64_relocs.cpp -text +/push64_relocs.h -text diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000000000000000000000000000000000000..4a030ca70bcdcdd838d54e6ab09ab718be4ae0d6 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,37 @@ + + + +SRCS=push64_relocs.cpp +OBJS=$(subst .cpp,.o, $(SRCS)) +EXE=push64_relocs.zpi + +CXX=@CXX@ +CXXFLAGS=@CXXFLAGS@ @OPTIMIZE@ +LDFLAGS=@LDFLAGS@ +LIBS= +#${SECURITY_TRANSFORMS_HOME}/tools/transforms/Rewrite_Utility.o +#-lpqxx -lpq -lIRDB-core -lBeaEngine_s_d -ltransform + +all: $(EXE) + +-include $(OBJS:.o=.d) + +$(EXE): $(OBJS) + $(CXX) $(CXXFLAGS) $(OBJS) $(LDFLAGS) $(LIBS) -o $@ + +%.o: %.cpp + $(CXX) -c $(CXXFLAGS) $*.cpp + @# + @# build dependencies -- http://scottmcpeak.com/autodepend/autodepend.html + @# + $(CXX) -MM $(CXXFLAGS) $*.cpp > $*.d + @cp -f $*.d $*.d.tmp + @sed -e 's/.*://' -e 's/\\$$//' < $*.d.tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $*.d + @rm -f $*.d.tmp + +install: + cp $(EXE) ${ZIPR_INSTALL}/plugins + + +clean: + rm -f $(OBJS) $(EXE) *.d *.o diff --git a/SConscript b/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..65a0389f5ffae37840b8c25c2936231e923f0fec --- /dev/null +++ b/SConscript @@ -0,0 +1,59 @@ +import shutil +import os +import tarfile + +Import('env') + + +#print 'env=' +#print env.Dump() + + + +myenv=env +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(ZIPR_INSTALL=os.environ['ZIPR_INSTALL']) +myenv.Replace(do_cgc=ARGUMENTS.get("do_cgc",0)) + +if 'do_cgc' in env and int(env['do_cgc']) == 1: + myenv.Append(CFLAGS=" -DCGC ") + myenv.Append(CCFLAGS=" -DCGC ") + + + + +files= ''' + push64_relocs.cpp + ''' + +# ELFIO needs to be first so we get the zipr version instead of the sectrans version. the zipr version is modified to include get_offset. +cpppath=''' + . + $ZIPR_HOME/third_party/ELFIO/elfio-2.2 + $SECURITY_TRANSFORMS_HOME/include/ + $SECURITY_TRANSFORMS_HOME/libIRDB/include/ + $SECURITY_TRANSFORMS_HOME/beaengine/include + $SECURITY_TRANSFORMS_HOME/beaengine/beaengineSources/Includes/ + $SECURITY_TRANSFORMS_HOME/tools/transforms + $ZIPR_HOME/include/ + $ZIPR_SDK/include/ + ''' + +libs=''' + ''' + +libpath=''' + $SECURITY_TRANSFORMS_HOME/lib + ''' + +myenv.Append(CCFLAGS=" -Wall ") + +myenv=myenv.Clone(CPPPATH=Split(cpppath), LIBS=Split(libs), LIBPATH=Split(libpath), SHLIBSUFFIX=".zpi", SHLIBPREFIX="") +lib=myenv.SharedLibrary("push64_relocs", Split(files)) + +install=myenv.Install("$ZIPR_INSTALL/plugins/", lib) +Default(install) + + diff --git a/SConstruct b/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..e49ab6491145004334861b205d61e6e48785b308 --- /dev/null +++ b/SConstruct @@ -0,0 +1,55 @@ +import os +import sys + + +env=Environment() + +# default build options +env.Replace(CFLAGS="-fPIC -w ") +env.Replace(CXXFLAGS="-fPIC -w ") +env.Replace(LINKFLAGS="-fPIC ") + +# parse arguments +env.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) +env.Replace(ZIPR_HOME=os.environ['ZIPR_HOME']) +env.Replace(ZIPR_INSTALL=os.environ['ZIPR_INSTALL']) +env.Replace(ZIPR_SDK=os.environ['ZIPR_SDK']) +env.Replace(debug=ARGUMENTS.get("debug",0)) +env.Replace(do_64bit_build=ARGUMENTS.get("do_64bit_build",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") +env.Append(CXXFLAGS=" -std=c++0x") + +# 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") + +env['build_appfw']=0 +env['build_tools']=0 + +Export('env') +SConscript("SConscript", variant_dir='build') + diff --git a/configure.in b/configure.in new file mode 100644 index 0000000000000000000000000000000000000000..a3eeeae9a3c37d745188838d011d26abd0bc9dff --- /dev/null +++ b/configure.in @@ -0,0 +1,66 @@ + +AC_INIT(myconfig, version-0.1) + + +AC_PREFIX_DEFAULT($ZIPR_INSTALL) +AC_PROG_CC +AC_CANONICAL_HOST + +AC_ARG_ENABLE([debugging], [ --enable-debugging enable -g when compiling]) +AC_ARG_ENABLE([cgc], [ --enable-cgc enable -DCGC when compiling for CGC binaries]) + +OPTIMIZE="-O3" +if test "$enable_debugging" = yes; then + OPTIMIZE="-g -DDEBUG" +fi + + + +AR=ar +CC=gcc +CXX=g++ +CFLAGS="$OPTIMIZE -fPIC -I$SECURITY_TRANSFORMS_HOME/include/elfio/elfio-2.2/ -I$ZIPR_SDK/include -I$SECURITY_TRANSFORMS_HOME/libIRDB/include -I$SECURITY_TRANSFORMS_HOME/beaengine/include -I$SECURITY_TRANSFORMS_HOME/include -I$SECURITY_TRANSFORMS_HOME/tools/transforms" +CXXFLAGS="$CFLAGS" +LD=gcc +LDFLAGS="-shared -o libscfi.zpi" +AS=nasm +ASFLAGS="-felf" + +case "$host" in + i686-pc-cygwin) + LDFLAGS="$LDFLAGS -L$ZIPR_INSTALL/lib -lzipr" + ;; + *) + + ;; +esac + + +if test "$enable_cgc" = yes; then + echo Enabling CGC build. + CFLAGS="$CFLAGS -DCGC -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64" + CXXFLAGS="$CXXFLAGS -DCGC -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64" + ASFLAGS="$ASFLAGS -DCGC -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64" + +fi + +AC_OUTPUT(Makefile) + +AC_SUBST(DIRS) +AC_SUBST(CC) +AC_SUBST(CFLAGS) +AC_SUBST(CXX) +AC_SUBST(CXXFLAGS) +AC_SUBST(LD) +AC_SUBST(LDFLAGS) +AC_SUBST(AS) +AC_SUBST(ASFLAGS) +AC_SUBST(ARCH) +AC_SUBST(AR) +AC_SUBST(OS) +AC_SUBST(LIB) +AC_SUBST(OPTIMIZE, $OPTIMIZE) +echo prefix=$prefix +AC_SUBST(prefix, $prefix) + +AC_OUTPUT diff --git a/install-sh b/install-sh new file mode 100644 index 0000000000000000000000000000000000000000..e4160c991dc958a11b89654e365c72a13639f6b2 --- /dev/null +++ b/install-sh @@ -0,0 +1,325 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2004-04-01.17 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename= +transform_arg= +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd= +chgrpcmd= +stripcmd= +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src= +dst= +dir_arg= + +usage="Usage: $0 [OPTION]... SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 -d DIRECTORIES... + +In the first form, install SRCFILE to DSTFILE, removing SRCFILE by default. +In the second, create the directory path DIR. + +Options: +-b=TRANSFORMBASENAME +-c copy source (using $cpprog) instead of moving (using $mvprog). +-d create directories instead of installing files. +-g GROUP $chgrp installed files to GROUP. +-m MODE $chmod installed files to MODE. +-o USER $chown installed files to USER. +-s strip installed files (using $stripprog). +-t=TRANSFORM +--help display this help and exit. +--version display version info and exit. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG +" + +while test -n "$1"; do + case $1 in + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + -c) instcmd=$cpprog + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + --help) echo "$usage"; exit 0;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + --version) echo "$0 $scriptversion"; exit 0;; + + *) # When -d is used, all remaining arguments are directories to create. + test -n "$dir_arg" && break + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dstarg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dstarg" + shift # fnord + fi + shift # arg + dstarg=$arg + done + break;; + esac +done + +if test -z "$1"; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src ;; + esac + + if test -n "$dir_arg"; then + dst=$src + src= + + if test -d "$dst"; then + instcmd=: + chmodcmd= + else + instcmd=$mkdirprog + fi + else + # Waiting for this to be detected by the "$instcmd $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dstarg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dstarg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst ;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + dst=$dst/`basename "$src"` + fi + fi + + # This sed command emulates the dirname command. + dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + + # Make sure that the destination directory exists. + + # Skip lots of stat calls in the usual case. + if test ! -d "$dstdir"; then + defaultIFS=' + ' + IFS="${IFS-$defaultIFS}" + + oIFS=$IFS + # Some sh's can't handle IFS=/ for some reason. + IFS='%' + set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` + IFS=$oIFS + + pathcomp= + + while test $# -ne 0 ; do + pathcomp=$pathcomp$1 + shift + if test ! -d "$pathcomp"; then + $mkdirprog "$pathcomp" || lasterr=$? + # mkdir can fail with a `File exist' error in case several + # install-sh are creating the directory concurrently. This + # is OK. + test ! -d "$pathcomp" && { (exit ${lasterr-1}); exit; } + fi + pathcomp=$pathcomp/ + done + fi + + if test -n "$dir_arg"; then + $doit $instcmd "$dst" \ + && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } + + else + # If we're going to rename the final executable, determine the name now. + if test -z "$transformarg"; then + dstfile=`basename "$dst"` + else + dstfile=`basename "$dst" $transformbasename \ + | sed $transformarg`$transformbasename + fi + + # don't allow the sed command to completely eliminate the filename. + test -z "$dstfile" && dstfile=`basename "$dst"` + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 + trap '(exit $?); exit' 1 2 13 15 + + # Move or copy the file name to the temp name + $doit $instcmd "$src" "$dsttmp" && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $instcmd $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && + + # Now rename the file to the real destination. + { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ + || { + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + if test -f "$dstdir/$dstfile"; then + $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ + || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ + || { + echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 + (exit 1); exit + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" + } + } + fi || { (exit 1); exit; } +done + +# The final little trick to "correctly" pass the exit status to the exit trap. +{ + (exit 0); exit +} + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/push64_relocs.cpp b/push64_relocs.cpp new file mode 100644 index 0000000000000000000000000000000000000000..57746ad91735aefbf86675413e589188a269209e --- /dev/null +++ b/push64_relocs.cpp @@ -0,0 +1,203 @@ +/*************************************************************************** + * Copyright (c) 2014 Zephyr Software LLC. All rights reserved. + * + * This software is furnished under a license and/or other restrictive + * terms and may be used and copied only in accordance with such terms + * and the inclusion of the above copyright notice. This software or + * any other copies thereof may not be provided or otherwise made + * available to any other person without the express written consent + * of an authorized representative of Zephyr Software LCC. Title to, + * ownership of, and all rights in the software is retained by + * Zephyr Software LCC. + * + * Zephyr Software LLC. Proprietary Information + * + * Unless otherwise specified, the information contained in this + * directory, following this legend, and/or referenced herein is + * Zephyr Software LLC. (Zephyr) Proprietary Information. + * + * CONTACT + * + * For technical assistance, contact Zephyr Software LCC. at: + * + * + * Zephyr Software, LLC + * 2040 Tremont Rd + * Charlottesville, VA 22911 + * + * E-mail: jwd@zephyr-software.com + **************************************************************************/ + + +#include <zipr_sdk.h> +#include <string> +#include <algorithm> +#include "utils.hpp" +#include "Rewrite_Utility.hpp" +#include "push64_relocs.h" + + +using namespace libIRDB; +using namespace std; +using namespace Zipr_SDK; +using namespace ELFIO; + +Push64Relocs_t::Push64Relocs_t(MemorySpace_t *p_ms, + elfio *p_elfio, + FileIR_t *p_firp, + Options_t *p_opts, + InstructionLocationMap_t *p_fil) : + m_memory_space(*p_ms), + m_elfio(*p_elfio), + m_firp(*p_firp), + m_opts(*p_opts), + final_insn_locations(*p_fil) +{ +} + +bool Push64Relocs_t::IsAdd64Relocation(Relocation_t *reloc) +{ + return (reloc->GetType().find("add64") != std::string::npos); +} + +Relocation_t* Push64Relocs_t::FindAdd64Relocation(Instruction_t* insn) +{ + Instruction_t* first_slow_path_insn=NULL; + RelocationSet_t::iterator rit = insn->GetRelocations().begin(); + for(rit; rit!=insn->GetRelocations().end(); rit++) + { + Relocation_t *reloc=*rit; + if (IsAdd64Relocation(reloc)) + return reloc; + } + return NULL; +} + + +bool Push64Relocs_t::IsPush64Relocation(Relocation_t *reloc) +{ + return (reloc->GetType().find("push64") != std::string::npos); +} + +Relocation_t* Push64Relocs_t::FindPush64Relocation(Instruction_t* insn) +{ + Instruction_t* first_slow_path_insn=NULL; + RelocationSet_t::iterator rit = insn->GetRelocations().begin(); + for(rit; rit!=insn->GetRelocations().end(); rit++) + { + Relocation_t *reloc=*rit; + if (IsPush64Relocation(reloc)) + return reloc; + } + return NULL; +} + +void Push64Relocs_t::HandlePush64Relocation(Instruction_t *insn, Relocation_t *reloc) +{ + std::unique_ptr<CallAddPair_t> reloc_pair(new CallAddPair_t(insn, insn->GetTarget())); + call_add_pairs.insert(std::move(reloc_pair)); +} + +void Push64Relocs_t::HandlePush64Relocs() +{ + int handled=0; + int insns=0; + int relocs=0; + // for each instruction + InstructionSet_t::iterator iit = m_firp.GetInstructions().begin(); + for(iit; iit!=m_firp.GetInstructions().end(); iit++) + { + Instruction_t& insn=*(*iit); + insns++; + + Relocation_t* reloc=FindPush64Relocation(&insn); + if(reloc) + { + if (m_opts.GetVerbose()) + cout << "Found a Push64 relocation." << endl; + HandlePush64Relocation(&insn,reloc); + handled++; + } + } + + cout<<"#ATTRIBUTE push64_relocations="<< std::dec<<handled<<endl; +} + + +void Push64Relocs_t::UpdatePush64Adds() +{ + if (m_opts.GetVerbose()) + cout << "UpdatePush64Adds()" << endl; + CallAddPairs_t::iterator cap_it = call_add_pairs.begin(); + for (cap_it; cap_it != call_add_pairs.end(); cap_it++) + { + bool change_to_add = false; + RangeAddress_t call_addr = 0; + RangeAddress_t add_addr = 0; + int add_offset = 0; + uint32_t relocated_value = 0; + Instruction_t *call = NULL, *add = NULL; + CallAddPair_t *cap = cap_it->get(); + Relocation_t *add_reloc = NULL; + + call = cap->first; + add = cap->second; + + call_addr = final_insn_locations[call]; + add_addr = final_insn_locations[add]; + + if (call_addr == 0 || add_addr == 0) + { + if (m_opts.GetVerbose()) + cout << "Call/Add pair not plopped?" << endl; + continue; + } + + add_reloc = FindAdd64Relocation(add); + assert(add_reloc && "Add in Call/Add pair must have relocation."); + + add_offset = add_reloc->GetOffset(); + + /* + * Stupid call will push the NEXT instruction address. + */ + call_addr+=call->GetDataBits().length(); + + if (add_offset>call_addr) + { + change_to_add = true; + relocated_value = add_offset-call_addr; + } + else + { + relocated_value = call_addr-add_offset; + } + + cout << "Relocating a(n) "<< ((change_to_add) ? "add":"sub") << " from " + << std::hex << call_addr + << " at " + << std::hex << add_addr + << endl + << "Using 0x" << std::hex << relocated_value + << " as the updated offset." << endl + << "Using 0x" << std::hex << add_offset + << " as the base offset." << endl; + if (change_to_add) + { + char add = (char)0x04; + m_memory_space.PlopBytes(add_addr+1, (const char*)&add, 1); + } + m_memory_space.PlopBytes(add_addr+3, (const char*)&relocated_value, 4); + } +} + +extern "C" +Zipr_SDK::ZiprPluginInterface_t* GetPluginInterface( + Zipr_SDK::MemorySpace_t *p_ms, + ELFIO::elfio *p_elfio, + libIRDB::FileIR_t *p_firp, + Zipr_SDK::Options_t *p_opts, + Zipr_SDK::InstructionLocationMap_t *p_fil) +{ + return new Push64Relocs_t(p_ms,p_elfio,p_firp,p_opts,p_fil); +} diff --git a/push64_relocs.h b/push64_relocs.h new file mode 100644 index 0000000000000000000000000000000000000000..ef9fa70985891cdeb37cf095a14b77cee6644fff --- /dev/null +++ b/push64_relocs.h @@ -0,0 +1,92 @@ +/*************************************************************************** + * Copyright (c) 2014 Zephyr Software LLC. All rights reserved. + * + * This software is furnished under a license and/or other restrictive + * terms and may be used and copied only in accordance with such terms + * and the inclusion of the above copyright notice. This software or + * any other copies thereof may not be provided or otherwise made + * available to any other person without the express written consent + * of an authorized representative of Zephyr Software LCC. Title to, + * ownership of, and all rights in the software is retained by + * Zephyr Software LCC. + * + * Zephyr Software LLC. Proprietary Information + * + * Unless otherwise specified, the information contained in this + * directory, following this legend, and/or referenced herein is + * Zephyr Software LLC. (Zephyr) Proprietary Information. + * + * CONTACT + * + * For technical assistance, contact Zephyr Software LCC. at: + * + * + * Zephyr Software, LLC + * 2040 Tremont Rd + * Charlottesville, VA 22911 + * + * E-mail: jwd@zephyr-software.com + **************************************************************************/ + +#ifndef nonce_relocs_h +#define nonce_relocs_h + +typedef std::pair<Instruction_t*, Instruction_t*> CallAddPair_t; +typedef std::set<std::unique_ptr<CallAddPair_t>> CallAddPairs_t; + +class Push64Relocs_t : public Zipr_SDK::ZiprPluginInterface_t +{ + public: + Push64Relocs_t(Zipr_SDK::MemorySpace_t *p_ms, + ELFIO::elfio *p_elfio, + libIRDB::FileIR_t *p_firp, + Zipr_SDK::Options_t *p_opts, + Zipr_SDK::InstructionLocationMap_t *p_fil); + virtual void PinningBegin() + { + } + virtual void PinningEnd() + { + cout<<"Push64Plugin: Ending pinning, applying push64 relocs."<<endl; + HandlePush64Relocs(); + } + virtual void DollopBegin() + { + } + virtual void DollopEnd() + { + } + virtual void CallbackLinkingBegin() + { + } + virtual void CallbackLinkingEnd() + { + cout<<"Push64Plugin: CBLinkEnd, updating adds." <<endl; + UpdatePush64Adds(); + } + + private: + // main workhorses + void HandlePush64Relocs(); + void UpdatePush64Adds(); + + // helpers + bool IsAdd64Relocation(libIRDB::Relocation_t *reloc); + libIRDB::Relocation_t* FindAdd64Relocation(libIRDB::Instruction_t* insn); + bool IsPush64Relocation(libIRDB::Relocation_t *reloc); + libIRDB::Relocation_t* FindPush64Relocation(libIRDB::Instruction_t* insn); + void HandlePush64Relocation(libIRDB::Instruction_t* insn, libIRDB::Relocation_t *reloc); + + // references to input + Zipr_SDK::MemorySpace_t &m_memory_space; + ELFIO::elfio& m_elfio; + libIRDB::FileIR_t& m_firp; + Zipr_SDK::Options_t& m_opts; + Zipr_SDK::InstructionLocationMap_t &final_insn_locations; + + // local data. + CallAddPairs_t call_add_pairs; + +}; + +#endif