1
0
mirror of https://github.com/hashcat/hashcat.git synced 2024-11-13 19:28:56 +00:00
hashcat/src/mpsp.c

1225 lines
29 KiB
C
Raw Normal View History

/**
* Author......: See docs/credits.txt
* License.....: MIT
*/
#if defined (__APPLE__)
2016-09-06 20:25:54 +00:00
#include <stdio.h>
#endif
#include "common.h"
#include "types.h"
2016-09-24 12:43:18 +00:00
#include "memory.h"
#include "logging.h"
#include "convert.h"
#include "filehandling.h"
#include "interface.h"
#include "mpsp.h"
2016-09-27 18:02:12 +00:00
#define MAX_MFS 5 // 4*charset, 1*mask
void mp_css_to_uniq_tbl (uint css_cnt, cs_t *css, uint uniq_tbls[SP_PW_MAX][CHARSIZ])
{
/* generates a lookup table where key is the char itself for fastest possible lookup performance */
if (css_cnt > SP_PW_MAX)
{
log_error ("ERROR: Mask length is too long");
exit (-1);
}
for (uint css_pos = 0; css_pos < css_cnt; css_pos++)
{
uint *uniq_tbl = uniq_tbls[css_pos];
uint *cs_buf = css[css_pos].cs_buf;
uint cs_len = css[css_pos].cs_len;
for (uint cs_pos = 0; cs_pos < cs_len; cs_pos++)
{
uint c = cs_buf[cs_pos] & 0xff;
uniq_tbl[c] = 1;
}
}
}
2016-09-30 16:39:31 +00:00
static void mp_add_cs_buf (uint *in_buf, size_t in_len, cs_t *css, uint css_cnt, const hashconfig_t *hashconfig)
{
cs_t *cs = &css[css_cnt];
size_t css_uniq_sz = CHARSIZ * sizeof (uint);
uint *css_uniq = (uint *) mymalloc (css_uniq_sz);
size_t i;
for (i = 0; i < cs->cs_len; i++)
{
const uint u = cs->cs_buf[i];
css_uniq[u] = 1;
}
for (i = 0; i < in_len; i++)
{
uint u = in_buf[i] & 0xff;
2016-09-09 14:54:48 +00:00
if (hashconfig->opts_type & OPTS_TYPE_PT_UPPER) u = (uint) toupper (u);
if (css_uniq[u] == 1) continue;
css_uniq[u] = 1;
cs->cs_buf[cs->cs_len] = u;
cs->cs_len++;
}
myfree (css_uniq);
}
2016-09-30 16:39:31 +00:00
static void mp_expand (char *in_buf, size_t in_len, cs_t *mp_sys, cs_t *mp_usr, uint mp_usr_offset, int interpret, const hashconfig_t *hashconfig, const user_options_t *user_options)
{
size_t in_pos;
for (in_pos = 0; in_pos < in_len; in_pos++)
{
uint p0 = in_buf[in_pos] & 0xff;
if (interpret == 1 && p0 == '?')
{
in_pos++;
if (in_pos == in_len) break;
uint p1 = in_buf[in_pos] & 0xff;
switch (p1)
{
2016-09-09 14:54:48 +00:00
case 'l': mp_add_cs_buf (mp_sys[0].cs_buf, mp_sys[0].cs_len, mp_usr, mp_usr_offset, hashconfig);
break;
2016-09-09 14:54:48 +00:00
case 'u': mp_add_cs_buf (mp_sys[1].cs_buf, mp_sys[1].cs_len, mp_usr, mp_usr_offset, hashconfig);
break;
2016-09-09 14:54:48 +00:00
case 'd': mp_add_cs_buf (mp_sys[2].cs_buf, mp_sys[2].cs_len, mp_usr, mp_usr_offset, hashconfig);
break;
2016-09-09 14:54:48 +00:00
case 's': mp_add_cs_buf (mp_sys[3].cs_buf, mp_sys[3].cs_len, mp_usr, mp_usr_offset, hashconfig);
break;
2016-09-09 14:54:48 +00:00
case 'a': mp_add_cs_buf (mp_sys[4].cs_buf, mp_sys[4].cs_len, mp_usr, mp_usr_offset, hashconfig);
break;
2016-09-09 14:54:48 +00:00
case 'b': mp_add_cs_buf (mp_sys[5].cs_buf, mp_sys[5].cs_len, mp_usr, mp_usr_offset, hashconfig);
break;
case '1': if (mp_usr[0].cs_len == 0) { log_error ("ERROR: Custom-charset 1 is undefined\n"); exit (-1); }
2016-09-09 14:54:48 +00:00
mp_add_cs_buf (mp_usr[0].cs_buf, mp_usr[0].cs_len, mp_usr, mp_usr_offset, hashconfig);
break;
case '2': if (mp_usr[1].cs_len == 0) { log_error ("ERROR: Custom-charset 2 is undefined\n"); exit (-1); }
2016-09-09 14:54:48 +00:00
mp_add_cs_buf (mp_usr[1].cs_buf, mp_usr[1].cs_len, mp_usr, mp_usr_offset, hashconfig);
break;
case '3': if (mp_usr[2].cs_len == 0) { log_error ("ERROR: Custom-charset 3 is undefined\n"); exit (-1); }
2016-09-09 14:54:48 +00:00
mp_add_cs_buf (mp_usr[2].cs_buf, mp_usr[2].cs_len, mp_usr, mp_usr_offset, hashconfig);
break;
case '4': if (mp_usr[3].cs_len == 0) { log_error ("ERROR: Custom-charset 4 is undefined\n"); exit (-1); }
2016-09-09 14:54:48 +00:00
mp_add_cs_buf (mp_usr[3].cs_buf, mp_usr[3].cs_len, mp_usr, mp_usr_offset, hashconfig);
break;
2016-09-09 14:54:48 +00:00
case '?': mp_add_cs_buf (&p0, 1, mp_usr, mp_usr_offset, hashconfig);
break;
default: log_error ("Syntax error: %s", in_buf);
exit (-1);
}
}
else
{
if (user_options->hex_charset == true)
{
in_pos++;
if (in_pos == in_len)
{
log_error ("ERROR: The hex-charset option always expects couples of exactly 2 hexadecimal chars, failed mask: %s", in_buf);
exit (-1);
}
uint p1 = in_buf[in_pos] & 0xff;
2016-09-30 16:39:31 +00:00
if ((is_valid_hex_char ((u8) p0) == false) || (is_valid_hex_char ((u8) p1) == false))
{
log_error ("ERROR: Invalid hex character detected in mask %s", in_buf);
exit (-1);
}
uint chr = 0;
2016-09-30 16:39:31 +00:00
chr = (uint) hex_convert ((u8) p1) << 0;
chr |= (uint) hex_convert ((u8) p0) << 4;
2016-09-09 14:54:48 +00:00
mp_add_cs_buf (&chr, 1, mp_usr, mp_usr_offset, hashconfig);
}
else
{
uint chr = p0;
2016-09-09 14:54:48 +00:00
mp_add_cs_buf (&chr, 1, mp_usr, mp_usr_offset, hashconfig);
}
}
}
}
u64 mp_get_sum (uint css_cnt, cs_t *css)
{
u64 sum = 1;
for (uint css_pos = 0; css_pos < css_cnt; css_pos++)
{
sum *= css[css_pos].cs_len;
}
return (sum);
}
cs_t *mp_gen_css (char *mask_buf, size_t mask_len, cs_t *mp_sys, cs_t *mp_usr, uint *css_cnt, const hashconfig_t *hashconfig, const user_options_t *user_options)
{
cs_t *css = (cs_t *) mycalloc (256, sizeof (cs_t));
uint mask_pos;
uint css_pos;
for (mask_pos = 0, css_pos = 0; mask_pos < mask_len; mask_pos++, css_pos++)
{
char p0 = mask_buf[mask_pos];
if (p0 == '?')
{
mask_pos++;
if (mask_pos == mask_len) break;
char p1 = mask_buf[mask_pos];
2016-09-30 16:39:31 +00:00
uint chr = (uint) p1;
switch (p1)
{
2016-09-09 14:54:48 +00:00
case 'l': mp_add_cs_buf (mp_sys[0].cs_buf, mp_sys[0].cs_len, css, css_pos, hashconfig);
break;
2016-09-09 14:54:48 +00:00
case 'u': mp_add_cs_buf (mp_sys[1].cs_buf, mp_sys[1].cs_len, css, css_pos, hashconfig);
break;
2016-09-09 14:54:48 +00:00
case 'd': mp_add_cs_buf (mp_sys[2].cs_buf, mp_sys[2].cs_len, css, css_pos, hashconfig);
break;
2016-09-09 14:54:48 +00:00
case 's': mp_add_cs_buf (mp_sys[3].cs_buf, mp_sys[3].cs_len, css, css_pos, hashconfig);
break;
2016-09-09 14:54:48 +00:00
case 'a': mp_add_cs_buf (mp_sys[4].cs_buf, mp_sys[4].cs_len, css, css_pos, hashconfig);
break;
2016-09-09 14:54:48 +00:00
case 'b': mp_add_cs_buf (mp_sys[5].cs_buf, mp_sys[5].cs_len, css, css_pos, hashconfig);
break;
case '1': if (mp_usr[0].cs_len == 0) { log_error ("ERROR: Custom-charset 1 is undefined\n"); exit (-1); }
2016-09-09 14:54:48 +00:00
mp_add_cs_buf (mp_usr[0].cs_buf, mp_usr[0].cs_len, css, css_pos, hashconfig);
break;
case '2': if (mp_usr[1].cs_len == 0) { log_error ("ERROR: Custom-charset 2 is undefined\n"); exit (-1); }
2016-09-09 14:54:48 +00:00
mp_add_cs_buf (mp_usr[1].cs_buf, mp_usr[1].cs_len, css, css_pos, hashconfig);
break;
case '3': if (mp_usr[2].cs_len == 0) { log_error ("ERROR: Custom-charset 3 is undefined\n"); exit (-1); }
2016-09-09 14:54:48 +00:00
mp_add_cs_buf (mp_usr[2].cs_buf, mp_usr[2].cs_len, css, css_pos, hashconfig);
break;
case '4': if (mp_usr[3].cs_len == 0) { log_error ("ERROR: Custom-charset 4 is undefined\n"); exit (-1); }
2016-09-09 14:54:48 +00:00
mp_add_cs_buf (mp_usr[3].cs_buf, mp_usr[3].cs_len, css, css_pos, hashconfig);
break;
2016-09-09 14:54:48 +00:00
case '?': mp_add_cs_buf (&chr, 1, css, css_pos, hashconfig);
break;
default: log_error ("ERROR: Syntax error: %s", mask_buf);
exit (-1);
}
}
else
{
if (user_options->hex_charset == true)
{
mask_pos++;
// if there is no 2nd hex character, show an error:
if (mask_pos == mask_len)
{
log_error ("ERROR: The hex-charset option always expects couples of exactly 2 hexadecimal chars, failed mask: %s", mask_buf);
exit (-1);
}
char p1 = mask_buf[mask_pos];
// if they are not valid hex character, show an error:
2016-09-30 16:39:31 +00:00
if ((is_valid_hex_char ((u8) p0) == false) || (is_valid_hex_char ((u8) p1) == false))
{
log_error ("ERROR: Invalid hex character detected in mask %s", mask_buf);
exit (-1);
}
uint chr = 0;
2016-09-30 16:39:31 +00:00
chr |= (uint) hex_convert ((u8) p1) << 0;
chr |= (uint) hex_convert ((u8) p0) << 4;
2016-09-09 14:54:48 +00:00
mp_add_cs_buf (&chr, 1, css, css_pos, hashconfig);
}
else
{
2016-09-30 16:39:31 +00:00
uint chr = (uint) p0;
2016-09-09 14:54:48 +00:00
mp_add_cs_buf (&chr, 1, css, css_pos, hashconfig);
}
}
}
if (css_pos == 0)
{
log_error ("ERROR: Invalid mask length (0)");
exit (-1);
}
*css_cnt = css_pos;
return (css);
}
void mp_exec (u64 val, char *buf, cs_t *css, int css_cnt)
{
for (int i = 0; i < css_cnt; i++)
{
2016-09-30 16:39:31 +00:00
u32 len = css[i].cs_len;
u64 next = val / len;
2016-09-30 16:39:31 +00:00
u32 pos = val % len;
buf[i] = (char) (css[i].cs_buf[pos] & 0xff);
val = next;
}
}
uint mp_get_length (char *mask)
{
uint len = 0;
uint mask_len = strlen (mask);
for (uint i = 0; i < mask_len; i++)
{
if (mask[i] == '?') i++;
len++;
}
return len;
}
void mp_cut_at (char *mask, uint max)
{
uint i;
uint j;
uint mask_len = strlen (mask);
for (i = 0, j = 0; i < mask_len && j < max; i++, j++)
{
if (mask[i] == '?') i++;
}
mask[i] = 0;
}
void mp_setup_sys (cs_t *mp_sys)
{
uint pos;
uint chr;
uint donec[CHARSIZ] = { 0 };
for (pos = 0, chr = 'a'; chr <= 'z'; chr++) { donec[chr] = 1;
mp_sys[0].cs_buf[pos++] = chr;
mp_sys[0].cs_len = pos; }
for (pos = 0, chr = 'A'; chr <= 'Z'; chr++) { donec[chr] = 1;
mp_sys[1].cs_buf[pos++] = chr;
mp_sys[1].cs_len = pos; }
for (pos = 0, chr = '0'; chr <= '9'; chr++) { donec[chr] = 1;
mp_sys[2].cs_buf[pos++] = chr;
mp_sys[2].cs_len = pos; }
for (pos = 0, chr = 0x20; chr <= 0x7e; chr++) { if (donec[chr]) continue;
mp_sys[3].cs_buf[pos++] = chr;
mp_sys[3].cs_len = pos; }
for (pos = 0, chr = 0x20; chr <= 0x7e; chr++) { mp_sys[4].cs_buf[pos++] = chr;
mp_sys[4].cs_len = pos; }
for (pos = 0, chr = 0x00; chr <= 0xff; chr++) { mp_sys[5].cs_buf[pos++] = chr;
mp_sys[5].cs_len = pos; }
}
void mp_setup_usr (cs_t *mp_sys, cs_t *mp_usr, char *buf, uint index, const hashconfig_t *hashconfig, const user_options_t *user_options)
{
FILE *fp = fopen (buf, "rb");
if (fp == NULL || feof (fp)) // feof() in case if file is empty
{
mp_expand (buf, strlen (buf), mp_sys, mp_usr, index, 1, hashconfig, user_options);
}
else
{
char mp_file[1024] = { 0 };
2016-09-30 16:39:31 +00:00
int len = (int) fread (mp_file, 1, sizeof (mp_file) - 1, fp);
fclose (fp);
len = in_superchop (mp_file);
if (len == 0)
{
log_info ("WARNING: Charset file corrupted");
mp_expand (buf, strlen (buf), mp_sys, mp_usr, index, 1, hashconfig, user_options);
}
else
{
2016-09-30 16:39:31 +00:00
mp_expand (mp_file, (size_t) len, mp_sys, mp_usr, index, 0, hashconfig, user_options);
}
}
}
void mp_reset_usr (cs_t *mp_usr, uint index)
{
mp_usr[index].cs_len = 0;
memset (mp_usr[index].cs_buf, 0, sizeof (mp_usr[index].cs_buf));
}
static char *mp_get_truncated_mask (const char *mask_buf, const size_t mask_len, const uint len, const user_options_t *user_options)
{
char *new_mask_buf = (char *) mymalloc (256);
uint mask_pos;
uint css_pos;
for (mask_pos = 0, css_pos = 0; mask_pos < mask_len; mask_pos++, css_pos++)
{
if (css_pos == len) break;
char p0 = mask_buf[mask_pos];
new_mask_buf[mask_pos] = p0;
if (p0 == '?')
{
mask_pos++;
if (mask_pos == mask_len) break;
new_mask_buf[mask_pos] = mask_buf[mask_pos];
}
else
{
if (user_options->hex_charset == true)
{
mask_pos++;
if (mask_pos == mask_len)
{
log_error ("ERROR: The hex-charset option always expects couples of exactly 2 hexadecimal chars, failed mask: %s", mask_buf);
exit (-1);
}
char p1 = mask_buf[mask_pos];
// if they are not valid hex character, show an error:
2016-09-30 16:39:31 +00:00
if ((is_valid_hex_char ((u8) p0) == false) || (is_valid_hex_char ((u8) p1) == false))
{
log_error ("ERROR: Invalid hex character detected in mask: %s", mask_buf);
exit (-1);
}
new_mask_buf[mask_pos] = p1;
}
}
}
if (css_pos == len) return (new_mask_buf);
myfree (new_mask_buf);
return (NULL);
}
u64 sp_get_sum (uint start, uint stop, cs_t *root_css_buf)
{
u64 sum = 1;
uint i;
for (i = start; i < stop; i++)
{
sum *= root_css_buf[i].cs_len;
}
return (sum);
}
void sp_exec (u64 ctx, char *pw_buf, cs_t *root_css_buf, cs_t *markov_css_buf, uint start, uint stop)
{
u64 v = ctx;
cs_t *cs = &root_css_buf[start];
uint i;
for (i = start; i < stop; i++)
{
const u64 m = v % cs->cs_len;
const u64 d = v / cs->cs_len;
v = d;
const uint k = cs->cs_buf[m];
pw_buf[i - start] = (char) k;
cs = &markov_css_buf[(i * CHARSIZ) + k];
}
}
int sp_comp_val (const void *p1, const void *p2)
{
hcstat_table_t *b1 = (hcstat_table_t *) p1;
hcstat_table_t *b2 = (hcstat_table_t *) p2;
return b2->val - b1->val;
}
void sp_setup_tbl (const char *shared_dir, char *hcstat, uint disable, uint classic, hcstat_table_t *root_table_buf, hcstat_table_t *markov_table_buf)
{
uint i;
uint j;
uint k;
/**
* Initialize hcstats
*/
u64 *root_stats_buf = (u64 *) mycalloc (SP_ROOT_CNT, sizeof (u64));
u64 *root_stats_ptr = root_stats_buf;
u64 *root_stats_buf_by_pos[SP_PW_MAX];
for (i = 0; i < SP_PW_MAX; i++)
{
root_stats_buf_by_pos[i] = root_stats_ptr;
root_stats_ptr += CHARSIZ;
}
u64 *markov_stats_buf = (u64 *) mycalloc (SP_MARKOV_CNT, sizeof (u64));
u64 *markov_stats_ptr = markov_stats_buf;
u64 *markov_stats_buf_by_key[SP_PW_MAX][CHARSIZ];
for (i = 0; i < SP_PW_MAX; i++)
{
for (j = 0; j < CHARSIZ; j++)
{
markov_stats_buf_by_key[i][j] = markov_stats_ptr;
markov_stats_ptr += CHARSIZ;
}
}
/**
* Load hcstats File
*/
if (hcstat == NULL)
{
char hcstat_tmp[256] = { 0 };
snprintf (hcstat_tmp, sizeof (hcstat_tmp) - 1, "%s/%s", shared_dir, SP_HCSTAT);
hcstat = hcstat_tmp;
}
FILE *fd = fopen (hcstat, "rb");
if (fd == NULL)
{
log_error ("%s: %s", hcstat, strerror (errno));
exit (-1);
}
if (fread (root_stats_buf, sizeof (u64), SP_ROOT_CNT, fd) != SP_ROOT_CNT)
{
log_error ("%s: Could not load data", hcstat);
fclose (fd);
exit (-1);
}
if (fread (markov_stats_buf, sizeof (u64), SP_MARKOV_CNT, fd) != SP_MARKOV_CNT)
{
log_error ("%s: Could not load data", hcstat);
fclose (fd);
exit (-1);
}
fclose (fd);
/**
* Markov modifier of hcstat_table on user request
*/
if (disable)
{
memset (root_stats_buf, 0, SP_ROOT_CNT * sizeof (u64));
memset (markov_stats_buf, 0, SP_MARKOV_CNT * sizeof (u64));
}
if (classic)
{
/* Add all stats to first position */
for (i = 1; i < SP_PW_MAX; i++)
{
u64 *out = root_stats_buf_by_pos[0];
u64 *in = root_stats_buf_by_pos[i];
for (j = 0; j < CHARSIZ; j++)
{
*out++ += *in++;
}
}
for (i = 1; i < SP_PW_MAX; i++)
{
u64 *out = markov_stats_buf_by_key[0][0];
u64 *in = markov_stats_buf_by_key[i][0];
for (j = 0; j < CHARSIZ; j++)
{
for (k = 0; k < CHARSIZ; k++)
{
*out++ += *in++;
}
}
}
/* copy them to all pw_positions */
for (i = 1; i < SP_PW_MAX; i++)
{
memcpy (root_stats_buf_by_pos[i], root_stats_buf_by_pos[0], CHARSIZ * sizeof (u64));
}
for (i = 1; i < SP_PW_MAX; i++)
{
memcpy (markov_stats_buf_by_key[i][0], markov_stats_buf_by_key[0][0], CHARSIZ * CHARSIZ * sizeof (u64));
}
}
/**
* Initialize tables
*/
hcstat_table_t *root_table_ptr = root_table_buf;
hcstat_table_t *root_table_buf_by_pos[SP_PW_MAX];
for (i = 0; i < SP_PW_MAX; i++)
{
root_table_buf_by_pos[i] = root_table_ptr;
root_table_ptr += CHARSIZ;
}
hcstat_table_t *markov_table_ptr = markov_table_buf;
hcstat_table_t *markov_table_buf_by_key[SP_PW_MAX][CHARSIZ];
for (i = 0; i < SP_PW_MAX; i++)
{
for (j = 0; j < CHARSIZ; j++)
{
markov_table_buf_by_key[i][j] = markov_table_ptr;
markov_table_ptr += CHARSIZ;
}
}
/**
* Convert hcstat to tables
*/
for (i = 0; i < SP_ROOT_CNT; i++)
{
uint key = i % CHARSIZ;
root_table_buf[i].key = key;
root_table_buf[i].val = root_stats_buf[i];
}
for (i = 0; i < SP_MARKOV_CNT; i++)
{
uint key = i % CHARSIZ;
markov_table_buf[i].key = key;
markov_table_buf[i].val = markov_stats_buf[i];
}
myfree (root_stats_buf);
myfree (markov_stats_buf);
/**
* Finally sort them
*/
for (i = 0; i < SP_PW_MAX; i++)
{
qsort (root_table_buf_by_pos[i], CHARSIZ, sizeof (hcstat_table_t), sp_comp_val);
}
for (i = 0; i < SP_PW_MAX; i++)
{
for (j = 0; j < CHARSIZ; j++)
{
qsort (markov_table_buf_by_key[i][j], CHARSIZ, sizeof (hcstat_table_t), sp_comp_val);
}
}
}
void sp_tbl_to_css (hcstat_table_t *root_table_buf, hcstat_table_t *markov_table_buf, cs_t *root_css_buf, cs_t *markov_css_buf, uint threshold, uint uniq_tbls[SP_PW_MAX][CHARSIZ])
{
2016-09-26 15:50:47 +00:00
memset (root_css_buf, 0, SP_PW_MAX * sizeof (cs_t));
memset (markov_css_buf, 0, SP_PW_MAX * CHARSIZ * sizeof (cs_t));
/**
* Convert tables to css
*/
for (uint i = 0; i < SP_ROOT_CNT; i++)
{
uint pw_pos = i / CHARSIZ;
cs_t *cs = &root_css_buf[pw_pos];
if (cs->cs_len == threshold) continue;
uint key = root_table_buf[i].key;
if (uniq_tbls[pw_pos][key] == 0) continue;
cs->cs_buf[cs->cs_len] = key;
cs->cs_len++;
}
/**
* Convert table to css
*/
for (uint i = 0; i < SP_MARKOV_CNT; i++)
{
uint c = i / CHARSIZ;
cs_t *cs = &markov_css_buf[c];
if (cs->cs_len == threshold) continue;
uint pw_pos = c / CHARSIZ;
uint key = markov_table_buf[i].key;
if ((pw_pos + 1) < SP_PW_MAX) if (uniq_tbls[pw_pos + 1][key] == 0) continue;
cs->cs_buf[cs->cs_len] = key;
cs->cs_len++;
}
/*
for (uint i = 0; i < 8; i++)
{
for (uint j = 0x20; j < 0x80; j++)
{
cs_t *ptr = &markov_css_buf[(i * CHARSIZ) + j];
printf ("pos:%u key:%u len:%u\n", i, j, ptr->cs_len);
for (uint k = 0; k < 10; k++)
{
printf (" %u\n", ptr->cs_buf[k]);
}
}
}
*/
}
void sp_stretch_root (hcstat_table_t *in, hcstat_table_t *out)
{
for (uint i = 0; i < SP_PW_MAX; i += 2)
{
memcpy (out, in, CHARSIZ * sizeof (hcstat_table_t));
out += CHARSIZ;
in += CHARSIZ;
out->key = 0;
out->val = 1;
out++;
for (uint j = 1; j < CHARSIZ; j++)
{
out->key = j;
out->val = 0;
out++;
}
}
}
void sp_stretch_markov (hcstat_table_t *in, hcstat_table_t *out)
{
for (uint i = 0; i < SP_PW_MAX; i += 2)
{
memcpy (out, in, CHARSIZ * CHARSIZ * sizeof (hcstat_table_t));
out += CHARSIZ * CHARSIZ;
in += CHARSIZ * CHARSIZ;
for (uint j = 0; j < CHARSIZ; j++)
{
out->key = 0;
out->val = 1;
out++;
for (uint k = 1; k < CHARSIZ; k++)
{
out->key = k;
out->val = 0;
out++;
}
}
}
}
static void mask_append_final (mask_ctx_t *mask_ctx, const char *mask)
{
if (mask_ctx->masks_avail == mask_ctx->masks_cnt)
{
mask_ctx->masks = (char **) myrealloc (mask_ctx->masks, mask_ctx->masks_avail * sizeof (char *), INCR_MASKS * sizeof (char *));
mask_ctx->masks_avail += INCR_MASKS;
}
mask_ctx->masks[mask_ctx->masks_cnt] = mystrdup (mask);
mask_ctx->masks_cnt++;
}
static void mask_append (mask_ctx_t *mask_ctx, const user_options_t *user_options, const char *mask)
{
if (user_options->increment == true)
{
for (uint mask_len = user_options->increment_min; mask_len <= user_options->increment_max; mask_len++)
{
char *mask_truncated = mp_get_truncated_mask (mask, strlen (mask), mask_len, user_options);
if (mask_truncated == NULL) break;
mask_append_final (mask_ctx, mask_truncated);
}
}
else
{
mask_append_final (mask_ctx, mask);
}
}
int mask_ctx_init (mask_ctx_t *mask_ctx, const user_options_t *user_options, const user_options_extra_t *user_options_extra, const folder_config_t *folder_config, const restore_ctx_t *restore_ctx, const hashconfig_t *hashconfig)
{
mask_ctx->enabled = false;
2016-09-30 10:13:52 +00:00
if (user_options->left == true) return 0;
if (user_options->opencl_info == true) return 0;
2016-09-30 10:13:52 +00:00
if (user_options->show == true) return 0;
if (user_options->usage == true) return 0;
if (user_options->version == true) return 0;
if (user_options->attack_mode == ATTACK_MODE_STRAIGHT) return 0;
if (user_options->attack_mode == ATTACK_MODE_COMBI) return 0;
mask_ctx->enabled = true;
mask_ctx->root_table_buf = (hcstat_table_t *) mycalloc (SP_ROOT_CNT, sizeof (hcstat_table_t));
mask_ctx->markov_table_buf = (hcstat_table_t *) mycalloc (SP_MARKOV_CNT, sizeof (hcstat_table_t));
sp_setup_tbl (folder_config->shared_dir, user_options->markov_hcstat, user_options->markov_disable, user_options->markov_classic, mask_ctx->root_table_buf, mask_ctx->markov_table_buf);
mask_ctx->root_css_buf = (cs_t *) mycalloc (SP_PW_MAX, sizeof (cs_t));
mask_ctx->markov_css_buf = (cs_t *) mycalloc (SP_PW_MAX * CHARSIZ, sizeof (cs_t));
mask_ctx->css_cnt = 0;
mask_ctx->css_buf = NULL;
mask_ctx->mask_from_file = false;
mask_ctx->masks = NULL;
mask_ctx->masks_pos = 0;
mask_ctx->masks_cnt = 0;
2016-09-27 18:02:12 +00:00
mask_ctx->mfs = (mf_t *) mycalloc (MAX_MFS, sizeof (mf_t));
mp_setup_sys (mask_ctx->mp_sys);
if (user_options->custom_charset_1) mp_setup_usr (mask_ctx->mp_sys, mask_ctx->mp_usr, user_options->custom_charset_1, 0, hashconfig, user_options);
if (user_options->custom_charset_2) mp_setup_usr (mask_ctx->mp_sys, mask_ctx->mp_usr, user_options->custom_charset_2, 1, hashconfig, user_options);
if (user_options->custom_charset_3) mp_setup_usr (mask_ctx->mp_sys, mask_ctx->mp_usr, user_options->custom_charset_3, 2, hashconfig, user_options);
if (user_options->custom_charset_4) mp_setup_usr (mask_ctx->mp_sys, mask_ctx->mp_usr, user_options->custom_charset_4, 3, hashconfig, user_options);
if (user_options->attack_mode == ATTACK_MODE_BF)
{
if (user_options->benchmark == false)
{
if ((user_options_extra->optind + 2) <= restore_ctx->argc)
{
char *arg = restore_ctx->argv[user_options_extra->optind + 1];
struct stat file_stat;
if (stat (arg, &file_stat) == -1)
{
mask_append (mask_ctx, user_options, arg);
}
else
{
mask_ctx->mask_from_file = true;
int arg_left = restore_ctx->argc - (user_options_extra->optind + 1);
for (int i = 0; i < arg_left; i++)
{
arg = restore_ctx->argv[user_options_extra->optind + 1 + i];
if (stat (arg, &file_stat) == -1)
{
log_error ("ERROR: %s: %s", arg, strerror (errno));
return -1;
}
if (S_ISREG (file_stat.st_mode))
{
FILE *mask_fp = fopen (arg, "r");
if (mask_fp == NULL)
{
log_error ("ERROR: %s: %s", arg, strerror (errno));
return -1;
}
char *line_buf = (char *) mymalloc (HCBUFSIZ_LARGE);
while (!feof (mask_fp))
{
const int line_len = fgetl (mask_fp, line_buf);
if (line_len == 0) continue;
if (line_buf[0] == '#') continue;
mask_append (mask_ctx, user_options, line_buf);
}
myfree (line_buf);
fclose (mask_fp);
}
else
{
log_error ("ERROR: %s: unsupported file-type", arg);
return -1;
}
}
}
}
else
{
const char *mask = "?1?2?2?2?2?2?2?3?3?3?3?d?d?d?d";
mask_append (mask_ctx, user_options, mask);
}
}
else
{
const char *mask = hashconfig_benchmark_mask (hashconfig);
mask_append (mask_ctx, user_options, mask);
}
}
else if (user_options->attack_mode == ATTACK_MODE_HYBRID1)
{
// display
char *arg = restore_ctx->argv[restore_ctx->argc - 1];
// mod
struct stat file_stat;
if (stat (arg, &file_stat) == -1)
{
mask_append (mask_ctx, user_options, arg);
}
else
{
if (S_ISREG (file_stat.st_mode))
{
mask_ctx->mask_from_file = true;
FILE *mask_fp = fopen (arg, "r");
if (mask_fp == NULL)
{
log_error ("ERROR: %s: %s", arg, strerror (errno));
return -1;
}
char *line_buf = (char *) mymalloc (HCBUFSIZ_LARGE);
while (!feof (mask_fp))
{
const int line_len = fgetl (mask_fp, line_buf);
if (line_len == 0) continue;
if (line_buf[0] == '#') continue;
mask_append (mask_ctx, user_options, line_buf);
}
myfree (line_buf);
fclose (mask_fp);
}
else
{
log_error ("ERROR: %s: unsupported file-type", arg);
return -1;
}
}
}
else if (user_options->attack_mode == ATTACK_MODE_HYBRID2)
{
// display
char *arg = restore_ctx->argv[user_options_extra->optind + 1];
// mod
struct stat file_stat;
if (stat (arg, &file_stat) == -1)
{
mask_append (mask_ctx, user_options, arg);
}
else
{
if (S_ISREG (file_stat.st_mode))
{
mask_ctx->mask_from_file = true;
FILE *mask_fp = fopen (arg, "r");
if (mask_fp == NULL)
{
log_error ("ERROR: %s: %s", arg, strerror (errno));
return -1;
}
char *line_buf = (char *) mymalloc (HCBUFSIZ_LARGE);
while (!feof (mask_fp))
{
const int line_len = fgetl (mask_fp, line_buf);
if (line_len == 0) continue;
if (line_buf[0] == '#') continue;
mask_append (mask_ctx, user_options, line_buf);
}
myfree (line_buf);
fclose (mask_fp);
}
else
{
log_error ("ERROR: %s: unsupported file-type", arg);
return -1;
}
}
}
if (mask_ctx->masks_cnt == 0)
{
log_error ("ERROR: Invalid mask");
return -1;
}
mask_ctx->mask = mask_ctx->masks[0];
return 0;
}
void mask_ctx_destroy (mask_ctx_t *mask_ctx)
{
if (mask_ctx->enabled == false) return;
myfree (mask_ctx->css_buf);
myfree (mask_ctx->root_css_buf);
myfree (mask_ctx->markov_css_buf);
myfree (mask_ctx->root_table_buf);
myfree (mask_ctx->markov_table_buf);
for (u32 mask_pos = 0; mask_pos < mask_ctx->masks_cnt; mask_pos++)
{
myfree (mask_ctx->masks[mask_pos]);
}
myfree (mask_ctx->masks);
2016-09-27 18:02:12 +00:00
myfree (mask_ctx->mfs);
memset (mask_ctx, 0, sizeof (mask_ctx_t));
}
2016-09-27 16:32:09 +00:00
2016-09-27 18:02:12 +00:00
int mask_ctx_parse_maskfile (mask_ctx_t *mask_ctx, user_options_t *user_options, const hashconfig_t *hashconfig)
2016-09-27 16:32:09 +00:00
{
2016-09-27 18:02:12 +00:00
if (mask_ctx->enabled == false) return 0;
2016-09-27 16:32:09 +00:00
2016-09-27 18:02:12 +00:00
if (mask_ctx->mask_from_file == false) return 0;
2016-09-27 16:32:09 +00:00
2016-09-27 18:02:12 +00:00
mf_t *mfs = mask_ctx->mfs;
2016-09-27 16:32:09 +00:00
2016-09-27 18:02:12 +00:00
mfs[0].mf_len = 0;
mfs[1].mf_len = 0;
mfs[2].mf_len = 0;
mfs[3].mf_len = 0;
mfs[4].mf_len = 0;
2016-09-27 16:32:09 +00:00
2016-09-27 18:02:12 +00:00
char *mask_buf = mask_ctx->mask;
2016-09-27 16:32:09 +00:00
2016-09-27 18:02:12 +00:00
const int mask_len = strlen (mask_buf);
2016-09-27 16:32:09 +00:00
2016-09-27 18:02:12 +00:00
bool escaped = false;
2016-09-27 16:32:09 +00:00
2016-09-27 18:02:12 +00:00
int mf_cnt = 0;
2016-09-27 16:32:09 +00:00
2016-09-27 18:02:12 +00:00
for (int i = 0; i < mask_len; i++)
{
mf_t *mf = mfs + mf_cnt;
if (escaped == true)
{
escaped = false;
2016-09-27 16:32:09 +00:00
2016-09-27 18:02:12 +00:00
mf->mf_buf[mf->mf_len] = mask_buf[i];
2016-09-27 16:32:09 +00:00
2016-09-27 18:02:12 +00:00
mf->mf_len++;
}
else
2016-09-27 16:32:09 +00:00
{
2016-09-27 18:02:12 +00:00
if (mask_buf[i] == '\\')
2016-09-27 16:32:09 +00:00
{
2016-09-27 18:02:12 +00:00
escaped = true;
}
else if (mask_buf[i] == ',')
{
mf->mf_buf[mf->mf_len] = 0;
2016-09-27 16:32:09 +00:00
2016-09-27 18:02:12 +00:00
mf_cnt++;
2016-09-27 16:32:09 +00:00
2016-09-27 18:02:12 +00:00
if (mf_cnt >= MAX_MFS)
{
log_error ("ERROR: Invalid line '%s' in maskfile", mask_buf);
return -1;
}
2016-09-27 16:32:09 +00:00
}
2016-09-27 18:02:12 +00:00
else
{
mf->mf_buf[mf->mf_len] = mask_buf[i];
2016-09-27 16:32:09 +00:00
2016-09-27 18:02:12 +00:00
mf->mf_len++;
}
}
}
2016-09-27 16:32:09 +00:00
2016-09-27 18:02:12 +00:00
mf_t *mf = mfs + mf_cnt;
2016-09-27 16:32:09 +00:00
2016-09-27 18:02:12 +00:00
mf->mf_buf[mf->mf_len] = 0;
2016-09-27 16:32:09 +00:00
2016-09-27 18:02:12 +00:00
for (int i = 0; i < mf_cnt; i++)
{
switch (i)
2016-09-27 16:32:09 +00:00
{
case 0:
2016-09-27 18:02:12 +00:00
user_options->custom_charset_1 = mfs[0].mf_buf;
2016-09-27 16:32:09 +00:00
mp_reset_usr (mask_ctx->mp_usr, 0);
mp_setup_usr (mask_ctx->mp_sys, mask_ctx->mp_usr, user_options->custom_charset_1, 0, hashconfig, user_options);
break;
case 1:
2016-09-27 18:02:12 +00:00
user_options->custom_charset_2 = mfs[1].mf_buf;
2016-09-27 16:32:09 +00:00
mp_reset_usr (mask_ctx->mp_usr, 1);
mp_setup_usr (mask_ctx->mp_sys, mask_ctx->mp_usr, user_options->custom_charset_2, 1, hashconfig, user_options);
break;
case 2:
2016-09-27 18:02:12 +00:00
user_options->custom_charset_3 = mfs[2].mf_buf;
2016-09-27 16:32:09 +00:00
mp_reset_usr (mask_ctx->mp_usr, 2);
mp_setup_usr (mask_ctx->mp_sys, mask_ctx->mp_usr, user_options->custom_charset_3, 2, hashconfig, user_options);
break;
case 3:
2016-09-27 18:02:12 +00:00
user_options->custom_charset_4 = mfs[3].mf_buf;
2016-09-27 16:32:09 +00:00
mp_reset_usr (mask_ctx->mp_usr, 3);
mp_setup_usr (mask_ctx->mp_sys, mask_ctx->mp_usr, user_options->custom_charset_4, 3, hashconfig, user_options);
break;
}
}
2016-09-27 18:02:12 +00:00
mask_ctx->mask = mfs[mf_cnt].mf_buf;
2016-09-27 16:32:09 +00:00
2016-09-27 18:02:12 +00:00
return 0;
2016-09-27 16:32:09 +00:00
}