hashcat Forum

Full Version: [RFC] Carmageddon cheat retrieval
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello,



Recently we've begun looking into reverse engineering the old venerable Carmageddon game.

As part of this, we found hashes of cheat codes in the binary.



The game engine applies a hash function on the recent keys and looks into a table for matches.

This avoids putting the cheat codes as strings into the binary.



I've created a hashcat module to find matches, at https://github.com/madebr/hashcat/tree/carmageddon.

I'm interested in feedback about ways to speed it up.


The c equivalent of the hashing algorithm can be found below.
It only accepts lower case letters [a-z].


Code:
#include <ctype.h>

#include <stdint.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>



typedef struct {

  uint32_t sum;

  uint32_t code1;

  uint32_t code2;

} state_t;



typedef struct {

  uint32_t code1;

  uint32_t code2;

} hash_t;



void

hash_reset(state_t *state) {

  memset(state, 0, sizeof(state_t));

}



void

hash_update(state_t *state, const char *txt) {

  while (*txt != '\0') {

    uint8_t letterCode = tolower(*txt) - 'a' + 22;

    state->sum += letterCode;

    state->code1 += letterCode << 11;

    state->code1 = (state->code1 >> 17) + (state->code1 << 4);

    state->code2 = (state->code2 >> 29) + (state->code2 << 3) + letterCode * letterCode;

    txt += 1;

  }

}



void

hash_digest(const state_t *state, hash_t *hash) {

hash->code1 = (state->code1 >> 11) + (state->sum << 21);

hash->code2 = state->code2;

}



int main(int argc, char *argv[]) {

  if (argc == 1) {

#ifdef _WIN32

    fprintf(stderr, "Need at least one argument\n");

    return 1;

#else

    char *line = NULL;

    size_t lineSize = 0;

    while (!feof(stdin)) {

      ssize_t nb = getline(&line, &lineSize, stdin);

      line[nb - 1] = '\0';

      printf("got '%s'\n", line);

    }

    free(line);

    return 0;

#endif

  }

  state_t state;

  hash_t hash;

  for (int i = 1; i < argc; i += 1) {

    hash_reset(&state);

    hash_update(&state, argv[i]);

    hash_digest(&state, &hash);

    printf("%08x:%08x %s\n", hash.code1, hash.code2, argv[i]);

  }

  return 0;

}