Skip to content

Commit b4731b5

Browse files
committed
regex 1.4 integration, and full restore logic
1 parent 9423af6 commit b4731b5

10 files changed

+129
-35
lines changed

.pre-commit.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ fi
3636
########################################################
3737
# Tests 2/3/4/5. Make sure source does not have execute bit set
3838
########################################################
39-
TXT_FILE_PATTERN='\.(cl|c|h|txt|S|s|in|chr|conf|txt|md|asm|cin|dep|gost|legacy|macros|stub|m4|cu|bash_completion|zsh_completion|lst)(\..+)?$'
39+
TXT_FILE_PATTERN='\.(ac|cl|c|h|txt|S|s|in|chr|conf|txt|md|asm|cin|dep|gost|legacy|macros|stub|m4|cu|bash_completion|zsh_completion|lst)(\..+)?$'
4040
TXT_FILES=`git diff --cached --name-only | grep -E $TXT_FILE_PATTERN`
4141
TXT_FILES="$TXT_FILES"`git diff --cached --name-only | grep -E ^doc/`
4242
if [ "x$TXT_FILES" != "x" ] ; then

doc/README.librexgen

+11-6
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ The current options we have are:
1414
will be run to convert the reg-ex AFTER the word has been
1515
prepared and delivered. Fun things like f mapping to ph
1616
or M mapping to |\/| can be done. Case can also easily be
17-
done here, but the case option is also used. These options
18-
are stored in teh regex_alphabest.conf file in ./run dir
17+
done here if the case option is also used. These options
18+
are stored in the regex_alphabets.conf file in ./run dir
1919
of JtR. There are these current alphabets:
2020
The default (if just =alpha is used). It is an empty
2121
alphabet, nothing will change. alpha:case This is the
@@ -31,7 +31,9 @@ The current options we have are:
3131
letter replacements which likely are not seen in garden
3232
variety passwords. h -> h H |-| ]-[ }-{ (-) )-( }{ #
3333
is one example of alpha:leet3.
34-
34+
alpha:ascii2nonascii is a alphabet which will convert ascii
35+
characters into non ascii utf8 characters which 'look'
36+
similar (i.e. a with grave, umlat, accent, hook, etc)
3537

3638

3739
Currently, rexgen can be used stand alone, OR with wordlist and rules.
@@ -108,11 +110,14 @@ rexgen '[0-2]password[A-C]'
108110
1passwordC
109111
2passwordC
110112

111-
Once you are at this point, rexgen is installed. JtR Makefile will
112-
(should) autodetect the library, and now build in code to use it.
113+
Once you are at this point, rexgen is installed. JtR ./configure should
114+
autodetect the library, and now build in code to use it. NOTE, JtR requires
115+
at least version 1.4.x to work properly. There were some bug fixes done
116+
when save/restore was added to rexgen, and versions of rexgen prior to
117+
this, simply do not work properly.
113118

114119
Note, JtR help document is NOT here to troubleshoot installation of this
115-
library. A simple how to do it (when thing work write), is what was listed.
120+
library. A simple how to do it (when thing work right), is what was listed.
116121
If there problems beyond what is addressed in this document, then the lib's
117122
author is probably the best way to go. A quick 'help me' post on john-users
118123
may get the proper answer, AND if we get a quick resolve, we will likely

src/configure

+8-3
Original file line numberDiff line numberDiff line change
@@ -10202,18 +10202,23 @@ $as_echo "$ac_cv_search_rexgen_version_int" >&6; }
1020210202
ac_res=$ac_cv_search_rexgen_version_int
1020310203
if test "$ac_res" != no; then :
1020410204
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
10205-
if test "$cross_compiling" = yes; then :
10205+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking librexgen minimum version" >&5
10206+
$as_echo_n "checking librexgen minimum version... " >&6; } && if test "$cross_compiling" = yes; then :
1020610207
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
1020710208
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
1020810209
as_fn_error $? "cannot run test program while cross compiling
1020910210
See \`config.log' for more details" "$LINENO" 5; }
1021010211
else
1021110212
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
1021210213
/* end confdefs.h. */
10213-
int main() { return ! (rexgen_version_int() >= 0x010300); }
10214+
int main() { return ! (rexgen_version_int() >= 0x010400); }
1021410215
_ACEOF
1021510216
if ac_fn_c_try_run "$LINENO"; then :
10216-
using_rexgen=yes
10217+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: usable" >&5
10218+
$as_echo "usable" >&6; } && using_rexgen=yes
10219+
else
10220+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: TOO old. Rexgen not usable!" >&5
10221+
$as_echo "TOO old. Rexgen not usable!" >&6; }
1021710222
fi
1021810223
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
1021910224
conftest.$ac_objext conftest.beam conftest.$ac_ext

src/configure.ac

+3-2
Original file line numberDiff line numberDiff line change
@@ -507,8 +507,9 @@ using_rexgen=no
507507
if test "x$enable_rexgen" != xno ; then
508508
AC_CHECK_HEADER([librexgen/version.h],
509509
[AC_SEARCH_LIBS([rexgen_version_int],[rexgen librexgen],
510-
[AC_TRY_RUN([int main() { return ! (rexgen_version_int() >= 0x010300); }],
511-
[using_rexgen=yes])]
510+
[AC_MSG_CHECKING([librexgen minimum version])] && [AC_TRY_RUN([int main() { return ! (rexgen_version_int() >= 0x010400); }],
511+
AC_MSG_RESULT([usable]) && [using_rexgen=yes],
512+
AC_MSG_RESULT([TOO old. Rexgen not usable!]))]
512513
)]
513514
)
514515
if test "x$using_rexgen" == "xyes" ; then

src/cracker.c

+9-1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
#include "mask_ext.h"
5353
#include "mask.h"
5454
#include "unicode.h"
55+
#include "cracker.h"
5556
#include "john.h"
5657
#include "fake_salts.h"
5758
#include "sha.h"
@@ -77,6 +78,7 @@
7778
static clock_t salt_time = 0;
7879
#endif
7980

81+
static fix_state_fp fp_fix_state;
8082
static struct db_main *crk_db;
8183
static struct fmt_params crk_params;
8284
static struct fmt_methods crk_methods;
@@ -758,6 +760,11 @@ static int crk_process_event(void)
758760
return event_abort;
759761
}
760762

763+
void crk_set_hybrid_fix_state_func_ptr(fix_state_fp fp)
764+
{
765+
fp_fix_state = fp;
766+
}
767+
761768
static int crk_password_loop(struct db_salt *salt)
762769
{
763770
void ext_hybrid_fix_state(void);
@@ -776,7 +783,8 @@ static int crk_password_loop(struct db_salt *salt)
776783
if (event_pending && crk_process_event())
777784
return -1;
778785

779-
ext_hybrid_fix_state();
786+
if (fp_fix_state)
787+
fp_fix_state();
780788

781789
count = crk_key_index;
782790
match = crk_methods.crypt_all(&count, salt);

src/cracker.h

+7
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,11 @@ extern int crk_reload_pot(void);
6060
* Exported for stacked modes
6161
*/
6262
extern void (*crk_fix_state)(void);
63+
64+
/*
65+
* This needs set for 2nd level save/resume code to get proper
66+
* information stashed away so resume is done properly.
67+
*/
68+
typedef void (*fix_state_fp)();
69+
extern void crk_set_hybrid_fix_state_func_ptr(fix_state_fp fp);
6370
#endif

src/external.c

+1
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,7 @@ int do_external_hybrid_crack(struct db_main *db, const char *base_word) {
645645
if (first) {
646646
strcpy(int_hybrid_base_word, base_word);
647647
rec_init_hybrid(save_state_hybrid);
648+
crk_set_hybrid_fix_state_func_ptr(ext_hybrid_fix_state);
648649
first = 0;
649650
just_restored = rec_restored;
650651
if (rec_restored) {

src/recovery.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#include "status.h"
5656
#include "recovery.h"
5757
#include "external.h"
58+
#include "regex.h"
5859
#include "john.h"
5960
#include "mask.h"
6061
#include "unicode.h"
@@ -652,12 +653,12 @@ void rec_restore_mode(int (*restore_mode)(FILE *file))
652653
if (ext_restore_state_hybrid(buf, rec_file))
653654
rec_format_error("external-hybrid");
654655
}
655-
/*
656+
#if HAVE_REXGEN
656657
else if (!strncmp(buf, "rex-v", 5)) {
657658
if (rexgen_restore_state_hybrid(buf, rec_file))
658659
rec_format_error("rexgen-hybrid");
659660
}
660-
*/
661+
#endif
661662
if (!strcmp(buf, "slt-v1")) {
662663
restore_salt_state();
663664
}

src/regex.c

+84-20
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,20 @@
3535
#define UNICODE
3636
#define _UNICODE
3737

38+
#ifdef _MSC_VER
39+
char *stpcpy(char *dst, const char *src) {
40+
strcpy(dst, src);
41+
return dst + strlen(dst);
42+
}
43+
#endif
44+
3845
char *rexgen_alphabets[256];
46+
static c_iterator_ptr iter = NULL;
47+
static c_regex_ptr regex_ptr = NULL;
48+
static char *save_str;
49+
static const char *cur_regex, *save_regex;
50+
static char *restore_str, *restore_regex;
51+
static int save_str_len;
3952

4053
static void fix_state(void)
4154
{
@@ -50,6 +63,52 @@ static void save_state(FILE *file)
5063
{
5164
}
5265

66+
int rexgen_restore_state_hybrid(const char *sig, FILE *file)
67+
{
68+
if (!strncmp(sig, "rex-v1", 6))
69+
{
70+
int len, ret;
71+
ret = fscanf(file, "%d\n", &len);
72+
if (ret != 1) return 1;
73+
restore_regex = mem_alloc_tiny(len+2, 8);
74+
fgetl(restore_regex, len+1, file);
75+
ret = fscanf(file, "%d\n", &len);
76+
if (ret != 1) return 1;
77+
restore_str = mem_alloc_tiny(len+2, 8);
78+
fgetl(restore_str, len+1, file);
79+
log_event("resuming a regex expr or %s and state of %s\n", restore_regex, restore_str);
80+
return 0;
81+
}
82+
return 1;
83+
}
84+
85+
static void save_state_hybrid(FILE *file)
86+
{
87+
if (save_str && strlen(save_str)) {
88+
fprintf(file, "rex-v1\n");
89+
fprintf(file, "%d\n", (int)strlen(save_regex));
90+
fprintf(file, "%s\n", save_regex);
91+
fprintf(file, "%d\n", (int)strlen(save_str));
92+
fprintf(file, "%s\n", save_str);
93+
}
94+
}
95+
96+
static void rex_hybrid_fix_state()
97+
{
98+
char *dstptr=0;
99+
if (iter)
100+
c_iterator_get_state(iter, &dstptr);
101+
if (dstptr) {
102+
if (strlen(dstptr) > save_str_len) {
103+
save_str_len = strlen(dstptr)+256;
104+
MEM_FREE(save_str);
105+
save_str = mem_alloc(save_str_len+1);
106+
}
107+
strcpy(save_str, dstptr);
108+
save_regex = cur_regex;
109+
}
110+
}
111+
53112
static int restore_state(FILE *file)
54113
{
55114
return 0;
@@ -76,6 +135,7 @@ static void rexgen_setlocale()
76135
}
77136
}
78137

138+
// Would be nice to have SOME way to be thread safe!!!
79139
static char BaseWord[1024];
80140

81141
size_t callback(char* dst, const size_t buffer_size)
@@ -134,24 +194,39 @@ int do_regex_hybrid_crack(struct db_main *db, const char *regex,
134194
const char *base_word, int regex_case, const char *regex_alpha)
135195
{
136196
c_simplestring_ptr buffer = c_simplestring_new();
137-
c_iterator_ptr iter = NULL;
138-
c_regex_ptr regex_ptr = NULL;
139197
char word[PLAINTEXT_BUFFER_SIZE];
140198
static int bFirst = 1;
141199
static int bALPHA = 0;
142200
int max_len = db->format->params.plaintext_length;
143201
int retval;
144202

203+
cur_regex = regex;
145204
if (options.req_maxlength)
146205
max_len = options.req_maxlength;
147206

207+
strcpy(BaseWord, base_word);
148208
if (bFirst) {
149209
bFirst = 0;
150210
rexgen_setlocale();
151211
if (regex_alpha && !strncmp(regex_alpha, "alpha", 5)) {
152212
bALPHA = 1;
153213
SetupAlpha(regex_alpha);
154214
}
215+
rec_init_hybrid(save_state_hybrid);
216+
crk_set_hybrid_fix_state_func_ptr(rex_hybrid_fix_state);
217+
218+
regex_ptr = c_regex_cb(regex, callback);
219+
if (!regex_ptr) {
220+
c_simplestring_delete(buffer);
221+
fprintf(stderr,
222+
"Error, invalid regex expression. John exiting now base_word=%s Regex= %s\n",
223+
base_word, regex);
224+
error();
225+
}
226+
iter = c_regex_iterator(regex_ptr);
227+
228+
if (restore_str)
229+
c_iterator_set_state(iter, restore_str);
155230
}
156231

157232
if (bALPHA) {
@@ -190,7 +265,6 @@ int do_regex_hybrid_crack(struct db_main *db, const char *regex,
190265
}
191266
}
192267

193-
strcpy(BaseWord, base_word);
194268
if (!regex[0]) {
195269
if (options.mask) {
196270
if (do_mask_crack(fmt_null_key)) {
@@ -208,15 +282,6 @@ int do_regex_hybrid_crack(struct db_main *db, const char *regex,
208282
goto out;
209283
}
210284

211-
regex_ptr = c_regex_cb(regex, callback);
212-
if (!regex_ptr) {
213-
c_simplestring_delete(buffer);
214-
fprintf(stderr,
215-
"Error, invalid regex expression. John exiting now base_word=%s Regex= %s\n",
216-
base_word, regex);
217-
error();
218-
}
219-
iter = c_regex_iterator(regex_ptr);
220285
while (c_iterator_next(iter)) {
221286
c_iterator_value(iter, buffer);
222287
c_simplestring_to_utf8_string(buffer, &word[0], sizeof(word));
@@ -240,38 +305,37 @@ int do_regex_hybrid_crack(struct db_main *db, const char *regex,
240305

241306
out:
242307
c_simplestring_delete(buffer);
243-
c_regex_delete(regex_ptr);
244-
c_iterator_delete(iter);
245308
return retval;
246309
}
247310

248311
void do_regex_crack(struct db_main *db, const char *regex)
249312
{
250313
c_simplestring_ptr buffer = c_simplestring_new();
251-
c_iterator_ptr iter = NULL;
252-
c_regex_ptr regex_ptr = NULL;
253314
char word[PLAINTEXT_BUFFER_SIZE];
254315
int max_len = db->format->params.plaintext_length;
255316

256317
if (options.req_maxlength)
257318
max_len = options.req_maxlength;
258319

259-
if (john_main_process)
260-
fprintf(stderr, "Warning: regex mode currently can't be "
261-
"resumed if aborted\n");
262-
320+
cur_regex = regex;
263321
rexgen_setlocale();
264322
status_init(&get_progress, 0);
265323
rec_restore_mode(restore_state);
266324
rec_init(db, save_state);
267325
crk_init(db, fix_state, NULL);
326+
rec_init_hybrid(save_state_hybrid);
327+
268328
regex_ptr = c_regex_cb(regex, callback);
269329
if (!regex_ptr) {
270330
fprintf(stderr,
271331
"Error, invalid regex expression. John exiting now\n");
272332
error();
273333
}
274334
iter = c_regex_iterator(regex_ptr);
335+
if (restore_str) {
336+
c_iterator_set_state(iter, restore_str);
337+
restore_str = 0;
338+
}
275339
while (c_iterator_next(iter)) {
276340
c_iterator_value(iter, buffer);
277341
c_simplestring_to_utf8_string(buffer, &word[0], sizeof(word));

src/regex.h

+2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ void do_regex_crack(struct db_main *db, const char *regex);
5252
int do_regex_hybrid_crack(struct db_main *db, const char *regex,
5353
const char *base_word, int bCase, const char *regex_alpha);
5454
char *prepare_regex(char *regex, int *bCase, char **regex_alpha);
55+
int rexgen_restore_state_hybrid(const char *sig, FILE *file);
56+
5557
#else
5658
#undef HAVE_REXGEN
5759
#define do_regex_hybrid_crack(a,word,b,c) crk_process_key(word)

0 commit comments

Comments
 (0)