mirror of
https://github.com/codestation/mhtools
synced 2024-11-10 05:44:17 +00:00
Added quest decrypt/encrypt and savedata decrypt.
Rewrote crypt package and updated file headers.
This commit is contained in:
parent
3367863918
commit
0f0d6ca0f4
24 changed files with 688 additions and 226 deletions
|
@ -1,4 +1,4 @@
|
|||
/* MHTRANS v1.0
|
||||
/* MHTrans - MH Utilities
|
||||
Copyright (C) 2011 Codestation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
@ -21,7 +21,7 @@ import java.io.EOFException;
|
|||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
public abstract class HelperDec extends EndianFixer {
|
||||
public abstract class HelperDec extends MHUtils {
|
||||
/**
|
||||
* The "readUTF8" function of java expects a different format of the
|
||||
* string so i have to make a custom one
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* MHTRANS v1.0
|
||||
/* MHTrans - MH Utilities
|
||||
Copyright (C) 2011 Codestation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
@ -21,7 +21,7 @@ import java.io.EOFException;
|
|||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
public abstract class HelperEnc extends EndianFixer {
|
||||
public abstract class HelperEnc extends MHUtils {
|
||||
protected String readString(RandomAccessFile file) throws IOException {
|
||||
byte[] buffer = new byte[1024];
|
||||
byte data = 0;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* MHTRANS v1.0
|
||||
/* MHTrans - MH Utilities
|
||||
Copyright (C) 2011 Codestation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
@ -18,14 +18,15 @@
|
|||
package base;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
public abstract class EndianFixer {
|
||||
public abstract class MHUtils {
|
||||
|
||||
protected int readInt(InputStream file) throws IOException, EOFException {
|
||||
public static int readInt(InputStream file) throws IOException, EOFException {
|
||||
int ch1 = file.read();
|
||||
int ch2 = file.read();
|
||||
int ch3 = file.read();
|
||||
|
@ -36,7 +37,7 @@ public abstract class EndianFixer {
|
|||
return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0);
|
||||
}
|
||||
|
||||
protected int readInt(RandomAccessFile file) throws IOException, EOFException {
|
||||
public static int readInt(RandomAccessFile file) throws IOException, EOFException {
|
||||
int ch1 = file.read();
|
||||
int ch2 = file.read();
|
||||
int ch3 = file.read();
|
||||
|
@ -47,7 +48,7 @@ public abstract class EndianFixer {
|
|||
return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0);
|
||||
}
|
||||
|
||||
protected int readShort(InputStream file) throws IOException, EOFException {
|
||||
public static int readShort(InputStream file) throws IOException, EOFException {
|
||||
int ch1 = file.read();
|
||||
int ch2 = file.read();
|
||||
if ((ch1 | ch2) < 0) {
|
||||
|
@ -56,7 +57,7 @@ public abstract class EndianFixer {
|
|||
return (ch2 << 8) + (ch1 << 0);
|
||||
}
|
||||
|
||||
protected void writeShort(OutputStream file, int value) throws IOException {
|
||||
public static void writeShort(OutputStream file, int value) throws IOException {
|
||||
int ch1 = (byte) (value >>> 8);
|
||||
int ch2 = (byte) value;
|
||||
file.write(ch2);
|
||||
|
@ -71,7 +72,7 @@ public abstract class EndianFixer {
|
|||
* @throws IOException
|
||||
* if any error occur while writing
|
||||
*/
|
||||
protected void writeInt(OutputStream file, int value) throws IOException {
|
||||
public static void writeInt(OutputStream file, int value) throws IOException {
|
||||
int ch1 = (byte) (value >>> 24);
|
||||
int ch2 = (byte) (value >>> 16);
|
||||
int ch3 = (byte) (value >>> 8);
|
||||
|
@ -82,7 +83,7 @@ public abstract class EndianFixer {
|
|||
file.write(ch1);
|
||||
}
|
||||
|
||||
protected void writeInt(RandomAccessFile file, int value) throws IOException {
|
||||
public static void writeInt(RandomAccessFile file, int value) throws IOException {
|
||||
int ch1 = (byte) (value >>> 24);
|
||||
int ch2 = (byte) (value >>> 16);
|
||||
int ch3 = (byte) (value >>> 8);
|
||||
|
@ -92,4 +93,24 @@ public abstract class EndianFixer {
|
|||
file.write(ch2);
|
||||
file.write(ch1);
|
||||
}
|
||||
|
||||
public static int extractNumber(String filename) {
|
||||
return Integer.parseInt(filename.substring(filename.indexOf(".") - 4,
|
||||
filename.indexOf(".")));
|
||||
}
|
||||
|
||||
|
||||
public static int getOffset(int value) throws EOFException,
|
||||
FileNotFoundException, IOException {
|
||||
int res = -1;
|
||||
if (value == 0) {
|
||||
res = 0;
|
||||
} else {
|
||||
RandomAccessFile table = new RandomAccessFile("index.bin", "r");
|
||||
table.seek(value * 4 - 4);
|
||||
res = readInt(table);
|
||||
table.close();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/* MHP2GDEC v1.0 - MHP2G xxxx.bin language table extractor/rebuilder/encrypter/decrypter
|
||||
Copyright (C) 2008 Codestation
|
||||
/* MHTrans - MH Utilities
|
||||
Copyright (C) 2008-2011 Codestation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -25,6 +25,8 @@ import java.io.IOException;
|
|||
|
||||
import crypt.Decrypter;
|
||||
import crypt.Encrypter;
|
||||
import crypt.QuestCypher;
|
||||
import crypt.SavedataCypher;
|
||||
import dec.ExtractPluginA;
|
||||
import dec.ExtractPluginB;
|
||||
import dec.ExtractPluginC;
|
||||
|
@ -123,6 +125,11 @@ public class Mhtrans {
|
|||
System.err.println(" java -jar mhtrans.jar --gen-index <data.bin>");
|
||||
System.err.println(" java -jar mhtrans.jar --dec-all <data.bin> <path to output folder>");
|
||||
System.err.println(" java -jar mhtrans.jar --create-patch <xxxx.bin.enc> [ ... <xxxx.bin.enc>] <output_file>");
|
||||
System.err.println(" java -jar mhtrans.jar --decrypt-quest <mxxxxx.mib>");
|
||||
System.err.println(" java -jar mhtrans.jar --encrypt-quest <mxxxxx.mib>");
|
||||
//System.err.println(" java -jar mhtrans.jar --update-sha1 <mxxxxx.mib>");
|
||||
System.err.println(" java -jar mhtrans.jar --decrypt-save <xxxxx.bin>");
|
||||
//System.err.println(" java -jar mhtrans.jar --encrypt-save <xxxxx.bin>");
|
||||
System.exit(1);
|
||||
} else {
|
||||
if (args[0].equals("--extract")) {
|
||||
|
@ -174,6 +181,16 @@ public class Mhtrans {
|
|||
new Decrypter().decrypt_whole(args[1], args[2]);
|
||||
} else if(args[0].equals("--create-patch")) {
|
||||
new PatchBuilder().create(args);
|
||||
} else if(args[0].equals("--encrypt-quest")) {
|
||||
new QuestCypher().encrypt(args[1]);
|
||||
} else if(args[0].equals("--decrypt-quest")) {
|
||||
new QuestCypher().decrypt(args[1]);
|
||||
//} else if(args[0].equals("--update-sha1")) {
|
||||
// new QuestCypher().update_sha1(args[1]);
|
||||
//} else if(args[0].equals("--encrypt-save")) {
|
||||
// new SavedataCypher().encrypt(args[1]);
|
||||
} else if(args[0].equals("--decrypt-save")) {
|
||||
new SavedataCypher().decrypt(args[1]);
|
||||
} else {
|
||||
System.err.println("Unknown parameter: " + args[0]);
|
||||
System.exit(1);
|
||||
|
|
|
@ -1,3 +1,20 @@
|
|||
/* MHTrans - MH Utilities
|
||||
Copyright (C) 2011 Codestation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package base;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
|
@ -15,9 +32,7 @@ import java.util.LinkedHashSet;
|
|||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
import crypt.DecryptTable;
|
||||
|
||||
public class PatchBuilder extends DecryptTable {
|
||||
public class PatchBuilder{// extends DecryptTable {
|
||||
public void create(String[] args) {
|
||||
List<String> list = new ArrayList<String>(Arrays.asList(args));
|
||||
list.remove(0);
|
||||
|
@ -34,13 +49,13 @@ public class PatchBuilder extends DecryptTable {
|
|||
out.setLength(table_size);
|
||||
out.seek(0);
|
||||
long current = 0;
|
||||
writeInt(out, list.size());
|
||||
MHUtils.writeInt(out, list.size());
|
||||
for (String file : list) {
|
||||
int offset = getOffset(extractNumber(file)) << 11;
|
||||
writeInt(out, offset);
|
||||
int offset = MHUtils.getOffset(MHUtils.extractNumber(file)) << 11;
|
||||
MHUtils.writeInt(out, offset);
|
||||
InputStream in = new FileInputStream(file);
|
||||
int len = (int)new File(file).length();
|
||||
writeInt(out, (int)len);
|
||||
MHUtils.writeInt(out, (int)len);
|
||||
System.out.println(file + ", offset: " + offset + ", size: " + len);
|
||||
current = out.getFilePointer();
|
||||
byte buffer[] = new byte[1024];
|
||||
|
@ -50,7 +65,7 @@ public class PatchBuilder extends DecryptTable {
|
|||
in.close();
|
||||
out.seek(current);
|
||||
}
|
||||
writeInt(out, 0);
|
||||
MHUtils.writeInt(out, 0);
|
||||
install_tables(out, list);
|
||||
out.close();
|
||||
}catch(FileNotFoundException e) {
|
||||
|
@ -83,21 +98,21 @@ public class PatchBuilder extends DecryptTable {
|
|||
}
|
||||
Vector<String> install_uniq = new Vector<String>(new LinkedHashSet<String>(install_files));
|
||||
while(install_uniq.remove("NONE"));
|
||||
writeInt(out, install_uniq.size());
|
||||
MHUtils.writeInt(out, install_uniq.size());
|
||||
int install_count = 0;
|
||||
String match = install_files.firstElement();
|
||||
out.write(match.getBytes());
|
||||
writeInt(out, install_count);
|
||||
MHUtils.writeInt(out, install_count);
|
||||
for(String file : install_files) {
|
||||
if(!file.equals("NONE") && !match.equals(file)) {
|
||||
out.write(file.getBytes());
|
||||
match = file;
|
||||
writeInt(out, install_count);
|
||||
MHUtils.writeInt(out, install_count);
|
||||
}
|
||||
install_count++;
|
||||
}
|
||||
for(String trans_file : list) {
|
||||
int index = patch_files.indexOf(extractNumber(trans_file));
|
||||
int index = patch_files.indexOf(MHUtils.extractNumber(trans_file));
|
||||
int offset = -1;
|
||||
if(index != -1) {
|
||||
// UGH!!, 11 years and the Integer.parseInt bug isn't fixed
|
||||
|
@ -107,7 +122,7 @@ public class PatchBuilder extends DecryptTable {
|
|||
} else {
|
||||
System.out.println("Install info not found for " + trans_file);
|
||||
}
|
||||
writeInt(out, offset);
|
||||
MHUtils.writeInt(out, offset);
|
||||
}
|
||||
long filelength = out.length();
|
||||
if(filelength % 16 > 0) {
|
||||
|
@ -121,24 +136,4 @@ public class PatchBuilder extends DecryptTable {
|
|||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The "writeInt" function of java writes in BigEndian mode but we need
|
||||
* LittleEndian so i made a custom function for that
|
||||
*
|
||||
* @param file
|
||||
* @throws IOException
|
||||
* if any error occur while writing
|
||||
*/
|
||||
private void writeInt(RandomAccessFile file, int value)
|
||||
throws IOException {
|
||||
int ch1 = (byte) (value >>> 24);
|
||||
int ch2 = (byte) (value >>> 16);
|
||||
int ch3 = (byte) (value >>> 8);
|
||||
int ch4 = (byte) value;
|
||||
file.write(ch4);
|
||||
file.write(ch3);
|
||||
file.write(ch2);
|
||||
file.write(ch1);
|
||||
}
|
||||
}
|
||||
|
|
90
src/crypt/DecryptUtils.java
Normal file
90
src/crypt/DecryptUtils.java
Normal file
|
@ -0,0 +1,90 @@
|
|||
/* MHTrans - MH decrypter utilities
|
||||
Copyright (C) 2008-2011 Codestation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package crypt;
|
||||
|
||||
public abstract class DecryptUtils {
|
||||
|
||||
protected byte decrypt_table[];
|
||||
|
||||
private long lower_offset;
|
||||
private long upper_offset;
|
||||
|
||||
private long seed_key_a;
|
||||
private long seed_key_b;
|
||||
|
||||
private long mod_a;
|
||||
private long mod_b;
|
||||
|
||||
abstract protected byte[] getDecryptTable();
|
||||
abstract protected long getSeedKeyA();
|
||||
abstract protected long getSeedKeyB();
|
||||
abstract protected long getModA();
|
||||
abstract protected long getModB();
|
||||
|
||||
public DecryptUtils() {
|
||||
decrypt_table = getDecryptTable();
|
||||
seed_key_a = getSeedKeyA();
|
||||
seed_key_b = getSeedKeyB();
|
||||
mod_a = getModA();
|
||||
mod_b = getModB();
|
||||
}
|
||||
|
||||
protected void initSeed(long seed) {
|
||||
lower_offset = seed & 0xFFFF;
|
||||
upper_offset = seed >> 0x10 & 0xFFFF;
|
||||
if (lower_offset == 0) {
|
||||
lower_offset = seed_key_a;
|
||||
}
|
||||
if (upper_offset == 0) {
|
||||
upper_offset = seed_key_b;
|
||||
}
|
||||
}
|
||||
|
||||
protected long getBeta() {
|
||||
lower_offset = (lower_offset * seed_key_a) % mod_a;
|
||||
upper_offset = (upper_offset * seed_key_b) % mod_b;
|
||||
return lower_offset + (upper_offset << 0x10);
|
||||
}
|
||||
|
||||
protected void set_table_value(byte table[], int pos, long value) {
|
||||
table[pos] = (byte) value;
|
||||
table[pos + 1] = (byte) (value >> 8);
|
||||
table[pos + 2] = (byte) (value >> 16);
|
||||
table[pos + 3] = (byte) (value >> 24);
|
||||
}
|
||||
|
||||
protected long get_table_value(byte table[], int pos) {
|
||||
return (table[pos] & 0xFF) + ((long) (table[pos + 1] & 0xFF) << 8)
|
||||
+ ((long) (table[pos + 2] & 0xFF) << 16)
|
||||
+ ((long) (table[pos + 3] & 0xFF) << 24);
|
||||
}
|
||||
|
||||
protected void get_table_value(byte table[], byte buffer[]) {
|
||||
buffer[0] = table[buffer[0] & 0xFF];
|
||||
buffer[1] = table[buffer[1] & 0xFF];
|
||||
buffer[2] = table[buffer[2] & 0xFF];
|
||||
buffer[3] = table[buffer[3] & 0xFF];
|
||||
}
|
||||
|
||||
protected void set_table_data(byte table[], int i) {
|
||||
table[i] = decrypt_table[table[i] & 0xFF];
|
||||
table[i + 1] = decrypt_table[table[i + 1] & 0xFF];
|
||||
table[i + 2] = decrypt_table[table[i + 2] & 0xFF];
|
||||
table[i + 3] = decrypt_table[table[i + 3] & 0xFF];
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/* MHP2GDEC v1.0 - MH data.bin/xxxx.bin decrypter
|
||||
Copyright (C) 2008 Codestation
|
||||
/* MHTrans - MH data.bin/xxxx.bin decrypter
|
||||
Copyright (C) 2008-2011 Codestation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -23,7 +23,12 @@ import java.io.FileNotFoundException;
|
|||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
public class Decrypter extends DecryptTable {
|
||||
import keys.DataKeys;
|
||||
|
||||
import base.MHUtils;
|
||||
|
||||
public class Decrypter extends DecryptUtils implements DataKeys {
|
||||
|
||||
private byte png[] = {(byte) 0x89, 0x50, 0x4e, 0x47};
|
||||
private byte gif[] = {0x47, 0x49, 0x46, 0x38};
|
||||
private byte tmh[] = {0x2e, 0x54, 0x4d, 0x48};
|
||||
|
@ -33,6 +38,31 @@ public class Decrypter extends DecryptTable {
|
|||
private byte dbst[] = {0x64, 0x62, 0x73, 0x54};
|
||||
private byte wav[] = {0x52, 0x49, 0x46, 0x46};
|
||||
|
||||
@Override
|
||||
protected byte[] getDecryptTable() {
|
||||
return decrypter_table;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getSeedKeyA() {
|
||||
return 0x7F8D;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getSeedKeyB() {
|
||||
return 0x2345;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getModA() {
|
||||
return 0xFFF1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getModB() {
|
||||
return 0xFFD9;
|
||||
}
|
||||
|
||||
public void decrypt_index(String in, ByteArrayOutputStream index_buffer) {
|
||||
try {
|
||||
RandomAccessFile filein = new RandomAccessFile(in, "r");
|
||||
|
@ -46,10 +76,7 @@ public class Decrypter extends DecryptTable {
|
|||
int i = 0;
|
||||
while (!table_end) {
|
||||
filein.read(buffer);
|
||||
buffer[0] = decrypt_table[buffer[0] & 0xFF];
|
||||
buffer[1] = decrypt_table[buffer[1] & 0xFF];
|
||||
buffer[2] = decrypt_table[buffer[2] & 0xFF];
|
||||
buffer[3] = decrypt_table[buffer[3] & 0xFF];
|
||||
get_table_value(decrypt_table, buffer);
|
||||
long beta = getBeta();
|
||||
long alpha = get_table_value(buffer, 0);
|
||||
long gamma = alpha ^ beta;
|
||||
|
@ -172,10 +199,7 @@ public class Decrypter extends DecryptTable {
|
|||
int read = filein.read(buffer);
|
||||
size -= read;
|
||||
for (int i = 0; i < read; i += 4) {
|
||||
buffer[i] = decrypt_table[buffer[i] & 0xFF];
|
||||
buffer[i + 1] = decrypt_table[buffer[i + 1] & 0xFF];
|
||||
buffer[i + 2] = decrypt_table[buffer[i + 2] & 0xFF];
|
||||
buffer[i + 3] = decrypt_table[buffer[i + 3] & 0xFF];
|
||||
set_table_data(buffer, i);
|
||||
long alpha = get_table_value(buffer, i);
|
||||
long beta = getBeta();
|
||||
long gamma = alpha ^ beta;
|
||||
|
@ -209,7 +233,7 @@ public class Decrypter extends DecryptTable {
|
|||
try {
|
||||
filein = new RandomAccessFile(in, "r");
|
||||
System.out.print("Decrypting " + out + " ... ");
|
||||
decrypt_internal(filein, getOffset(extractNumber(in)),
|
||||
decrypt_internal(filein, MHUtils.getOffset(MHUtils.extractNumber(in)),
|
||||
filein.length(), out, true);
|
||||
|
||||
} catch (FileNotFoundException e) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* MHP2GDEC v1.0 - MHP2G data.bin/xxxx.bin encrypter
|
||||
Copyright (C) 2008 Codestation
|
||||
/* MHTrans - MH data.bin/xxxx.bin decrypter
|
||||
Copyright (C) 2008-2011 Codestation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -21,10 +21,39 @@ import java.io.FileNotFoundException;
|
|||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
public class Encrypter extends DecryptTable {
|
||||
import keys.DataKeys;
|
||||
|
||||
import base.MHUtils;
|
||||
|
||||
public class Encrypter extends DecryptUtils implements DataKeys {
|
||||
|
||||
private byte[] encrypt_table;
|
||||
|
||||
@Override
|
||||
protected byte[] getDecryptTable() {
|
||||
return decrypter_table;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getSeedKeyA() {
|
||||
return 0x7F8D;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getSeedKeyB() {
|
||||
return 0x2345;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getModA() {
|
||||
return 0xFFF1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getModB() {
|
||||
return 0xFFD9;
|
||||
}
|
||||
|
||||
public Encrypter() {
|
||||
encrypt_table = new byte[256];
|
||||
for (int i = 0; i < 256; i++) {
|
||||
|
@ -36,9 +65,9 @@ public class Encrypter extends DecryptTable {
|
|||
try {
|
||||
RandomAccessFile filein = new RandomAccessFile(in, "r");
|
||||
RandomAccessFile fileout = new RandomAccessFile(out, "rw");
|
||||
int file_number = extractNumber(in);
|
||||
int file_number = MHUtils.extractNumber(in);
|
||||
long file_len = filein.length();
|
||||
long table_len = (getOffset(file_number + 1) << 11) - (getOffset(file_number) << 11);
|
||||
long table_len = (MHUtils.getOffset(file_number + 1) << 11) - (MHUtils.getOffset(file_number) << 11);
|
||||
if(file_len < table_len) {
|
||||
System.out.println(in + " filesize is less than the stored table by " +
|
||||
(table_len - file_len) + " bytes, fill the file with 0x00 at the end");
|
||||
|
@ -48,7 +77,7 @@ public class Encrypter extends DecryptTable {
|
|||
(file_len - table_len) + " bytes, aborting");
|
||||
System.exit(1);
|
||||
}
|
||||
initSeed(getOffset(file_number));
|
||||
initSeed(MHUtils.getOffset(file_number));
|
||||
byte[] buffer = new byte[4];
|
||||
System.out.println("Encrypting " + in);
|
||||
while (filein.read(buffer) >= 0) {
|
||||
|
@ -56,10 +85,7 @@ public class Encrypter extends DecryptTable {
|
|||
long beta = getBeta();
|
||||
long alpha = beta ^ gamma;
|
||||
set_table_value(buffer, 0, alpha);
|
||||
buffer[0] = encrypt_table[buffer[0] & 0xFF];
|
||||
buffer[1] = encrypt_table[buffer[1] & 0xFF];
|
||||
buffer[2] = encrypt_table[buffer[2] & 0xFF];
|
||||
buffer[3] = encrypt_table[buffer[3] & 0xFF];
|
||||
get_table_value(encrypt_table, buffer);
|
||||
fileout.write(buffer);
|
||||
}
|
||||
filein.close();
|
||||
|
|
150
src/crypt/QuestCypher.java
Normal file
150
src/crypt/QuestCypher.java
Normal file
|
@ -0,0 +1,150 @@
|
|||
/* MHTrans - MH quest decrypter/encrypter
|
||||
Copyright (C) 2011 Codestation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package crypt;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.ShortBuffer;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import keys.QuestKeys;
|
||||
|
||||
public class QuestCypher implements QuestKeys {
|
||||
|
||||
private short key_var_table[] = {0, 0, 0, 0};
|
||||
|
||||
public boolean decrypt(String filein) {
|
||||
try {
|
||||
File fd = new File(filein);
|
||||
FileInputStream in = new FileInputStream(fd);
|
||||
byte byte_bt[] = new byte[(int)fd.length()];
|
||||
in.read(byte_bt);
|
||||
in.close();
|
||||
ByteBuffer bt = ByteBuffer.wrap(byte_bt);
|
||||
bt.order(ByteOrder.LITTLE_ENDIAN);
|
||||
ShortBuffer sb = bt.asShortBuffer();
|
||||
short short_bt[] = new short[byte_bt.length/2];
|
||||
sb.get(short_bt);
|
||||
decrypt_quest(short_bt);
|
||||
sb.rewind();
|
||||
sb.put(short_bt);
|
||||
FileOutputStream out = new FileOutputStream(filein + ".dec");
|
||||
out.write(byte_bt);
|
||||
out.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean encrypt(String filein) {
|
||||
try {
|
||||
File fd = new File(filein);
|
||||
FileInputStream in = new FileInputStream(fd);
|
||||
byte byte_bt[] = new byte[(int)fd.length()];
|
||||
in.read(byte_bt);
|
||||
in.close();
|
||||
update_sha1(byte_bt);
|
||||
ByteBuffer bt = ByteBuffer.wrap(byte_bt);
|
||||
bt.order(ByteOrder.LITTLE_ENDIAN);
|
||||
ShortBuffer sb = bt.asShortBuffer();
|
||||
short short_bt[] = new short[byte_bt.length/2];
|
||||
sb.get(short_bt);
|
||||
encrypt_quest(short_bt);
|
||||
sb.rewind();
|
||||
sb.put(short_bt);
|
||||
FileOutputStream out = new FileOutputStream(filein + ".enc");
|
||||
out.write(byte_bt);
|
||||
out.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void decrypt_quest(short pData[]) {
|
||||
calc_key(key_var_table, pData);
|
||||
for(int i = 8; i < pData.length*2; i += 2) {
|
||||
int index = (i >> 1);
|
||||
int key = get_xor_key(key_var_table, index & 0x03);
|
||||
pData[index] ^= (short)(key & 0xFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
private void encrypt_quest(short pData[]) {
|
||||
decrypt_quest(pData);
|
||||
}
|
||||
|
||||
private void calc_key(short pTable[], short pData[]) {
|
||||
for(int i = 0; i < 4; i++) {
|
||||
pTable[i] = pData[i];
|
||||
if (pTable[i] == 0){
|
||||
pTable[i] = (short)(seed_0[i] & 0xFFFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
int i = 0;
|
||||
private int get_xor_key(short pTable[], int pos) {
|
||||
int key = (int) ((long)(pTable[pos] & 0xFFFF) * (long)(seed_0[pos] & 0xFFFF) % (seed_1[pos] & 0xFFFF));
|
||||
pTable[pos] = (short)(key & 0xFFFF);
|
||||
return key;
|
||||
}
|
||||
|
||||
public void update_sha1(String file) {
|
||||
try {
|
||||
RandomAccessFile fd = new RandomAccessFile(file, "rw");
|
||||
byte byte_bt[] = new byte[(int)fd.length()];
|
||||
fd.read(byte_bt);
|
||||
fd.seek(0);
|
||||
update_sha1(byte_bt);
|
||||
fd.write(byte_bt);
|
||||
fd.close();
|
||||
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void update_sha1(byte buf[]) {
|
||||
int len = ((buf[8+3] << 24) & 0xFFFFFFFF) + ((buf[8+2] << 16) & 0xFFFFFF) + ((buf[8+1] << 8) & 0xFFFF) + ((buf[8+0] << 0) & 0xFF);
|
||||
len += 0x10;
|
||||
byte buffer[] = new byte[len];
|
||||
System.arraycopy(buf, 0x20, buffer, 0, len-0x10);
|
||||
System.arraycopy(quest_sha1_key.getBytes(), 0, buffer, len-0x10, 0x10);
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("sha-1");
|
||||
byte digest[] = md.digest(buffer);
|
||||
System.arraycopy(digest, 0, buf, 12, 0x10);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
87
src/crypt/SavedataCypher.java
Normal file
87
src/crypt/SavedataCypher.java
Normal file
|
@ -0,0 +1,87 @@
|
|||
/* MHTrans - MH savedata decrypter/encrypter
|
||||
Copyright (C) 2011 Codestation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package crypt;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
import keys.SavedataKeys;
|
||||
|
||||
public class SavedataCypher extends DecryptUtils implements SavedataKeys {
|
||||
|
||||
@Override
|
||||
protected byte[] getDecryptTable() {
|
||||
return decrypter_table;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getSeedKeyA() {
|
||||
return seed_a;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getSeedKeyB() {
|
||||
return seed_b;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getModA() {
|
||||
return mod_a;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getModB() {
|
||||
return mod_b;
|
||||
}
|
||||
|
||||
public boolean decrypt(String file) {
|
||||
try {
|
||||
RandomAccessFile fd = new RandomAccessFile(file, "rw");
|
||||
byte byte_bt[] = new byte[(int)fd.length()];
|
||||
fd.read(byte_bt);
|
||||
fd.seek(0);
|
||||
decrypt_buffer(byte_bt);
|
||||
fd.write(byte_bt);
|
||||
fd.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void decrypt_buffer(byte buffer[]) {
|
||||
int len = buffer.length - 4;
|
||||
byte seed[] = new byte[4];
|
||||
System.arraycopy(buffer, len, seed, 0, 4);
|
||||
get_table_value(decrypt_table, seed);
|
||||
get_table_value(decrypt_table, seed);
|
||||
long alpha = get_table_value(seed, 0);
|
||||
initSeed(alpha);
|
||||
for (int i = 0; i < len; i += 4) {
|
||||
set_table_data(buffer, i);
|
||||
alpha = get_table_value(buffer, i);
|
||||
long beta = getBeta();
|
||||
long gamma = alpha ^ beta;
|
||||
set_table_value(buffer, i, gamma);
|
||||
set_table_data(buffer, i);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/* MHP2GDEC v1.0 - MHP2G 0016/0017/475x.bin language table extractor
|
||||
Copyright (C) 2008-2010 Codestation
|
||||
/* MHTrans - MHP2G 0016/0017/475x.bin language table extractor
|
||||
Copyright (C) 2008-2011 Codestation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* MHP2GDEC v1.0 - MHP2G 53xx.bin language table extractor
|
||||
Copyright (C) 2008 Codestation
|
||||
/* MHTrans - MHP2G 53xx.bin language table extractor
|
||||
Copyright (C) 2008-2011 Codestation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* MHP2GDEC v1.0 - MHP2G 537x.bin language table extractor
|
||||
Copyright (C) 2008 Codestation
|
||||
/* MHTrans - MHP2G 537x.bin language table extractor
|
||||
Copyright (C) 2008-2011 Codestation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* MHP2GDEC v1.0 - MH TMH image extractor
|
||||
/* MHTrans - MH TMH image extractor
|
||||
Copyright (C) 2011 Codestation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
@ -30,14 +30,14 @@ import javax.imageio.ImageIO;
|
|||
|
||||
|
||||
import base.Decoder;
|
||||
import base.EndianFixer;
|
||||
import base.MHUtils;
|
||||
|
||||
/**
|
||||
* ExtractPluginD v1.0
|
||||
*
|
||||
* @author Codestation
|
||||
*/
|
||||
public class ExtractPluginD extends EndianFixer implements Decoder {
|
||||
public class ExtractPluginD extends MHUtils implements Decoder {
|
||||
|
||||
@Override
|
||||
public void extract(String filename) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* MHP2GDEC v1.0 - MH TMH image extractor
|
||||
/* MHTrans - MH TMH image extractor
|
||||
Copyright (C) 2011 Codestation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
@ -24,7 +24,7 @@ import java.io.IOException;
|
|||
import java.io.RandomAccessFile;
|
||||
|
||||
import base.Decoder;
|
||||
import base.EndianFixer;
|
||||
import base.MHUtils;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -32,7 +32,7 @@ import base.EndianFixer;
|
|||
*
|
||||
* @author Codestation
|
||||
*/
|
||||
public class ExtractPluginE extends EndianFixer implements Decoder {
|
||||
public class ExtractPluginE extends MHUtils implements Decoder {
|
||||
|
||||
byte pmo[] = {0x70, 0x6d, 0x6f, 0x00};
|
||||
byte tmh[] = {0x2E, 0x54, 0x4D, 0x48};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* MHP2GENC v1.0 - MHP 0016/475x/0017.bin language table rebuilder
|
||||
Copyright (C) 2008-2010 codestation
|
||||
/* MHTrans - MHP 0016/475x/0017.bin language table rebuilder
|
||||
Copyright (C) 2008-2011 Codestation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* MHP2GENC v1.0 - MHP2G 53xx.bin language table rebuilder
|
||||
Copyright (C) 2008 Codestation
|
||||
/* MHTrans - MHP2G 53xx.bin language table rebuilder
|
||||
Copyright (C) 2008-2011 Codestation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* MHP2GENC v1.0 - MHP2G 537x.bin language table rebuilder
|
||||
Copyright (C) 2008 Codestation
|
||||
/* MHTrans - MHP2G 537x.bin language table rebuilder
|
||||
Copyright (C) 2008-2011 Codestation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* MHP2GENC v1.0 - TMH image rebuilder
|
||||
Copyright (C) 2008-2010 codestation
|
||||
/* MHTrans - TMH image rebuilder
|
||||
Copyright (C) 2011 Codestation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -33,14 +33,14 @@ import javax.imageio.ImageIO;
|
|||
|
||||
|
||||
import base.Encoder;
|
||||
import base.EndianFixer;
|
||||
import base.MHUtils;
|
||||
|
||||
/**
|
||||
* RebuildPluginD v1.0
|
||||
*
|
||||
* @author Codestation
|
||||
*/
|
||||
public class RebuildPluginD extends EndianFixer implements Encoder {
|
||||
public class RebuildPluginD extends MHUtils implements Encoder {
|
||||
|
||||
private byte id[] = {0x2e, 0x54, 0x4d, 0x48, 0x30, 0x2e, 0x31, 0x34};
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* MHP2GENC v1.0 - PAK rebuilder
|
||||
Copyright (C) 2008-2010 codestation
|
||||
/* MHTrans - PAK rebuilder
|
||||
Copyright (C) 2011 Codestation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -28,14 +28,14 @@ import java.util.Comparator;
|
|||
import java.util.Vector;
|
||||
|
||||
import base.Encoder;
|
||||
import base.EndianFixer;
|
||||
import base.MHUtils;
|
||||
|
||||
/**
|
||||
* RebuildPluginE v1.0
|
||||
*
|
||||
* @author Codestation
|
||||
*/
|
||||
public class RebuildPluginE extends EndianFixer implements Encoder {
|
||||
public class RebuildPluginE extends MHUtils implements Encoder {
|
||||
|
||||
@Override
|
||||
public void compile(String filepath) {
|
||||
|
|
|
@ -1,3 +1,20 @@
|
|||
/* MHTrans - GIM image creator
|
||||
Copyright (C) 2011 Codestation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package img;
|
||||
|
||||
import java.io.EOFException;
|
||||
|
@ -5,9 +22,9 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import base.EndianFixer;
|
||||
import base.MHUtils;
|
||||
|
||||
public class Gim extends EndianFixer {
|
||||
public class Gim extends MHUtils {
|
||||
|
||||
public static final int RGBA8888 = 3;
|
||||
public static final int RGBA5551 = 1;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* MHP2GDEC v1.0 - MH data.bin/xxxx.bin encrypter/decrypter
|
||||
Copyright (C) 2008 codestation
|
||||
/* MHTrans - MHP3 data keys
|
||||
Copyright (C) 2011 Codestation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -15,17 +15,10 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package crypt;
|
||||
package keys;
|
||||
|
||||
//import java.io.EOFException;
|
||||
import java.io.EOFException;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
public abstract class DecryptTable {
|
||||
|
||||
protected final byte decrypt_table[] = { (byte) 0xCB, (byte) 0x96,
|
||||
public interface DataKeys {
|
||||
final byte decrypter_table[] = { (byte) 0xCB, (byte) 0x96,
|
||||
(byte) 0x85, (byte) 0xA6, (byte) 0x5F, (byte) 0x3E, (byte) 0xAB,
|
||||
(byte) 0x03, (byte) 0x50, (byte) 0xB7, (byte) 0x9C, (byte) 0x5C,
|
||||
(byte) 0xB2, (byte) 0x40, (byte) 0xEF, (byte) 0xF6, (byte) 0xFF,
|
||||
|
@ -78,70 +71,9 @@ public abstract class DecryptTable {
|
|||
(byte) 0x60, (byte) 0xEE, (byte) 0x98, (byte) 0x6B, (byte) 0x0D,
|
||||
(byte) 0x99, (byte) 0xEA, (byte) 0xC5, (byte) 0xAC };
|
||||
|
||||
private long lower_offset;
|
||||
private long upper_offset;
|
||||
final long seed_a = 0x7F8D;
|
||||
final long seed_b = 0x2345;
|
||||
final long mod_a = 0xFFF1;
|
||||
final long mod_b = 0xFFD9;
|
||||
|
||||
protected void initSeed(long seed) {
|
||||
lower_offset = seed & 0xFFFF;
|
||||
upper_offset = seed >> 0x10 & 0xFFFF;
|
||||
if (lower_offset == 0) {
|
||||
lower_offset = 0x7F8D;
|
||||
}
|
||||
if (upper_offset == 0) {
|
||||
upper_offset = 0x2345;
|
||||
}
|
||||
}
|
||||
|
||||
protected long getBeta() {
|
||||
lower_offset = (lower_offset * 0x7F8D) % 0xFFF1;
|
||||
upper_offset = (upper_offset * 0x2345) % 0xFFD9;
|
||||
return lower_offset + (upper_offset << 0x10);
|
||||
}
|
||||
|
||||
protected void set_table_value(byte table[], int pos, long value) {
|
||||
table[pos] = (byte) value;
|
||||
table[pos + 1] = (byte) (value >> 8);
|
||||
table[pos + 2] = (byte) (value >> 16);
|
||||
table[pos + 3] = (byte) (value >> 24);
|
||||
}
|
||||
|
||||
protected long get_table_value(byte table[], int pos) {
|
||||
return (table[pos] & 0xFF) + ((long) (table[pos + 1] & 0xFF) << 8)
|
||||
+ ((long) (table[pos + 2] & 0xFF) << 16)
|
||||
+ ((long) (table[pos + 3] & 0xFF) << 24);
|
||||
}
|
||||
|
||||
/*
|
||||
* Can't use the RandomAccessFile readInt func as we need the bytes in
|
||||
* reverse order
|
||||
*/
|
||||
private int readInt(RandomAccessFile file) throws IOException, EOFException {
|
||||
int ch1 = file.read();
|
||||
int ch2 = file.read();
|
||||
int ch3 = file.read();
|
||||
int ch4 = file.read();
|
||||
if ((ch1 | ch2 | ch3 | ch4) < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0);
|
||||
}
|
||||
|
||||
protected int getOffset(int value) throws EOFException,
|
||||
FileNotFoundException, IOException {
|
||||
int res = -1;
|
||||
if (value == 0) {
|
||||
res = 0;
|
||||
} else {
|
||||
RandomAccessFile table = new RandomAccessFile("index.bin", "r");
|
||||
table.seek(value * 4 - 4);
|
||||
res = readInt(table);
|
||||
table.close();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
protected int extractNumber(String filename) {
|
||||
return Integer.parseInt(filename.substring(filename.indexOf(".") - 4,
|
||||
filename.indexOf(".")));
|
||||
}
|
||||
}
|
25
src/keys/QuestKeys.java
Normal file
25
src/keys/QuestKeys.java
Normal file
|
@ -0,0 +1,25 @@
|
|||
/* MHTrans - MHP3 quest keys
|
||||
Copyright (C) 2011 Codestation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package keys;
|
||||
|
||||
public interface QuestKeys {
|
||||
final int seed_0[] = {0x3DF3, 0x1709, 0xB381, 0x747B};
|
||||
final int seed_1[] = {0xFFA9, 0xFF9D, 0xFFF1, 0xFFC7};
|
||||
|
||||
final String quest_sha1_key = "sR2Tf4eLAj8b3TH7";
|
||||
}
|
78
src/keys/SavedataKeys.java
Normal file
78
src/keys/SavedataKeys.java
Normal file
|
@ -0,0 +1,78 @@
|
|||
/* MHTrans - MHP3 savedata keys
|
||||
Copyright (C) 2011 Codestation
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package keys;
|
||||
|
||||
public interface SavedataKeys {
|
||||
final byte decrypter_table[] = { (byte) 0xA6, (byte) 0x21,
|
||||
(byte) 0x22, (byte) 0xF9, (byte) 0x3D, (byte) 0xFB, (byte) 0xF5,
|
||||
(byte) 0x06, (byte) 0x87, (byte) 0x54, (byte) 0x76, (byte) 0x75,
|
||||
(byte) 0xED, (byte) 0x16, (byte) 0x33, (byte) 0x2E, (byte) 0x5A,
|
||||
(byte) 0x17, (byte) 0x50, (byte) 0x1C, (byte) 0xDE, (byte) 0xAF,
|
||||
(byte) 0x73, (byte) 0x39, (byte) 0xB5, (byte) 0x28, (byte) 0xD9,
|
||||
(byte) 0xF1, (byte) 0xCD, (byte) 0x98, (byte) 0x5F, (byte) 0x2D,
|
||||
(byte) 0x78, (byte) 0x62, (byte) 0x29, (byte) 0xC9, (byte) 0xFD,
|
||||
(byte) 0xEA, (byte) 0x32, (byte) 0xCC, (byte) 0x31, (byte) 0x70,
|
||||
(byte) 0x34, (byte) 0x61, (byte) 0xAE, (byte) 0x4D, (byte) 0xFE,
|
||||
(byte) 0xC2, (byte) 0x45, (byte) 0x24, (byte) 0xF8, (byte) 0xFC,
|
||||
(byte) 0xD7, (byte) 0x2F, (byte) 0xD8, (byte) 0x26, (byte) 0x59,
|
||||
(byte) 0xA0, (byte) 0xBD, (byte) 0xA5, (byte) 0x01, (byte) 0x18,
|
||||
(byte) 0xA1, (byte) 0x95, (byte) 0xEE, (byte) 0x4B, (byte) 0x1A,
|
||||
(byte) 0x7A, (byte) 0x5B, (byte) 0xDB, (byte) 0xF0, (byte) 0x27,
|
||||
(byte) 0xE6, (byte) 0xF4, (byte) 0xB2, (byte) 0xAD, (byte) 0x4A,
|
||||
(byte) 0x14, (byte) 0x9A, (byte) 0x20, (byte) 0xB9, (byte) 0x36,
|
||||
(byte) 0x4F, (byte) 0x3B, (byte) 0xCA, (byte) 0xE4, (byte) 0x41,
|
||||
(byte) 0x85, (byte) 0x3A, (byte) 0x46, (byte) 0x5C, (byte) 0xCB,
|
||||
(byte) 0x3C, (byte) 0xEC, (byte) 0x63, (byte) 0x84, (byte) 0x66,
|
||||
(byte) 0xC4, (byte) 0xEB, (byte) 0x25, (byte) 0xAA, (byte) 0x7E,
|
||||
(byte) 0xC3, (byte) 0x47, (byte) 0x9B, (byte) 0x74, (byte) 0x8B,
|
||||
(byte) 0x5D, (byte) 0x23, (byte) 0x8F, (byte) 0x72, (byte) 0x81,
|
||||
(byte) 0x8C, (byte) 0x56, (byte) 0xC6, (byte) 0xD4, (byte) 0x40,
|
||||
(byte) 0x60, (byte) 0xA2, (byte) 0x6D, (byte) 0xE5, (byte) 0xB0,
|
||||
(byte) 0x15, (byte) 0x58, (byte) 0x52, (byte) 0x0F, (byte) 0x7D,
|
||||
(byte) 0x67, (byte) 0xEF, (byte) 0xD2, (byte) 0x0B, (byte) 0xCF,
|
||||
(byte) 0x0D, (byte) 0xD6, (byte) 0x2B, (byte) 0x0A, (byte) 0x9F,
|
||||
(byte) 0x80, (byte) 0x5E, (byte) 0x3F, (byte) 0x71, (byte) 0x68,
|
||||
(byte) 0x05, (byte) 0x86, (byte) 0xBB, (byte) 0x38, (byte) 0xCE,
|
||||
(byte) 0x7F, (byte) 0xF3, (byte) 0x83, (byte) 0x03, (byte) 0x48,
|
||||
(byte) 0xD3, (byte) 0xFA, (byte) 0x35, (byte) 0xDF, (byte) 0x44,
|
||||
(byte) 0x7C, (byte) 0x82, (byte) 0x93, (byte) 0x53, (byte) 0xA3,
|
||||
(byte) 0x09, (byte) 0x6A, (byte) 0x77, (byte) 0x13, (byte) 0x55,
|
||||
(byte) 0xDD, (byte) 0xBE, (byte) 0x00, (byte) 0x9C, (byte) 0xB4,
|
||||
(byte) 0xE3, (byte) 0x9E, (byte) 0xBC, (byte) 0x96, (byte) 0xA7,
|
||||
(byte) 0xE2, (byte) 0x42, (byte) 0x4E, (byte) 0x37, (byte) 0x0E,
|
||||
(byte) 0xF6, (byte) 0x9D, (byte) 0x1B, (byte) 0x2A, (byte) 0x79,
|
||||
(byte) 0xBF, (byte) 0xDC, (byte) 0xA9, (byte) 0x88, (byte) 0x4C,
|
||||
(byte) 0xD0, (byte) 0xAB, (byte) 0xC5, (byte) 0x69, (byte) 0xD1,
|
||||
(byte) 0xE1, (byte) 0xAC, (byte) 0xE9, (byte) 0xC1, (byte) 0xB6,
|
||||
(byte) 0x7B, (byte) 0x57, (byte) 0x90, (byte) 0x07, (byte) 0x30,
|
||||
(byte) 0x92, (byte) 0xB7, (byte) 0x1E, (byte) 0xDA, (byte) 0x49,
|
||||
(byte) 0x0C, (byte) 0xB8, (byte) 0xA4, (byte) 0xFF, (byte) 0xB3,
|
||||
(byte) 0xF2, (byte) 0x64, (byte) 0x8A, (byte) 0xC7, (byte) 0x02,
|
||||
(byte) 0x6C, (byte) 0x08, (byte) 0x6F, (byte) 0xF7, (byte) 0x89,
|
||||
(byte) 0xC0, (byte) 0x10, (byte) 0xA8, (byte) 0x8D, (byte) 0xBA,
|
||||
(byte) 0x91, (byte) 0x43, (byte) 0x6B, (byte) 0x3E, (byte) 0xD5,
|
||||
(byte) 0x65, (byte) 0xE0, (byte) 0x6E, (byte) 0x12, (byte) 0x2C,
|
||||
(byte) 0x94, (byte) 0x99, (byte) 0xE8, (byte) 0x1F, (byte) 0xC8,
|
||||
(byte) 0x11, (byte) 0x8E, (byte) 0xB1, (byte) 0xE7, (byte) 0x51,
|
||||
(byte) 0x1D, (byte) 0x97, (byte) 0x04, (byte) 0x19 };
|
||||
|
||||
final long seed_a = 0x215F;
|
||||
final long seed_b = 0xDFA3;
|
||||
final long mod_a = 0xFF8F;
|
||||
final long mod_b = 0xFFEF;
|
||||
}
|
Loading…
Reference in a new issue