101 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			101 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C
		
	
	
	
| /* Copyright 2020 Google Inc.
 | |
| 
 | |
| Licensed under the Apache License, Version 2.0 (the "License");
 | |
| you may not use this file except in compliance with the License.
 | |
| You may obtain a copy of the License at
 | |
| 
 | |
|       http://www.apache.org/licenses/LICENSE-2.0
 | |
| 
 | |
| Unless required by applicable law or agreed to in writing, software
 | |
| distributed under the License is distributed on an "AS IS" BASIS,
 | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
| See the License for the specific language governing permissions and
 | |
| limitations under the License.
 | |
| */
 | |
| 
 | |
| #include "sysdep.h"
 | |
| #include "bfd.h"
 | |
| #include "dis-asm.h"
 | |
| #include "disassemble.h"
 | |
| 
 | |
| #include <stdint.h>
 | |
| 
 | |
| #define MAX_TEXT_SIZE 256
 | |
| 
 | |
| typedef struct
 | |
| {
 | |
|     char *buffer;
 | |
|     size_t pos;
 | |
| } SFILE;
 | |
| 
 | |
| static int objdump_sprintf (void *vf, const char *format, ...)
 | |
| {
 | |
|     SFILE *f = (SFILE *) vf;
 | |
|     size_t n;
 | |
|     va_list args;
 | |
| 
 | |
|     va_start (args, format);
 | |
|     if (f->pos >= MAX_TEXT_SIZE){
 | |
|         printf("buffer needs more space\n");
 | |
|         //reset
 | |
|         f->pos=0;
 | |
|         return 0;
 | |
|     }
 | |
|     n = vsnprintf (f->buffer + f->pos, MAX_TEXT_SIZE - f->pos, format, args);
 | |
|     //vfprintf(stdout, format, args);
 | |
|     va_end (args);
 | |
|     f->pos += n;
 | |
|     return n;
 | |
| }
 | |
| 
 | |
| 
 | |
| int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
 | |
|     char AssemblyText[MAX_TEXT_SIZE];
 | |
|     struct disassemble_info disasm_info;
 | |
|     SFILE s;
 | |
| 
 | |
|     if (Size < 10 || Size > 16394) {
 | |
|         // 10 bytes for options
 | |
|         // 16394 limit code to prevent timeouts
 | |
|         return 0;
 | |
|     }
 | |
| 
 | |
|     init_disassemble_info (&disasm_info, stdout, (fprintf_ftype) fprintf);
 | |
|     disasm_info.fprintf_func = objdump_sprintf;
 | |
|     disasm_info.print_address_func = generic_print_address;
 | |
|     disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_LITTLE;
 | |
|     disasm_info.buffer = (bfd_byte *) Data;
 | |
|     disasm_info.buffer_vma = 0x1000;
 | |
|     disasm_info.buffer_length = Size-10;
 | |
|     disasm_info.insn_info_valid = 0;
 | |
|     s.buffer = AssemblyText;
 | |
|     s.pos = 0;
 | |
|     disasm_info.stream = &s;
 | |
|     disasm_info.bytes_per_line = 0;
 | |
| 
 | |
|     disasm_info.arch = Data[Size-1];
 | |
|     disasm_info.mach = bfd_getl64(&Data[Size-9]);
 | |
|     disasm_info.flavour = Data[Size-10];
 | |
| 
 | |
|     if (bfd_lookup_arch (disasm_info.arch, disasm_info.mach) != NULL) {
 | |
|         disassembler_ftype disasfunc = disassembler(disasm_info.arch, 0, disasm_info.mach, NULL);
 | |
|         if (disasfunc != NULL) {
 | |
|             disassemble_init_for_target(&disasm_info);
 | |
|             while (1) {
 | |
|                 s.pos = 0;
 | |
|                 int octets = disasfunc(disasm_info.buffer_vma, &disasm_info);
 | |
|                 if (octets < (int) disasm_info.octets_per_byte)
 | |
|                     break;
 | |
|                 if (disasm_info.buffer_length <= (size_t) octets)
 | |
|                     break;
 | |
|                 disasm_info.buffer += octets;
 | |
|                 disasm_info.buffer_vma += octets / disasm_info.octets_per_byte;
 | |
|                 disasm_info.buffer_length -= octets;
 | |
|             }
 | |
|             disassemble_free_target(&disasm_info);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return 0;
 | |
| }
 |