Removed generic encryptor for cheats specific tools.

This commit is contained in:
David Benepe
2020-06-15 11:34:38 -05:00
parent 6f6791a99f
commit 4a9cee6542
10 changed files with 210 additions and 113 deletions
+5 -5
View File
@@ -55,7 +55,7 @@ FixPath = $(subst /,,$1)
N64CRC = $(TOOLS_DIR)/n64crc
TEXBUILDER = $(TOOLS_DIR)/dkr_texbuilder
COMPRESS = $(TOOLS_DIR)/dkr_decompressor -c
ENCRYPT = $(TOOLS_DIR)/dkr_encryptor
CHEAT_ENCRYPTOR = $(TOOLS_DIR)/dkr_cheats_encryptor
ASM_DIRS := asm asm/boot asm/assets
SRC_DIRS := src
@@ -125,8 +125,8 @@ UCODE_BUILT := $(patsubst $(UCODE_IN_DIR)/%.bin,$(UCODE_OUT_DIR)/%.bin,$(UCODE))
CHEATS_IN_DIR = $(ASSETS_DIR)/cheats
CHEATS_OUT_DIR = $(BUILD_DIR)/cheats
CHEATS = $(wildcard $(CHEATS_IN_DIR)/*.ebin)
CHEATS_BUILT := $(patsubst $(CHEATS_IN_DIR)/%.ebin,$(CHEATS_OUT_DIR)/%.ebin,$(CHEATS))
CHEATS = $(wildcard $(CHEATS_IN_DIR)/*.cheats)
CHEATS_BUILT := $(patsubst %.cheats,%.bin,$(patsubst $(CHEATS_IN_DIR)/%.cheats,$(CHEATS_OUT_DIR)/%.cheats,$(CHEATS)))
ALL_ASSETS_BUILT := $(ANIMATIONS_BUILT) $(BINS_BUILT) $(CHEATS_BUILT) $(LEVELS_BUILT) $(OBJECTS_BUILT) $(TEXTURES_BUILT) $(TEXTURES_BIN_BUILT) $(TEXT_BUILT) $(UCODE_BUILT)
@@ -160,8 +160,8 @@ $(ANIMATIONS_OUT_DIR)/%.cbin: $(ANIMATIONS_IN_DIR)/%.cbin
$(BINS_OUT_DIR)/%.bin: $(BINS_IN_DIR)/%.bin
$(ASSETS_OBJCOPY) $^ $@
$(CHEATS_OUT_DIR)/%.ebin: $(CHEATS_IN_DIR)/%.ebin
$(ENCRYPT) $^ $@
$(CHEATS_OUT_DIR)/%.bin: $(CHEATS_IN_DIR)/%.cheats
$(CHEAT_ENCRYPTOR) $^ $@
$(LEVELS_OUT_DIR)/%.bin: $(LEVELS_IN_DIR)/%.bin
$(ASSETS_OBJCOPY) $^ $@
+1 -1
View File
@@ -4631,7 +4631,7 @@
.incbin "./build/text/menu_text_french.37ed10.bin"
.incbin "./build/text/menu_text_german.37fb30.bin"
.incbin "./build/bin/unknown.380bb0.bin"
.incbin "./build/cheats/magic_codes.3833a0.ebin"
.incbin "./build/cheats/magic_codes.3833a0.bin"
.incbin "./build/bin/unknown.383760.bin"
.balign 16
.incbin "./build/levels/level_object_maps_lut.383aa0.bin"
+1 -1
View File
@@ -100,7 +100,7 @@ include: "extract-textures/textures_2-us-1.0.extract-config"
[0x27F0]: "Binary", "unknown", "bin"
# [0x3833A0, 0x383760] = Unknown
[0x3C0]: "Encrypted", "magic_codes", "cheats"
[0x3C0]: "Cheats", "magic_codes", "cheats"
# [0x383760, 0x383AA0] = Unknown
[0x340]: "Binary", "unknown", "bin"
+1 -1
View File
@@ -1,5 +1,5 @@
/n64crc
/dkr_decompressor
/dkr_encryptor
/dkr_cheats_encryptor
/dkr_extractor
/dkr_texbuilder
+3 -3
View File
@@ -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
+155
View File
@@ -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;
}
-84
View File
@@ -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
View File
@@ -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;
+1 -1
View File
@@ -16,7 +16,7 @@ enum ConfigRangeType {
BINARY,
NOEXTRACT,
COMPRESSED,
ENCRYPTED,
CHEATS,
TEXTURE
};