Skip to content
Snippets Groups Projects
Commit da2b4f0b authored by dnguyen's avatar dnguyen
Browse files

plugin to rewrite calls to random() syscall with configurable sequence

Former-commit-id: 20718dbccf5345c98b4ef5ce719c53c43ed8ae95
parent 4886c09c
No related branches found
No related tags found
No related merge requests found
......@@ -561,6 +561,10 @@ tools/cgc_hlx/cgc_hlx.hpp -text
tools/cgc_hlx/cgc_hlx_driver.cpp -text
tools/cgc_protect/cgc_protect_one.sh -text
tools/cgc_protect/pov_to_cso.sh -text
tools/cgc_rigrandom/Makefile.in -text
tools/cgc_rigrandom/rigrandom_driver.cpp -text
tools/cgc_rigrandom/rigrandom_instr.cpp -text
tools/cgc_rigrandom/rigrandom_instr.hpp -text
tools/cgclibc/Makefile -text
tools/cgclibc/README -text
tools/cgclibc/cgclibc.cpp -text
......
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)
LIBS=-L../../lib -lxform -lIRDB-core -lIRDB-cfg -lBeaEngine_s_d -lpqxx -lMEDSannotation -ltransform ../transforms/Rewrite_Utility.o -lpq
OBJS=rigrandom_driver.o rigrandom_instr.o
programs=rigrandom.exe
.SUFFIXES: .o .c .exe .cpp .hpp
all: $(programs)
@echo "-----------------------------------"
@echo "- cgc_rigrandom directory -- Build complete -"
@echo "-----------------------------------"
-include $(OBJS:.o=.d)
%.o: %.cpp
$(CXX) -c $(CXXFLAGS) $*.cpp
@#
@# build dependencies -- http://scottmcpeak.com/autodepend/autodepend.html
@#
@cpp -MM $(CXXFLAGS) $*.cpp > $*.d 2> /dev/null || true # might fail on solaris with CXX=sun's CC.
@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
$(programs): $(OBJS)
$(CXX) $(CXXFLAGS) $^ $(INCLUDE) $(LIBS) -o $@
cp $@ ${SECURITY_TRANSFORMS_HOME}/plugins_install/
#include <stdlib.h>
#include <fstream>
#include <libIRDB-core.hpp>
#include <libgen.h>
#include "rigrandom_instr.hpp"
using namespace std;
using namespace libIRDB;
void usage(char* name)
{
cerr<<"Usage: " << name << " <variant_id> <random_byte>\n";
}
int main(int argc, char **argv)
{
if (argc != 3)
{
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 << argv[0] << " started with 'random' byte " << argv[2][0] << "\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
{
RigRandom_Instrument rri(firp, argv[2][0]);
int success = rri.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;
}
#include "utils.hpp"
#include "rigrandom_instr.hpp"
#include "Rewrite_Utility.hpp"
#include <stdlib.h>
#include <sstream>
using namespace std;
using namespace libIRDB;
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;
}
Instruction_t* RigRandom_Instrument::insertRandom(Instruction_t* after)
{
/*
d: 85 d2 test %ecx,%ecx
J1: 7e 11 jle L4
11: b8 00 00 00 00 mov $0x0,%eax
L3: 88 04 01 mov [%ebx+%eax*1], 0x41 (or passed-in value)
19: 83 c0 01 add $0x1,%eax
1c: 39 d0 cmp %ecx,%eax
J2: 75 f6 jne L3
20: eb 05 jmp L2
L4: ba 00 00 00 00 mov $0x0,%ecx
L2: 85 db test %edx,%edx
J3: 74 02 je L1
2b: 89 13 mov %ecx,(%edx)
L1: b8 00 00 00 00 mov $0x0,%eax
*/
Instruction_t *J1=NULL, *J2=NULL, *J3=NULL, *L1=NULL, *L2=NULL, *L3=NULL, *L4=NULL;
after=insertAssemblyAfter(firp, after, "test ecx, ecx");
J1=after=insertAssemblyAfter(firp, after, "jle 0x0");
after=insertAssemblyAfter(firp, after, "mov eax, 0");
// user-selected random sequence
stringstream ss;
ss << "mov [ebx+eax], byte 0x" << std::hex << (int) random_start << std::dec;
L3=after=insertAssemblyAfter(firp, after, ss.str().c_str());
after=insertAssemblyAfter(firp, after, "add eax, 1");
after=insertAssemblyAfter(firp, after, "cmp eax, ecx");
J2=after=insertAssemblyAfter(firp, after, "jne 0x0");
L4=after=insertAssemblyAfter(firp, after, "mov ecx, 0");
L2=after=insertAssemblyAfter(firp, after, "test edx, edx");
J3=after=insertAssemblyAfter(firp, after, "je 0x0");
after=insertAssemblyAfter(firp, after, "mov [edx], ecx");
L1=after=insertAssemblyAfter(firp, after, "mov eax, 0");
J1->SetTarget(L4);
J2->SetTarget(L3);
J2->SetFallthrough(L2);
J3->SetTarget(L1);
return after;
}
bool RigRandom_Instrument::add_rr_instrumentation(libIRDB::Instruction_t* insn)
{
assert(insn);
cout<<"Adding CGC->Elf instrumentation for "<<insn->GetBaseID()<<":"<<insn->getDisassembly()<<endl;
Instruction_t* tmp=insn;
Instruction_t* randomjmp=NULL, *randominsn=NULL;
Instruction_t* old=insn;
Instruction_t* failinsn=NULL;
old=insertAssemblyBefore(firp,tmp,"cmp eax, 7"); // terminate
randominsn=tmp;
randomjmp=tmp=insertAssemblyAfter(firp,tmp,"jne 0");
tmp=insertRandom(tmp);
tmp->SetFallthrough(old);
failinsn=tmp=addNewAssembly(firp,NULL,"mov eax, 13"); // fail
failinsn->SetFallthrough(old);
randomjmp->SetTarget(failinsn);
// nop
string bits;
bits.resize(1);
bits[0]=0x90;
old->SetDataBits(bits);
}
bool RigRandom_Instrument::needs_rr_instrumentation(libIRDB::Instruction_t* insn)
{
// instrument int instructions
DISASM d;
insn->Disassemble(d);
return strstr(d.CompleteInstr,"int")!=0;
}
bool RigRandom_Instrument::instrument_ints()
{
bool success=true;
// only instrument syscall to random
bool eax_7=false;
for(InstructionSet_t::iterator it=firp->GetInstructions().begin();
it!=firp->GetInstructions().end();
++it)
{
Instruction_t* insn=*it;
DISASM d;
insn->Disassemble(d);
if (strstr(d.Instruction.Mnemonic,"mov") != 0 &&
strstr(d.Argument1.ArgMnemonic, "eax") != 0 &&
strstr(d.Argument2.ArgMnemonic, "00000007") != 0)
eax_7 = true;
if (eax_7 && strstr(d.CompleteInstr,"int") != 0)
{
success = success && add_rr_instrumentation(insn);
eax_7 = false;
}
}
return success;
}
bool RigRandom_Instrument::execute()
{
bool success=true;
success = success && instrument_ints();
return success;
}
#ifndef rigrandom_instrument_hpp
#define rigrandom_instrument_hpp
#include <libIRDB-core.hpp>
#include <syscall.h>
class RigRandom_Instrument
{
public:
RigRandom_Instrument(libIRDB::FileIR_t *the_firp, char random_start='A') : firp(the_firp), random_start(random_start) {}
bool execute();
private:
libIRDB::Instruction_t* insertRandom(libIRDB::Instruction_t* after) ;
bool add_rr_instrumentation(libIRDB::Instruction_t* insn);
bool needs_rr_instrumentation(libIRDB::Instruction_t* insn);
bool instrument_ints();
libIRDB::FileIR_t* firp;
char random_start;
};
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment