Newer
Older
#include "mg.hpp"
#include <assert.h>
#include <stdexcept>
#include <unistd.h>
#include <memory>
#include <inttypes.h>
#include <algorithm>
#include <elf.h>
#include <cctype>
#include <iomanip>
#include <cstdlib>
#include <random>

Will Hawkins
committed
#include <functional>
using namespace std;
using namespace IRDB_SDK;
using namespace EXEIO;
#define ALLOF(s) begin(s), end(s)
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// use this to determine whether a scoop has a given name.
static struct ScoopFinder : binary_function<DataScoop_t*,string,bool>
{
// declare a simple scoop finder function that finds scoops by name
bool operator()(const DataScoop_t* scoop, const string word) const
{
return (scoop->getName() == word);
};
} finder;
template<class S, class T> inline
static bool contains(const S &container, const T& value)
{
return find(container.begin(), container.end(), value) != container.end();
}
static bool arg_has_memory(const DecodedOperand_t &arg)
{
/* if it's relative memory, watch out! */
if(arg.isMemory())
return true;
return false;
}
static bool arg_has_relative(const DecodedOperand_t &arg)
{
/* if it's relative memory, watch out! */
if(arg.isMemory() && arg.isPcrel())
return true;
return false;
}
static DecodedOperandVector_t::iterator find_memory_operand(DecodedOperandVector_t &operands)
{
// const auto operands=disasm.getOperands();
auto the_arg=operands.end();
if(operands.size()>0 && arg_has_memory(*operands[0]))
the_arg=next(operands.begin(),0);
if(operands.size()>1 && arg_has_memory(*operands[1]))
the_arg=next(operands.begin(),1);
if(operands.size()>2 && arg_has_memory(*operands[2]))
the_arg=next(operands.begin(),2);
if(operands.size()>3 && arg_has_memory(*operands[3]))
the_arg=next(operands.begin(),3);
return the_arg;
}
template< typename T >
static std::string to_hex_string( T i )
{
std::stringstream stream;
stream << "0x"
<< std::hex << i;
return stream.str();
}
template <class T_Sym, class T_Rela, class T_Rel, class T_Dyn, class T_Extractor>
bool MoveGlobals_t<T_Sym,T_Rela,T_Rel,T_Dyn,T_Extractor>::is_elftable(DataScoop_t* ret)
{
return find(ALLOF(elftable_names), ret->getName()) != elftable_names.end() ;
};
template <class T_Sym, class T_Rela, class T_Rel, class T_Dyn, class T_Extractor>
bool MoveGlobals_t<T_Sym,T_Rela,T_Rel,T_Dyn,T_Extractor>::is_noptr_table(DataScoop_t* ret)
{
return find(ALLOF(elftable_nocodeptr_names), ret->getName()) != elftable_nocodeptr_names.end() ;
};
template <class T_Sym, class T_Rela, class T_Rel, class T_Dyn, class T_Extractor>
MoveGlobals_t<T_Sym,T_Rela,T_Rel,T_Dyn,T_Extractor>::MoveGlobals_t(
VariantID_t *p_variantID,
FileIR_t *p_variantIR,
const string &p_dont_move,
const string &p_move_only,
const int p_max_mov,
const bool p_random,
const bool p_aggressive,
const bool p_use_stars)
:

Jason Hiser
committed
Transform_t(p_variantIR),
exe_reader(NULL),
tied_unpinned(0),
tied_pinned(0),
tied_nochange(0),
ties_for_folded_constants(0),
dont_move(p_dont_move),
move_only(p_move_only),
max_moveables(p_max_mov),
random(p_random),
aggressive(p_aggressive),
m_use_stars(p_use_stars),
m_verbose(getenv("MG_VERBOSE") != nullptr)
{
}
template <class T_Sym, class T_Rela, class T_Rel, class T_Dyn, class T_Extractor>
int MoveGlobals_t<T_Sym,T_Rela,T_Rel,T_Dyn,T_Extractor>::execute(pqxxDB_t &pqxx_interface)
{
// read the executeable file
// load the executable.
exe_reader = new EXEIO::exeio;
assert(exe_reader);
exe_reader->load((char*)"a.ncexe");
if(m_use_stars)
{
auto deep_analysis=DeepAnalysis_t::factory(getFileIR(), aeSTARS, {"SetDeepLoopAnalyses=true", "SetConstantPropagation=true"});
deep_global_static_ranges = deep_analysis -> getStaticGlobalRanges();
sentinels = deep_analysis -> getRangeSentinels();
cout<<dec;
cout<<"#ATTRIBUTE "<<deep_global_static_ranges->size() <<" num_global_static_range_annotations" <<endl;
cout<<"#ATTRIBUTE "<<sentinels->size() <<" num_sentinel_annotations" <<endl;
}
ParseSyms(exe_reader);
SetupScoopMap();
FilterScoops();
TieScoops();
FindInstructionReferences(); // may record some scoops are tied together
FindDataReferences();
FilterAndCoalesceTiedScoops();
UpdateScoopLocations();
PrintStats();
return 0;
}
// go through the .symtab and .dynsym bits of the table and make scoops for each symbol.
template <class T_Sym, class T_Rela, class T_Rel, class T_Dyn, class T_Extractor>
void MoveGlobals_t<T_Sym,T_Rela,T_Rel,T_Dyn,T_Extractor>::SetupScoopMap()
{
for(auto &s : getFileIR()->getDataScoops())
{

Jason Hiser
committed
if(s->getStart()->getVirtualOffset() == 0)
continue;
if(s->getName() == ".tdata")
continue;
if(s->getName() == ".tbss")
continue;
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
RangePair_t p(s->getStart()->getVirtualOffset(), s->getEnd()->getVirtualOffset());
scoop_map[p]=s;
}
}
template <class T_Sym, class T_Rela, class T_Rel, class T_Dyn, class T_Extractor>
DataScoop_t* MoveGlobals_t<T_Sym,T_Rela,T_Rel,T_Dyn,T_Extractor>::findScoopByAddress(const IRDB_SDK::VirtualOffset_t a) const
{
RangePair_t p(a,a);
auto smit=scoop_map.find(p);
if(smit==scoop_map.end())
return NULL;
return smit->second;
}
template <class T_Sym, class T_Rela, class T_Rel, class T_Dyn, class T_Extractor>
bool MoveGlobals_t<T_Sym, T_Rela, T_Rel, T_Dyn, T_Extractor>::AreScoopsAdjacent(const DataScoop_t *a, const DataScoop_t *b) const
{
bool adjacent = true;
const IRDB_SDK::VirtualOffset_t aStart = a->getStart()->getVirtualOffset();
const IRDB_SDK::VirtualOffset_t aEnd = a->getEnd()->getVirtualOffset();
const IRDB_SDK::VirtualOffset_t bStart = b->getStart()->getVirtualOffset();
const IRDB_SDK::VirtualOffset_t bEnd = b->getEnd()->getVirtualOffset();
IRDB_SDK::VirtualOffset_t FirstEnd, SecondStart;
if (aStart > bStart)
{
Loading
Loading full blame...