diff --git a/.gitattributes b/.gitattributes
index e77d24f3ce9b03ae1ee346ae4572d99da07ce1a5..2e88f925e0e6be09a787ec70c8178630301e7dd9 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -976,6 +976,11 @@ tools/c2e/SConstruct -text
 tools/c2e/c2e_driver.cpp -text
 tools/c2e/c2e_instr.cpp -text
 tools/c2e/c2e_instr.hpp -text
+tools/cgc_buffrecv/SConscript -text
+tools/cgc_buffrecv/SConstruct -text
+tools/cgc_buffrecv/buffrecv_driver.cpp -text
+tools/cgc_buffrecv/buffrecv_instrument.cpp -text
+tools/cgc_buffrecv/buffrecv_instrument.hpp -text
 tools/cgc_hlx/Makefile.in -text
 tools/cgc_hlx/SConscript -text
 tools/cgc_hlx/SConstruct -text
diff --git a/tools/cgc_buffrecv/SConscript b/tools/cgc_buffrecv/SConscript
new file mode 100644
index 0000000000000000000000000000000000000000..5c1c4e03072c5438adb185c7b43dea11df4c0987
--- /dev/null
+++ b/tools/cgc_buffrecv/SConscript
@@ -0,0 +1,33 @@
+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/libIRDB/include 
+	 $SECURITY_TRANSFORMS_HOME/libMEDSannotation/include 
+	 $SECURITY_TRANSFORMS_HOME/beaengine/include 
+	 $SECURITY_TRANSFORMS_HOME/tools/transforms 
+	'''
+
+myenv.Append(CCFLAGS=" -DCGC")
+
+files=Glob( Dir('.').srcnode().abspath+"/*.cpp")
+
+
+pgm="buffrecv.exe"
+
+LIBPATH="$SECURITY_TRANSFORMS_HOME/lib"
+LIBS=Split( env.subst('$BASE_IRDB_LIBS')+ " IRDB-cfg IRDB-syscall IRDB-util transform rewrite MEDSannotation ") 
+myenv=myenv.Clone(CPPPATH=Split(cpppath))
+pgm=myenv.Program(pgm,  files,  LIBPATH=LIBPATH, LIBS=LIBS)
+install=myenv.Install("$SECURITY_TRANSFORMS_HOME/bin/", pgm)
+myenv.Alias("install", "$SECURITY_TRANSFORMS_HOME/bin/")
+Default(install)
+
+
+
diff --git a/tools/cgc_buffrecv/SConstruct b/tools/cgc_buffrecv/SConstruct
new file mode 100644
index 0000000000000000000000000000000000000000..c96332f0422ad5df0853931209219d9a2e20bc17
--- /dev/null
+++ b/tools/cgc_buffrecv/SConstruct
@@ -0,0 +1,6 @@
+
+
+
+env=Environment()
+Export('env')
+lib=SConscript("SConscript")
diff --git a/tools/cgc_buffrecv/buffrecv_driver.cpp b/tools/cgc_buffrecv/buffrecv_driver.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ca7a75ea43dab384e3dcdd072f11a0df77cc151a
--- /dev/null
+++ b/tools/cgc_buffrecv/buffrecv_driver.cpp
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 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 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <fstream>
+#include <libgen.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#include <libIRDB-core.hpp>
+#include "buffrecv_instrument.hpp"
+
+using namespace std;
+using namespace libIRDB;
+
+void usage(char* name)
+{
+	cerr<<"Usage: "<<name<<" --varid=<variant_id>\n"; 
+}
+
+
+int varid=0;
+
+int parse_args(int p_argc, char* p_argv[])
+{
+	int option = 0;
+	char options[] = "v:";
+	struct option long_options[] = {
+		{"varid", required_argument, NULL, 'v'},
+		{NULL, no_argument, NULL, '\0'},         // end-of-array marker
+	};
+
+	while ((option = getopt_long(
+		p_argc,
+		p_argv,
+		options,
+		long_options,
+		NULL)) != -1)
+	{
+		printf("Found option %c\n", option);
+		switch (option)
+		{
+			case 'v':
+			{
+				varid=atoi(::optarg);	
+				cout<<"Transforming variant "<<dec<<varid<<endl;
+				break;
+			}
+			default:
+				return 1;
+		}
+	}
+	return 0;
+}
+
+
+int main(int argc, char **argv)
+{
+	if(0 != parse_args(argc,argv))
+	{
+		usage(argv[0]);
+		exit(1);
+	}
+
+	string programName(argv[0]);
+	int variantID = varid;
+
+	VariantID_t *pidp=NULL;
+
+	/* setup the interface to the sql server */
+	pqxxDB_t pqxx_interface;
+	BaseObj_t::SetInterface(&pqxx_interface);
+
+	pidp=new VariantID_t(variantID);
+	assert(pidp->IsRegistered()==true);
+
+	cout << argv[0] << " started\n";
+
+	bool success = false;
+	bool one_success = false;
+	bool one_fail=false;
+
+	for(set<File_t*>::iterator it=pidp->GetFiles().begin();
+		it!=pidp->GetFiles().end();
+		++it)
+	{
+		File_t* this_file = *it;
+		try
+		{
+			FileIR_t *firp = new FileIR_t(*pidp, this_file);
+	
+			cout<<"Transforming "<<this_file->GetURL()<<endl;
+	
+			assert(firp && pidp);
+
+			BuffRecv_Instrument wsci(firp);
+
+			success = wsci.execute();
+
+			if (success)
+			{	
+				cout<<"Writing changes for "<<this_file->GetURL()<<endl;
+				one_success = true;
+	
+				firp->WriteToDB();
+			}
+			else
+			{
+				one_fail=true;
+				cout<<"Skipping (no changes) "<<this_file->GetURL()<<endl;
+			}
+
+			delete firp;
+		}
+		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 transforms for any files succeeded, we commit
+	if (one_success)
+	{
+		cout<<"Commiting changes...\n";
+		pqxx_interface.Commit();
+	}
+
+	return one_fail;
+}
+
diff --git a/tools/cgc_buffrecv/buffrecv_instrument.cpp b/tools/cgc_buffrecv/buffrecv_instrument.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..81b4c33d2619268dbcc50ed1ba0e374891088b8b
--- /dev/null
+++ b/tools/cgc_buffrecv/buffrecv_instrument.cpp
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 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 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string>
+#include <iostream>
+
+#include "buffrecv_instrument.hpp"
+#include "Rewrite_Utility.hpp"
+
+
+using namespace std;
+using namespace libIRDB;
+
+virtual_offset_t getAvailableAddress(FileIR_t *p_virp)
+{
+        static int counter = -16;
+        counter += 16;
+        return 0xf0080000 + counter;
+}
+
+static Instruction_t* 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,BaseObj_t::NOT_IN_DATABASE, NULL);
+
+        firp->RegisterAssembly(newinstr, p_asm);
+
+        if (p_instr)
+        {
+                newinstr->SetFallthrough(p_instr->GetFallthrough());
+                p_instr->SetFallthrough(newinstr);
+        }
+
+        return newinstr;
+}
+
+// site should be: int 0x80 instruction in receive() wrapper
+bool BuffRecv_Instrument::_add_buffered_receive_instrumentation(Instruction_t *site)
+{
+        string bits;
+        bits.resize(1);
+        bits[0]=0x90;
+        site->SetDataBits(bits);	 // convert site to nop instruction
+
+//cout<<"Found syscall to instrument "<<site->getDisassembly()<<endl;
+
+        virtual_offset_t postCallbackReturn = getAvailableAddress(firp);
+	char tmpbuf[100];
+        sprintf(tmpbuf,"push  0x%x", postCallbackReturn);
+
+	Instruction_t *tmp=site, *callback=NULL, *post_callback=NULL;
+        tmp=insertAssemblyAfter(firp,tmp,"pushf");
+        tmp=insertAssemblyAfter(firp,tmp,"pusha");
+        tmp=insertAssemblyAfter(firp,tmp,tmpbuf);	 // push <ret addr>
+        callback=tmp=insertAssemblyAfter(firp,tmp,"nop");
+        post_callback=tmp=insertAssemblyAfter(firp,tmp,"popa");
+        tmp=insertAssemblyAfter(firp,tmp,"popf");
+        tmp=insertAssemblyAfter(firp,tmp,"mov eax, 0");
+        post_callback->GetAddress()->SetVirtualOffset(postCallbackReturn);
+	callback->SetCallback("buffered_receive");
+	return true;
+}
+
+bool BuffRecv_Instrument::add_buffered_receive_instrumentation()
+{
+
+	bool success=true;
+
+	for(SyscallSiteSet_t::iterator it=syscalls.GetSyscalls().begin();
+		it!=syscalls.GetSyscalls().end();
+		++it)
+	{
+		SyscallSite_t ss=*it;
+		Instruction_t *site=ss.GetSyscallSite();
+		SyscallNumber_t num=ss.GetSyscallNumber();
+		if(num==SNT_receive) 
+		{
+			cout << "Found RECEIVE syscall - @todo: implement: " << site->getDisassembly() << " " << hex << site->GetAddress()->GetVirtualOffset() << dec << endl;
+//			success = success && add_buffered_receive_instrumentation(site);
+		}
+	}
+
+	/* return an exit code */
+	return success; /* success? */
+}
+
+
+static const ARGTYPE* FindMemoryArgument(const DISASM &d)
+{
+	 if((d.Argument1.ArgType & MEMORY_TYPE) == MEMORY_TYPE)
+		return &d.Argument1;
+	 if((d.Argument2.ArgType & MEMORY_TYPE) == MEMORY_TYPE)
+		return &d.Argument2;
+	 if((d.Argument3.ArgType & MEMORY_TYPE) == MEMORY_TYPE)
+		return &d.Argument3;
+	 if((d.Argument4.ArgType & MEMORY_TYPE) == MEMORY_TYPE)
+		return &d.Argument4;
+
+	return NULL;
+}
+
+
+static string get_memory_addr(const DISASM& d)
+{
+	string s=d.CompleteInstr;
+	size_t pos=s.find('[');
+
+	assert(pos!=string::npos);
+
+	s.replace(0,pos-1,"");
+
+	pos=s.find(']');
+	s.replace(pos+1,s.length(),"");
+
+	return s;
+}
+
+static bool has_index_register(Instruction_t* i)
+{
+	DISASM d;
+	i->Disassemble(d);
+	const ARGTYPE* arg=FindMemoryArgument(d);
+
+	if(!arg)
+		return false;
+
+	if(arg->Memory.Scale)
+		return true;
+	return false;
+	
+}
+
+static string regToRegstring(size_t regno)
+{
+	switch(regno)
+	{
+		case REG0: return "eax";
+		case REG1: return "ecx";
+		case REG2: return "edx";
+		case REG3: return "ebx";
+		case REG4: return "esp";
+		case REG5: return "ebp";
+		case REG6: return "esi";
+		case REG7: return "edi";
+		default: assert(0);
+	}
+}
+
+std::ostream& BuffRecv_Instrument::displayStatistics(std::ostream &os)
+{
+}
+
+bool BuffRecv_Instrument::execute()
+{
+	bool success=true;
+
+	success = success && add_buffered_receive_instrumentation();
+
+	return success;
+}
+
+
diff --git a/tools/cgc_buffrecv/buffrecv_instrument.hpp b/tools/cgc_buffrecv/buffrecv_instrument.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..20353d44e15216e337701d63d20f61bbd609ed43
--- /dev/null
+++ b/tools/cgc_buffrecv/buffrecv_instrument.hpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 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 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.
+ *
+ */
+
+#ifndef buffrecv_instrument_hpp
+#define buffrecv_instrument_hpp
+
+#include <libIRDB-core.hpp>
+#include <libIRDB-util.hpp>
+#include <libIRDB-syscall.hpp>
+
+#include "elfio/elfio.hpp"
+#include "elfio/elfio_dump.hpp"
+
+class BuffRecv_Instrument
+{
+	public:
+		BuffRecv_Instrument(libIRDB::FileIR_t *the_firp) : firp(the_firp), syscalls(firp)
+		{
+                        int elfoid=firp->GetFile()->GetELFOID();
+                        pqxx::largeobject lo(elfoid);
+			libIRDB::pqxxDB_t *interface=dynamic_cast<libIRDB::pqxxDB_t*>(libIRDB::BaseObj_t::GetInterface());
+			assert(interface);
+                        lo.to_file(interface->GetTransaction(),"readeh_tmp_file.exe");
+
+                        elfiop=new ELFIO::elfio;
+                        elfiop->load("readeh_tmp_file.exe");
+                        ELFIO::dump::header(std::cout,*elfiop);
+                        ELFIO::dump::section_headers(std::cout,*elfiop);
+                        ELFIO::dump::segment_headers(std::cout,*elfiop);
+		} 
+		virtual ~BuffRecv_Instrument() { delete elfiop; }
+		bool execute();
+
+	private:
+		// main tasks
+		bool _add_buffered_receive_instrumentation(libIRDB::Instruction_t *site);
+		bool add_buffered_receive_instrumentation();
+		std::ostream& displayStatistics(std::ostream &os);
+
+	private:
+		libIRDB::FileIR_t* firp;
+		libIRDB::Syscalls_t syscalls;
+		ELFIO::elfio*    elfiop;
+};
+
+#endif
+