Skip to content
Snippets Groups Projects
scfi_driver.cpp 5.99 KiB
/*
 * 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 <fstream>
#include <libIRDB-core.hpp>
#include <libgen.h>

#include "scfi_instr.hpp"

using namespace std;
using namespace libIRDB;


#define BINARY_NAME "a.ncexe"
#define SHARED_OBJECTS_DIR "shared_objects"


void usage(char* name)
{
	cerr<<" Usage: "<<name<<" <variant_id>  \n"
"		[--color|--no-color]  \n"
"		[--protect-jumps|--no-protect-jumps]  \n"
"		[--protect-calls|--no-protect-calls]  \n"
"		[--protect-rets|--no-protect-rets] \n"
"		[--protect-safefn|--no-protect-safefn]  \n"
"		[ --common-slow-path | --no-common-slow-path ] \n"
"		[ --multimodule | --no-multimodule ] \n"
"		[--exe-nonce-for-call|--no-exe-nonce-for-call]  \n"
" \n"
"default: --no-color --protect-jumps --protect-calls --protect-rets --protect-safefn --common-slow-path --no-multimodule --no-exe-nonce-for-call\n"; 
}

int main(int argc, char **argv)
{
        if(argc < 2)
        {
                usage(argv[0]);
                exit(1);
        }

#if 0
// CFI step is asserting with error message if a call is found.
	if(!getenv("FIX_CALLS_FIX_ALL_CALLS"))
	{
		cerr<<"FIX_CALLS_FIX_ALL_CALLS should be set."<<endl;
                exit(1);
	}
#endif

	bool do_coloring=false;
	bool do_common_slow_path=true;
	bool do_jumps=false;
	bool do_calls=true;
	bool do_rets=true;
	bool do_safefn=true;
	bool do_multimodule=false;
	bool do_exe_nonce_for_call=false;
	for(int  i=2;i<argc;i++)
	{
		if(string(argv[i])=="--color")
		{
			cout<<"Using coloring..."<<endl;
			do_coloring=true;
		}
		else if(string(argv[i])=="--no-color")
		{
			cout<<"Not using coloring..."<<endl;
			do_coloring=false;
		}
		else if(string(argv[i])=="--protect-calls")
		{
			cout<<"protecting calls..."<<endl;
			do_calls=true;
		}
		else if(string(argv[i])=="--no-protect-calls")
		{
			cout<<"Not protecting calls..."<<endl;
			do_calls=false;
		}
		else if(string(argv[i])=="--protect-jumps")
		{
			cout<<"protecting jumps..."<<endl;
			do_jumps=true;
		}
		else if(string(argv[i])=="--no-protect-jumps")
		{
			cout<<"Not protecting jumps..."<<endl;
			do_jumps=false;
		}
		else if(string(argv[i])=="--protect-rets")
		{
			cout<<"protecting returns..."<<endl;
			do_rets=true;
		}
		else if(string(argv[i])=="--no-protect-rets")
		{
			cout<<"Not protecting returns..."<<endl;
			do_rets=false;
		}
		else if(string(argv[i])=="--protect-safefn")
		{
			cout<<"protecting safe functions..."<<endl;
			do_safefn=true;
		}
		else if(string(argv[i])=="--no-protect-safefn")
		{
			cout<<"Not protecting safe functions..."<<endl;
			do_safefn=false;
		}
		else if(string(argv[i])=="--no-multimodule")
		{
			cout<<"Not adding multimodule support..."<<endl;
			do_multimodule=false;
		}
		else if(string(argv[i])=="--multimodule")
		{
			cout<<"Adding multimodule support ..."<<endl;
			do_multimodule=true;
		}
		else if(string(argv[i])=="--no-exe-nonce-for-call")
		{
			cout<<"Not adding exe-nonce-for-call support..."<<endl;
			do_exe_nonce_for_call=false;
		}
		else if(string(argv[i])=="--exe-nonce-for-call")
		{
			cout<<"Adding exe-nonce-for-call support ..."<<endl;
			do_exe_nonce_for_call=true;
		}
		else if(string(argv[i])=="--common-slow-path")
		{
			cout<<"Using common slow path..."<<endl;
			do_common_slow_path=true;
		}
		else if(string(argv[i])=="--no-common-slow-path")
		{
			cout<<"Not using common slow path..."<<endl;
			do_common_slow_path=false;
		}
		else
		{
			cerr<<"Unknown option: "<< argv[i] << endl;
			usage(argv[0]);
			exit(1);
		}
	}

        string programName(argv[0]);
        int variantID = atoi(argv[1]);

        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<<"selective_cfi.exe started\n";

        bool one_success = false;
        for(set<File_t*>::iterator it=pidp->GetFiles().begin();
            it!=pidp->GetFiles().end();
                ++it)
        {
                File_t* this_file = *it;
                FileIR_t *firp = new FileIR_t(*pidp, this_file);

		cout<<"Transforming "<<this_file->GetURL()<<endl;

                assert(firp && pidp);

                try
                {
			SCFI_Instrument scfii(firp, do_coloring, do_common_slow_path, do_jumps, do_calls, do_rets, do_safefn, do_multimodule, do_exe_nonce_for_call);


			int success=scfii.execute();

                        if (success)
                        {
				cout<<"Writing changes for "<<this_file->GetURL()<<endl;
                                one_success = true;
                                firp->WriteToDB();
                                delete firp;
                        }
			else
			{
				cout<<"Skipping (no changes) "<<this_file->GetURL()<<endl;
			}
                }
                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;
}