1 /**
2  * Author......: See docs/credits.txt
3  * License.....: MIT
4  */
5 
6 #include "common.h"
7 #include "types.h"
8 #include "memory.h"
9 #include "event.h"
10 #include "convert.h"
11 #include "mpsp.h"
12 #include "rp.h"
13 #include "emu_inc_rp.h"
14 #include "emu_inc_rp_optimized.h"
15 #include "backend.h"
16 #include "shared.h"
17 #include "locking.h"
18 #include "outfile.h"
19 
outfile_format_parse(const char * format_string)20 u32 outfile_format_parse (const char *format_string)
21 {
22   if (format_string == NULL) return 0;
23 
24   char *format = hcstrdup (format_string);
25 
26   if (format == NULL) return 0;
27 
28   char *saveptr = NULL;
29 
30   char *next = strtok_r (format, ",", &saveptr);
31 
32   if (next == NULL)
33   {
34     hcfree (format);
35 
36     return 0;
37   }
38 
39   u32 outfile_format = 0;
40 
41   do
42   {
43     const int tok_len = strlen (next);
44 
45     // reject non-numbers:
46 
47     if (is_valid_digit_string ((const u8 *) next, tok_len) == false)
48     {
49       outfile_format = 0;
50       break;
51     }
52 
53     // string to number conversion:
54 
55     const u32 num = hc_strtoul (next, NULL, 10);
56 
57     if (num == 0)
58     {
59       outfile_format = 0;
60       break;
61     }
62 
63     if (num > 31)
64     {
65       outfile_format = 0;
66       break;
67     }
68 
69     // to bitmask:
70 
71     const u32 bit = 1 << (num - 1);
72 
73     bool accepted = false;
74 
75     switch (bit)
76     {
77       // allowed formats:
78       case OUTFILE_FMT_HASH:
79       case OUTFILE_FMT_PLAIN:
80       case OUTFILE_FMT_HEXPLAIN:
81       case OUTFILE_FMT_CRACKPOS:
82       case OUTFILE_FMT_TIME_ABS:
83       case OUTFILE_FMT_TIME_REL:
84         accepted = true;
85         break;
86       // NOT acceptable formats:
87       default:
88         accepted = false;
89         break;
90     }
91 
92     if (accepted == false)
93     {
94       outfile_format = 0;
95       break;
96     }
97 
98     // the user should specify any format at most once:
99 
100     if (outfile_format & bit)
101     {
102       outfile_format = 0;
103       break;
104     }
105 
106     outfile_format |= bit;
107 
108   } while ((next = strtok_r ((char *) NULL, ",", &saveptr)) != NULL);
109 
110   hcfree (format);
111 
112   return outfile_format;
113 }
114 
build_plain(hashcat_ctx_t * hashcat_ctx,hc_device_param_t * device_param,plain_t * plain,u32 * plain_buf,int * out_len)115 int build_plain (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, plain_t *plain, u32 *plain_buf, int *out_len)
116 {
117   const combinator_ctx_t     *combinator_ctx     = hashcat_ctx->combinator_ctx;
118   const hashconfig_t         *hashconfig         = hashcat_ctx->hashconfig;
119   const hashes_t             *hashes             = hashcat_ctx->hashes;
120   const mask_ctx_t           *mask_ctx           = hashcat_ctx->mask_ctx;
121   const straight_ctx_t       *straight_ctx       = hashcat_ctx->straight_ctx;
122   const user_options_t       *user_options       = hashcat_ctx->user_options;
123   const user_options_extra_t *user_options_extra = hashcat_ctx->user_options_extra;
124 
125   const u64 gidvid = plain->gidvid;
126   const u32 il_pos = plain->il_pos;
127 
128   int plain_len = 0;
129 
130   u8 *plain_ptr = (u8 *) plain_buf;
131 
132   if (user_options->slow_candidates == true)
133   {
134     pw_t pw;
135 
136     const int rc = gidd_to_pw_t (hashcat_ctx, device_param, gidvid, &pw);
137 
138     if (rc == -1) return -1;
139 
140     memcpy (plain_buf, pw.i, pw.pw_len);
141 
142     plain_len = pw.pw_len;
143   }
144   else
145   {
146     if ((user_options->attack_mode == ATTACK_MODE_STRAIGHT) || (user_options->attack_mode == ATTACK_MODE_ASSOCIATION))
147     {
148       pw_t pw;
149 
150       const int rc = gidd_to_pw_t (hashcat_ctx, device_param, gidvid, &pw);
151 
152       if (rc == -1) return -1;
153 
154       const u64 off = device_param->innerloop_pos + il_pos;
155 
156       if (hashconfig->opti_type & OPTI_TYPE_OPTIMIZED_KERNEL)
157       {
158         if ((user_options->rp_files_cnt == 0) && (user_options->rp_gen == 0))
159         {
160           for (int i = 0; i < 14; i++)
161           {
162             plain_buf[i] = pw.i[i];
163           }
164 
165           plain_len = pw.pw_len;
166         }
167         else
168         {
169           for (int i = 0; i < 8; i++)
170           {
171             plain_buf[i] = pw.i[i];
172           }
173 
174           plain_len = apply_rules_optimized (straight_ctx->kernel_rules_buf[off].cmds, &plain_buf[0], &plain_buf[4], pw.pw_len);
175         }
176       }
177       else
178       {
179         for (int i = 0; i < 64; i++)
180         {
181           plain_buf[i] = pw.i[i];
182         }
183 
184         plain_len = apply_rules (straight_ctx->kernel_rules_buf[off].cmds, plain_buf, pw.pw_len);
185       }
186     }
187     else if (user_options->attack_mode == ATTACK_MODE_COMBI)
188     {
189       pw_t pw;
190 
191       const int rc = gidd_to_pw_t (hashcat_ctx, device_param, gidvid, &pw);
192 
193       if (rc == -1) return -1;
194 
195       for (int i = 0; i < 64; i++)
196       {
197         plain_buf[i] = pw.i[i];
198       }
199 
200       plain_len = (int) pw.pw_len;
201 
202       char *comb_buf = (char *) device_param->combs_buf[il_pos].i;
203       u32   comb_len =          device_param->combs_buf[il_pos].pw_len;
204 
205       if (combinator_ctx->combs_mode == COMBINATOR_MODE_BASE_LEFT)
206       {
207         memcpy (plain_ptr + plain_len, comb_buf, (size_t) comb_len);
208       }
209       else
210       {
211         memmove (plain_ptr + comb_len, plain_ptr, (size_t) plain_len);
212 
213         memcpy (plain_ptr, comb_buf, comb_len);
214       }
215 
216       plain_len += comb_len;
217     }
218     else if (user_options->attack_mode == ATTACK_MODE_BF)
219     {
220       u64 l_off = device_param->kernel_params_mp_l_buf64[3] + gidvid;
221       u64 r_off = device_param->kernel_params_mp_r_buf64[3] + il_pos;
222 
223       u32 l_start = device_param->kernel_params_mp_l_buf32[5];
224       u32 r_start = device_param->kernel_params_mp_r_buf32[5];
225 
226       u32 l_stop = device_param->kernel_params_mp_l_buf32[4];
227       u32 r_stop = device_param->kernel_params_mp_r_buf32[4];
228 
229       sp_exec (l_off, (char *) plain_ptr + l_start, mask_ctx->root_css_buf, mask_ctx->markov_css_buf, l_start, l_start + l_stop);
230       sp_exec (r_off, (char *) plain_ptr + r_start, mask_ctx->root_css_buf, mask_ctx->markov_css_buf, r_start, r_start + r_stop);
231 
232       plain_len = (int) mask_ctx->css_cnt;
233     }
234     else if (user_options->attack_mode == ATTACK_MODE_HYBRID1)
235     {
236       pw_t pw;
237 
238       const int rc = gidd_to_pw_t (hashcat_ctx, device_param, gidvid, &pw);
239 
240       if (rc == -1) return -1;
241 
242       for (int i = 0; i < 64; i++)
243       {
244         plain_buf[i] = pw.i[i];
245       }
246 
247       plain_len = (int) pw.pw_len;
248 
249       u64 off = device_param->kernel_params_mp_buf64[3] + il_pos;
250 
251       u32 start = 0;
252       u32 stop  = device_param->kernel_params_mp_buf32[4];
253 
254       sp_exec (off, (char *) plain_ptr + plain_len, mask_ctx->root_css_buf, mask_ctx->markov_css_buf, start, start + stop);
255 
256       plain_len += start + stop;
257     }
258     else if (user_options->attack_mode == ATTACK_MODE_HYBRID2)
259     {
260       if (hashconfig->opti_type & OPTI_TYPE_OPTIMIZED_KERNEL)
261       {
262         pw_t pw;
263 
264         const int rc = gidd_to_pw_t (hashcat_ctx, device_param, gidvid, &pw);
265 
266         if (rc == -1) return -1;
267 
268         for (int i = 0; i < 64; i++)
269         {
270           plain_buf[i] = pw.i[i];
271         }
272 
273         plain_len = (int) pw.pw_len;
274 
275         u64 off = device_param->kernel_params_mp_buf64[3] + il_pos;
276 
277         u32 start = 0;
278         u32 stop  = device_param->kernel_params_mp_buf32[4];
279 
280         memmove (plain_ptr + stop, plain_ptr, plain_len);
281 
282         sp_exec (off, (char *) plain_ptr, mask_ctx->root_css_buf, mask_ctx->markov_css_buf, start, start + stop);
283 
284         plain_len += start + stop;
285       }
286       else
287       {
288         pw_t pw;
289 
290         const int rc = gidd_to_pw_t (hashcat_ctx, device_param, gidvid, &pw);
291 
292         if (rc == -1) return -1;
293 
294         u64 off = device_param->kernel_params_mp_buf64[3] + gidvid;
295 
296         u32 start = 0;
297         u32 stop  = device_param->kernel_params_mp_buf32[4];
298 
299         sp_exec (off, (char *) plain_ptr, mask_ctx->root_css_buf, mask_ctx->markov_css_buf, start, start + stop);
300 
301         plain_len = stop;
302 
303         char *comb_buf = (char *) device_param->combs_buf[il_pos].i;
304         u32   comb_len =          device_param->combs_buf[il_pos].pw_len;
305 
306         memcpy (plain_ptr + plain_len, comb_buf, comb_len);
307 
308         plain_len += comb_len;
309       }
310     }
311 
312     if (user_options->attack_mode == ATTACK_MODE_BF)
313     {
314       if (hashconfig->opti_type & OPTI_TYPE_BRUTE_FORCE) // lots of optimizations can happen here
315       {
316         if (hashconfig->opti_type & OPTI_TYPE_SINGLE_HASH)
317         {
318           if (hashconfig->opti_type & OPTI_TYPE_APPENDED_SALT)
319           {
320             plain_len = plain_len - hashes->salts_buf[0].salt_len;
321           }
322         }
323 
324         if (hashconfig->opts_type & OPTS_TYPE_PT_UTF16LE)
325         {
326           for (int i = 0, j = 0; i < plain_len; i += 2, j += 1)
327           {
328             plain_ptr[j] = plain_ptr[i];
329           }
330 
331           plain_len = plain_len / 2;
332         }
333         else if (hashconfig->opts_type & OPTS_TYPE_PT_UTF16BE)
334         {
335           for (int i = 1, j = 0; i < plain_len; i += 2, j += 1)
336           {
337             plain_ptr[j] = plain_ptr[i];
338           }
339 
340           plain_len = plain_len / 2;
341         }
342       }
343     }
344   }
345 
346   int pw_max = (const int) hashconfig->pw_max;
347 
348   // pw_max is per pw_t element but in combinator we have two pw_t elements.
349   // therefore we can support up to 64 in combinator in optimized mode (but limited by general hash limit 55)
350   // or full 512 in pure mode (but limited by hashcat buffer size limit 256).
351   // some algorithms do not support general default pw_max = 31,
352   // therefore we need to use pw_max as a base and not hardcode it.
353 
354   if (plain_len > pw_max)
355   {
356     if (user_options_extra->attack_kern == ATTACK_KERN_COMBI)
357     {
358       if (hashconfig->opti_type & OPTI_TYPE_OPTIMIZED_KERNEL)
359       {
360         pw_max = MIN ((pw_max * 2), 55);
361       }
362       else
363       {
364         pw_max = MIN ((pw_max * 2), 256);
365       }
366     }
367   }
368 
369   if (plain_len > pw_max) plain_len = MIN (plain_len, pw_max);
370 
371   plain_ptr[plain_len] = 0;
372 
373   *out_len = plain_len;
374 
375   return 0;
376 }
377 
build_crackpos(hashcat_ctx_t * hashcat_ctx,hc_device_param_t * device_param,plain_t * plain,u64 * out_pos)378 int build_crackpos (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, plain_t *plain, u64 *out_pos)
379 {
380   const combinator_ctx_t      *combinator_ctx     = hashcat_ctx->combinator_ctx;
381   const mask_ctx_t            *mask_ctx           = hashcat_ctx->mask_ctx;
382   const straight_ctx_t        *straight_ctx       = hashcat_ctx->straight_ctx;
383   const user_options_t        *user_options       = hashcat_ctx->user_options;
384   const user_options_extra_t  *user_options_extra = hashcat_ctx->user_options_extra;
385 
386   const u64 gidvid = plain->gidvid;
387   const u32 il_pos = plain->il_pos;
388 
389   u64 crackpos = device_param->words_off;
390 
391   if (user_options->slow_candidates == true)
392   {
393     crackpos = gidvid;
394   }
395   else
396   {
397     if (user_options_extra->attack_kern == ATTACK_KERN_STRAIGHT)
398     {
399       crackpos += gidvid;
400       crackpos *= straight_ctx->kernel_rules_cnt;
401       crackpos += device_param->innerloop_pos + il_pos;
402     }
403     else if (user_options_extra->attack_kern == ATTACK_KERN_COMBI)
404     {
405       crackpos += gidvid;
406       crackpos *= combinator_ctx->combs_cnt;
407       crackpos += device_param->innerloop_pos + il_pos;
408     }
409     else if (user_options_extra->attack_kern == ATTACK_MODE_BF)
410     {
411       crackpos += gidvid;
412       crackpos *= mask_ctx->bfs_cnt;
413       crackpos += device_param->innerloop_pos + il_pos;
414     }
415   }
416 
417   *out_pos = crackpos;
418 
419   return 0;
420 }
421 
build_debugdata(hashcat_ctx_t * hashcat_ctx,hc_device_param_t * device_param,plain_t * plain,u8 * debug_rule_buf,int * debug_rule_len,u8 * debug_plain_ptr,int * debug_plain_len)422 int build_debugdata (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, plain_t *plain, u8 *debug_rule_buf, int *debug_rule_len, u8 *debug_plain_ptr, int *debug_plain_len)
423 {
424   const debugfile_ctx_t *debugfile_ctx = hashcat_ctx->debugfile_ctx;
425   const straight_ctx_t  *straight_ctx  = hashcat_ctx->straight_ctx;
426   const user_options_t  *user_options  = hashcat_ctx->user_options;
427 
428   const u64 gidvid = plain->gidvid;
429   const u32 il_pos = plain->il_pos;
430 
431   if ((user_options->attack_mode != ATTACK_MODE_STRAIGHT) && (user_options->attack_mode != ATTACK_MODE_ASSOCIATION)) return 0;
432 
433   const u32 debug_mode = debugfile_ctx->mode;
434 
435   if (debug_mode == 0) return 0;
436 
437   if (user_options->slow_candidates == true)
438   {
439     pw_pre_t *pw_base = device_param->pws_base_buf + gidvid;
440 
441     // save rule
442     if ((debug_mode == 1) || (debug_mode == 3) || (debug_mode == 4))
443     {
444       const int len = kernel_rule_to_cpu_rule ((char *) debug_rule_buf, &straight_ctx->kernel_rules_buf[pw_base->rule_idx]);
445 
446       debug_rule_buf[len] = 0;
447 
448       *debug_rule_len = len;
449     }
450 
451     // save plain
452     if ((debug_mode == 2) || (debug_mode == 3) || (debug_mode == 4))
453     {
454       memcpy (debug_plain_ptr, pw_base->base_buf, pw_base->base_len);
455 
456       debug_plain_ptr[pw_base->base_len] = 0;
457 
458       *debug_plain_len = pw_base->base_len;
459     }
460   }
461   else
462   {
463     pw_t pw;
464 
465     const int rc = gidd_to_pw_t (hashcat_ctx, device_param, gidvid, &pw);
466 
467     if (rc == -1) return -1;
468 
469     int plain_len = (int) pw.pw_len;
470 
471     const u64 off = device_param->innerloop_pos + il_pos;
472 
473     // save rule
474     if ((debug_mode == 1) || (debug_mode == 3) || (debug_mode == 4))
475     {
476       const int len = kernel_rule_to_cpu_rule ((char *) debug_rule_buf, &straight_ctx->kernel_rules_buf[off]);
477 
478       debug_rule_buf[len] = 0;
479 
480       *debug_rule_len = len;
481     }
482 
483     // save plain
484     if ((debug_mode == 2) || (debug_mode == 3) || (debug_mode == 4))
485     {
486       memcpy (debug_plain_ptr, (char *) pw.i, (size_t) plain_len);
487 
488       debug_plain_ptr[plain_len] = 0;
489 
490       *debug_plain_len = plain_len;
491     }
492   }
493 
494   return 0;
495 }
496 
outfile_init(hashcat_ctx_t * hashcat_ctx)497 int outfile_init (hashcat_ctx_t *hashcat_ctx)
498 {
499   outfile_ctx_t  *outfile_ctx  = hashcat_ctx->outfile_ctx;
500   user_options_t *user_options = hashcat_ctx->user_options;
501 
502   outfile_ctx->fp.pfp          = NULL;
503   outfile_ctx->filename        = user_options->outfile;
504   outfile_ctx->outfile_format  = user_options->outfile_format;
505   outfile_ctx->outfile_autohex = user_options->outfile_autohex;
506 
507   return 0;
508 }
509 
outfile_destroy(hashcat_ctx_t * hashcat_ctx)510 void outfile_destroy (hashcat_ctx_t *hashcat_ctx)
511 {
512   outfile_ctx_t *outfile_ctx = hashcat_ctx->outfile_ctx;
513 
514   memset (outfile_ctx, 0, sizeof (outfile_ctx_t));
515 }
516 
outfile_write_open(hashcat_ctx_t * hashcat_ctx)517 int outfile_write_open (hashcat_ctx_t *hashcat_ctx)
518 {
519   outfile_ctx_t *outfile_ctx = hashcat_ctx->outfile_ctx;
520 
521   if (outfile_ctx->filename == NULL) return 0;
522 
523   if (hc_fopen (&outfile_ctx->fp, outfile_ctx->filename, "ab") == false)
524   {
525     event_log_error (hashcat_ctx, "%s: %s", outfile_ctx->filename, strerror (errno));
526 
527     return -1;
528   }
529 
530   if (hc_lockfile (&outfile_ctx->fp) == -1)
531   {
532     hc_fclose (&outfile_ctx->fp);
533 
534     event_log_error (hashcat_ctx, "%s: %s", outfile_ctx->filename, strerror (errno));
535 
536     return -1;
537   }
538 
539   return 0;
540 }
541 
outfile_write_close(hashcat_ctx_t * hashcat_ctx)542 void outfile_write_close (hashcat_ctx_t *hashcat_ctx)
543 {
544   outfile_ctx_t *outfile_ctx = hashcat_ctx->outfile_ctx;
545 
546   if (outfile_ctx->fp.pfp == NULL) return;
547 
548   hc_unlockfile (&outfile_ctx->fp);
549 
550   hc_fclose (&outfile_ctx->fp);
551 }
552 
outfile_write(hashcat_ctx_t * hashcat_ctx,const char * out_buf,const int out_len,const unsigned char * plain_ptr,const u32 plain_len,const u64 crackpos,const unsigned char * username,const u32 user_len,const bool print_eol,char * tmp_buf)553 int outfile_write (hashcat_ctx_t *hashcat_ctx, const char *out_buf, const int out_len, const unsigned char *plain_ptr, const u32 plain_len, const u64 crackpos, const unsigned char *username, const u32 user_len, const bool print_eol, char *tmp_buf)
554 {
555   const hashconfig_t   *hashconfig   = hashcat_ctx->hashconfig;
556   const user_options_t *user_options = hashcat_ctx->user_options;
557   outfile_ctx_t        *outfile_ctx  = hashcat_ctx->outfile_ctx;
558   status_ctx_t         *status_ctx   = hashcat_ctx->status_ctx;
559 
560   const u32 outfile_format = (hashconfig->opts_type & OPTS_TYPE_PT_ALWAYS_HEXIFY) ? 5 : outfile_ctx->outfile_format;
561 
562   int tmp_len = 0;
563 
564   if (user_len > 0)
565   {
566     if (username != NULL)
567     {
568       memcpy (tmp_buf + tmp_len, username, user_len);
569 
570       tmp_len += user_len;
571 
572       if (outfile_format & (OUTFILE_FMT_TIME_ABS | OUTFILE_FMT_TIME_REL | OUTFILE_FMT_HASH | OUTFILE_FMT_PLAIN | OUTFILE_FMT_HEXPLAIN | OUTFILE_FMT_CRACKPOS))
573       {
574         tmp_buf[tmp_len] = hashconfig->separator;
575 
576         tmp_len += 1;
577       }
578     }
579   }
580 
581   if (outfile_format & OUTFILE_FMT_TIME_ABS)
582   {
583     time_t now;
584 
585     time (&now);
586 
587     tmp_len += snprintf (tmp_buf + tmp_len, HCBUFSIZ_LARGE - tmp_len, "%" PRIu64, (u64) now);
588 
589     if (outfile_format & (OUTFILE_FMT_TIME_REL | OUTFILE_FMT_HASH | OUTFILE_FMT_PLAIN | OUTFILE_FMT_HEXPLAIN | OUTFILE_FMT_CRACKPOS))
590     {
591       tmp_buf[tmp_len] = hashconfig->separator;
592 
593       tmp_len += 1;
594     }
595   }
596 
597   if (outfile_format & OUTFILE_FMT_TIME_REL)
598   {
599     time_t time_now;
600 
601     time (&time_now);
602 
603     time_t time_started = status_ctx->runtime_start;
604 
605     u64 diff = 0;
606 
607     if (time_now > time_started) // should always be true, but you never know
608     {
609       diff = (u64) time_now - (u64) time_started;
610     }
611 
612     tmp_len += snprintf (tmp_buf + tmp_len, HCBUFSIZ_LARGE - tmp_len, "%" PRIu64, diff);
613 
614     if (outfile_format & (OUTFILE_FMT_HASH | OUTFILE_FMT_PLAIN | OUTFILE_FMT_HEXPLAIN | OUTFILE_FMT_CRACKPOS))
615     {
616       tmp_buf[tmp_len] = hashconfig->separator;
617 
618       tmp_len += 1;
619     }
620   }
621 
622   if (outfile_format & OUTFILE_FMT_HASH)
623   {
624     memcpy (tmp_buf + tmp_len, out_buf, out_len);
625 
626     tmp_len += out_len;
627 
628     if (outfile_format & (OUTFILE_FMT_PLAIN | OUTFILE_FMT_HEXPLAIN | OUTFILE_FMT_CRACKPOS))
629     {
630       tmp_buf[tmp_len] = hashconfig->separator;
631 
632       tmp_len += 1;
633     }
634   }
635 
636   if (outfile_format & OUTFILE_FMT_PLAIN)
637   {
638     bool convert_to_hex = false;
639 
640     if (user_options->show == false)
641     {
642       if (user_options->outfile_autohex == true)
643       {
644         const bool always_ascii = (hashconfig->opts_type & OPTS_TYPE_PT_ALWAYS_ASCII) ? true : false;
645 
646         convert_to_hex = need_hexify (plain_ptr, plain_len, hashconfig->separator, always_ascii);
647       }
648     }
649 
650     if (convert_to_hex)
651     {
652       tmp_buf[tmp_len++] = '$';
653       tmp_buf[tmp_len++] = 'H';
654       tmp_buf[tmp_len++] = 'E';
655       tmp_buf[tmp_len++] = 'X';
656       tmp_buf[tmp_len++] = '[';
657 
658       exec_hexify (plain_ptr, plain_len, (u8 *) tmp_buf + tmp_len);
659 
660       tmp_len += plain_len * 2;
661 
662       tmp_buf[tmp_len++] = ']';
663     }
664     else
665     {
666       memcpy (tmp_buf + tmp_len, plain_ptr, plain_len);
667 
668       tmp_len += plain_len;
669     }
670 
671     if (outfile_format & (OUTFILE_FMT_HEXPLAIN | OUTFILE_FMT_CRACKPOS))
672     {
673       tmp_buf[tmp_len] = hashconfig->separator;
674 
675       tmp_len += 1;
676     }
677   }
678 
679   if (outfile_format & OUTFILE_FMT_HEXPLAIN)
680   {
681     exec_hexify (plain_ptr, plain_len, (u8 *) tmp_buf + tmp_len);
682 
683     tmp_len += plain_len * 2;
684 
685     if (outfile_format & (OUTFILE_FMT_CRACKPOS))
686     {
687       tmp_buf[tmp_len] = hashconfig->separator;
688 
689       tmp_len += 1;
690     }
691   }
692 
693   if (outfile_format & OUTFILE_FMT_CRACKPOS)
694   {
695     tmp_len += snprintf (tmp_buf + tmp_len, HCBUFSIZ_LARGE - tmp_len, "%" PRIu64, crackpos);
696   }
697 
698   tmp_buf[tmp_len] = 0;
699 
700   if (outfile_ctx->fp.pfp != NULL)
701   {
702     hc_fwrite (tmp_buf, tmp_len, 1, &outfile_ctx->fp);
703 
704     if (print_eol == true)
705     {
706       hc_fwrite (EOL, strlen (EOL), 1, &outfile_ctx->fp);
707     }
708   }
709 
710   return tmp_len;
711 }
712