Skip to content

Commit a3e6909

Browse files
committed
Rules: Complete support for lengths beyond 128
See #5873
1 parent 18d8c49 commit a3e6909

File tree

1 file changed

+55
-48
lines changed

1 file changed

+55
-48
lines changed

src/rules.c

Lines changed: 55 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ int rules_mute, stack_rules_mute;
106106
static int fmt_case;
107107

108108
static struct {
109-
unsigned int vars[0x100];
109+
int vars[0x100]; /* may be negative */
110110
/*
111111
* pass == -2 initial syntax checking of rules
112112
* pass == -1 optimization of rules (no-ops are removed)
@@ -192,8 +192,8 @@ static char *conv_source = CONV_SOURCE;
192192
static char *conv_shift, *conv_invert, *conv_vowels, *conv_right, *conv_left;
193193
static char *conv_tolower, *conv_toupper;
194194

195-
#define INVALID_LENGTH 0x81
196-
#define INFINITE_LENGTH 0xFF
195+
#define INFINITE_LENGTH (MAX_PLAINTEXT_LENGTH * 2)
196+
#define INVALID_LENGTH (INFINITE_LENGTH + 1)
197197

198198
#define RULE (*rule++)
199199
#define LAST (*(rule - 1))
@@ -527,7 +527,7 @@ static void rules_init_length(int max_length)
527527
{
528528
int c;
529529

530-
memset(rules_vars, INVALID_LENGTH, sizeof(rules_vars));
530+
for (c = 0; c < 0x100; c++) rules_vars[c] = INVALID_LENGTH;
531531

532532
for (c = '0'; c <= '9'; c++) rules_vars[c] = c - '0';
533533
for (c = 'A'; c <= 'Z'; c++) rules_vars[c] = c - ('A' - 10);
@@ -806,7 +806,7 @@ char *rules_apply(char *word_in, char *rule, int split)
806806
* exceed INVALID_LENGTH.
807807
*/
808808
rules_vars['l'] = length;
809-
rules_vars['m'] = (unsigned char)length - 1;
809+
rules_vars['m'] = length - 1; /* may be -1 if hc_logic or rules_pass */
810810

811811
if (rules_stacked_after != length_initiated_as) {
812812
if (rules_stacked_after) {
@@ -848,15 +848,15 @@ char *rules_apply(char *word_in, char *rule, int split)
848848

849849
case '<':
850850
{
851-
int pos;
851+
unsigned int pos;
852852
POSITION(pos)
853853
if (length >= pos) REJECT
854854
}
855855
break;
856856

857857
case '>':
858858
{
859-
int pos;
859+
unsigned int pos;
860860
POSITION(pos)
861861
if (length <= pos) REJECT
862862
}
@@ -912,9 +912,9 @@ char *rules_apply(char *word_in, char *rule, int split)
912912
case 'p':
913913
if (hc_logic || (*rule >= '1' && *rule <= '9')) {
914914
/* HC rule: duplicate word N times */
915-
unsigned char x, y;
915+
unsigned int x, y;
916916
POSITION(x)
917-
if (x * length > RULE_WORD_SIZE - 1)
917+
if (x > RULE_WORD_SIZE - 1 || x * length > RULE_WORD_SIZE - 1)
918918
x = (RULE_WORD_SIZE - 1) / length;
919919
y = x;
920920
in[length*(x + 1)] = 0;
@@ -999,7 +999,7 @@ char *rules_apply(char *word_in, char *rule, int split)
999999
case 'x':
10001000
if (hc_logic) {
10011001
/* Slightly different edge logic for HC */
1002-
int pos, pos2;
1002+
unsigned int pos, pos2;
10031003
POSITION(pos)
10041004
POSITION(pos2)
10051005
if (pos < length && pos+pos2 <= length) {
@@ -1013,7 +1013,7 @@ char *rules_apply(char *word_in, char *rule, int split)
10131013
break;
10141014
} else
10151015
{
1016-
int pos;
1016+
unsigned int pos;
10171017
POSITION(pos)
10181018
if (pos < length) {
10191019
char *out;
@@ -1031,7 +1031,7 @@ char *rules_apply(char *word_in, char *rule, int split)
10311031

10321032
case 'i':
10331033
{
1034-
int pos;
1034+
unsigned int pos;
10351035
POSITION(pos)
10361036
if (pos < length) {
10371037
char *p = in + pos;
@@ -1057,7 +1057,7 @@ char *rules_apply(char *word_in, char *rule, int split)
10571057

10581058
case 'o':
10591059
{
1060-
int pos;
1060+
unsigned int pos;
10611061
char value;
10621062
POSITION(pos)
10631063
VALUE(value);
@@ -1096,7 +1096,7 @@ char *rules_apply(char *word_in, char *rule, int split)
10961096

10971097
case '=':
10981098
{
1099-
int pos;
1099+
unsigned int pos;
11001100
POSITION(pos)
11011101
if (pos >= length) {
11021102
SKIP_CLASS
@@ -1169,7 +1169,7 @@ char *rules_apply(char *word_in, char *rule, int split)
11691169

11701170
case '\'':
11711171
{
1172-
int pos;
1172+
unsigned int pos;
11731173
POSITION(pos)
11741174
if (pos < length)
11751175
in[length = pos] = 0;
@@ -1178,7 +1178,7 @@ char *rules_apply(char *word_in, char *rule, int split)
11781178

11791179
case '%':
11801180
{
1181-
int count = 0, required, pos;
1181+
unsigned int count = 0, required, pos;
11821182
POSITION(required)
11831183
CLASS_export_pos(0,
11841184
if (++count >= required) break, {})
@@ -1190,13 +1190,13 @@ char *rules_apply(char *word_in, char *rule, int split)
11901190
/* Rules added in John */
11911191
case 'A': /* append/insert/prepend string */
11921192
{
1193-
int pos;
1193+
unsigned int pos;
11941194
char term;
11951195
POSITION(pos)
11961196
VALUE(term)
11971197
if (pos >= length) { /* append */
11981198
char *start, *end, *p;
1199-
start = p = &in[pos = length];
1199+
start = p = &in[length];
12001200
end = &in[RULE_WORD_SIZE - 1];
12011201
do {
12021202
char c = RULE;
@@ -1238,15 +1238,16 @@ char *rules_apply(char *word_in, char *rule, int split)
12381238

12391239
case 'T':
12401240
{
1241-
int pos;
1241+
unsigned int pos;
12421242
POSITION(pos)
1243-
in[pos] = conv_invert[ARCH_INDEX(in[pos])];
1243+
if (pos < length)
1244+
in[pos] = conv_invert[ARCH_INDEX(in[pos])];
12441245
}
12451246
break;
12461247

12471248
case 'D':
12481249
{
1249-
int pos;
1250+
unsigned int pos;
12501251
POSITION(pos)
12511252
if (pos < length) {
12521253
memmove(&in[pos], &in[pos + 1],
@@ -1312,7 +1313,7 @@ char *rules_apply(char *word_in, char *rule, int split)
13121313
case 'R':
13131314
if (hc_logic || (*rule >= '0' && *rule <= '9')) {
13141315
/* HC rule: bit-shift character right */
1315-
unsigned char n;
1316+
unsigned int n;
13161317
unsigned char val;
13171318
POSITION(n)
13181319
if (n < length) {
@@ -1328,7 +1329,7 @@ char *rules_apply(char *word_in, char *rule, int split)
13281329
case 'L':
13291330
if (hc_logic || (*rule >= '0' && *rule <= '9')) {
13301331
/* HC rule: bit-shift character left */
1331-
unsigned char n;
1332+
unsigned int n;
13321333
unsigned char val;
13331334
POSITION(n)
13341335
if (n < length) {
@@ -1382,7 +1383,7 @@ char *rules_apply(char *word_in, char *rule, int split)
13821383

13831384
case 'M':
13841385
memcpy(memory = memory_buffer, in, length + 1);
1385-
rules_vars['m'] = (unsigned char)length - 1;
1386+
rules_vars['m'] = length - 1;
13861387
break;
13871388

13881389
case 'Q':
@@ -1395,14 +1396,16 @@ char *rules_apply(char *word_in, char *rule, int split)
13951396

13961397
case 'X': /* append/insert/prepend substring from memory */
13971398
{
1398-
int mpos, count, ipos, mleft;
1399+
unsigned int mpos, count, ipos, mleft;
13991400
char *inp;
14001401
const char *mp;
14011402
POSITION(mpos)
14021403
POSITION(count)
14031404
POSITION(ipos)
1404-
mleft = (int)(unsigned char)
1405-
(rules_vars['m'] + 1) - mpos;
1405+
mleft = rules_vars['m'] + 1;
1406+
if (mleft < mpos)
1407+
break;
1408+
mleft -= mpos;
14061409
if (count > mleft)
14071410
count = mleft;
14081411
if (count <= 0)
@@ -1423,14 +1426,14 @@ char *rules_apply(char *word_in, char *rule, int split)
14231426
case 'v': /* assign value to numeric variable */
14241427
{
14251428
char var;
1426-
unsigned char a, s;
1429+
int a, s; /* may be negative */
14271430
VALUE(var)
14281431
if (var < 'a' || var > 'k')
14291432
goto out_ERROR_POSITION;
14301433
rules_vars['l'] = length;
14311434
POSITION(a)
14321435
POSITION(s)
1433-
rules_vars[ARCH_INDEX(var)] = a - s;
1436+
rules_vars[ARCH_INDEX(var)] = a - s; /* may be negative */
14341437
}
14351438
break;
14361439

@@ -1476,7 +1479,7 @@ char *rules_apply(char *word_in, char *rule, int split)
14761479
case '+':
14771480
if (hc_logic || !which) {
14781481
/* HC rule: increment character */
1479-
unsigned char x;
1482+
unsigned int x;
14801483
POSITION(x)
14811484
if (x < length)
14821485
++in[x];
@@ -1508,7 +1511,7 @@ char *rules_apply(char *word_in, char *rule, int split)
15081511
/* Rules added in Jumbo */
15091512
case 'a':
15101513
{
1511-
int pos;
1514+
unsigned int pos;
15121515
POSITION(pos)
15131516
if (!rules_stacked_after) {
15141517
if (length + pos > rules_max_length)
@@ -1521,7 +1524,7 @@ char *rules_apply(char *word_in, char *rule, int split)
15211524

15221525
case 'b':
15231526
{
1524-
int pos;
1527+
unsigned int pos;
15251528
POSITION(pos)
15261529
if (!rules_stacked_after) {
15271530
if (length - pos > rules_max_length)
@@ -1534,9 +1537,10 @@ char *rules_apply(char *word_in, char *rule, int split)
15341537

15351538
case 'W':
15361539
{
1537-
int pos;
1540+
unsigned int pos;
15381541
POSITION(pos)
1539-
in[pos] = conv_shift[ARCH_INDEX(in[pos])];
1542+
if (pos < length)
1543+
in[pos] = conv_shift[ARCH_INDEX(in[pos])];
15401544
}
15411545
break;
15421546

@@ -1548,15 +1552,15 @@ char *rules_apply(char *word_in, char *rule, int split)
15481552
/* Hashcat rules added to Jumbo */
15491553
case '_': /* reject unless length equals to N */
15501554
{
1551-
int pos;
1555+
unsigned int pos;
15521556
POSITION(pos)
15531557
if (length != pos) REJECT
15541558
}
15551559
break;
15561560

15571561
case '-': /* decrement character */
15581562
{
1559-
unsigned char x;
1563+
unsigned int x;
15601564
POSITION(x)
15611565
if (x < length)
15621566
--in[x];
@@ -1575,7 +1579,7 @@ char *rules_apply(char *word_in, char *rule, int split)
15751579

15761580
case '*': /* swap any two characters */
15771581
{
1578-
unsigned char x, y;
1582+
unsigned int x, y;
15791583
POSITION(x)
15801584
POSITION(y)
15811585
if (length > x && length > y)
@@ -1585,9 +1589,10 @@ char *rules_apply(char *word_in, char *rule, int split)
15851589

15861590
case 'z': /* duplicate first char N times */
15871591
{
1588-
unsigned char x;
1589-
int y;
1592+
unsigned int x, y;
15901593
POSITION(x)
1594+
if (x > MAX_PLAINTEXT_LENGTH)
1595+
break;
15911596
y = length;
15921597
while (y) {
15931598
in[y + x] = in[y];
@@ -1602,10 +1607,12 @@ char *rules_apply(char *word_in, char *rule, int split)
16021607
}
16031608
break;
16041609

1605-
case 'Z': /* duplicate char char N times */
1610+
case 'Z': /* duplicate last char N times */
16061611
{
1607-
unsigned char x;
1612+
unsigned int x;
16081613
POSITION(x)
1614+
if (x > MAX_PLAINTEXT_LENGTH)
1615+
break;
16091616
while (x) {
16101617
in[length] = in[length - 1];
16111618
++length;
@@ -1629,7 +1636,7 @@ char *rules_apply(char *word_in, char *rule, int split)
16291636

16301637
case '.': /* replace character with next */
16311638
{
1632-
unsigned char n;
1639+
unsigned int n;
16331640
POSITION(n)
16341641
if (n < length - 1 && length > 1)
16351642
in[n] = in[n + 1];
@@ -1638,7 +1645,7 @@ char *rules_apply(char *word_in, char *rule, int split)
16381645

16391646
case ',': /* replace character with prior */
16401647
{
1641-
unsigned char n;
1648+
unsigned int n;
16421649
POSITION(n)
16431650
if (n >= 1 && length > 1 && n < length)
16441651
in[n] = in[n - 1];
@@ -1647,7 +1654,7 @@ char *rules_apply(char *word_in, char *rule, int split)
16471654

16481655
case 'y': /* duplicate first n characters */
16491656
{
1650-
unsigned char n;
1657+
unsigned int n;
16511658
POSITION(n)
16521659
if (n <= length) {
16531660
memmove(&in[n], in, length);
@@ -1659,7 +1666,7 @@ char *rules_apply(char *word_in, char *rule, int split)
16591666

16601667
case 'Y': /* duplicate last n characters */
16611668
{
1662-
unsigned char n;
1669+
unsigned int n;
16631670
POSITION(n)
16641671
if (n <= length) {
16651672
memmove(&in[length], &in[length - n], n);
@@ -1690,13 +1697,13 @@ char *rules_apply(char *word_in, char *rule, int split)
16901697

16911698
case 'O': /* Omit */
16921699
{
1693-
int pos, pos2;
1700+
unsigned int pos, pos2;
16941701
POSITION(pos)
16951702
POSITION(pos2)
1696-
if (pos < length && pos+pos2 <= length) {
1703+
if (pos < length && pos2 <= length && pos + pos2 <= length) {
16971704
char *out;
16981705
GET_OUT
1699-
strncpy(out, in, pos);
1706+
memcpy(out, in, pos);
17001707
in += pos + pos2;
17011708
strnzcpy(out + pos, in, length - (pos + pos2) + 1);
17021709
length -= pos2;

0 commit comments

Comments
 (0)