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