-
Notifications
You must be signed in to change notification settings - Fork 283
Expand file tree
/
Copy pathdisasm.cpp
More file actions
163 lines (132 loc) · 3.37 KB
/
disasm.cpp
File metadata and controls
163 lines (132 loc) · 3.37 KB
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#include <cstdio>
#include <cstdlib>
#include <cstdint>
#include <sys/types.h>
#include <sys/stat.h>
#include "binaryninjacore.h"
#include "binaryninjaapi.h"
using namespace BinaryNinja;
/* forward declarations */
int parse_nib(const char* str, uint8_t* val);
int parse_uint8_hex(const char* str, uint8_t* result);
/******************************************************************************
MAIN
******************************************************************************/
void usage(int ac, char** av)
{
(void)ac;
printf(" syntax: %s <arch+mode> <byte0> <byte1> ...\n", av[0]);
printf("examples:\n");
printf(" %s x86 83 83 ec 0c\n", av[0]);
printf(" %s x86_64 48 89 e5\n", av[0]);
printf(" %s armv7 14 d0 4d e2\n", av[0]);
printf(" %s armv7eb d0 14 e2 4d\n", av[0]);
printf(" %s thumb2 4f f0 00 0c\n", av[0]);
printf(" %s thumb2eb f0 4f 0c 00\n", av[0]);
printf(" %s ppc 93 e1 ff fc\n", av[0]);
printf(" %s aarch64 ff 43 00 d1\n", av[0]);
printf(" %s mips32 27 bd ff f0\n", av[0]);
printf(" %s mipsel32 f0 ff bd 27\n", av[0]);
}
int main(int ac, char** av)
{
int rc = -1;
unsigned int i;
char* archmode;
BNArchitecture* arch;
size_t nBytesDisasm;
uint8_t input[64];
unsigned int input_n;
BNInstructionTextToken* ttResult = NULL;
size_t ttCount;
char* path_bundled_plugins;
/* plugin path */
path_bundled_plugins = BNGetBundledPluginDirectory();
printf("using bundled plugin path: %s\n", path_bundled_plugins);
BNSetBundledPluginDirectory(path_bundled_plugins);
BNInitPlugins(true);
/* parse architecture argument */
if (ac < 2)
{
usage(ac, av);
goto cleanup;
}
archmode = av[1];
printf("looking up architecture \"%s\"\n", archmode);
arch = BNGetArchitectureByName(archmode);
if (!arch)
{
printf("ERROR: BNGetArchitectureByName() (is \"%s\" valid?)\n", archmode);
usage(ac, av);
goto cleanup;
}
/* parse bytes argument */
input_n = ac - 2;
for (i = 0; i < input_n && i < sizeof(input); ++i)
{
if (parse_uint8_hex(av[i + 2], input + i))
{
printf("ERROR: can't parse byte: %s\n", av[i + 2]);
goto cleanup;
}
}
printf("parsed bytes: ");
for (i = 0; i < input_n; ++i)
printf("%02X ", input[i]);
printf("\n");
/* actually disassemble now */
nBytesDisasm = input_n;
BNGetInstructionText(arch, (const uint8_t*)input, 0, &nBytesDisasm, &ttResult, &ttCount);
// printf("%zu text tokens\n", ttCount);
for (i = 0; i < ttCount; ++i)
printf("%s", ttResult[i].text);
printf("\n");
/* done! */
cleanup:
if (ttResult)
BNFreeInstructionText(ttResult, ttCount);
// Shutting down is required to allow for clean exit of the core
BNShutdown();
return rc;
}
/******************************************************************************
PARSING
******************************************************************************/
int parse_nib(const char* str, uint8_t* val)
{
int rc = -1;
char c = *str;
if (c >= '0' && c <= '9')
{
*val = c - '0';
rc = 0;
}
else if (c >= 'a' && c <= 'f')
{
*val = 10 + (c - 'a');
rc = 0;
}
else if (c >= 'A' && c <= 'F')
{
*val = 10 + (c - 'A');
rc = 0;
}
else
{
printf("ERROR: %s('%c', ...)\n", __func__, c);
}
return rc;
}
int parse_uint8_hex(const char* str, uint8_t* result)
{
int rc = -1;
uint8_t v1, v2;
if (parse_nib(str, &v1))
goto cleanup;
if (parse_nib(str + 1, &v2))
goto cleanup;
*result = (v1 << 4) | v2;
rc = 0;
cleanup:
return rc;
}