special case handling for commas within masks of .hcmask file
[hashcat.git] / src / hashcat.c
index 41b6144..e508082 100644 (file)
@@ -468,14 +468,14 @@ const char *USAGE_BIG[] =
   "     40 | md5($salt.unicode($pass))                        | Raw Hash, Salted and / or Iterated",
   "   3800 | md5($salt.$pass.$salt)                           | Raw Hash, Salted and / or Iterated",
   "   3710 | md5($salt.md5($pass))                            | Raw Hash, Salted and / or Iterated",
-  "   2600 | md5(md5($pass)                                   | Raw Hash, Salted and / or Iterated",
+  "   2600 | md5(md5($pass))                                  | Raw Hash, Salted and / or Iterated",
   "   4300 | md5(strtoupper(md5($pass)))                      | Raw Hash, Salted and / or Iterated",
   "   4400 | md5(sha1($pass))                                 | Raw Hash, Salted and / or Iterated",
   "    110 | sha1($pass.$salt)                                | Raw Hash, Salted and / or Iterated",
   "    120 | sha1($salt.$pass)                                | Raw Hash, Salted and / or Iterated",
   "    130 | sha1(unicode($pass).$salt)                       | Raw Hash, Salted and / or Iterated",
   "    140 | sha1($salt.unicode($pass))                       | Raw Hash, Salted and / or Iterated",
-  "   4500 | sha1(sha1($pass)                                 | Raw Hash, Salted and / or Iterated",
+  "   4500 | sha1(sha1($pass))                                | Raw Hash, Salted and / or Iterated",
   "   4700 | sha1(md5($pass))                                 | Raw Hash, Salted and / or Iterated",
   "   4900 | sha1($salt.$pass.$salt)                          | Raw Hash, Salted and / or Iterated",
   "   1410 | sha256($pass.$salt)                              | Raw Hash, Salted and / or Iterated",
@@ -925,6 +925,9 @@ void status_display ()
   if (data.devices_status == STATUS_INIT)     return;
   if (data.devices_status == STATUS_STARTING) return;
 
+  // in this case some required buffers are free'd, ascii_digest() would run into segfault
+  if (data.shutdown_inner == 1) return;
+
   if (data.machine_readable == 1)
   {
     status_display_machine_readable ();
@@ -1339,26 +1342,22 @@ void status_display ()
       }
       else
       {
-        char display_etc[32] = { 0 };
+        char display_etc[32]     = { 0 };
+        char display_runtime[32] = { 0 };
 
         struct tm tm_etc;
+        struct tm tm_runtime;
 
         struct tm *tmp = NULL;
 
         #ifdef WIN
-
         tmp = _gmtime64 (&sec_etc);
-
         #else
-
         tmp = gmtime (&sec_etc);
-
         #endif
 
         if (tmp != NULL)
         {
-          memset (&tm_etc, 0, sizeof (tm_etc));
-
           memcpy (&tm_etc, tmp, sizeof (tm_etc));
 
           format_timer_display (&tm_etc, display_etc, sizeof (display_etc));
@@ -1376,7 +1375,43 @@ void status_display ()
           if (etc[etc_len - 1] == '\n') etc[etc_len - 1] = 0;
           if (etc[etc_len - 2] == '\r') etc[etc_len - 2] = 0;
 
-          log_info ("Time.Estimated.: %s (%s)", etc, display_etc);
+          if (data.runtime)
+          {
+            time_t runtime_cur;
+
+            time (&runtime_cur);
+
+            #ifdef WIN
+
+            __time64_t runtime_left = data.proc_start + data.runtime - runtime_cur;
+
+            tmp = _gmtime64 (&runtime_left);
+
+            #else
+
+            time_t runtime_left = data.proc_start + data.runtime - runtime_cur;
+
+            tmp = gmtime (&runtime_left);
+
+            #endif
+
+            if ((tmp != NULL) && (runtime_left > 0) && (runtime_left < sec_etc))
+            {
+              memcpy (&tm_runtime, tmp, sizeof (tm_runtime));
+
+              format_timer_display (&tm_runtime, display_runtime, sizeof (display_runtime));
+
+              log_info ("Time.Estimated.: %s (%s), but limited (%s)", etc, display_etc, display_runtime);
+            }
+            else
+            {
+              log_info ("Time.Estimated.: %s (%s), but limit exceeded", etc, display_etc);
+            }
+          }
+          else
+          {
+            log_info ("Time.Estimated.: %s (%s)", etc, display_etc);
+          }
         }
       }
     }
@@ -1683,6 +1718,8 @@ static void status_benchmark ()
   if (data.devices_status == STATUS_INIT)     return;
   if (data.devices_status == STATUS_STARTING) return;
 
+  if (data.shutdown_inner == 1) return;
+
   if (data.machine_readable == 1)
   {
     status_benchmark_automate ();
@@ -6134,11 +6171,25 @@ int main (int argc, char **argv)
 
   char *exec_path = get_exec_path ();
 
-  #ifdef LINUX
+  #if defined(LINUX) || defined(__APPLE__)
 
   char *resolved_install_folder = realpath (INSTALL_FOLDER, NULL);
   char *resolved_exec_path      = realpath (exec_path, NULL);
 
+  if (resolved_install_folder == NULL)
+  {
+    log_error ("ERROR: %s: %s", resolved_install_folder, strerror (errno));
+
+    return (-1);
+  }
+
+  if (resolved_exec_path == NULL)
+  {
+    log_error ("ERROR: %s: %s", resolved_exec_path, strerror (errno));
+
+    return (-1);
+  }
+
   char *install_dir = get_install_dir (resolved_exec_path);
   char *profile_dir = NULL;
   char *session_dir = NULL;
@@ -17448,6 +17499,36 @@ int main (int argc, char **argv)
 
             mask = mask + str_pos + 1;
           }
+
+          /**
+           * What follows is a very special case where "\," is within the mask field of a line in a .hcmask file only because otherwise (without the "\")
+           * it would be interpreted as a custom charset definition.
+           *
+           * We need to replace all "\," with just "," within the mask (but allow the special case "\\," which means "\" followed by ",")
+           * Note: "\\" is not needed to replace all "\" within the mask! The meaning of "\\" within a line containing the string "\\," is just to allow "\" followed by ","
+           */
+
+          uint mask_len_cur = strlen (mask);
+
+          uint mask_out_pos = 0;
+          char mask_prev = 0;
+
+          for (uint mask_iter = 0; mask_iter < mask_len_cur; mask_iter++, mask_out_pos++)
+          {
+            if (mask[mask_iter] == ',')
+            {
+              if (mask_prev == '\\')
+              {
+                mask_out_pos -= 1; // this means: skip the previous "\"
+              }
+            }
+
+            mask_prev = mask[mask_iter];
+
+            mask[mask_out_pos] = mask[mask_iter];
+          }
+
+          mask[mask_out_pos] = '\0';
         }
 
         if ((attack_mode == ATTACK_MODE_HYBRID1) || (attack_mode == ATTACK_MODE_HYBRID2))
@@ -18295,10 +18376,17 @@ int main (int argc, char **argv)
 
             log_info ("");
 
-            if (stdout_flag == 0) status_display ();
+            status_display ();
 
             log_info ("");
           }
+          else
+          {
+            if (status == 1)
+            {
+              status_display ();
+            }
+          }
         }
 
         if (induction_dictionaries_cnt)