@@ -106,7 +106,7 @@ int rules_mute, stack_rules_mute;
106106static int fmt_case ;
107107
108108static 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;
192192static char * conv_shift , * conv_invert , * conv_vowels , * conv_right , * conv_left ;
193193static 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