mirror of
https://github.com/izzy2lost/Diddy-Kong-Racing.git
synced 2026-06-19 01:16:26 -07:00
Removed generic encryptor for cheats specific tools.
This commit is contained in:
+1
-1
@@ -1,5 +1,5 @@
|
||||
/n64crc
|
||||
/dkr_decompressor
|
||||
/dkr_encryptor
|
||||
/dkr_cheats_encryptor
|
||||
/dkr_extractor
|
||||
/dkr_texbuilder
|
||||
+3
-3
@@ -3,17 +3,17 @@ CXX := g++
|
||||
CFLAGS := -I . -Wall -Wextra -Wno-unused-parameter -pedantic -std=c99 -O2 -s
|
||||
LDFLAGS := -lm
|
||||
PROGRAMS := n64crc
|
||||
CXX_PROGRAMS := dkr_decompressor dkr_encryptor dkr_extractor dkr_texbuilder
|
||||
CXX_PROGRAMS := dkr_cheats_encryptor dkr_decompressor dkr_extractor dkr_texbuilder
|
||||
|
||||
default: all
|
||||
|
||||
n64crc_SOURCES := n64crc.c
|
||||
|
||||
dkr_cheats_encryptor_SOURCES := dkr_cheats_encryptor.cpp
|
||||
|
||||
dkr_decompressor_SOURCES := dkr_decompressor.cpp $(wildcard dkr_decompressor_src/*.cpp dkr_decompressor_src/*.c)
|
||||
dkr_decompressor_CXXFLAGS := -lstdc++fs -lcrypto -lssl
|
||||
|
||||
dkr_encryptor_SOURCES := dkr_encryptor.cpp
|
||||
|
||||
dkr_extractor_SOURCES := dkr_extractor.cpp $(wildcard dkr_decompressor_src/*.cpp dkr_decompressor_src/*.c dkr_extractor_classes/*.cpp n64graphics/*.c)
|
||||
dkr_extractor_CXXFLAGS := -lstdc++fs -lcrypto -lssl
|
||||
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <regex>
|
||||
|
||||
void show_help() {
|
||||
std::cout << "Usage: ./dkr_encryptor <input_file> <output_file>" << std::endl;
|
||||
}
|
||||
|
||||
void encrypt_data(std::vector<uint8_t>& data) {
|
||||
int numWords = data.size() / 4;
|
||||
int a, b, c, d, sp0, sp1, sp2, sp3;
|
||||
for(int i = 0; i < numWords; i++) {
|
||||
a = (data[(i * 4) + 3] & 0xC0) >> 6;
|
||||
b = (data[(i * 4) + 0] & 0xC0);
|
||||
c = (data[(i * 4) + 1] & 0xC0) >> 2;
|
||||
d = (data[(i * 4) + 2] & 0xC0) >> 4;
|
||||
sp0 = a | b | c | d;
|
||||
a = (data[(i * 4) + 3] & 0x30) >> 4;
|
||||
b = (data[(i * 4) + 0] & 0x30) << 2;
|
||||
c = (data[(i * 4) + 1] & 0x30);
|
||||
d = (data[(i * 4) + 2] & 0x30) >> 2;
|
||||
sp1 = a | b | c | d;
|
||||
a = (data[(i * 4) + 3] & 0x0C) >> 2;
|
||||
b = (data[(i * 4) + 0] & 0x0C) << 4;
|
||||
c = (data[(i * 4) + 1] & 0x0C) << 2;
|
||||
d = (data[(i * 4) + 2] & 0x0C);
|
||||
sp2 = a | b | c | d;
|
||||
a = (data[(i * 4) + 3] & 0x03);
|
||||
b = (data[(i * 4) + 0] ) << 6;
|
||||
c = (data[(i * 4) + 1] & 0x03) << 4;
|
||||
d = (data[(i * 4) + 2] & 0x03) << 2;
|
||||
sp3 = a | b | c | d;
|
||||
a = (sp0 & 0xAA) >> 1;
|
||||
b = (sp0 & 0x55) << 1;
|
||||
data[(i * 4) + 0] = a | b;
|
||||
a = (sp1 & 0xAA) >> 1;
|
||||
b = (sp1 & 0x55) << 1;
|
||||
data[(i * 4) + 1] = a | b;
|
||||
a = (sp2 & 0xAA) >> 1;
|
||||
b = (sp2 & 0x55) << 1;
|
||||
data[(i * 4) + 2] = a | b;
|
||||
a = (sp3 & 0xAA) >> 1;
|
||||
b = (sp3 & 0x55) << 1;
|
||||
data[(i * 4) + 3] = a | b;
|
||||
}
|
||||
}
|
||||
|
||||
std::string read_text_file(std::string& filename) {
|
||||
std::ifstream t(filename);
|
||||
t.seekg(0, std::ios::end);
|
||||
size_t size = t.tellg();
|
||||
std::string buffer(size, ' ');
|
||||
t.seekg(0);
|
||||
t.read(&buffer[0], size);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void write_binary_file(std::vector<uint8_t>& data, std::string& filename) {
|
||||
std::ofstream wf(filename.c_str(), std::ios::out | std::ios::binary);
|
||||
for(int i = 0; i < data.size(); i++)
|
||||
wf.write((char *)&data[i], 1);
|
||||
wf.close();
|
||||
}
|
||||
|
||||
std::string trim(std::string input) {
|
||||
size_t b = input.find_first_not_of(' ');
|
||||
if (b == std::string::npos) b = 0;
|
||||
return input.substr(b, input.find_last_not_of(' ') + 1 - b);
|
||||
}
|
||||
|
||||
std::vector<std::string> split_string(std::string s, char delim) {
|
||||
std::stringstream ss(s);
|
||||
std::string item;
|
||||
std::vector<std::string> elems;
|
||||
while (std::getline(ss, item, delim)) {
|
||||
if(item.length() > 0) {
|
||||
elems.push_back(trim(item));
|
||||
}
|
||||
}
|
||||
return elems;
|
||||
}
|
||||
|
||||
#define push_back_u16(data, offset, value) \
|
||||
data.push_back((value >> 8) & 0xFF); \
|
||||
data.push_back(value & 0xFF)
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
if(argc != 3) {
|
||||
show_help();
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string inputFile = argv[1];
|
||||
std::string outputFile = argv[2];
|
||||
|
||||
std::vector<std::string> lines = split_string(read_text_file(inputFile), '\n');
|
||||
|
||||
int numCheats = lines.size();
|
||||
|
||||
std::vector<uint8_t> data;
|
||||
|
||||
push_back_u16(data, 0, numCheats);
|
||||
|
||||
std::regex regex_cheat("^[\"]([^\"]+)[\"]\\s*[,]\\s*[\"]([^\"]+)[\"]$");
|
||||
std::smatch match;
|
||||
|
||||
// Create look-up table
|
||||
uint16_t offset = 2 + (numCheats * 4);
|
||||
for(auto& line : lines) {
|
||||
if (std::regex_search(line, match, regex_cheat)) {
|
||||
push_back_u16(data, 0, offset);
|
||||
offset += match[1].length() + 1; // +1 for the null terminator
|
||||
push_back_u16(data, 0, offset);
|
||||
offset += match[2].length() + 1;
|
||||
} else {
|
||||
std::cout << "Invalid line: " << line << std::endl;
|
||||
throw 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Now insert the strings
|
||||
for(auto& line : lines) {
|
||||
if (std::regex_search(line, match, regex_cheat)) {
|
||||
std::string codeWord = match[1];
|
||||
std::string codeDescription = match[2];
|
||||
for(int ch = 0; ch < codeWord.length(); ch++) {
|
||||
data.push_back(codeWord[ch]);
|
||||
}
|
||||
data.push_back(0);
|
||||
for(int ch = 0; ch < codeDescription.length(); ch++) {
|
||||
data.push_back(codeDescription[ch]);
|
||||
}
|
||||
data.push_back(0);
|
||||
} else {
|
||||
std::cout << "Invalid line: " << line << std::endl;
|
||||
throw 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the data is 16-byte aligned.
|
||||
while(data.size() % 16 != 0) {
|
||||
data.push_back(0);
|
||||
}
|
||||
|
||||
encrypt_data(data);
|
||||
write_binary_file(data, outputFile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
void show_help() {
|
||||
std::cout << "Usage: ./dkr_encryptor <input_file> <output_file>" << std::endl;
|
||||
}
|
||||
|
||||
void encrypt_data(std::vector<uint8_t>& data) {
|
||||
int numWords = data.size() / 4;
|
||||
int a, b, c, d, sp0, sp1, sp2, sp3;
|
||||
for(int i = 0; i < numWords; i++) {
|
||||
a = (data[(i * 4) + 3] & 0xC0) >> 6;
|
||||
b = (data[(i * 4) + 0] & 0xC0);
|
||||
c = (data[(i * 4) + 1] & 0xC0) >> 2;
|
||||
d = (data[(i * 4) + 2] & 0xC0) >> 4;
|
||||
sp0 = a | b | c | d;
|
||||
a = (data[(i * 4) + 3] & 0x30) >> 4;
|
||||
b = (data[(i * 4) + 0] & 0x30) << 2;
|
||||
c = (data[(i * 4) + 1] & 0x30);
|
||||
d = (data[(i * 4) + 2] & 0x30) >> 2;
|
||||
sp1 = a | b | c | d;
|
||||
a = (data[(i * 4) + 3] & 0x0C) >> 2;
|
||||
b = (data[(i * 4) + 0] & 0x0C) << 4;
|
||||
c = (data[(i * 4) + 1] & 0x0C) << 2;
|
||||
d = (data[(i * 4) + 2] & 0x0C);
|
||||
sp2 = a | b | c | d;
|
||||
a = (data[(i * 4) + 3] & 0x03);
|
||||
b = (data[(i * 4) + 0] ) << 6;
|
||||
c = (data[(i * 4) + 1] & 0x03) << 4;
|
||||
d = (data[(i * 4) + 2] & 0x03) << 2;
|
||||
sp3 = a | b | c | d;
|
||||
a = (sp0 & 0xAA) >> 1;
|
||||
b = (sp0 & 0x55) << 1;
|
||||
data[(i * 4) + 0] = a | b;
|
||||
a = (sp1 & 0xAA) >> 1;
|
||||
b = (sp1 & 0x55) << 1;
|
||||
data[(i * 4) + 1] = a | b;
|
||||
a = (sp2 & 0xAA) >> 1;
|
||||
b = (sp2 & 0x55) << 1;
|
||||
data[(i * 4) + 2] = a | b;
|
||||
a = (sp3 & 0xAA) >> 1;
|
||||
b = (sp3 & 0x55) << 1;
|
||||
data[(i * 4) + 3] = a | b;
|
||||
}
|
||||
}
|
||||
|
||||
void read_binary_file(std::vector<uint8_t>& data, std::string filename) {
|
||||
std::ifstream is;
|
||||
is.open(filename.c_str(), std::ios::binary);
|
||||
is.seekg(0, std::ios::end);
|
||||
size_t filesize = is.tellg();
|
||||
is.seekg(0, std::ios::beg);
|
||||
data.resize(filesize);
|
||||
is.read((char *)data.data(), filesize);
|
||||
is.close();
|
||||
}
|
||||
|
||||
void write_binary_file(std::vector<uint8_t>& data, std::string& filename) {
|
||||
std::ofstream wf(filename.c_str(), std::ios::out | std::ios::binary);
|
||||
for(int i = 0; i < data.size(); i++)
|
||||
wf.write((char *)&data[i], 1);
|
||||
wf.close();
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
if(argc != 3) {
|
||||
show_help();
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string inputFile = argv[1];
|
||||
std::string outputFile = argv[2];
|
||||
std::vector<uint8_t> data;
|
||||
|
||||
read_binary_file(data, inputFile);
|
||||
encrypt_data(data);
|
||||
write_binary_file(data, outputFile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+42
-16
@@ -70,15 +70,21 @@ void write_binary_file(std::vector<uint8_t>& data, std::string& filename) {
|
||||
wf.close();
|
||||
}
|
||||
|
||||
void extract_binary(std::vector<uint8_t>& data, int startOffset, int endOffset, std::string& name, const char* extension, std::string& subfolder, std::string& outFolder) {
|
||||
// std::cout << "Extracting Binary! " << startHex << std::endl;
|
||||
void write_text_file(std::string& text, std::string& filename) {
|
||||
std::ofstream myfile;
|
||||
myfile.open(filename);
|
||||
myfile << text;
|
||||
myfile.close();
|
||||
}
|
||||
|
||||
void get_filename(std::string& rangeHex, std::string& startHex, std::string& filename, int startOffset, int endOffset, std::string& name, const char* extension, std::string& subfolder, std::string& outFolder) {
|
||||
std::stringstream hexStream, rangeStream, filenameStream;
|
||||
|
||||
hexStream << std::setfill('0') << std::setw(6) << std::hex << std::uppercase << startOffset;
|
||||
std::string startHex = hexStream.str();
|
||||
startHex = hexStream.str();
|
||||
|
||||
rangeStream << startHex << "-" << std::setfill('0') << std::setw(6) << std::hex << std::uppercase << endOffset;
|
||||
std::string rangeHex = rangeStream.str();
|
||||
rangeHex = rangeStream.str();
|
||||
|
||||
to_lowercase(startHex);
|
||||
|
||||
@@ -88,15 +94,13 @@ void extract_binary(std::vector<uint8_t>& data, int startOffset, int endOffset,
|
||||
}
|
||||
|
||||
filenameStream << outputDirectory << "/" << name << "." << startHex << extension;
|
||||
std::string filename = filenameStream.str();
|
||||
|
||||
// Make sure the file is 16-byte aligned.
|
||||
/*
|
||||
while(data.size() % 16 != 0) {
|
||||
data.push_back(0);
|
||||
}
|
||||
*/
|
||||
filename = filenameStream.str();
|
||||
}
|
||||
|
||||
void extract_binary(std::vector<uint8_t>& data, int startOffset, int endOffset, std::string& name, const char* extension, std::string& subfolder, std::string& outFolder) {
|
||||
std::string rangeHex, startHex, filename;
|
||||
|
||||
get_filename(rangeHex, startHex, filename, startOffset, endOffset, name, extension, subfolder, outFolder);
|
||||
write_binary_file(data, filename);
|
||||
|
||||
std::cout << "Extracted " << rangeHex << " as /" << outFolder << "/" << name << "." << startHex << ".bin" << std::endl;
|
||||
@@ -154,9 +158,31 @@ void decrypt_data(std::vector<uint8_t>& data) {
|
||||
}
|
||||
}
|
||||
|
||||
void extract_encrypted(std::vector<uint8_t>& data, int startOffset, int endOffset, std::string& name, std::string& subfolder, std::string& outFolder) {
|
||||
#define get_u16(data, offset) (uint16_t)((data[offset] << 8) | data[offset + 1])
|
||||
|
||||
void extract_cheats(std::vector<uint8_t>& data, int startOffset, int endOffset, std::string& name, std::string& subfolder, std::string& outFolder) {
|
||||
decrypt_data(data);
|
||||
extract_binary(data, startOffset, endOffset, name, ".ebin", subfolder, outFolder);
|
||||
|
||||
std::string rangeHex, startHex, filename;
|
||||
|
||||
get_filename(rangeHex, startHex, filename, startOffset, endOffset, name, ".cheats", subfolder, outFolder);
|
||||
|
||||
std::stringstream outFile;
|
||||
|
||||
uint16_t numOfCheats = get_u16(data, 0);
|
||||
|
||||
for(int i = 0; i < numOfCheats; i++) {
|
||||
uint16_t codeWordOffset = get_u16(data, 2 + (i * 4));
|
||||
uint16_t codeDescriptionOffset = get_u16(data, 2 + (i * 4) + 2);
|
||||
char* codeWord = (char*)&data[codeWordOffset];
|
||||
char* codeDescription = (char*)&data[codeDescriptionOffset];
|
||||
outFile << "\"" << codeWord << "\", \"" << codeDescription << "\"" << std::endl;
|
||||
}
|
||||
|
||||
std::string outText = outFile.str();
|
||||
|
||||
write_text_file(outText, filename);
|
||||
std::cout << "Extracted " << rangeHex << " as /" << outFolder << "/" << name << "." << startHex << ".cheats" << std::endl;
|
||||
}
|
||||
|
||||
int get_texture_size(int width, int height, int textureFormat) {
|
||||
@@ -424,10 +450,10 @@ void extract_range(std::string subfolder, ConfigRange& range, ROM& rom) {
|
||||
numberOfFilesExtracted++;
|
||||
break;
|
||||
}
|
||||
case ConfigRangeType::ENCRYPTED:
|
||||
case ConfigRangeType::CHEATS:
|
||||
{
|
||||
std::vector<uint8_t> data = rom.get_bytes_from_range(startOffset, range.get_size());
|
||||
extract_encrypted(data, startOffset, endOffset, name, subfolder, outFolder);
|
||||
extract_cheats(data, startOffset, endOffset, name, subfolder, outFolder);
|
||||
numberOfFilesExtracted++;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ ConfigRangeType Config::get_range_type(std::string typeString) {
|
||||
if(type == "binary") return ConfigRangeType::BINARY;
|
||||
if(type == "noextract") return ConfigRangeType::NOEXTRACT;
|
||||
if(type == "compressed") return ConfigRangeType::COMPRESSED;
|
||||
if(type == "encrypted") return ConfigRangeType::ENCRYPTED;
|
||||
if(type == "cheats") return ConfigRangeType::CHEATS;
|
||||
if(type == "texture") return ConfigRangeType::TEXTURE;
|
||||
|
||||
std::cout << "Unknown extraction type: " << type << std::endl;
|
||||
|
||||
@@ -16,7 +16,7 @@ enum ConfigRangeType {
|
||||
BINARY,
|
||||
NOEXTRACT,
|
||||
COMPRESSED,
|
||||
ENCRYPTED,
|
||||
CHEATS,
|
||||
TEXTURE
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user