Created
July 29, 2015 15:44
-
-
Save Jakz/314ff792044fd9be792e to your computer and use it in GitHub Desktop.
Simple cmmand line byte modifier that replaces raw bytes inside a given file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdint.h> | |
#include <cstdio> | |
#include <cstdlib> | |
#include <vector> | |
#include <string> | |
using namespace std; | |
struct Patch | |
{ | |
uint32_t address; | |
vector<uint8_t> values; | |
}; | |
vector<Patch> entries; | |
void printUsage() | |
{ | |
printf("Usage: hexalter filename address1=byte1,..,byten ... addressn=byte1,...,byten\n"); | |
} | |
bool parsePatch(const std::string& token) | |
{ | |
size_t equalIndex = token.find_first_of('='); | |
if (equalIndex == string::npos) | |
return false; | |
Patch patch; | |
patch.address = strtoul(token.substr(0, equalIndex).c_str(), NULL, 16); | |
string values = token.substr(equalIndex+1); | |
size_t startIndex = 0; | |
size_t commaIndex; | |
while ((commaIndex = values.find_first_of(',', startIndex)) != string::npos) | |
{ | |
uint8_t value = strtoul(values.substr(startIndex, commaIndex).c_str(), NULL, 16); | |
startIndex = commaIndex + 1; | |
patch.values.push_back(value); | |
} | |
uint8_t value = strtoul(values.substr(startIndex).c_str(), NULL, 16); | |
patch.values.push_back(value); | |
entries.push_back(patch); | |
return true; | |
} | |
int main(int argc, const char* argv[]) | |
{ | |
if (argc < 3) | |
{ | |
printUsage(); | |
return 1; | |
} | |
const char* filename = argv[1]; | |
for (int i = 2; i < argc; ++i) | |
{ | |
if (!parsePatch(argv[i])) | |
{ | |
printUsage(); | |
return 1; | |
} | |
} | |
FILE* file = fopen(filename, "r+b"); | |
if (!file) | |
{ | |
printf("Unable to open file. Exiting.\n"); | |
return 1; | |
} | |
fseek(file, 0L, SEEK_END); | |
long fileSize = ftell(file); | |
for (vector<Patch>::const_iterator it = entries.begin(); it != entries.end(); ++it) | |
{ | |
const Patch& patch = *it; | |
if (patch.address + patch.values.size() >= fileSize) | |
{ | |
printf("Patch exceeds file size. Exiting.\n"); | |
break; | |
} | |
fseek(file, patch.address, SEEK_SET); | |
fwrite(&patch.values[0], 1, patch.values.size(), file); | |
} | |
fclose(file); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment