diff --git a/.gitattributes b/.gitattributes
index 36b39ffeb9793664a4b72c3dc72278de5c72ea8b..cdf835e7b6c97828826f46d48f5a9beea15d034b 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -228,6 +228,7 @@ libIRDB/include/libIRDB-syscall.hpp -text
 libIRDB/include/libIRDB-util.hpp -text
 libIRDB/include/syscall/syscall.hpp -text
 libIRDB/include/util/insn_preds.hpp -text
+libIRDB/include/util/params.hpp -text
 libIRDB/include/utils.hpp -text
 libIRDB/install_libs.sh -text
 libIRDB/src/Makefile.in -text
@@ -266,6 +267,7 @@ libIRDB/src/util/Makefile -text
 libIRDB/src/util/SConscript -text
 libIRDB/src/util/SConstruct -text
 libIRDB/src/util/insn_preds.cpp -text
+libIRDB/src/util/params.cpp -text
 libIRDB/test/SConscript -text
 libIRDB/test/SConstruct -text
 libIRDB/test/build_callgraph.cpp -text
diff --git a/libIRDB/include/libIRDB-util.hpp b/libIRDB/include/libIRDB-util.hpp
index ca47f67ef3a544ccc492ed362fac8743bc34cead..829b8e0dbb22b26ad227cb573eb2463834fa2d78 100644
--- a/libIRDB/include/libIRDB-util.hpp
+++ b/libIRDB/include/libIRDB-util.hpp
@@ -34,6 +34,7 @@ namespace libIRDB
 {
 
 #include <util/insn_preds.hpp>
+#include <util/params.hpp>
 
 };
 
diff --git a/libIRDB/include/util/params.hpp b/libIRDB/include/util/params.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..de6006c13459b8ef1b5635507c127630421fc5f1
--- /dev/null
+++ b/libIRDB/include/util/params.hpp
@@ -0,0 +1,7 @@
+#ifndef _PARAMS_H
+#define _PARAMS_H
+
+extern bool IsParameterWrite(const libIRDB::FileIR_t *firp, libIRDB::Instruction_t* insn, std::string& output_dst);
+extern bool CallFollows(libIRDB::FileIR_t *firp, libIRDB::Instruction_t* insn, const std::string& arg_str);
+
+#endif
diff --git a/libIRDB/include/utils.hpp b/libIRDB/include/utils.hpp
index 3e8262a9f1ac15ee4c42ba81d535e935187b3636..b9a2899c5facee5dd2653ec9bcfbb8b933cb8d91 100644
--- a/libIRDB/include/utils.hpp
+++ b/libIRDB/include/utils.hpp
@@ -119,5 +119,6 @@ inline Funct for_randomOrder_each(const IterType &b, const IterType & e, const F
        });
 }
 
-
 #endif
+
+
diff --git a/libIRDB/src/util/SConscript b/libIRDB/src/util/SConscript
index 777fc63737a9adf02c849d0a066248475afb2ba5..6bb27dc65e63018410821ac1fbd47602ed8dabf2 100644
--- a/libIRDB/src/util/SConscript
+++ b/libIRDB/src/util/SConscript
@@ -8,6 +8,7 @@ myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME'])
 libname="IRDB-util"
 files=  '''
 	insn_preds.cpp
+	params.cpp
 	'''
 cpppath=''' 
 	$SECURITY_TRANSFORMS_HOME/include/
@@ -19,6 +20,7 @@ cpppath='''
 #myenv.Append(CCFLAGS=" -Wall -W -Wextra -Wconversion ")
 
 myenv=myenv.Clone(CPPPATH=Split(cpppath))
+myenv.Append(CXXFLAGS = " -std=c++11 ")
 lib=myenv.Library(libname, Split(files))
 
 install=env.Install("$SECURITY_TRANSFORMS_HOME/lib/", lib)
diff --git a/libIRDB/src/util/params.cpp b/libIRDB/src/util/params.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..43c654ee43983aa905fc3c1d7b767bf032f13e9d
--- /dev/null
+++ b/libIRDB/src/util/params.cpp
@@ -0,0 +1,143 @@
+/*
+ * 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 <utils.hpp>
+
+using namespace libIRDB;
+using namespace std;
+
+// Does instruction potentially write to a parameter to a call?
+bool libIRDB::IsParameterWrite(const FileIR_t *firp, Instruction_t* insn, string& output_dst)
+{
+	DISASM d;
+	insn->Disassemble(d);
+	if(d.Argument1.AccessMode!=WRITE)
+	{
+		return false;
+	}
+
+	/* 64 bit machines use regs to pass parameters */
+	if(firp->GetArchitectureBitWidth()==64)
+	{
+		// if it's a register
+		if((d.Argument1.ArgType&REGISTER_TYPE)==REGISTER_TYPE)
+		{
+			int regno=(d.Argument1.ArgType)&0xFFFF;
+			switch(regno)
+			{
+				case REG7:	// rdi
+				case REG6:	// rsi
+				case REG2:	// rdx
+				case REG1:	// rcx
+				case REG8:	// r8
+				case REG9:	// r9
+					output_dst=d.Argument1.ArgMnemonic;
+					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.Argument1.ArgType&MEMORY_TYPE)!=MEMORY_TYPE)
+		return false;
+
+	// check that base reg is esp.
+	if(d.Argument1.Memory.BaseRegister != REG4)
+		return false;
+
+	// check that there's no index reg
+	if(d.Argument1.Memory.IndexRegister != 0)
+		return false;
+
+	// get k out of [esp + k ]
+	unsigned int k=d.Argument1.Memory.Displacement;
+
+	// check that we know the frame layout.
+	if(insn->GetFunction() == NULL)
+		return false;
+
+	if(k < insn->GetFunction()->GetOutArgsRegionSize())
+	{
+		output_dst=string("[")+d.Argument1.ArgMnemonic+string("]");
+		return true;
+	}
+
+	// return we didn't find a memory of the right type
+	return false;
+}
+
+// is instruction originally a call?
+static bool IsOrWasCall(const FileIR_t *firp, Instruction_t* insn)
+{
+	if (firp == NULL || insn == NULL)
+		return false;
+
+	DISASM d;
+	insn->Disassemble(d);
+	if(d.Instruction.Mnemonic == string("call "))
+		return true;
+	else {
+		// call may have been converted to push/jmp in previous phase
+		// look for "push64" type reloc
+		auto it = std::find_if(insn->GetRelocations().begin(),insn->GetRelocations().end(),[&](const Relocation_t* reloc) 
+		{
+			if (reloc)
+				cout << "IsOrWasCall(): reloc: " << reloc->GetType() << endl;
+			return (reloc && ((reloc->GetType() == string("push64")) || reloc->GetType() == string("fix_call_fallthrough")));
+		});
+
+		if (it != insn->GetRelocations().end())
+			return true;
+	}
+
+	return false;
+}
+
+// Does a call follow the instruction?
+bool libIRDB::CallFollows(FileIR_t *firp, Instruction_t* insn, const string& arg_str)
+{
+	for(Instruction_t* ptr=insn->GetFallthrough(); ptr!=NULL; ptr=ptr->GetFallthrough())
+	{
+		DISASM d;
+		ptr->Disassemble(d);
+		if(IsOrWasCall(firp, ptr))
+		{
+			// found it
+			return true;
+		}
+
+		// found reference to argstring, assume it's a write and exit
+		if(string(d.CompleteInstr).find(arg_str)!= string::npos)
+			return false;
+	}
+
+	return false;
+}
+
diff --git a/libIRDB/test/fill_in_indtargs.cpp b/libIRDB/test/fill_in_indtargs.cpp
index cca30a95c343e4f77fd4d9ef0150df546eb6da05..2747075c9c923b02067215f342128ba975013f63 100644
--- a/libIRDB/test/fill_in_indtargs.cpp
+++ b/libIRDB/test/fill_in_indtargs.cpp
@@ -20,6 +20,7 @@
  */
 
 #include <libIRDB-core.hpp>
+#include <libIRDB-util.hpp>
 #include <iostream>
 #include <fstream>
 #include <limits>
@@ -281,6 +282,7 @@ void mark_targets(FileIR_t *firp)
 }
 
 
+#ifdef MOMVED
 bool IsParameterWrite(FileIR_t *firp,Instruction_t* insn, string& output_dst)
 {
 	DISASM d;
@@ -347,6 +349,7 @@ bool IsParameterWrite(FileIR_t *firp,Instruction_t* insn, string& output_dst)
 	// return we didn't find a memory of the right type
 	return false;
 }
+#endif
 
 
 bool CallToPrintfFollows(FileIR_t *firp, Instruction_t* insn, const string& arg_str)