Exemplo n.º 1
0
bool BPatch_binaryEdit::writeFile(const char * outFile)
{
    assert(pendingInsertions);

    // This should be a parameter...
    //bool atomic = false;

    // Define up here so we don't have gotos causing issues
    std::set<func_instance *> instrumentedFunctions;

    // Two loops: first addInst, then generate/install/link
    pdvector<miniTramp *> workDone;
    //bool err = false;

    // Iterate over our AddressSpaces, triggering relocation
    // in each one.
    std::vector<AddressSpace *> as;
    getAS(as);
    bool ret = true;

    /* PatchAPI stuffs */
    if (as.size() > 0) {
          ret = AddressSpace::patch(as[0]);
    }
    /* end of PatchAPI stuffs */


   // Now that we've instrumented we can see if we need to replace the
   // trap handler.
   replaceTrapHandler();

   for(std::map<std::string, BinaryEdit*>::iterator i = llBinEdits.begin();
       i != llBinEdits.end(); i++)
   {
      (*i).second->trapMapping.flush();
   }


   if( !origBinEdit->writeFile(outFile) ) return false;

   std::map<std::string, BinaryEdit *>::iterator curBinEdit;
   for (curBinEdit = llBinEdits.begin(); curBinEdit != llBinEdits.end(); curBinEdit++) {
     BinaryEdit *bin = (*curBinEdit).second;
     if (bin == origBinEdit)
       continue;
     if (!bin->isDirty())
       continue;

     std::string newname = bin->getMappedObject()->fileName();
     if( !bin->writeFile(newname) ) return false;
   }
   return ret;
}
Exemplo n.º 2
0
BPatch_variableExpr *BPatch_addressSpace::createVariable(
                        Dyninst::Address at_addr,
                        BPatch_type *type, std::string var_name,
                        BPatch_module *in_module)
{
   BPatch_binaryEdit *binEdit = dynamic_cast<BPatch_binaryEdit *>(this);
   if (binEdit && !in_module) {
      //Address alone isn't unique when binary rewriting
      return NULL;
   }
   if (!type) {
      //Required for size information.
      return NULL;
   }
   AddressSpace *ll_addressSpace = NULL;

   std::vector<AddressSpace *> as;
   getAS(as);
   if (binEdit) {
      std::vector<AddressSpace *>::iterator as_i;
      for (as_i = as.begin(); as_i != as.end(); as_i++)
      {
         BinaryEdit *b = dynamic_cast<BinaryEdit *>(*as_i);
         assert(b);
         if (in_module->mod->obj() == b->getMappedObject()) {
            ll_addressSpace = *as_i;
            break;
         }
      }
   }
   else {
      assert(as.size() == 1);
      ll_addressSpace = as[0];
   }

   if (!ll_addressSpace) {
      //in_module doesn't belong to 'this'
      return NULL;
   }

   if (!var_name.size()) {
      std::stringstream namestream;
      namestream << "dyninst_var_" << std::hex << at_addr;
      var_name = namestream.str();
   }

   return BPatch_variableExpr::makeVariableExpr(this, ll_addressSpace, var_name,
                                                (void *) at_addr, type);
}
Exemplo n.º 3
0
mapped_object *BinaryEdit::openResolvedLibraryName(std::string filename, std::map<std::string, BinaryEdit *> &allOpened) {
    /*
     * Note: this does not actually do any library name resolution, as that is OS-dependent
     * If resolution is required, it should be implemented in an OS-dependent file
     * (see linux.C for an example)
     *
     * However, this version allows the RT library to be opened with this function regardless
     * if library name resolution has been implemented on a platform.
     */
    std::map<std::string, BinaryEdit *> retMap;
    assert(mgr());
    BinaryEdit *temp = BinaryEdit::openFile(filename, mgr(), patcher());

    if( temp && temp->getAddressWidth() == getAddressWidth() ) {
       allOpened.insert(std::make_pair(filename, temp));
       return temp->getMappedObject();
    }
    
    return NULL;
}
Exemplo n.º 4
0
mapped_object *BinaryEdit::openResolvedLibraryName(std::string filename,
                                                   std::map<std::string, BinaryEdit*> &retMap) {
    std::vector<std::string> paths;
    std::vector<std::string>::iterator pathIter;
    // First, find the specified library file
    bool resolved = getResolvedLibraryPath(filename, paths);

    // Second, create a set of BinaryEdits for the found library
    if ( resolved ) {
        startup_printf("[%s:%u] - Opening dependent file %s\n",
                       FILE__, __LINE__, filename.c_str());

        Symtab *origSymtab = getMappedObject()->parse_img()->getObject();
	assert(mgr());
        // Dynamic case
        if ( !origSymtab->isStaticBinary() ) {
            for(pathIter = paths.begin(); pathIter != paths.end(); ++pathIter) {
               BinaryEdit *temp = BinaryEdit::openFile(*pathIter, mgr(), patcher());

                if (temp && temp->getAddressWidth() == getAddressWidth()) {
                    retMap.insert(std::make_pair(*pathIter, temp));
                    return temp->getMappedObject();
                }
                delete temp;
            }
        } else {
            // Static executable case

            /* 
             * Alright, this is a kludge, but even though the Archive is opened
             * twice (once here and once by the image class later on), it is
             * only parsed once because the Archive class keeps track of all
             * open Archives.
             *
             * This is partly due to the fact that Archives are collections of
             * Symtab objects and their is one Symtab for each BinaryEdit. In
             * some sense, an Archive is a collection of BinaryEdits.
             */
            for(pathIter = paths.begin(); pathIter != paths.end(); ++pathIter) {
                Archive *library;
                Symtab *singleObject;
                if (Archive::openArchive(library, *pathIter)) {
                    std::vector<Symtab *> members;
                    if (library->getAllMembers(members)) {
                        std::vector <Symtab *>::iterator member_it;
                        for (member_it = members.begin(); member_it != members.end();
                             ++member_it) 
                        {
                           BinaryEdit *temp = BinaryEdit::openFile(*pathIter, 
                                                                   mgr(), patcher(), (*member_it)->memberName());

                            if (temp && temp->getAddressWidth() == getAddressWidth()) {
                                std::string mapName = *pathIter + string(":") +
                                    (*member_it)->memberName();
                                retMap.insert(std::make_pair(mapName, temp));
                            }else{
                                if(temp) delete temp;
                                retMap.clear();
                                break;
                            }
                        }

                        if (retMap.size() > 0) {
                            origSymtab->addLinkingResource(library);
                            // So we tried loading "libc.a", and got back a swarm of individual members. 
                            // Lovely. 
                            // Just return the first thing...
                            return retMap.begin()->second->getMappedObject();
                        }
                        //if( library ) delete library;
                    }
                } else if (Symtab::openFile(singleObject, *pathIter)) {
                   BinaryEdit *temp = BinaryEdit::openFile(*pathIter, mgr(), patcher());


                    if (temp && temp->getAddressWidth() == getAddressWidth()) {
                        if( singleObject->getObjectType() == obj_SharedLib ||
                            singleObject->getObjectType() == obj_Executable ) 
                        {
                          startup_printf("%s[%d]: cannot load dynamic object(%s) when rewriting a static binary\n", 
                                  FILE__, __LINE__, pathIter->c_str());
                          std::string msg = std::string("Cannot load a dynamic object when rewriting a static binary");
                          showErrorCallback(71, msg.c_str());

                          delete singleObject;
                        }else{
                            retMap.insert(std::make_pair(*pathIter, temp));
                            return temp->getMappedObject();
                        }
                    }
                    if(temp) delete temp;
                }
            }
        }
    }

    startup_printf("[%s:%u] - Creation error opening %s\n",
                   FILE__, __LINE__, filename.c_str());
    // If the only thing we could find was a dynamic lib for a static executable, we can reach here; caller should handle this.
    return NULL;
}