|
#include <cstdio> |
|
#include <string> |
|
#include <vector> |
|
#include <utility> |
|
#include <iostream> |
|
#include <tuple> |
|
#include <fstream> |
|
// #define DEBUGOUT |
|
#define DATASTART __data_start |
|
#define DATAEND edata |
|
#define NOINITSTORE __attribute__((section(".data"))) |
|
extern char DATASTART; |
|
extern char DATAEND; |
|
static std::vector<std::tuple<char* /*ptr*/,size_t /*size*/,char* /*fileOffset*/>> preserveList; |
|
NOINITSTORE int foo = 0, arr[10]; |
|
int bar = 456, foobar; char* baseAddr; char* startAddr = &DATASTART;char *endAddr = &DATAEND; |
|
static std::string exeRelPath; |
|
template<class T> |
|
void preserveVal(T& val) { |
|
char* addr = (char*)&val; |
|
if(addr >= startAddr && addr < endAddr) |
|
preserveList.push_back(std::make_tuple(addr, sizeof(val), addr - startAddr + baseAddr)); |
|
} |
|
void listPreserve() { |
|
#ifdef DEBUGOUT |
|
for(auto x : preserveList) |
|
printf("%x %d %x\n", std::get<0>(x), std::get<1>(x), std::get<2>(x)); |
|
#endif |
|
} |
|
void writePreserve(const char* fileName) { |
|
std::fstream fs; |
|
fs.open(fileName, std::ios::in | std::ios::out | std::ios::binary); |
|
for(auto item : preserveList) { |
|
fs.seekp((long)std::get<2>(item)); |
|
fs.write(std::get<0>(item),std::get<1>(item)); |
|
} |
|
fs.close(); |
|
} |
|
void initPreserve(char** &argv) { |
|
exeRelPath = (std::string)(argv[0]); |
|
#ifdef DEBUGOUT |
|
printf("%s\n",argv[0]); |
|
printf("%s\n", ("objdump -h " + exeRelPath + "| grep \"\\.data\" | awk '{print $6}'").c_str()); |
|
#endif |
|
FILE* f = popen(("objdump -h " + exeRelPath + " | grep \"\\.data\" | awk '{print $6}'").c_str(),"r"); |
|
fscanf(f, "%x", &baseAddr); |
|
pclose(f); |
|
#ifdef DEBUGOUT |
|
printf("%x\n", baseAddr); |
|
#endif |
|
} |
|
void finalizePreserve() { |
|
system(("cp " + exeRelPath + " " + exeRelPath + ".tmp").c_str()); |
|
writePreserve((exeRelPath+".tmp").c_str()); |
|
system(("rm -rf " + exeRelPath).c_str()); |
|
system(("cp " + exeRelPath + ".tmp" + " " + exeRelPath).c_str()); |
|
#ifdef DEBUGOUT |
|
printf("%x %x %x %x\n",&DATASTART,&foo,&bar,&foobar); |
|
#endif |
|
} |
|
int main(int argc, char* argv[]) { |
|
printf("%d %d %d\n",foo,bar, arr[3]); |
|
initPreserve(argv); |
|
preserveVal(foo); preserveVal(bar); preserveVal(arr); |
|
listPreserve(); |
|
foo++;bar+=2; |
|
arr[3]+=5; |
|
finalizePreserve(); |
|
return 0; |
|
} |