-
Notifications
You must be signed in to change notification settings - Fork 1
/
disasm.c
91 lines (75 loc) · 3.81 KB
/
disasm.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <assert.h>
#include <memory.h>
#include <stdarg.h>
#include <stdlib.h>
#include "disasm.h"
static void DisAsmPrintAddress(bfd_vma addr, struct disassemble_info *info)
{
info->fprintf_func(info->stream, "%p", (void *) addr);
} // DisAsmPrintAddress()
static int DisAsmPrintf(void *b, const char *fmt, ...)
{
DisAsmPrintBufferPtr pbPtr = (DisAsmPrintBufferPtr) b;
va_list arglist;
va_start(arglist, fmt);
int result = vsprintf(pbPtr->data + pbPtr->index, fmt, arglist);
assert(pbPtr->index + result < sizeof(pbPtr->data));
pbPtr->index += result;
va_end(arglist);
return result;
}
DisAsmInfoPtr DisAsmInfoInit(DisAsmPtr start, DisAsmPtr end)
{
DisAsmInfoPtr disAsmInfoPtr = calloc(1, sizeof(*disAsmInfoPtr));
disAsmInfoPtr->info.flavour = bfd_target_unknown_flavour;
disAsmInfoPtr->info.arch = bfd_arch_i386;
disAsmInfoPtr->info.mach = bfd_mach_x86_64_intel_syntax;
disAsmInfoPtr->info.endian = BFD_ENDIAN_LITTLE;
disAsmInfoPtr->info.octets_per_byte = 1;
disAsmInfoPtr->info.fprintf_func = DisAsmPrintf;
disAsmInfoPtr->info.stream = &disAsmInfoPtr->disAsmPrintBuffer;
disAsmInfoPtr->info.read_memory_func = buffer_read_memory;
disAsmInfoPtr->info.memory_error_func = perror_memory;
disAsmInfoPtr->info.print_address_func = DisAsmPrintAddress;
disAsmInfoPtr->info.symbol_at_address_func = generic_symbol_at_address;
disAsmInfoPtr->info.symbol_is_valid = generic_symbol_is_valid;
disAsmInfoPtr->info.display_endian = BFD_ENDIAN_LITTLE;
disAsmInfoPtr->info.buffer_vma = (unsigned long) start;
disAsmInfoPtr->info.buffer_length = end - start + 1;
disAsmInfoPtr->info.buffer = start;
return disAsmInfoPtr;
} // DisAsmInfoInit()
DisAsmInfoPtr DisAsmInfoInitBytes(DisAsmPtr start, DisAsmPtr end, void *b)
{
DisAsmInfoPtr disAsmInfoPtr = calloc(1, sizeof(*disAsmInfoPtr));
disAsmInfoPtr->info.flavour = bfd_target_unknown_flavour;
disAsmInfoPtr->info.arch = bfd_arch_i386;
disAsmInfoPtr->info.mach = bfd_mach_x86_64_intel_syntax;
disAsmInfoPtr->info.endian = BFD_ENDIAN_LITTLE;
disAsmInfoPtr->info.octets_per_byte = 1;
disAsmInfoPtr->info.fprintf_func = DisAsmPrintf;
disAsmInfoPtr->info.stream = &disAsmInfoPtr->disAsmPrintBuffer;
disAsmInfoPtr->info.read_memory_func = buffer_read_memory;
disAsmInfoPtr->info.memory_error_func = perror_memory;
disAsmInfoPtr->info.print_address_func = DisAsmPrintAddress;
disAsmInfoPtr->info.symbol_at_address_func = generic_symbol_at_address;
disAsmInfoPtr->info.symbol_is_valid = generic_symbol_is_valid;
disAsmInfoPtr->info.display_endian = BFD_ENDIAN_LITTLE;
disAsmInfoPtr->info.buffer_vma = (unsigned long) start;
disAsmInfoPtr->info.buffer_length = end - start + 1;
disAsmInfoPtr->info.buffer = b;
return disAsmInfoPtr;
} // DisAsmInfoInitBytes()
DisAsmLen DisAsmDecodeInstruction(DisAsmInfoType *disAsmInfoPtr, DisAsmPtr pc)
{
disAsmInfoPtr->disAsmPrintBuffer.index = 0;
//DisAsmPrintf(disAsmInfoPtr->info.stream, "%p ", pc);
int count = (int) print_insn_i386((unsigned long) pc, &disAsmInfoPtr->info);
assert(count != 0);
//DisAsmPrintf(disAsmInfoPtr->info.stream, "\n");
return count;
} // DisAsmDecodeInstruction()
void DisAsmInfoFree(DisAsmInfoPtr disAsmInfoPtr)
{
free(disAsmInfoPtr);
} // DisAsmInfoFree()