diff --git a/tools/c2e/c2e_driver.cpp b/tools/c2e/c2e_driver.cpp index 5af975a6048bd5229c768a051932b022fd86e073..40446e4a54dca26f6bdd59efe357239ef1f1088e 100644 --- a/tools/c2e/c2e_driver.cpp +++ b/tools/c2e/c2e_driver.cpp @@ -12,6 +12,10 @@ using namespace libIRDB; #define BINARY_NAME "a.ncexe" #define SHARED_OBJECTS_DIR "shared_objects" +// @todo: make these command line options +bool forceExitOnReadEOF = true; // cleanly terminate when EOF encountered +bool forceReadFromStdin = true; // force all reads from fd 0 +bool forceWriteToStdout = true; // force all reads from fd 0 void usage(char* name) { @@ -55,7 +59,9 @@ int main(int argc, char **argv) try { Cgc2Elf_Instrument c2ei(firp); - + c2ei.setForceReadFromStdin(forceReadFromStdin); + c2ei.setForceExitOnReadEOF(forceExitOnReadEOF); + c2ei.setForceWriteToStdout(forceWriteToStdout); int success= c2ei.execute(); diff --git a/tools/c2e/c2e_instr.cpp b/tools/c2e/c2e_instr.cpp index 0799038105c35d1f85c0d3018988e0ccfcd005a3..aadcb38605848064e081efc84f7b05d43523cb72 100644 --- a/tools/c2e/c2e_instr.cpp +++ b/tools/c2e/c2e_instr.cpp @@ -12,6 +12,7 @@ + using namespace std; using namespace libIRDB; @@ -206,15 +207,26 @@ Instruction_t* Cgc2Elf_Instrument::insertTerminate(Instruction_t* after) return after; } -Instruction_t* Cgc2Elf_Instrument::insertTransmit(Instruction_t* after, int sysno) +Instruction_t* Cgc2Elf_Instrument::insertTransmit(Instruction_t* after, int sysno, int force_fd) { Instruction_t *jmp2return=NULL, *jmp2error=NULL, *success=NULL, *error=NULL; + char fdbuf[100]; char buf[100]; sprintf(buf, "mov eax, %d", sysno); + if (force_fd >= 0) + { + sprintf(fdbuf, "mov ebx, %d", force_fd); + after=insertAssemblyAfter(firp, after, "push ebx"); // push old fd + after=insertAssemblyAfter(firp, after, fdbuf); // force fd + } after=insertAssemblyAfter(firp, after, "push esi"); // push tx_bytes after=insertAssemblyAfter(firp, after, buf); // set eax to syscall # after=insertAssemblyAfter(firp, after, "int 0x80"); // make syscall after=insertAssemblyAfter(firp, after, "pop esi"); // pop tx_bytes + if (force_fd >= 0) + { + after=insertAssemblyAfter(firp, after, "pop ebx"); // restore old fd + } after=insertAssemblyAfter(firp, after, "cmp eax, -1"); // if return == -1 jmp2error=after=insertAssemblyAfter(firp, after, "je 0x0"); // jmp to error after=insertAssemblyAfter(firp, after, "cmp esi, 0"); // if tx_bytes == 0 @@ -451,7 +463,6 @@ bool Cgc2Elf_Instrument::add_c2e_instrumentation(libIRDB::Instruction_t* insn) Instruction_t* old=insn; Instruction_t* failinsn=NULL; - old=insertAssemblyBefore(firp,tmp,"cmp eax, 1"); // terminate terminsn=tmp; termjmp=tmp=insertAssemblyAfter(firp,tmp,"jne 0"); @@ -459,11 +470,14 @@ bool Cgc2Elf_Instrument::add_c2e_instrumentation(libIRDB::Instruction_t* insn) tmp->SetFallthrough(old); transmitinsn=tmp=addNewAssembly(firp,NULL,"cmp eax, 2"); //transmit transmitjmp=tmp=insertAssemblyAfter(firp,tmp,"jne 0"); - tmp=insertTransmit(tmp); + if (getForceWriteToStdout()) + tmp=insertTransmit(tmp, SYS_write, getForceWriteFd()); // force output on fd=1 + else + tmp=insertTransmit(tmp); tmp->SetFallthrough(old); receiveinsn=tmp=addNewAssembly(firp,NULL,"cmp eax, 3"); //receive receivejmp=tmp=insertAssemblyAfter(firp,tmp,"jne 0"); - tmp=insertReceive(tmp); + tmp=insertReceive(tmp, getForceReadFromStdin(), getForceExitOnReadEOF()); tmp->SetFallthrough(old); fdwaitinsn=tmp=addNewAssembly(firp,NULL,"cmp eax, 4"); //fdwait fdwaitjmp=tmp=insertAssemblyAfter(firp,tmp,"jne 0"); diff --git a/tools/c2e/c2e_instr.hpp b/tools/c2e/c2e_instr.hpp index de9782e21bfb591b67c8db483670fee6e9cd8176..2d42b09af02b488cdc7f82cbbf5f2d6d850bc683 100644 --- a/tools/c2e/c2e_instr.hpp +++ b/tools/c2e/c2e_instr.hpp @@ -10,13 +10,27 @@ class Cgc2Elf_Instrument { public: - Cgc2Elf_Instrument(libIRDB::FileIR_t *the_firp) : firp(the_firp) {} + Cgc2Elf_Instrument(libIRDB::FileIR_t *the_firp) : firp(the_firp) { + forceReadFromStdin = false; + forceExitOnReadEOF = false; + forceWriteToStdout = false; + forceWriteFd = -1; + } bool execute(); + void setForceReadFromStdin(bool force) { forceReadFromStdin = force; } + void setForceExitOnReadEOF(bool force) { forceExitOnReadEOF = force; } + void setForceWriteToStdout(bool force, int fd = 1) { forceWriteToStdout = force; forceWriteFd = fd; } + + bool getForceReadFromStdin() const { return forceReadFromStdin; } + bool getForceExitOnReadEOF() const { return forceExitOnReadEOF; } + bool getForceWriteToStdout() const { return forceWriteToStdout; } + int getForceWriteFd() const { return forceWriteFd; } + private: libIRDB::Instruction_t* insertTerminate(libIRDB::Instruction_t* after) ; - libIRDB::Instruction_t* insertTransmit(libIRDB::Instruction_t* after, int sysno=SYS_write); + libIRDB::Instruction_t* insertTransmit(libIRDB::Instruction_t* after, int sysno=SYS_write, int force_fd=-1); libIRDB::Instruction_t* insertReadExitOnEOF(libIRDB::Instruction_t* after); libIRDB::Instruction_t* insertReceive(libIRDB::Instruction_t* after, bool force_stdin=true, bool forceExitOnEOF=true) ; libIRDB::Instruction_t* insertFdwait(libIRDB::Instruction_t* after) ; @@ -33,6 +47,10 @@ class Cgc2Elf_Instrument libIRDB::FileIR_t* firp; + bool forceReadFromStdin; + bool forceExitOnReadEOF; + bool forceWriteToStdout; + int forceWriteFd; };