Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Commits on Source (2)
......@@ -367,26 +367,6 @@ class ZiprImpl_t : public Zipr_t
std::string AddCallbacksToNewSegment(const std::string& tmpname, RangeAddress_t end_of_new_space);
RangeAddress_t FindCallbackAddress(RangeAddress_t end_of_new_space,RangeAddress_t start_addr, const std::string &callback);
#if 0
IRDB_SDK::Instruction_t *FindPinnedInsnAtAddr(RangeAddress_t addr);
// bool ShouldPinImmediately(IRDB_SDK::Instruction_t *upinsn);
// bool IsPinFreeZone(RangeAddress_t addr, int size);
// routines to deal with a "68 sled"
// int Calc68SledSize(RangeAddress_t addr, size_t sled_overhead=6);
// RangeAddress_t Do68Sled(RangeAddress_t addr);
// void Update68Sled(Sled_t, Sled_t &);
// IRDB_SDK::Instruction_t* Emit68Sled(Sled_t sled);
// IRDB_SDK::Instruction_t* Emit68Sled(RangeAddress_t addr, Sled_t sled, IRDB_SDK::Instruction_t* next_sled);
/*
* The goal here is to simply clear out chain entries
* that may be in the way. This will not clear out
* previously added PUSHs.
*/
// void Clear68SledArea(Sled_t sled);
// void InsertJumpPoints68SledArea(Sled_t &sled);
#endif
// support
RangeAddress_t extend_section(ELFIO::section *sec,ELFIO::section *next_sec);
......@@ -412,15 +392,12 @@ class ZiprImpl_t : public Zipr_t
// structures necessary for ZIPR algorithm.
// std::set<UnresolvedUnpinned_t> unresolved_unpinned_addrs;
// std::set<UnresolvedPinned_t,pin_sorter_t> unresolved_pinned_addrs;
std::multimap<UnresolvedUnpinned_t,Patch_t> patch_list;
// a manager for all dollops
ZiprDollopManager_t m_dollop_mgr;
// final mapping of instruction to address.
// std::map<IRDB_SDK::Instruction_t*,RangeAddress_t>
Zipr_SDK::InstructionLocationMap_t final_insn_locations;
std::map<RangeAddress_t,UnresolvedUnpinnedPatch_t> m_PatchAtAddrs;
......
......@@ -63,7 +63,6 @@ inline uintptr_t page_round_down(uintptr_t x)
return ( (((uintptr_t)(x)) - (PAGE_SIZE-1)) & (~(PAGE_SIZE-1)) );
}
int find_magic_segment_index(ELFIO::elfio *elfiop);
template < typename T > std::string to_hex_string( const T& n )
{
......@@ -179,45 +178,6 @@ void ZiprImpl_t::registerOptions()
m_variant->setRequired(true);
#if 0
m_add_sections.setDescription("Enable writing of section headers using elfwriter.");
m_bss_opts.setDescription("Enable/Disable optimizing BSS segments so they aren't written to the binary.");
m_verbose.setDescription("Enable verbose output");
m_apply_nop.setDescription("Apply NOP to patches that fallthrough.");
m_variant.setDescription("Variant ID.");
m_output_filename.setDescription("Output file name.");
m_architecture.setDescription("Override default system "
"architecture detection");
m_replop.setDescription("Replop all dollops.");
m_objcopy.setDescription("Set the path of objcopy to use.");
m_callbacks.setDescription("Set the path of the file "
"which contains any required callbacks.");
m_seed.setDescription("Seed the random number generator with this value.");
m_dollop_map_filename.setDescription("Specify filename to save dollop map.");
m_paddable_minimum_distance.setDescription("Specify the minimum size of a gap to be filled.");
// our pid is a fine default value -- had issues with time(nullptr) as two copies of zipr from
// were getting the same time(nullptr) return value since we invoked them in parallel.
m_seed.setValue((int)getpid());
zipr_namespace->addOption(&m_output_filename);
zipr_namespace->addOption(&m_callbacks);
zipr_namespace->addOption(&m_architecture);
zipr_namespace->addOption(&m_replop);
zipr_namespace->addOption(&m_objcopy);
zipr_namespace->addOption(&m_seed);
zipr_namespace->addOption(&m_dollop_map_filename);
zipr_namespace->addOption(&m_paddable_minimum_distance);
global->addOption(&m_variant);
global->addOption(&m_verbose);
global->addOption(&m_vverbose);
global->addOption(&m_apply_nop);
global->addOption(&m_add_sections);
global->addOption(&m_bss_opts);
return zipr_namespace;
#endif
memory_space.registerOptions(&m_zipr_options);
}
......@@ -1556,17 +1516,6 @@ size_t ZiprImpl_t::DetermineDollopEntrySize(Zipr_SDK::DollopEntry_t *entry, bool
if (*m_verbose)
{
#if 0
cout << "Adding opening size of " << opening_size << "." << endl;
cout << "Adding closing size of " << closing_size << "." << endl;
cout << "WCDES of " << std::hex << entry << ":"
<< std::dec << wcis+opening_size+closing_size << endl;
#else
// if we need these, please add additional levels of verbose logging!
// this log line accounts for 80% of a 744mb log file.
//cout << "Open/close/wcdes for "<<hex<<entry<<": " << dec << opening_size
// <<"/" << closing_size << "/" << wcis+opening_size+closing_size << endl;
#endif
}
return wcis+opening_size+closing_size;
......@@ -1949,187 +1898,12 @@ DataScoop_t* ZiprImpl_t::FindScoop(const RangeAddress_t &addr)
return find_it==m_firp->getDataScoops().end() ? nullptr : *find_it;
}
void ZiprImpl_t::WriteScoop(section* sec, FILE* fexe)
{
assert(0);
#if 0
// skip any nobits/tls sections.
if ( (sec->get_flags() & SHF_TLS) == SHF_TLS && sec->get_type() == SHT_NOBITS )
return;
RangeAddress_t start=sec->get_address();
RangeAddress_t end=sec->get_size()+start;
for(RangeAddress_t i=start;i<end;i++)
{
DataScoop_t* scoop=FindScoop(i);
if(!scoop)
continue;
const string &the_contents=scoop->getContents();
char b=the_contents[i-scoop->getStart()->getVirtualOffset()];
if( sec->get_type() == SHT_NOBITS )
{
assert(b==0); // cannot write non-zero's to NOBITS sections.
// and we can't do the write, because the sec. isn't in the binary.
continue;
}
int file_off=sec->get_offset()+i-start;
fseek(fexe, file_off, SEEK_SET);
fwrite(&b,1,1,fexe);
if(i-start<200)// keep verbose output short enough.
{
if (*m_verbose)
printf("Writing scoop byte %#2x at %p, fileoffset=%x\n",
((unsigned)b)&0xff, (void*)i, file_off);
}
}
#endif
}
#if 0
static bool InScoop(VirtualOffset_t addr, DataScoop_t* scoop)
{
if(scoop->getStart()->getVirtualOffset()==0)
return false;
// check before
if(addr < scoop->getStart()->getVirtualOffset())
return false;
if(scoop->getEnd()->getVirtualOffset()<addr)
return false;
return true;
}
#endif
void ZiprImpl_t::FillSection(section* sec, FILE* fexe)
{
assert(0);
#if 0
RangeAddress_t start=sec->get_address();
RangeAddress_t end=sec->get_size()+start;
DataScoop_t* scoop=nullptr;
if (*m_verbose)
printf("Dumping addrs %p-%p\n", (void*)start, (void*)end);
for(RangeAddress_t i=start;i<end;i++)
{
if(scoop==nullptr || InScoop(i,scoop))
{
scoop=FindScoop(i);
}
if(!memory_space.IsByteFree(i))
{
// get byte and write it into exe.
char b=memory_space[i];
int file_off=sec->get_offset()+i-start;
fseek(fexe, file_off, SEEK_SET);
fwrite(&b,1,1,fexe);
if(i-start<200)// keep verbose output short enough.
{
if (*m_verbose)
printf("Writing byte %#2x at %p, fileoffset=%x\n",
((unsigned)b)&0xff, (void*)i, file_off);
}
}
}
#endif
}
void ZiprImpl_t::OutputBinaryFile(const string &name)
{
#if 0
assert(elfiop);
#ifdef support_stratafier_mode
// ELFIO::dump::section_headers(cout,*elfiop);
string callback_file_name;
ELFIO::elfio *rewrite_headers_elfiop = new ELFIO::elfio;
ELFIO::Elf_Half total_sections;
/*
* Unfortunately, we need to have a special
* "pass" to rewrite section header lengths.
* Elfio does not work properly otherwise.
*/
rewrite_headers_elfiop->load(name);
total_sections = rewrite_headers_elfiop->sections.size();
for ( ELFIO::Elf_Half i = 0; i < total_sections; ++i )
{
section* sec = rewrite_headers_elfiop->sections[i];
assert(sec);
if( (sec->get_flags() & SHF_ALLOC) == 0 )
continue;
if( (sec->get_flags() & SHF_EXECINSTR) == 0)
continue;
#ifdef EXTEND_SECTIONS
section* next_sec = nullptr;
if ((i+1)<total_sections)
{
next_sec = rewrite_headers_elfiop->sections[i+1];
}
extend_section(sec, next_sec);
#endif //EXTEND_SECTIONS
}
rewrite_headers_elfiop->save(name);
string myfn=name;
#ifdef CGC
if(!use_stratafier_mode)
myfn+=".stripped";
#endif //CGC
printf("Opening %s\n", myfn.c_str());
FILE* fexe=fopen(myfn.c_str(),"r+");
assert(fexe);
// For all sections
ELFIO::Elf_Half n = elfiop->sections.size();
for ( ELFIO::Elf_Half i = 0; i < n; ++i )
{
section* sec = elfiop->sections[i];
assert(sec);
if( (sec->get_flags() & SHF_ALLOC) == 0 )
continue;
if( (sec->get_flags() & SHF_EXECINSTR) == 0)
WriteScoop(sec, fexe);
else
FillSection(sec, fexe);
}
fclose(fexe);
string tmpname=name+string(".to_insert");
printf("Opening %s\n", tmpname.c_str());
FILE* to_insert=fopen(tmpname.c_str(),"w");
if(!to_insert)
perror( "void ZiprImpl_t::OutputBinaryFile(const string &name)");
#endif //support_stratafier_mode
#ifdef support_stratafier_mode
fclose(to_insert);
callback_file_name = AddCallbacksToNewSegment(tmpname,end_of_new_space);
InsertNewSegmentIntoExe(name,callback_file_name,start_of_new_space);
#endif
// now that the textra scoop has been crated and setup, we have the info we need to
// re-generate the eh information.
RelayoutEhInfo();
#endif
// create the output file in a totally different way using elfwriter. later we may
......@@ -2170,264 +1944,6 @@ void ZiprImpl_t::PrintStats()
dump_instruction_map();
}
int find_magic_segment_index(ELFIO::elfio *elfiop)
{
ELFIO::Elf_Half n = elfiop->segments.size();
ELFIO::Elf_Half i=0;
ELFIO::segment* last_seg=nullptr;
int last_seg_index=-1;
for ( i = 0; i < n; ++i )
{
ELFIO::segment* seg = elfiop->segments[i];
assert(seg);
if(seg->get_type() != PT_LOAD)
continue;
if(last_seg && (last_seg->get_virtual_address() + last_seg->get_memory_size()) > (seg->get_virtual_address() + seg->get_memory_size()))
continue;
if(seg->get_file_size()==0)
continue;
last_seg=seg;
last_seg_index=i;
}
cout<<"Found magic Seg #"<<std::dec<<last_seg_index<<" has file offset "<<last_seg->get_offset()<<endl;
return last_seg_index;
}
void ZiprImpl_t::InsertNewSegmentIntoExe(string rewritten_file, string bin_to_add, RangeAddress_t sec_start)
{
// from stratafy.pl
// #system("objcopy --add-section .strata=strata.linked.data.$$ --change-section-address .strata=$maxaddr --set-section-flags .strata=alloc --set-start $textoffset $exe_copy $newfile") == 0 or die ("command failed $? \n") ;
// system("$stratafier/add_strata_segment $newfile $exe_copy ") == 0 or die (" command failed : $? \n");
string chmod_cmd="";
if(use_stratafier_mode)
{
string objcopy_cmd = "", stratafier_cmd = "", sstrip_cmd;
//objcopy_cmd= m_opts.getObjcopyPath() + string(" --add-section .strata=")+bin_to_add+" "+
objcopy_cmd= string(*m_objcopy) + string(" --add-section .strata=")+bin_to_add+" "+
string("--change-section-address .strata=")+to_string(sec_start)+" "+
string("--set-section-flags .strata=alloc,code ")+" "+
// --set-start $textoffset // set-start not needed, as we aren't changing the entry point.
rewritten_file; // editing file in place, no $newfile needed.
printf("Attempting: %s\n", objcopy_cmd.c_str());
if(-1 == system(objcopy_cmd.c_str()))
{
perror(__FUNCTION__);
}
if ( elfiop->get_type() == ET_EXEC )
stratafier_cmd="$STRATAFIER/add_strata_segment";
else
// move_segheaders is needed for shared objects.
stratafier_cmd="$STRATAFIER/move_segheaders";
if (*m_architecture == 64) {
stratafier_cmd += "64";
}
stratafier_cmd += " " + rewritten_file+ " " + rewritten_file +".addseg"+" .strata";
printf("Attempting: %s\n", stratafier_cmd.c_str());
if(-1 == system(stratafier_cmd.c_str()))
{
perror(__FUNCTION__);
}
#ifdef CGC
sstrip_cmd=string("")+getenv("SECURITY_TRANSFORMS_HOME")+"/third_party/ELFkickers-3.0a/sstrip/sstrip "+rewritten_file+".addseg";
printf("Attempting: %s\n", sstrip_cmd.c_str());
if(-1 == system(sstrip_cmd.c_str()))
{
perror(__FUNCTION__);
}
#endif
}
else
{
#ifndef CGC
assert(0); // "not stratafier" mode available only for CGC
#elif support_stratafier_mode
string cmd="";
string zeroes_file=rewritten_file+".zeroes";
cout<<"Note: bss_needed=="<<std::dec<<bss_needed<<endl;
cmd="cat /dev/zero | head -c "+to_string(bss_needed)+" > "+zeroes_file;
printf("Attempting: %s\n", cmd.c_str());
if(-1 == system(cmd.c_str()))
{
perror(__FUNCTION__);
}
cmd="cat "+rewritten_file+".stripped "+zeroes_file+" "+bin_to_add+" > "+rewritten_file+".addseg";
printf("Attempting: %s\n", cmd.c_str());
if(-1 == system(cmd.c_str()))
{
perror(__FUNCTION__);
}
std::ifstream::pos_type orig_size=filesize((rewritten_file+".stripped").c_str());
std::ifstream::pos_type incr_size=bss_needed+filesize(bin_to_add.c_str());
assert(orig_size+incr_size=filesize((rewritten_file+".addseg").c_str()));
std::ifstream::pos_type total_size=orig_size+incr_size;
ELFIO::elfio *boutaddseg=new ELFIO::elfio;
boutaddseg->load(rewritten_file+".addseg");
ELFIO::dump::header(cout,*boutaddseg);
ELFIO::dump::segment_headers(cout,*boutaddseg);
cout<<"Segments offset is "<<boutaddseg->get_segments_offset()<<endl;
ELFIO::Elf_Half i=find_magic_segment_index(boutaddseg);
FILE* fboutaddseg=fopen((rewritten_file+".addseg").c_str(),"r+");
assert(fboutaddseg);
ELFIO::Elf32_Phdr myphdr;
int file_off=boutaddseg->get_segments_offset()+sizeof(ELFIO::Elf32_Phdr)*(i);
cout<<"Seeking to "<<std::hex<<file_off<<endl;
fseek(fboutaddseg, file_off, SEEK_SET);
fread(&myphdr, sizeof(myphdr), 1, fboutaddseg);
cout<<"My phdr has vaddr="<<std::hex<<myphdr.p_vaddr<<endl;
cout<<"My phdr has phys addr="<<std::hex<<myphdr.p_paddr<<endl;
cout<<"My phdr has file size="<<std::hex<<myphdr.p_filesz<<endl;
myphdr.p_filesz=(int)((int)total_size-(int)myphdr.p_offset);
myphdr.p_memsz=myphdr.p_filesz;
myphdr.p_flags|=PF_X|PF_R|PF_W;
cout<<"Updated file size="<<std::hex<<myphdr.p_filesz<<endl;
fseek(fboutaddseg, file_off, SEEK_SET);
fwrite(&myphdr, sizeof(myphdr), 1, fboutaddseg);
fclose(fboutaddseg);
ELFIO::Elf32_Shdr myseg_header;
#endif // #elif support_stratafier_mode from #ifndef CGC
}
chmod_cmd=string("chmod +x ")+rewritten_file+".addseg";
printf("Attempting: %s\n", chmod_cmd.c_str());
if(-1 == system(chmod_cmd.c_str()))
{
perror(__FUNCTION__);
}
}
/*
FIXME
*/
static RangeAddress_t getCallbackStartAddr()
{
// add option later, or write code to fix this
const RangeAddress_t callback_start_addr=0x8048000;
return 0;
return callback_start_addr;
}
string ZiprImpl_t::AddCallbacksToNewSegment(const string& tmpname, RangeAddress_t end_of_new_space)
{
const RangeAddress_t callback_start_addr=getCallbackStartAddr();
//if(m_opts.getCallbackFileName() == "" )
if((string)(*m_callbacks) == "" )
return tmpname;
string tmpname2=tmpname+"2";
string tmpname3=tmpname+"3";
printf("Setting strata library at: %p\n", (void*)end_of_new_space);
printf("Strata symbols are at %p+addr(symbol)\n", (void*)(end_of_new_space-callback_start_addr));
#if 0
string cmd= string("$STRATAFIER/strata_to_data ")+
m_opts.getCallbackFileName()+string(" ")+tmpname2+" "+to_hex_string(callback_start_addr);
#else
/*
objcopy -O binary /home/jdh8d/umbrella/uvadev.peasoup/zipr_install/bin/callbacks.exe b.out.to_insert2
*/
//string cmd= m_opts.getObjcopyPath() + string(" -O binary ")+ m_opts.getCallbackFileName()+string(" ")+tmpname2;
string cmd= string(*m_objcopy) + string(" -O binary ")+string(*m_callbacks)+string(" ")+tmpname2;
#endif
printf("Attempting: %s\n", cmd.c_str());
if(-1 == system(cmd.c_str()))
{
perror(__FUNCTION__);
return tmpname;
}
cmd="cat "+tmpname+" "+tmpname2+" > "+tmpname3;
printf("Attempting: %s\n", cmd.c_str());
if(-1 == system(cmd.c_str()))
{
perror(__FUNCTION__);
return tmpname;
}
return tmpname3;
}
// horrible code, rewrite in C++ please!
static RangeAddress_t getSymbolAddress(const string &symbolFilename, const string &symbol) throw(exception)
{
string symbolFullName = symbolFilename + "+" + symbol;
// nm -a stratafier.o.exe | egrep " integer_overflow_detector$" | cut -f1 -d' '
string command = "nm -a " + symbolFilename + " | egrep \" " + symbol + "$\" | cut -f1 -d' '";
char address[1024]="";
cerr<<"Attempting: "<<command<<endl;
FILE *fp = popen(command.c_str(), "r");
int res=fscanf(fp,"%s", address);
cerr<<"Looking for "<<symbol<<". Address string is "<<address<<endl;
string addressString = string(address);
pclose(fp);
RangeAddress_t ret= (uintptr_t) strtoull(addressString.c_str(),nullptr,16);
//TODO: throw exception if address is not found.
//for now assert the address string isn't empty
if(addressString.empty() || res==0)
{
cerr<<"Cannot find symbol "<< symbol << " in " << symbolFilename << "."<<endl;
addressString="0x0";
return 0;
}
else
{
cerr<<"Found symbol "<< symbol << " in " << symbolFilename << " at " << std::hex << ret << "."<<endl;
return ret;
}
}
RangeAddress_t ZiprImpl_t::FindCallbackAddress(RangeAddress_t end_of_new_space, RangeAddress_t start_addr, const string &callback)
{
if(callback_addrs.find(callback)==callback_addrs.end())
{
//RangeAddress_t addr=getSymbolAddress(m_opts.getCallbackFileName(),callback);
RangeAddress_t addr=getSymbolAddress(*m_callbacks,callback);
if(addr!=0)
{
/* adjust by start of new location, - beginning of old location */
addr=addr+end_of_new_space-start_addr;
}
cout<<" Addr adjusted to "<<std::hex<<addr<<endl;
callback_addrs[callback]=addr;
}
return callback_addrs[callback];
}
void ZiprImpl_t::UpdateCallbacks()
{
// first byte of this range is the last used byte.
......