1 /*
2 american fuzzy lop++ - python extension routines
3 ------------------------------------------------
4
5 Originally written by Michal Zalewski
6
7 Now maintained by Marc Heuse <[email protected]>,
8 Heiko Eißfeldt <[email protected]> and
9 Andrea Fioraldi <[email protected]>
10
11 Copyright 2016, 2017 Google Inc. All rights reserved.
12 Copyright 2019-2024 AFLplusplus Project. All rights reserved.
13
14 Licensed under the Apache License, Version 2.0 (the "License");
15 you may not use this file except in compliance with the License.
16 You may obtain a copy of the License at:
17
18 https://www.apache.org/licenses/LICENSE-2.0
19
20 This is the real deal: the program takes an instrumented binary and
21 attempts a variety of basic fuzzing tricks, paying close attention to
22 how they affect the execution path.
23
24 */
25
26 #include "afl-fuzz.h"
27
28 /* Python stuff */
29 #ifdef USE_PYTHON
30
31 // Tries to cast a python bytearray or bytes to a char ptr
py_bytes(PyObject * py_value,char ** bytes,size_t * size)32 static inline bool py_bytes(PyObject *py_value, /* out */ char **bytes,
33 /* out */ size_t *size) {
34
35 if (!py_value) { return false; }
36
37 *bytes = PyByteArray_AsString(py_value);
38 if (*bytes) {
39
40 // we got a bytearray
41 *size = PyByteArray_Size(py_value);
42
43 } else {
44
45 *bytes = PyBytes_AsString(py_value);
46 if (!*bytes) {
47
48 // No valid type returned.
49 return false;
50
51 }
52
53 *size = PyBytes_Size(py_value);
54
55 }
56
57 return true;
58
59 }
60
unsupported(afl_state_t * afl,unsigned int seed)61 static void *unsupported(afl_state_t *afl, unsigned int seed) {
62
63 (void)afl;
64 (void)seed;
65
66 FATAL("Python Mutator cannot be called twice yet");
67 return NULL;
68
69 }
70
71 /* sorry for this makro...
72 it just fills in `&py_mutator->something_buf, &py_mutator->something_size`. */
73 #define BUF_PARAMS(name) (void **)&((py_mutator_t *)py_mutator)->name##_buf
74
fuzz_py(void * py_mutator,u8 * buf,size_t buf_size,u8 ** out_buf,u8 * add_buf,size_t add_buf_size,size_t max_size)75 static size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf,
76 u8 *add_buf, size_t add_buf_size, size_t max_size) {
77
78 size_t mutated_size;
79 PyObject *py_args, *py_value;
80 py_args = PyTuple_New(3);
81 py_mutator_t *py = (py_mutator_t *)py_mutator;
82
83 /* buf */
84 py_value = PyByteArray_FromStringAndSize(buf, buf_size);
85 if (!py_value) {
86
87 Py_DECREF(py_args);
88 FATAL("Failed to convert arguments");
89
90 }
91
92 PyTuple_SetItem(py_args, 0, py_value);
93
94 /* add_buf */
95 py_value = PyByteArray_FromStringAndSize(add_buf, add_buf_size);
96 if (!py_value) {
97
98 Py_DECREF(py_args);
99 FATAL("Failed to convert arguments");
100
101 }
102
103 PyTuple_SetItem(py_args, 1, py_value);
104
105 /* max_size */
106 #if PY_MAJOR_VERSION >= 3
107 py_value = PyLong_FromLong(max_size);
108 #else
109 py_value = PyInt_FromLong(max_size);
110 #endif
111 if (!py_value) {
112
113 Py_DECREF(py_args);
114 FATAL("Failed to convert arguments");
115
116 }
117
118 PyTuple_SetItem(py_args, 2, py_value);
119
120 py_value = PyObject_CallObject(py->py_functions[PY_FUNC_FUZZ], py_args);
121
122 Py_DECREF(py_args);
123
124 if (py_value != NULL) {
125
126 char *bytes;
127 if (!py_bytes(py_value, &bytes, &mutated_size)) {
128
129 FATAL("Python mutator fuzz() should return a bytearray or bytes");
130
131 }
132
133 if (mutated_size) {
134
135 *out_buf = afl_realloc(BUF_PARAMS(fuzz), mutated_size);
136 if (unlikely(!*out_buf)) { PFATAL("alloc"); }
137
138 memcpy(*out_buf, bytes, mutated_size);
139
140 }
141
142 Py_DECREF(py_value);
143 return mutated_size;
144
145 } else {
146
147 PyErr_Print();
148 FATAL("python custom fuzz: call failed");
149
150 }
151
152 }
153
custom_describe_py(void * py_mutator,size_t max_description_len)154 static const char *custom_describe_py(void *py_mutator,
155 size_t max_description_len) {
156
157 PyObject *py_args, *py_value;
158
159 py_args = PyTuple_New(1);
160
161 PyLong_FromSize_t(max_description_len);
162
163 /* add_buf */
164 py_value = PyLong_FromSize_t(max_description_len);
165 if (!py_value) {
166
167 Py_DECREF(py_args);
168 FATAL("Failed to convert arguments");
169
170 }
171
172 PyTuple_SetItem(py_args, 0, py_value);
173
174 py_value = PyObject_CallObject(
175 ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_DESCRIBE], py_args);
176
177 Py_DECREF(py_args);
178
179 if (py_value != NULL) { return PyBytes_AsString(py_value); }
180
181 return NULL;
182
183 }
184
init_py_module(afl_state_t * afl,u8 * module_name)185 static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) {
186
187 (void)afl;
188
189 if (!module_name) { return NULL; }
190
191 py_mutator_t *py = calloc(1, sizeof(py_mutator_t));
192 if (!py) { PFATAL("Could not allocate memory for python mutator!"); }
193
194 Py_Initialize();
195
196 #if PY_MAJOR_VERSION >= 3
197 PyObject *py_name = PyUnicode_FromString(module_name);
198 #else
199 PyObject *py_name = PyString_FromString(module_name);
200 #endif
201
202 py->py_module = PyImport_Import(py_name);
203 Py_DECREF(py_name);
204
205 PyObject *py_module = py->py_module;
206 PyObject **py_functions = py->py_functions;
207
208 // initialize the post process buffer; ensures it's always valid
209 PyObject *unused_bytes = PyByteArray_FromStringAndSize("OHAI", 4);
210 if (!unused_bytes) { FATAL("allocation failed!"); }
211 if (PyObject_GetBuffer(unused_bytes, &py->post_process_buf, PyBUF_SIMPLE) ==
212 -1) {
213
214 FATAL("buffer initialization failed");
215
216 }
217
218 Py_DECREF(unused_bytes);
219
220 if (py_module != NULL) {
221
222 u8 py_notrim = 0;
223 py_functions[PY_FUNC_INIT] = PyObject_GetAttrString(py_module, "init");
224 if (!py_functions[PY_FUNC_INIT]) {
225
226 WARNF("init function not found in python module");
227
228 }
229
230 py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "fuzz");
231 if (!py_functions[PY_FUNC_FUZZ])
232 py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "mutate");
233 py_functions[PY_FUNC_DESCRIBE] =
234 PyObject_GetAttrString(py_module, "describe");
235 py_functions[PY_FUNC_FUZZ_COUNT] =
236 PyObject_GetAttrString(py_module, "fuzz_count");
237 py_functions[PY_FUNC_POST_PROCESS] =
238 PyObject_GetAttrString(py_module, "post_process");
239 py_functions[PY_FUNC_INIT_TRIM] =
240 PyObject_GetAttrString(py_module, "init_trim");
241 py_functions[PY_FUNC_POST_TRIM] =
242 PyObject_GetAttrString(py_module, "post_trim");
243 py_functions[PY_FUNC_TRIM] = PyObject_GetAttrString(py_module, "trim");
244 py_functions[PY_FUNC_HAVOC_MUTATION] =
245 PyObject_GetAttrString(py_module, "havoc_mutation");
246 py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY] =
247 PyObject_GetAttrString(py_module, "havoc_mutation_probability");
248 py_functions[PY_FUNC_QUEUE_GET] =
249 PyObject_GetAttrString(py_module, "queue_get");
250 py_functions[PY_FUNC_FUZZ_SEND] =
251 PyObject_GetAttrString(py_module, "fuzz_send");
252 py_functions[PY_FUNC_POST_RUN] =
253 PyObject_GetAttrString(py_module, "post_run");
254 py_functions[PY_FUNC_SPLICE_OPTOUT] =
255 PyObject_GetAttrString(py_module, "splice_optout");
256 if (py_functions[PY_FUNC_SPLICE_OPTOUT]) { afl->custom_splice_optout = 1; }
257 py_functions[PY_FUNC_QUEUE_NEW_ENTRY] =
258 PyObject_GetAttrString(py_module, "queue_new_entry");
259 py_functions[PY_FUNC_INTROSPECTION] =
260 PyObject_GetAttrString(py_module, "introspection");
261 py_functions[PY_FUNC_DEINIT] = PyObject_GetAttrString(py_module, "deinit");
262 if (!py_functions[PY_FUNC_DEINIT])
263 WARNF("deinit function not found in python module");
264
265 if (py_notrim) {
266
267 py_functions[PY_FUNC_INIT_TRIM] = NULL;
268 py_functions[PY_FUNC_POST_TRIM] = NULL;
269 py_functions[PY_FUNC_TRIM] = NULL;
270 WARNF(
271 "Python module does not implement trim API, standard trimming will "
272 "be used.");
273
274 }
275
276 } else {
277
278 PyErr_Print();
279 fprintf(stderr, "Failed to load \"%s\"\n", module_name);
280 free(py);
281 return NULL;
282
283 }
284
285 return py;
286
287 }
288
finalize_py_module(void * py_mutator)289 void finalize_py_module(void *py_mutator) {
290
291 py_mutator_t *py = (py_mutator_t *)py_mutator;
292
293 if (py->py_module != NULL) {
294
295 deinit_py(py_mutator);
296
297 u32 i;
298 for (i = 0; i < PY_FUNC_COUNT; ++i) {
299
300 Py_XDECREF(py->py_functions[i]);
301
302 }
303
304 Py_DECREF(py->py_module);
305
306 }
307
308 Py_Finalize();
309
310 }
311
init_py(afl_state_t * afl,py_mutator_t * py_mutator,unsigned int seed)312 static void init_py(afl_state_t *afl, py_mutator_t *py_mutator,
313 unsigned int seed) {
314
315 (void)afl;
316
317 if (py_mutator->py_functions[PY_FUNC_INIT] == NULL) { return; }
318
319 PyObject *py_args, *py_value;
320
321 /* Provide the init function a seed for the Python RNG */
322 py_args = PyTuple_New(1);
323 #if PY_MAJOR_VERSION >= 3
324 py_value = PyLong_FromLong(seed);
325 #else
326 py_value = PyInt_FromLong(seed);
327 #endif
328
329 if (!py_value) {
330
331 Py_DECREF(py_args);
332 FATAL("Cannot convert argument in python init.");
333
334 }
335
336 PyTuple_SetItem(py_args, 0, py_value);
337
338 py_value =
339 PyObject_CallObject(py_mutator->py_functions[PY_FUNC_INIT], py_args);
340
341 Py_DECREF(py_args);
342
343 if (py_value == NULL) {
344
345 PyErr_Print();
346 fprintf(stderr, "Call failed\n");
347 FATAL("Custom py mutator INIT failed.");
348
349 }
350
351 }
352
deinit_py(void * py_mutator)353 void deinit_py(void *py_mutator) {
354
355 PyObject *py_args, *py_value;
356
357 py_args = PyTuple_New(0);
358 py_value = PyObject_CallObject(
359 ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_DEINIT], py_args);
360 Py_DECREF(py_args);
361
362 if (py_value != NULL) {
363
364 Py_DECREF(py_value);
365
366 } else {
367
368 PyErr_Print();
369 FATAL("Call failed");
370
371 }
372
373 }
374
splice_optout_py(void * py_mutator)375 void splice_optout_py(void *py_mutator) {
376
377 // this is never called
378 (void)(py_mutator);
379
380 }
381
load_custom_mutator_py(afl_state_t * afl,char * module_name)382 struct custom_mutator *load_custom_mutator_py(afl_state_t *afl,
383 char *module_name) {
384
385 struct custom_mutator *mutator;
386
387 mutator = ck_alloc(sizeof(struct custom_mutator));
388 mutator->name = module_name;
389 ACTF("Loading Python mutator library from '%s'...", module_name);
390
391 if (memchr(module_name, '/', strlen(module_name))) {
392
393 mutator->name_short = strdup(strrchr(module_name, '/') + 1);
394
395 } else {
396
397 mutator->name_short = strdup(module_name);
398
399 }
400
401 if (strlen(mutator->name_short) > 22) { mutator->name_short[21] = 0; }
402
403 py_mutator_t *py_mutator;
404 py_mutator = init_py_module(afl, module_name);
405 mutator->data = py_mutator;
406 if (!py_mutator) { FATAL("Failed to load python mutator."); }
407
408 PyObject **py_functions = py_mutator->py_functions;
409
410 if (py_functions[PY_FUNC_INIT]) { mutator->afl_custom_init = unsupported; }
411
412 if (py_functions[PY_FUNC_DEINIT]) { mutator->afl_custom_deinit = deinit_py; }
413
414 if (py_functions[PY_FUNC_FUZZ]) { mutator->afl_custom_fuzz = fuzz_py; }
415
416 if (py_functions[PY_FUNC_DESCRIBE]) {
417
418 mutator->afl_custom_describe = custom_describe_py;
419
420 }
421
422 if (py_functions[PY_FUNC_POST_PROCESS]) {
423
424 mutator->afl_custom_post_process = post_process_py;
425
426 }
427
428 if (py_functions[PY_FUNC_INIT_TRIM]) {
429
430 mutator->afl_custom_init_trim = init_trim_py;
431
432 }
433
434 if (py_functions[PY_FUNC_FUZZ_COUNT]) {
435
436 mutator->afl_custom_fuzz_count = fuzz_count_py;
437
438 }
439
440 if (py_functions[PY_FUNC_POST_TRIM]) {
441
442 mutator->afl_custom_post_trim = post_trim_py;
443
444 }
445
446 if (py_functions[PY_FUNC_TRIM]) { mutator->afl_custom_trim = trim_py; }
447
448 if (py_functions[PY_FUNC_HAVOC_MUTATION]) {
449
450 mutator->afl_custom_havoc_mutation = havoc_mutation_py;
451
452 }
453
454 if (py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY]) {
455
456 mutator->afl_custom_havoc_mutation_probability =
457 havoc_mutation_probability_py;
458
459 }
460
461 if (py_functions[PY_FUNC_QUEUE_GET]) {
462
463 mutator->afl_custom_queue_get = queue_get_py;
464
465 }
466
467 if (py_functions[PY_FUNC_FUZZ_SEND]) {
468
469 mutator->afl_custom_fuzz_send = fuzz_send_py;
470
471 }
472
473 if (py_functions[PY_FUNC_POST_RUN]) {
474
475 mutator->afl_custom_post_run = post_run_py;
476
477 }
478
479 if (py_functions[PY_FUNC_SPLICE_OPTOUT]) {
480
481 mutator->afl_custom_splice_optout = splice_optout_py;
482 afl->custom_splice_optout = 1;
483
484 }
485
486 if (py_functions[PY_FUNC_QUEUE_NEW_ENTRY]) {
487
488 mutator->afl_custom_queue_new_entry = queue_new_entry_py;
489
490 }
491
492 #ifdef INTROSPECTION
493 if (py_functions[PY_FUNC_INTROSPECTION]) {
494
495 mutator->afl_custom_introspection = introspection_py;
496
497 }
498
499 #endif
500
501 OKF("Python mutator '%s' installed successfully.", module_name);
502
503 /* Initialize the custom mutator */
504 init_py(afl, py_mutator, rand_below(afl, 0xFFFFFFFF));
505
506 mutator->stacked_custom = (mutator && mutator->afl_custom_havoc_mutation);
507 mutator->stacked_custom_prob =
508 6; // like one of the default mutations in havoc
509
510 return mutator;
511
512 }
513
post_process_py(void * py_mutator,u8 * buf,size_t buf_size,u8 ** out_buf)514 size_t post_process_py(void *py_mutator, u8 *buf, size_t buf_size,
515 u8 **out_buf) {
516
517 PyObject *py_args, *py_value;
518 py_mutator_t *py = (py_mutator_t *)py_mutator;
519
520 // buffer returned previously must be released; initialized during init
521 // so we don't need to do comparisons
522 PyBuffer_Release(&py->post_process_buf);
523
524 py_args = PyTuple_New(1);
525 py_value = PyByteArray_FromStringAndSize(buf, buf_size);
526 if (!py_value) {
527
528 Py_DECREF(py_args);
529 FATAL("Failed to convert arguments in custom post_process");
530
531 }
532
533 PyTuple_SetItem(py_args, 0, py_value);
534
535 py_value = PyObject_CallObject(
536 ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_POST_PROCESS],
537 py_args);
538
539 Py_DECREF(py_args);
540
541 if (py_value != NULL) {
542
543 if (PyObject_GetBuffer(py_value, &py->post_process_buf, PyBUF_SIMPLE) ==
544 -1) {
545
546 PyErr_Print();
547 FATAL(
548 "Python custom mutator: post_process call return value not a "
549 "bytes-like object");
550
551 }
552
553 Py_DECREF(py_value);
554
555 if (unlikely(py->post_process_buf.len == 0)) {
556
557 *out_buf = NULL;
558
559 } else {
560
561 *out_buf = (u8 *)py->post_process_buf.buf;
562
563 }
564
565 return py->post_process_buf.len;
566
567 } else {
568
569 PyErr_Print();
570 FATAL("Python custom mutator: post_process call failed.");
571
572 }
573
574 }
575
init_trim_py(void * py_mutator,u8 * buf,size_t buf_size)576 s32 init_trim_py(void *py_mutator, u8 *buf, size_t buf_size) {
577
578 PyObject *py_args, *py_value;
579
580 py_args = PyTuple_New(1);
581 py_value = PyByteArray_FromStringAndSize(buf, buf_size);
582 if (!py_value) {
583
584 Py_DECREF(py_args);
585 FATAL("Failed to convert arguments");
586
587 }
588
589 PyTuple_SetItem(py_args, 0, py_value);
590
591 py_value = PyObject_CallObject(
592 ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_INIT_TRIM], py_args);
593 Py_DECREF(py_args);
594
595 if (py_value != NULL) {
596
597 #if PY_MAJOR_VERSION >= 3
598 u32 retcnt = (u32)PyLong_AsLong(py_value);
599 #else
600 u32 retcnt = PyInt_AsLong(py_value);
601 #endif
602 Py_DECREF(py_value);
603 return retcnt;
604
605 } else {
606
607 PyErr_Print();
608 FATAL("Call failed");
609
610 }
611
612 }
613
fuzz_count_py(void * py_mutator,const u8 * buf,size_t buf_size)614 u32 fuzz_count_py(void *py_mutator, const u8 *buf, size_t buf_size) {
615
616 PyObject *py_args, *py_value;
617
618 py_args = PyTuple_New(1);
619 py_value = PyByteArray_FromStringAndSize(buf, buf_size);
620 if (!py_value) {
621
622 Py_DECREF(py_args);
623 FATAL("Failed to convert arguments");
624
625 }
626
627 PyTuple_SetItem(py_args, 0, py_value);
628
629 py_value = PyObject_CallObject(
630 ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_FUZZ_COUNT], py_args);
631 Py_DECREF(py_args);
632
633 if (py_value != NULL) {
634
635 #if PY_MAJOR_VERSION >= 3
636 u32 retcnt = (u32)PyLong_AsLong(py_value);
637 #else
638 u32 retcnt = PyInt_AsLong(py_value);
639 #endif
640 Py_DECREF(py_value);
641 return retcnt;
642
643 } else {
644
645 PyErr_Print();
646 FATAL("Call failed");
647
648 }
649
650 }
651
post_trim_py(void * py_mutator,u8 success)652 s32 post_trim_py(void *py_mutator, u8 success) {
653
654 PyObject *py_args, *py_value;
655
656 py_args = PyTuple_New(1);
657
658 py_value = PyBool_FromLong(success);
659 if (!py_value) {
660
661 Py_DECREF(py_args);
662 FATAL("Failed to convert arguments");
663
664 }
665
666 PyTuple_SetItem(py_args, 0, py_value);
667
668 py_value = PyObject_CallObject(
669 ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_POST_TRIM], py_args);
670 Py_DECREF(py_args);
671
672 if (py_value != NULL) {
673
674 #if PY_MAJOR_VERSION >= 3
675 u32 retcnt = (u32)PyLong_AsLong(py_value);
676 #else
677 u32 retcnt = PyInt_AsLong(py_value);
678 #endif
679 Py_DECREF(py_value);
680 return retcnt;
681
682 } else {
683
684 PyErr_Print();
685 FATAL("Call failed");
686
687 }
688
689 }
690
trim_py(void * py_mutator,u8 ** out_buf)691 size_t trim_py(void *py_mutator, u8 **out_buf) {
692
693 PyObject *py_args, *py_value;
694 size_t trimmed_size;
695
696 py_args = PyTuple_New(0);
697 py_value = PyObject_CallObject(
698 ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_TRIM], py_args);
699 Py_DECREF(py_args);
700
701 if (py_value != NULL) {
702
703 char *bytes;
704 if (!py_bytes(py_value, &bytes, &trimmed_size)) {
705
706 FATAL("Python mutator fuzz() should return a bytearray");
707
708 }
709
710 if (trimmed_size) {
711
712 *out_buf = afl_realloc(BUF_PARAMS(trim), trimmed_size);
713 if (unlikely(!*out_buf)) { PFATAL("alloc"); }
714 memcpy(*out_buf, bytes, trimmed_size);
715
716 }
717
718 Py_DECREF(py_value);
719
720 } else {
721
722 PyErr_Print();
723 FATAL("Call failed");
724
725 }
726
727 return trimmed_size;
728
729 }
730
havoc_mutation_py(void * py_mutator,u8 * buf,size_t buf_size,u8 ** out_buf,size_t max_size)731 size_t havoc_mutation_py(void *py_mutator, u8 *buf, size_t buf_size,
732 u8 **out_buf, size_t max_size) {
733
734 size_t mutated_size;
735 PyObject *py_args, *py_value;
736 py_args = PyTuple_New(2);
737
738 /* buf */
739 py_value = PyByteArray_FromStringAndSize(buf, buf_size);
740 if (!py_value) {
741
742 Py_DECREF(py_args);
743 FATAL("Failed to convert arguments");
744
745 }
746
747 PyTuple_SetItem(py_args, 0, py_value);
748
749 /* max_size */
750 #if PY_MAJOR_VERSION >= 3
751 py_value = PyLong_FromLong(max_size);
752 #else
753 py_value = PyInt_FromLong(max_size);
754 #endif
755 if (!py_value) {
756
757 Py_DECREF(py_args);
758 FATAL("Failed to convert arguments");
759
760 }
761
762 PyTuple_SetItem(py_args, 1, py_value);
763
764 py_value = PyObject_CallObject(
765 ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_HAVOC_MUTATION],
766 py_args);
767
768 Py_DECREF(py_args);
769
770 if (py_value != NULL) {
771
772 char *bytes;
773 if (!py_bytes(py_value, &bytes, &mutated_size)) {
774
775 FATAL("Python mutator fuzz() should return a bytearray");
776
777 }
778
779 if (mutated_size <= buf_size) {
780
781 /* We reuse the input buf here. */
782 *out_buf = buf;
783
784 } else {
785
786 /* A new buf is needed... */
787 *out_buf = afl_realloc(BUF_PARAMS(havoc), mutated_size);
788 if (unlikely(!*out_buf)) { PFATAL("alloc"); }
789
790 }
791
792 if (mutated_size) { memcpy(*out_buf, bytes, mutated_size); }
793
794 Py_DECREF(py_value);
795 return mutated_size;
796
797 } else {
798
799 PyErr_Print();
800 FATAL("Call failed");
801
802 }
803
804 }
805
havoc_mutation_probability_py(void * py_mutator)806 u8 havoc_mutation_probability_py(void *py_mutator) {
807
808 PyObject *py_args, *py_value;
809
810 py_args = PyTuple_New(0);
811 py_value = PyObject_CallObject(
812 ((py_mutator_t *)py_mutator)
813 ->py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY],
814 py_args);
815 Py_DECREF(py_args);
816
817 if (py_value != NULL) {
818
819 long prob = PyLong_AsLong(py_value);
820 Py_DECREF(py_value);
821 return (u8)prob;
822
823 } else {
824
825 PyErr_Print();
826 FATAL("Call failed");
827
828 }
829
830 }
831
introspection_py(void * py_mutator)832 const char *introspection_py(void *py_mutator) {
833
834 PyObject *py_args, *py_value;
835
836 py_args = PyTuple_New(0);
837 py_value = PyObject_CallObject(
838 ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_INTROSPECTION],
839 py_args);
840 Py_DECREF(py_args);
841
842 if (py_value == NULL) {
843
844 return NULL;
845
846 } else {
847
848 char *ret;
849 size_t len;
850 if (!py_bytes(py_value, &ret, &len)) {
851
852 FATAL(
853 "Python mutator introspection call returned illegal type (expected "
854 "bytes or bytearray)");
855
856 }
857
858 return ret;
859
860 }
861
862 }
863
queue_get_py(void * py_mutator,const u8 * filename)864 u8 queue_get_py(void *py_mutator, const u8 *filename) {
865
866 PyObject *py_args, *py_value;
867
868 py_args = PyTuple_New(1);
869
870 // File name
871 #if PY_MAJOR_VERSION >= 3
872 py_value = PyUnicode_FromString(filename);
873 #else
874 py_value = PyString_FromString(filename);
875 #endif
876 if (!py_value) {
877
878 Py_DECREF(py_args);
879 FATAL("Failed to convert arguments");
880
881 }
882
883 PyTuple_SetItem(py_args, 0, py_value);
884
885 // Call Python function
886 py_value = PyObject_CallObject(
887 ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_QUEUE_GET], py_args);
888 Py_DECREF(py_args);
889
890 if (py_value != NULL) {
891
892 int ret = PyObject_IsTrue(py_value);
893 Py_DECREF(py_value);
894
895 if (ret == -1) {
896
897 PyErr_Print();
898 FATAL("Failed to convert return value");
899
900 }
901
902 return (u8)ret & 0xFF;
903
904 } else {
905
906 PyErr_Print();
907 FATAL("Call failed");
908
909 }
910
911 }
912
fuzz_send_py(void * py_mutator,const u8 * buf,size_t buf_size)913 void fuzz_send_py(void *py_mutator, const u8 *buf, size_t buf_size) {
914
915 PyObject *py_args, *py_value;
916
917 py_args = PyTuple_New(1);
918 py_value = PyByteArray_FromStringAndSize(buf, buf_size);
919 if (!py_value) {
920
921 Py_DECREF(py_args);
922 FATAL("Failed to convert arguments");
923
924 }
925
926 PyTuple_SetItem(py_args, 0, py_value);
927
928 py_value = PyObject_CallObject(
929 ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_FUZZ_SEND], py_args);
930 Py_DECREF(py_args);
931
932 if (py_value != NULL) { Py_DECREF(py_value); }
933
934 }
935
post_run_py(void * py_mutator)936 void post_run_py(void *py_mutator) {
937
938 PyObject *py_args, *py_value;
939
940 py_args = PyTuple_New(0);
941 py_value = PyObject_CallObject(
942 ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_POST_RUN], py_args);
943 Py_DECREF(py_args);
944
945 if (py_value != NULL) {
946
947 Py_DECREF(py_value);
948
949 } else {
950
951 PyErr_Print();
952 FATAL("Call failed");
953
954 }
955
956 }
957
queue_new_entry_py(void * py_mutator,const u8 * filename_new_queue,const u8 * filename_orig_queue)958 u8 queue_new_entry_py(void *py_mutator, const u8 *filename_new_queue,
959 const u8 *filename_orig_queue) {
960
961 PyObject *py_args, *py_value;
962
963 py_args = PyTuple_New(2);
964
965 // New queue
966 #if PY_MAJOR_VERSION >= 3
967 py_value = PyUnicode_FromString(filename_new_queue);
968 #else
969 py_value = PyString_FromString(filename_new_queue);
970 #endif
971 if (!py_value) {
972
973 Py_DECREF(py_args);
974 FATAL("Failed to convert arguments");
975
976 }
977
978 PyTuple_SetItem(py_args, 0, py_value);
979
980 // Orig queue
981 py_value = Py_None;
982 if (filename_orig_queue) {
983
984 #if PY_MAJOR_VERSION >= 3
985 py_value = PyUnicode_FromString(filename_orig_queue);
986 #else
987 py_value = PyString_FromString(filename_orig_queue);
988 #endif
989 if (!py_value) {
990
991 Py_DECREF(py_args);
992 FATAL("Failed to convert arguments");
993
994 }
995
996 }
997
998 PyTuple_SetItem(py_args, 1, py_value);
999
1000 // Call
1001 py_value = PyObject_CallObject(
1002 ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_QUEUE_NEW_ENTRY],
1003 py_args);
1004 Py_DECREF(py_args);
1005
1006 if (py_value != NULL) {
1007
1008 int ret = PyObject_IsTrue(py_value);
1009 Py_DECREF(py_value);
1010
1011 if (ret == -1) {
1012
1013 PyErr_Print();
1014 FATAL("Failed to convert return value");
1015
1016 }
1017
1018 return (u8)ret & 0xFF;
1019
1020 } else {
1021
1022 PyErr_Print();
1023 FATAL("Call failed");
1024
1025 }
1026
1027 }
1028
1029 #undef BUF_PARAMS
1030
1031 #endif /* USE_PYTHON */
1032
1033