summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--INSTALL.md1
-rw-r--r--Makefile4
-rw-r--r--tools/Makefile4
-rw-r--r--tools/mwasmarm_patcher/Makefile7
-rw-r--r--tools/mwasmarm_patcher/mwasmarm_patcher.c94
5 files changed, 95 insertions, 15 deletions
diff --git a/INSTALL.md b/INSTALL.md
index 29c650d8..76059419 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -17,7 +17,6 @@ Building the ROM requires the following packages:
* make
* git
* build-essentials
-* libssl-dev
* binutils-arm-linux-gnueabi
#### Windows
diff --git a/Makefile b/Makefile
index 0b43fef2..3a21944c 100644
--- a/Makefile
+++ b/Makefile
@@ -34,7 +34,7 @@ O_FILES := $(foreach file,$(C_FILES),$(BUILD_DIR)/$(file:.c=.o)) \
################### Universal Dependencies ###################
# Make tools if out of date
-DUMMY != make -s -C tools >&2 || echo FAIL
+DUMMY != make -s -C tools/mwasmarm_patcher >&2 || echo FAIL
ifeq ($(DUMMY),FAIL)
$(error Failed to build tools)
endif
@@ -96,7 +96,7 @@ $(BUILD_DIR)/$(LD_SCRIPT): $(LD_SCRIPT)
$(CPP) $(VERSION_CFLAGS) -MMD -MP -MT $@ -MF $@.d -I include/ -I . -DBUILD_DIR=$(BUILD_DIR) -o $@ $<
$(ELF): $(O_FILES) $(BUILD_DIR)/$(LD_SCRIPT)
- $(LD) $(BUILD_DIR)/$(LD_SCRIPT) -o $(ELF) $(O_FILES) -nodead -w off
+ $(LD) $(BUILD_DIR)/$(LD_SCRIPT) -o $(ELF) $(O_FILES) -nodead -w off -interworking
$(ROM): $(ELF)
$(OBJCOPY) -O binary $< $@
diff --git a/tools/Makefile b/tools/Makefile
deleted file mode 100644
index 5a9eeb69..00000000
--- a/tools/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-all: mwasmarm_patcher
-
-mwasmarm_patcher: mwasmarm_patcher/mwasmarm_patcher.c
- gcc mwasmarm_patcher/mwasmarm_patcher.c -o mwasmarm_patcher/mwasmarm_patcher -lssl -lcrypto
diff --git a/tools/mwasmarm_patcher/Makefile b/tools/mwasmarm_patcher/Makefile
new file mode 100644
index 00000000..5cf20ee4
--- /dev/null
+++ b/tools/mwasmarm_patcher/Makefile
@@ -0,0 +1,7 @@
+CC := gcc
+CFLAGS := -O3
+
+all: mwasmarm_patcher
+
+mwasmarm_patcher: mwasmarm_patcher.c
+ $(CC) $(CFLAGS) -o $@ $< -lssl -lcrypto
diff --git a/tools/mwasmarm_patcher/mwasmarm_patcher.c b/tools/mwasmarm_patcher/mwasmarm_patcher.c
index 41271ae5..1330e650 100644
--- a/tools/mwasmarm_patcher/mwasmarm_patcher.c
+++ b/tools/mwasmarm_patcher/mwasmarm_patcher.c
@@ -1,6 +1,5 @@
#include <stdint.h>
#include <stdio.h>
-#include <openssl/sha.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
@@ -49,6 +48,76 @@ struct PatchDef gPatchDefs[] = {
}
};
+void sha1_process_block (const unsigned char * block, uint32_t * state);
+
+// Credit to ax6 for implementation
+unsigned char * calculate_sha1 (const void * data, unsigned length) {
+ uint32_t state[5] = {0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0};
+ const char * current;
+ unsigned remaining;
+ for (current = data, remaining = length; remaining >= 64; current += 64, remaining -= 64) sha1_process_block(current, state);
+ // technically only {0} is necessary, but better safe than sorry
+ unsigned char last_block[64] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ memcpy(last_block, current, remaining);
+ last_block[remaining] = 0x80;
+ if (remaining >= 56) {
+ sha1_process_block(last_block, state);
+ memset(last_block, 0, 64);
+ }
+ unsigned long long bit_length = ((unsigned long long) length) << 3;
+ for (remaining = 5; remaining; remaining --) {
+ last_block[58 + remaining] = bit_length;
+ bit_length >>= 8;
+ }
+ sha1_process_block(last_block, state);
+ unsigned char * result = malloc(20);
+ for (remaining = 0; remaining < 20; remaining ++) result[remaining] = state[remaining >> 2] >> ((~remaining & 3) << 3);
+ return result;
+}
+
+static inline unsigned sha1_rotate (unsigned value, unsigned count) {
+ return (value << count) | (value >> (32 - count));
+}
+
+void sha1_process_block (const unsigned char * block, uint32_t * state) {
+ uint32_t words[80];
+ unsigned pos, temp, count, a, b, c, d, e;
+ // constants used by SHA-1; they are actually simply the square roots of 2, 3, 5 and 10 as a fixed-point number (2.30 format)
+ const uint32_t hash_constants[4] = {0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6};
+ memset(words, 0, 16 * sizeof(uint32_t));
+ for (pos = 0; pos < 64; pos ++) words[pos >> 2] = (words[pos >> 2] << 8) | block[pos];
+ for (pos = 16; pos < 80; pos ++) words[pos] = sha1_rotate(words[pos - 3] ^ words[pos - 8] ^ words[pos - 14] ^ words[pos - 16], 1);
+ a = *state;
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+ for (pos = 0; pos < 4; pos ++) for (count = 0; count < 20; count ++) {
+ temp = sha1_rotate(a, 5) + e + words[pos * 20 + count] + hash_constants[pos];
+ switch (pos) {
+ case 0:
+ temp += (b & c) | (~b & d);
+ break;
+ case 2:
+ temp += (b & c) | (b & d) | (c & d);
+ break;
+ default:
+ temp += b ^ c ^ d;
+ }
+ e = d;
+ d = c;
+ c = sha1_rotate(b, 30);
+ b = a;
+ a = temp;
+ }
+ *state += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+}
+
void fatal_printf(char *str, ...) {
va_list args;
va_start(args, str);
@@ -66,14 +135,13 @@ int get_file_size (FILE * fp) {
return result;
}
+#define SHA_DIGEST_LENGTH 20
+
void print_help(void) {
printf("mwasmarm patcher usage: input (example: mwasmarm_patcher mwasmarm.exe)\n");
}
int main(int argc, char *argv[]) {
- unsigned char temp[SHA_DIGEST_LENGTH];
- char buf[SHA_DIGEST_LENGTH*2];
-
if (argc != 2) {
print_help();
return 1;
@@ -84,16 +152,26 @@ int main(int argc, char *argv[]) {
fatal_printf("ERROR: No file detected\n");
}
int fsize = get_file_size(f);
- char *string = malloc(fsize + 1);
- fread(string, 1, fsize, f);
+ unsigned char *string = malloc(fsize + 1);
+ if(string == NULL) {
+ fatal_printf("ERROR: Failed to allocate string variable\n");
+ }
+ int readvar = fread(string, 1, fsize, f); // var to surpress warning
// Check if sha1 matches either known assembler hashes.
- SHA1(string, fsize, temp);
+ unsigned char *sha1 = calculate_sha1(string, fsize);
+ if(sha1 == NULL) {
+ fatal_printf("ERROR: Failed to retrieve sha1 hash\n");
+ }
+ free(string);
+ unsigned char buf[SHA_DIGEST_LENGTH*2];
for (int i=0; i < SHA_DIGEST_LENGTH; i++) {
- sprintf((char*)&(buf[i*2]), "%02x", temp[i]);
+ sprintf((unsigned char*)&(buf[i*2]), "%02x", sha1[i]);
}
+ printf("SHA1: %s\n", buf);
+
for(int i = 0; gPatchDefs[i].sha1before != NULL; i++) {
// check if already patched for the current loop.
if(!strcmp(buf, gPatchDefs[i].sha1after)) {