Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. /* udis86 - libudis86/udis86.c
  2. *
  3. * Copyright (c) 2002-2013 Vivek Thampi
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * * Redistributions of source code must retain the above copyright notice,
  10. * this list of conditions and the following disclaimer.
  11. * * Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  16. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  19. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  20. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  21. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  22. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  24. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #include "udint.h"
  27. #include "extern.h"
  28. #include "decode.h"
  29. #if !defined(__UD_STANDALONE__)
  30. # if HAVE_STRING_H
  31. # include <string.h>
  32. # endif
  33. #endif /* !__UD_STANDALONE__ */
  34. static void ud_inp_init(struct ud *u);
  35. /* =============================================================================
  36. * ud_init
  37. * Initializes ud_t object.
  38. * =============================================================================
  39. */
  40. extern void
  41. ud_init(struct ud* u)
  42. {
  43. memset((void*)u, 0, sizeof(struct ud));
  44. ud_set_mode(u, 16);
  45. u->mnemonic = UD_Iinvalid;
  46. ud_set_pc(u, 0);
  47. #ifndef __UD_STANDALONE__
  48. ud_set_input_file(u, stdin);
  49. #endif /* __UD_STANDALONE__ */
  50. ud_set_asm_buffer(u, u->asm_buf_int, sizeof(u->asm_buf_int));
  51. }
  52. /* =============================================================================
  53. * ud_disassemble
  54. * Disassembles one instruction and returns the number of
  55. * bytes disassembled. A zero means end of disassembly.
  56. * =============================================================================
  57. */
  58. extern unsigned int
  59. ud_disassemble(struct ud* u)
  60. {
  61. int len;
  62. if (u->inp_end) {
  63. return 0;
  64. }
  65. if ((len = ud_decode(u)) > 0) {
  66. if (u->translator != NULL) {
  67. u->asm_buf[0] = '\0';
  68. u->translator(u);
  69. }
  70. }
  71. return len;
  72. }
  73. /* =============================================================================
  74. * ud_set_mode() - Set Disassemly Mode.
  75. * =============================================================================
  76. */
  77. extern void
  78. ud_set_mode(struct ud* u, uint8_t m)
  79. {
  80. switch(m) {
  81. case 16:
  82. case 32:
  83. case 64: u->dis_mode = m ; return;
  84. default: u->dis_mode = 16; return;
  85. }
  86. }
  87. /* =============================================================================
  88. * ud_set_vendor() - Set vendor.
  89. * =============================================================================
  90. */
  91. extern void
  92. ud_set_vendor(struct ud* u, unsigned v)
  93. {
  94. switch(v) {
  95. case UD_VENDOR_INTEL:
  96. u->vendor = v;
  97. break;
  98. case UD_VENDOR_ANY:
  99. u->vendor = v;
  100. break;
  101. default:
  102. u->vendor = UD_VENDOR_AMD;
  103. }
  104. }
  105. /* =============================================================================
  106. * ud_set_pc() - Sets code origin.
  107. * =============================================================================
  108. */
  109. extern void
  110. ud_set_pc(struct ud* u, uint64_t o)
  111. {
  112. u->pc = o;
  113. }
  114. /* =============================================================================
  115. * ud_set_syntax() - Sets the output syntax.
  116. * =============================================================================
  117. */
  118. extern void
  119. ud_set_syntax(struct ud* u, void (*t)(struct ud*))
  120. {
  121. u->translator = t;
  122. }
  123. /* =============================================================================
  124. * ud_insn() - returns the disassembled instruction
  125. * =============================================================================
  126. */
  127. const char*
  128. ud_insn_asm(const struct ud* u)
  129. {
  130. return u->asm_buf;
  131. }
  132. /* =============================================================================
  133. * ud_insn_offset() - Returns the offset.
  134. * =============================================================================
  135. */
  136. uint64_t
  137. ud_insn_off(const struct ud* u)
  138. {
  139. return u->insn_offset;
  140. }
  141. /* =============================================================================
  142. * ud_insn_hex() - Returns hex form of disassembled instruction.
  143. * =============================================================================
  144. */
  145. const char*
  146. ud_insn_hex(struct ud* u)
  147. {
  148. u->insn_hexcode[0] = 0;
  149. if (!u->error) {
  150. unsigned int i;
  151. const unsigned char *src_ptr = ud_insn_ptr(u);
  152. char* src_hex;
  153. src_hex = (char*) u->insn_hexcode;
  154. /* for each byte used to decode instruction */
  155. for (i = 0; i < ud_insn_len(u) && i < sizeof(u->insn_hexcode) / 2;
  156. ++i, ++src_ptr) {
  157. sprintf(src_hex, "%02x", *src_ptr & 0xFF);
  158. src_hex += 2;
  159. }
  160. }
  161. return u->insn_hexcode;
  162. }
  163. /* =============================================================================
  164. * ud_insn_ptr
  165. * Returns a pointer to buffer containing the bytes that were
  166. * disassembled.
  167. * =============================================================================
  168. */
  169. extern const uint8_t*
  170. ud_insn_ptr(const struct ud* u)
  171. {
  172. return (u->inp_buf == NULL) ?
  173. u->inp_sess : u->inp_buf + (u->inp_buf_index - u->inp_ctr);
  174. }
  175. /* =============================================================================
  176. * ud_insn_len
  177. * Returns the count of bytes disassembled.
  178. * =============================================================================
  179. */
  180. extern unsigned int
  181. ud_insn_len(const struct ud* u)
  182. {
  183. return u->inp_ctr;
  184. }
  185. /* =============================================================================
  186. * ud_insn_get_opr
  187. * Return the operand struct representing the nth operand of
  188. * the currently disassembled instruction. Returns NULL if
  189. * there's no such operand.
  190. * =============================================================================
  191. */
  192. const struct ud_operand*
  193. ud_insn_opr(const struct ud *u, unsigned int n)
  194. {
  195. if (n > 2 || u->operand[n].type == UD_NONE) {
  196. return NULL;
  197. } else {
  198. return &u->operand[n];
  199. }
  200. }
  201. /* =============================================================================
  202. * ud_opr_is_sreg
  203. * Returns non-zero if the given operand is of a segment register type.
  204. * =============================================================================
  205. */
  206. int
  207. ud_opr_is_sreg(const struct ud_operand *opr)
  208. {
  209. return opr->type == UD_OP_REG &&
  210. opr->base >= UD_R_ES &&
  211. opr->base <= UD_R_GS;
  212. }
  213. /* =============================================================================
  214. * ud_opr_is_sreg
  215. * Returns non-zero if the given operand is of a general purpose
  216. * register type.
  217. * =============================================================================
  218. */
  219. int
  220. ud_opr_is_gpr(const struct ud_operand *opr)
  221. {
  222. return opr->type == UD_OP_REG &&
  223. opr->base >= UD_R_AL &&
  224. opr->base <= UD_R_R15;
  225. }
  226. /* =============================================================================
  227. * ud_set_user_opaque_data
  228. * ud_get_user_opaque_data
  229. * Get/set user opaqute data pointer
  230. * =============================================================================
  231. */
  232. void
  233. ud_set_user_opaque_data(struct ud * u, void* opaque)
  234. {
  235. u->user_opaque_data = opaque;
  236. }
  237. void*
  238. ud_get_user_opaque_data(const struct ud *u)
  239. {
  240. return u->user_opaque_data;
  241. }
  242. /* =============================================================================
  243. * ud_set_asm_buffer
  244. * Allow the user to set an assembler output buffer. If `buf` is NULL,
  245. * we switch back to the internal buffer.
  246. * =============================================================================
  247. */
  248. void
  249. ud_set_asm_buffer(struct ud *u, char *buf, size_t size)
  250. {
  251. if (buf == NULL) {
  252. ud_set_asm_buffer(u, u->asm_buf_int, sizeof(u->asm_buf_int));
  253. } else {
  254. u->asm_buf = buf;
  255. u->asm_buf_size = size;
  256. }
  257. }
  258. /* =============================================================================
  259. * ud_set_sym_resolver
  260. * Set symbol resolver for relative targets used in the translation
  261. * phase.
  262. *
  263. * The resolver is a function that takes a uint64_t address and returns a
  264. * symbolic name for the that address. The function also takes a second
  265. * argument pointing to an integer that the client can optionally set to a
  266. * non-zero value for offsetted targets. (symbol+offset) The function may
  267. * also return NULL, in which case the translator only prints the target
  268. * address.
  269. *
  270. * The function pointer maybe NULL which resets symbol resolution.
  271. * =============================================================================
  272. */
  273. void
  274. ud_set_sym_resolver(struct ud *u, const char* (*resolver)(struct ud*,
  275. uint64_t addr,
  276. int64_t *offset))
  277. {
  278. u->sym_resolver = resolver;
  279. }
  280. /* =============================================================================
  281. * ud_insn_mnemonic
  282. * Return the current instruction mnemonic.
  283. * =============================================================================
  284. */
  285. enum ud_mnemonic_code
  286. ud_insn_mnemonic(const struct ud *u)
  287. {
  288. return u->mnemonic;
  289. }
  290. /* =============================================================================
  291. * ud_lookup_mnemonic
  292. * Looks up mnemonic code in the mnemonic string table.
  293. * Returns NULL if the mnemonic code is invalid.
  294. * =============================================================================
  295. */
  296. const char*
  297. ud_lookup_mnemonic(enum ud_mnemonic_code c)
  298. {
  299. if (c < UD_MAX_MNEMONIC_CODE) {
  300. return ud_mnemonics_str[c];
  301. } else {
  302. return NULL;
  303. }
  304. }
  305. /*
  306. * ud_inp_init
  307. * Initializes the input system.
  308. */
  309. static void
  310. ud_inp_init(struct ud *u)
  311. {
  312. u->inp_hook = NULL;
  313. u->inp_buf = NULL;
  314. u->inp_buf_size = 0;
  315. u->inp_buf_index = 0;
  316. u->inp_curr = 0;
  317. u->inp_ctr = 0;
  318. u->inp_end = 0;
  319. UD_NON_STANDALONE(u->inp_file = NULL);
  320. }
  321. /* =============================================================================
  322. * ud_inp_set_hook
  323. * Sets input hook.
  324. * =============================================================================
  325. */
  326. void
  327. ud_set_input_hook(register struct ud* u, int (*hook)(struct ud*))
  328. {
  329. ud_inp_init(u);
  330. u->inp_hook = hook;
  331. }
  332. /* =============================================================================
  333. * ud_inp_set_buffer
  334. * Set buffer as input.
  335. * =============================================================================
  336. */
  337. void
  338. ud_set_input_buffer(register struct ud* u, const uint8_t* buf, size_t len)
  339. {
  340. ud_inp_init(u);
  341. u->inp_buf = buf;
  342. u->inp_buf_size = len;
  343. u->inp_buf_index = 0;
  344. }
  345. #ifndef __UD_STANDALONE__
  346. /* =============================================================================
  347. * ud_input_set_file
  348. * Set FILE as input.
  349. * =============================================================================
  350. */
  351. static int
  352. inp_file_hook(struct ud* u)
  353. {
  354. return fgetc(u->inp_file);
  355. }
  356. void
  357. ud_set_input_file(register struct ud* u, FILE* f)
  358. {
  359. ud_inp_init(u);
  360. u->inp_hook = inp_file_hook;
  361. u->inp_file = f;
  362. }
  363. #endif /* __UD_STANDALONE__ */
  364. /* =============================================================================
  365. * ud_input_skip
  366. * Skip n input bytes.
  367. * ============================================================================
  368. */
  369. void
  370. ud_input_skip(struct ud* u, size_t n)
  371. {
  372. if (u->inp_end) {
  373. return;
  374. }
  375. if (u->inp_buf == NULL) {
  376. while (n--) {
  377. int c = u->inp_hook(u);
  378. if (c == UD_EOI) {
  379. goto eoi;
  380. }
  381. }
  382. return;
  383. } else {
  384. if (n > u->inp_buf_size ||
  385. u->inp_buf_index > u->inp_buf_size - n) {
  386. u->inp_buf_index = u->inp_buf_size;
  387. goto eoi;
  388. }
  389. u->inp_buf_index += n;
  390. return;
  391. }
  392. eoi:
  393. u->inp_end = 1;
  394. UDERR(u, "cannot skip, eoi received\b");
  395. return;
  396. }
  397. /* =============================================================================
  398. * ud_input_end
  399. * Returns non-zero on end-of-input.
  400. * =============================================================================
  401. */
  402. int
  403. ud_input_end(const struct ud *u)
  404. {
  405. return u->inp_end;
  406. }
  407. /* vim:set ts=2 sw=2 expandtab */