From ac13ebc803c4ca1fa32887500fe2fe4cb520f690 Mon Sep 17 00:00:00 2001 From: Jason Hiser <jdhiser@gmail.com> Date: Mon, 16 Dec 2019 13:48:56 -0500 Subject: [PATCH] some fixups for windows pgms --- src/cmdstr.hpp | 88 +++++++++++++++++++++++++++++++++++++++++++++++++ src/ehwrite.cpp | 3 +- src/pewrite.cpp | 7 ++-- src/zipr.cpp | 21 +++++++----- 4 files changed, 107 insertions(+), 12 deletions(-) create mode 100644 src/cmdstr.hpp diff --git a/src/cmdstr.hpp b/src/cmdstr.hpp new file mode 100644 index 000000000..48d67c5e5 --- /dev/null +++ b/src/cmdstr.hpp @@ -0,0 +1,88 @@ +#ifndef cmdstr_hpp +#define cmdstr_hpp + +/*BINFMTCXX: -std=c++11 -Wall -Werror +*/ + +#include <spawn.h> // see manpages-posix-dev +#include <poll.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/wait.h> +#include <iostream> +#include <string> +#include <vector> +using namespace std; + + +static inline pair<string,int> command_to_string( const string& command) +{ + auto ret=string(); + int exit_code=0; + int cout_pipe[2]; + int cerr_pipe[2]; + posix_spawn_file_actions_t action; + + if(pipe(cout_pipe) || pipe(cerr_pipe)) + cout << "pipe returned an error.\n"; + + posix_spawn_file_actions_init(&action); + posix_spawn_file_actions_addclose(&action, cout_pipe[0]); + posix_spawn_file_actions_addclose(&action, cerr_pipe[0]); + posix_spawn_file_actions_adddup2(&action, cout_pipe[1], 1); + posix_spawn_file_actions_adddup2(&action, cerr_pipe[1], 2); + + posix_spawn_file_actions_addclose(&action, cout_pipe[1]); + posix_spawn_file_actions_addclose(&action, cerr_pipe[1]); + + // string command = "echo bla"; // example #1 + // string command = "pgmcrater -width 64 -height 9 |pgmtopbm |pnmtoplainpnm"; + vector<char> argsmem[] = {{'s', 'h', '\0'}, {'-', 'c', '\0'}}; // allows non-const access to literals + char *args[] = {&argsmem[0][0], &argsmem[1][0],const_cast<char*>(command.c_str()),nullptr}; + + pid_t pid; + if(posix_spawnp(&pid, args[0], &action, NULL, args, environ) != 0) + cout << "posix_spawnp failed with error: " << strerror(errno) << "\n"; + + close(cout_pipe[1]), close(cerr_pipe[1]); // close child-side of pipes + + // Read from pipes + string buffer(1024,' '); + std::vector<pollfd> plist = { {cout_pipe[0],POLLIN}, {cerr_pipe[0],POLLIN} }; + for ( int rval; (rval=poll(&plist[0],plist.size(),/*timeout*/-1))>0; ) + { + if ( plist[0].revents&POLLIN) { + const auto bytes_read = read(cout_pipe[0], &buffer[0], buffer.length()); + // cout << "read " << bytes_read << " bytes from stdout.\n"; + // cout << buffer.substr(0, static_cast<size_t>(bytes_read)) << "\n"; + ret += buffer.substr(0, static_cast<size_t>(bytes_read)); + } + else if ( plist[1].revents&POLLIN ) { + const auto bytes_read = read(cerr_pipe[0], &buffer[0], buffer.length()); + // cout << "read " << bytes_read << " bytes from stderr.\n"; + // cout << buffer.substr(0, static_cast<size_t>(bytes_read)) << "\n"; + ret += buffer.substr(0, static_cast<size_t>(bytes_read)); + } + else + break; // nothing left to read + } + + waitpid(pid,&exit_code,0); + cout << "exit code: " << exit_code << "\n"; + + posix_spawn_file_actions_destroy(&action); + return {ret,exit_code}; +} + +static inline int command_to_stream(const string& command, ostream& stream) +{ + cout << "Issuing command: " << command << endl; + const auto res = command_to_string(command); + + stream << res.first << endl; + return res.second; +} + +#endif diff --git a/src/ehwrite.cpp b/src/ehwrite.cpp index 331461d2c..2a00872e5 100644 --- a/src/ehwrite.cpp +++ b/src/ehwrite.cpp @@ -17,6 +17,7 @@ #include <zipr_dwarf2.hpp> #include "exeio.h" +#include "cmdstr.hpp" using namespace IRDB_SDK; using namespace std; @@ -1506,7 +1507,7 @@ void ElfEhWriter_t<ptrsize>::CompileEhOutput() // create and execute the command to build the ehframe. auto cmd=(string)"$PEASOUP_HOME/tools/eh_frame_tools/eh_to_bin.sh "+ehframe_s_filename+" "+eh_frame_hdr_addr_str+" "+ehframe_exe_filename; cout << "Running: " << cmd << endl; - auto res=system(cmd.c_str()); + auto res=command_to_stream(cmd,cout); // system(cmd.c_str()); // err check. if( res==-1 || WEXITSTATUS(res)!=0 ) diff --git a/src/pewrite.cpp b/src/pewrite.cpp index 5a5b9b147..4c72dc4a6 100644 --- a/src/pewrite.cpp +++ b/src/pewrite.cpp @@ -87,8 +87,9 @@ void PeWriter<width,uintMa_t>::InitHeaders() assert(pebliss); const auto orig_file_full_headers_str = pebliss -> get_full_headers_data(); - const auto orig_file_full_headres_cstr = orig_file_full_headers_str.c_str(); - const auto orig_file_standard_coff_header = (standard_coff_header_t*)(orig_file_full_headres_cstr+sizeof(dos_header)+sizeof(coff_header_t)); + const auto orig_file_full_headers_cstr = orig_file_full_headers_str.c_str(); + const auto coff_header_offset = *reinterpret_cast<const uint32_t*>(orig_file_full_headers_cstr + 0x3c); // coff header at header ptr at 0x3c + const auto orig_file_standard_coff_header = (standard_coff_header_t*)(orig_file_full_headers_cstr+coff_header_offset+sizeof(coff_header_t)); // calculate the total size (last-first), rounded to page boundaries so that the OS can allocate that much virtual memory // for this object. @@ -146,7 +147,7 @@ void PeWriter<width,uintMa_t>::InitHeaders() (uint32_t)image_size, // sizeof_image in memory (not including headers?) 0x1000, // sizeof_headers (OK to over estimate?) 0, // checksum ?? need to fix later - 3, // subsystem ?? read from input file? + pebliss->get_subsystem(), // subsystem ?? read from input file? pebliss->get_dll_characteristics(), // dll_characteristics uintMa_t(pebliss->get_stack_size_reserve_64()), // sizeof_stack_reserve uintMa_t(pebliss->get_stack_size_commit_64 ()), // sizeof_stack_commit diff --git a/src/zipr.cpp b/src/zipr.cpp index 14bfdc5be..20f4b14e9 100644 --- a/src/zipr.cpp +++ b/src/zipr.cpp @@ -40,6 +40,7 @@ #include <iostream> // std::cout #include <string> // std::string, std::to_string #include <fstream> +#include "cmdstr.hpp" #define ALLOF(a) begin(a),end(a) @@ -1922,8 +1923,8 @@ void ZiprImpl_t::OutputBinaryFile(const string &name) ew.reset(nullptr); // explicitly free ew as we're done with it // change permissions on output file - auto chmod_cmd=string("chmod +x ")+output_filename; - auto res=system(chmod_cmd.c_str()); + const auto chmod_cmd=string("chmod +x ")+output_filename; + const auto res=command_to_stream(chmod_cmd,cout); assert(res!=-1); } @@ -2184,21 +2185,25 @@ void ZiprImpl_t::FixNoFallthroughs() void ZiprImpl_t::FixTwoByteWithPrefix() { + const auto is_x64 = m_firp->getArchitecture()->getMachineType() == admtX86_64; + const auto is_x32 = m_firp->getArchitecture()->getMachineType() == admtI386; + + if(!is_x64 && !is_x32) return; // only do this for x86 machines. + for(const auto insn : m_firp->getInstructions()) { const auto d=DecodedInstruction_t::factory(insn); - if(!d->isBranch()) continue; // skip non-branches - if(d->isReturn()) continue; // skip returns - if(d->getOperands().size()!=1) continue; // skip branches that have no operands or more than one + if(!d->isBranch()) continue; // skip non-branches + if(d->isReturn()) continue; // skip returns + if(d->getOperands().size()!=1) continue; // skip branches that have no operands or more than one if(!d->getOperand(0)->isConstant()) continue; // skip anything where the operand isn't a constant - if(d->getPrefixCount()==0) continue; // prevents arm instructions from being xformed. while (true) { - const auto b=insn->getDataBits()[0]; + const auto b=static_cast<uint8_t>(insn->getDataBits()[0]); // basic prefix check - const auto prefixes=set<uint8_t>({0x2e, 0x3e, 0x64, 0x65, 0xf2, 0xf3}); + const auto prefixes=set<uint8_t>({0x2e, 0x36, 0x3e, 0x26, 0x64, 0x65, 0x2e, 0x3e, 0xf0, 0xf2, 0xf3, 0x66, 0x67}); if(prefixes.find(b)!=end(prefixes)) { // remove prefix -- GitLab