From 5f1318919376ec679f5300257b41b28dc68e6f4f Mon Sep 17 00:00:00 2001 From: ProjectRevoTPP Date: Sat, 18 Apr 2020 13:51:39 -0400 Subject: update mwasmarm_patcher to get rid of libssl dependency. --- tools/mwasmarm_patcher/mwasmarm_patcher.c | 94 ++++++++++++++++++++++++++++--- 1 file changed, 86 insertions(+), 8 deletions(-) (limited to 'tools/mwasmarm_patcher/mwasmarm_patcher.c') 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 #include -#include #include #include #include @@ -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)) { -- cgit v1.2.3