PageRenderTime 54ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/codes/dante.c

http://nicola-bonelli-repo.googlecode.com/
C | 899 lines | 646 code | 178 blank | 75 comment | 93 complexity | f329d69ff74519537c67061fbbdb90a0 MD5 | raw file
  1. /*
  2. * dante.c: write arbitrary plaintext string in i386 executable opcodes.
  3. *
  4. *
  5. * Copyright (c) 2002 Nicola Bonelli <bonelli@antifork.org>
  6. *
  7. * All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  19. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  22. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  23. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  24. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  25. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  26. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  27. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. *
  30. */
  31. #include <stdlib.h>
  32. #include <stdio.h>
  33. #include <unistd.h>
  34. #include <signal.h>
  35. #include <string.h>
  36. #include <stdarg.h>
  37. #include <sysexits.h>
  38. #include <errno.h>
  39. #include <err.h>
  40. static const char cvsid[] = "$Id: dante.c 7 2009-01-26 10:32:36Z nicola.bonelli $";
  41. static const char copyright[] = "Copyright (c) 2002 Bonelli Nicola <bonelli@antifork.org>";
  42. static const char usage_str[]=
  43. "Usage: %s [OPTIONS]\n"
  44. " -a Set EAX offset\n"
  45. " -b Set EBX offset\n"
  46. " -c Set ECX offset\n"
  47. " -d Set EDX offset\n"
  48. " -S Set ESI offset\n"
  49. " -D Set EDI offset\n"
  50. " default values are set to 0\n"
  51. " -v Display version number.\n"
  52. " -h Print this help\n";
  53. /* macro */
  54. #define VERSION "0.91"
  55. #define MAX_SIZE 1024 /* stack */
  56. /* registers' identifiers */
  57. #define EAX 1
  58. #define ECX 2
  59. #define EDX 3
  60. #define EBX 4
  61. #define ESP 5
  62. #define EBP 6
  63. #define ESI 7
  64. #define EDI 8
  65. #define AL EAX
  66. #define CL ECX
  67. #define DL EDX
  68. #define BL EBX
  69. #define SI ESI
  70. #define DI EDI
  71. #define BP EBP
  72. #define SP ESP
  73. /*
  74. * macro
  75. */
  76. #define CARRY4(x,y) do { \
  77. x+=y>>2; \
  78. y =y&0x03; \
  79. } while (0)
  80. #define SETUP_REG(x,y) do { \
  81. x.id=y; \
  82. x.delta=0; \
  83. x.offset=0; \
  84. } while (0)
  85. #define MSG(f,arg...) do { \
  86. fprintf(stderr,f,## arg); \
  87. } while (0)
  88. #define NCUT(x) do { \
  89. register int i=0; \
  90. while(x[i]!=0) \
  91. { if (x[i]=='\n') x[i]=0; \
  92. i++; } \
  93. } while (0)
  94. #define SPACE(x) do { \
  95. register int i=0; \
  96. while(x[i]!=0) \
  97. { if (x[i]==' ') x[i]='.'; \
  98. i++; } \
  99. } while (0)
  100. #define VALIDATE_CHARSET(c) do { \
  101. if ( charset[(int)c] == 0 ) \
  102. { MSG("\n\"%c\" is out of charset! \
  103. [A-Z@\\[\\]\\^\\_/\\.]\n" \
  104. ,c); return 0; } \
  105. } while (0)
  106. #define HEX(h) do { \
  107. char t1[8]; \
  108. char t2[8]; \
  109. sprintf(t1,"\\x%.2x",h); \
  110. strcat(std_out,t1); \
  111. sprintf(t2,"%c",h); \
  112. strcat(std_code,t2); \
  113. } while (0)
  114. #define TEXT(s) do { \
  115. strcat(std_out,s); \
  116. strcat(std_code,s); \
  117. } while (0)
  118. #define INTEL_(x) intel_tab[*(x)-'@']
  119. #define INTEL_CODE(x) intel_tab[*(x)-'@'].opcode
  120. #define INTEL_BIT(x) intel_tab[*(x)-'@'].regbit
  121. #define INTEL_SEFF(x) intel_tab[*(x)-'@'].seffect
  122. #define MIN(a,b) ( (a) < (b) ? (a) : (b) )
  123. #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
  124. #define SIGN(x) ( (x) > 0 ? 1 : ( (x) == 0 ? 0 : -1 ) )
  125. #define SET(r,b) ( r |= b )
  126. #define ISSET(r,b) ( r & b )
  127. #define CLR(r,b) ( r &= ~b )
  128. #define BIT(x) ( 1<<(x-1))
  129. #define INC(REG) HEX('@'-1+REG)
  130. #define DEC(REG) HEX('H'-1+REG)
  131. #define ADD(VAL,REG) switch(REG) {\
  132. case AL: HEX(0x04); HEX(VAL); break;\
  133. case BL: HEX(0x80); HEX(0xc3); HEX(VAL); break;\
  134. case CL: HEX(0x80); HEX(0xc1); HEX(VAL); break;\
  135. case DL: HEX(0x80); HEX(0xc2); HEX(VAL); break;\
  136. case SI: HEX(0x66); HEX(0x83); HEX(0xc6); HEX(VAL); break;\
  137. case DI: HEX(0x66); HEX(0x83); HEX(0xc7); HEX(VAL); break;\
  138. case BP: HEX(0x66); HEX(0x83); HEX(0xc5); HEX(VAL); break;\
  139. case SP: HEX(0x66); HEX(0x83); HEX(0xc4); HEX(VAL); break;\
  140. default: fatal("unknown register"); break;}
  141. #define SUB(VAL,REG) switch(REG) {\
  142. case AL: HEX(0x2c); HEX(VAL); break;\
  143. case BL: HEX(0x80); HEX(0xeb); HEX(VAL); break;\
  144. case CL: HEX(0x80); HEX(0xe9); HEX(VAL); break;\
  145. case DL: HEX(0x80); HEX(0xea); HEX(VAL); break;\
  146. case SI: HEX(0x66); HEX(0x83); HEX(0xee); HEX(VAL); break;\
  147. case DI: HEX(0x66); HEX(0x83); HEX(0xef); HEX(VAL); break;\
  148. case BP: HEX(0x66); HEX(0x83); HEX(0xed); HEX(VAL); break;\
  149. case SP: HEX(0x66); HEX(0x83); HEX(0xec); HEX(VAL); break;\
  150. default: fatal("unknown register"); break;}
  151. /*
  152. * typedefs
  153. */
  154. typedef struct {
  155. int id; /* register identifer */
  156. int delta; /* effective offset */
  157. int offset; /* expected offset, default is 0 */
  158. } dnt_reg_t;
  159. typedef struct {
  160. dnt_reg_t eax;
  161. dnt_reg_t ebx;
  162. dnt_reg_t ecx;
  163. dnt_reg_t edx;
  164. dnt_reg_t esp;
  165. dnt_reg_t ebp;
  166. dnt_reg_t esi;
  167. dnt_reg_t edi;
  168. int poisoned; /* bitfield */
  169. int dirty;
  170. } dnt_regset_t;
  171. typedef struct {
  172. int (*opcode) (dnt_reg_t *); /* opcode function */
  173. dnt_reg_t *p_reg; /* involved register */
  174. int seffect; /* stack's side effect */
  175. int regbit;
  176. } dnt_table_t;
  177. typedef struct {
  178. dnt_reg_t rgstr[MAX_SIZE];
  179. int top;
  180. int top4;
  181. int offset;
  182. int depth;
  183. } dnt_stack_t;
  184. /*
  185. * prototypes
  186. */
  187. int inc (dnt_reg_t *);
  188. int dec (dnt_reg_t *);
  189. int push(dnt_reg_t *);
  190. int pop (dnt_reg_t *);
  191. /*
  192. * globals
  193. */
  194. int charset[256] = {['.'] = 1,['/'] = 1,[64 ... 91] = 1,[93 ... 95] = 1}; /* good set */
  195. /* stack */
  196. dnt_stack_t stack;
  197. /* registers */
  198. dnt_regset_t reg;
  199. extern char *__progname;
  200. /* buffers*/
  201. char std_in[MAX_SIZE];
  202. char std_out[MAX_SIZE];
  203. char std_code[MAX_SIZE];
  204. /* instructions tables */
  205. dnt_table_t intel_tab[] = {
  206. {inc, &reg.eax, 0, EAX}, {inc, &reg.ecx, 0, ECX},
  207. {inc, &reg.edx, 0, EDX}, {inc, &reg.ebx, 0, EBX},
  208. {inc, &reg.esp, -1, ESP}, {inc, &reg.ebp, 0, EBP},
  209. {inc, &reg.esi, 0, ESI}, {inc, &reg.edi, 0, EDI},
  210. {dec, &reg.eax, 0, EAX}, {dec, &reg.ecx, 0, ECX},
  211. {dec, &reg.edx, 0, EDX}, {dec, &reg.ebx, 0, EBX},
  212. {dec, &reg.esp, 1, ESP}, {dec, &reg.ebp, 0, EBP},
  213. {dec, &reg.esi, 0, ESI}, {dec, &reg.edi, 0, EDI},
  214. {push, &reg.eax, 4, EAX}, {push, &reg.ecx, 4, ECX},
  215. {push, &reg.edx, 4, EDX}, {push, &reg.ebx, 4, EBX},
  216. {push, &reg.esp, 4, ESP}, {push, &reg.ebp, 4, EBP},
  217. {push, &reg.esi, 4, ESI}, {push, &reg.edi, 4, EDI},
  218. {pop, &reg.eax, -4, EAX}, {pop, &reg.ecx, -4, ECX},
  219. {pop, &reg.edx, -4, EDX}, {pop, &reg.ebx, -4, EBX},
  220. {pop, &reg.esp, -4, ESP}, {pop, &reg.ebp, -4, EBP},
  221. {pop, &reg.esi, -4, ESI}, {pop, &reg.edi, -4, EDI}
  222. };
  223. int i386_len[256] = {[0x04] = 1,[0x2c] = 1,[0x80] = 2,[0x83] = 2,[0x66] = 3};
  224. char *i386_table_0[256] = {
  225. ['@'] "inc %eax",['A'] "inc %ecx",['B'] "inc %edx",['C'] "inc %ebx",
  226. ['D'] "inc %esp",['E'] "inc %ebp",['F'] "inc %esi",['G'] "inc %edi",
  227. ['H'] "dec %eax",['I'] "dec %ecx",['J'] "dec %edx",['K'] "dec %ebx",
  228. ['L'] "dec %esp",['M'] "dec %ebp",['N'] "dec %esi",['O'] "dec %edi",
  229. ['P'] "push %eax",['Q'] "push %ecx",['R'] "push %edx",['S'] "push %ebx",
  230. ['T'] "push %esp",['U'] "push %ebp",['V'] "push %esi",['W'] "push %edi",
  231. ['X'] "pop %eax",['Y'] "pop %ecx",['Z'] "pop %edx",['['] "pop %ebx",
  232. ['\\'] "pop %esp",[']'] "pop %ebp",['^'] "pop %esi",['_'] "pop %edi",
  233. ['/'] "das",['.'] "cs",
  234. };
  235. char *i386_table_1[256] = {
  236. [0x04] = "add \t$0x%.2x, %%al\n",
  237. [0x2c] = "sub \t$0x%.2x, %%al\n",
  238. };
  239. char *i386_table_2[256] = {
  240. [0xc1] = "add \t$0x%.2x, %%cl\n",
  241. [0xc2] = "add \t$0x%.2x, %%dl\n",
  242. [0xc3] = "add \t$0x%.2x, %%bl\n",
  243. [0xc4] = "add \t$0x%.2x, %%esp\n", /* special \x83\xc4\x.. */
  244. [0xe9] = "sub \t$0x%.2x, %%cl\n",
  245. [0xea] = "sub \t$0x%.2x, %%dl\n",
  246. [0xeb] = "sub \t$0x%.2x, %%bl\n",
  247. };
  248. char *i386_table_3[256] = {
  249. [0xc6] = "add \t$0x%.2x, %%si\n",
  250. [0xc7] = "add \t$0x%.2x, %%di\n",
  251. [0xc5] = "add \t$0x%.2x, %%bp\n",
  252. [0xc4] = "add \t$0x%.2x, %%sp\n",
  253. [0xee] = "sub \t$0x%.2x, %%si\n",
  254. [0xef] = "sub \t$0x%.2x, %%di\n",
  255. [0xed] = "sub \t$0x%.2x, %%bp\n",
  256. [0xec] = "sub \t$0x%.2x, %%sp\n",
  257. };
  258. /*
  259. * fatal
  260. */
  261. void fatal(char *pattern,...) __attribute__((noreturn));
  262. void
  263. fatal(char *pattern,...)
  264. {
  265. va_list ap;
  266. va_start(ap, pattern);
  267. if (errno)
  268. verr(EX_SOFTWARE,pattern,ap);
  269. else
  270. verrx(EX_SOFTWARE,pattern,ap);
  271. }
  272. void version(void) __attribute__((noreturn));
  273. void
  274. version()
  275. {
  276. MSG("Dante %s. (c) Bonelli Nicola <bonelli@antifork.org>\n", VERSION);
  277. exit(0);
  278. }
  279. void usage(void) __attribute__((noreturn));
  280. void
  281. usage()
  282. {
  283. fprintf(stderr, usage_str, __progname);
  284. exit(0);
  285. }
  286. inline void
  287. setup_registers()
  288. {
  289. SETUP_REG(reg.eax, EAX);
  290. SETUP_REG(reg.ebx, EBX);
  291. SETUP_REG(reg.ecx, ECX);
  292. SETUP_REG(reg.edx, EDX);
  293. SETUP_REG(reg.esp, ESP);
  294. SETUP_REG(reg.ebp, EBP);
  295. SETUP_REG(reg.esi, ESI);
  296. SETUP_REG(reg.edi, EDI);
  297. }
  298. int
  299. inc(dnt_reg_t * r)
  300. {
  301. if (r == &reg.esp)
  302. stack.top4--;
  303. CARRY4(stack.top, stack.top4);
  304. return ++r->delta;
  305. }
  306. int
  307. dec(dnt_reg_t * r)
  308. {
  309. if (r == &reg.esp)
  310. stack.top4++;
  311. CARRY4(stack.top, stack.top4);
  312. return --r->delta;
  313. }
  314. int
  315. push(dnt_reg_t * r)
  316. {
  317. stack.top++;
  318. stack.rgstr[stack.top].id = r->id;
  319. stack.rgstr[stack.top].delta = r->delta;
  320. return stack.top;
  321. }
  322. int
  323. pop(dnt_reg_t * r)
  324. {
  325. if (stack.top < 0)
  326. fatal("stack empty");
  327. r->id = stack.rgstr[stack.top].id;
  328. r->delta = stack.rgstr[stack.top].delta;
  329. return --stack.top;
  330. }
  331. /*
  332. * Scan the human readable string in order to estimate the depth of the stack
  333. * identifying poisoned registers...
  334. */
  335. int
  336. scan_set(unsigned char *r)
  337. {
  338. int stepi=0;
  339. if (r == NULL || *r == 0)
  340. return 0;
  341. while (*r != '\0') {
  342. VALIDATE_CHARSET(*r);
  343. switch (*r) {
  344. case '.':
  345. case 'd':
  346. break;
  347. case '/':
  348. /* das istruction ( AL poisoning ) */
  349. if (!ISSET(reg.poisoned, BIT(EAX)))
  350. reg.dirty++;
  351. SET(reg.poisoned, BIT(EAX));
  352. break;
  353. default:
  354. if (INTEL_SEFF(r) == -4) {
  355. /* -4 identifies a popl */
  356. if (!ISSET(reg.poisoned, BIT(INTEL_BIT(r))))
  357. reg.dirty++;
  358. SET(reg.poisoned, BIT(INTEL_BIT(r)));
  359. }
  360. stack.offset += INTEL_SEFF(r) & 3;
  361. stepi += INTEL_SEFF(r) >> 2;
  362. stack.depth = MIN(stack.depth, stepi);
  363. break;
  364. }
  365. r++;
  366. }
  367. return 0;
  368. }
  369. int
  370. exec_code(char *r)
  371. {
  372. if (r == NULL || *r == 0)
  373. return 0;
  374. while (*r != '\0') {
  375. switch (*r) {
  376. case '.':
  377. case '/':
  378. case 'd':
  379. break;
  380. default:
  381. (*INTEL_CODE(r)) (INTEL_(r).p_reg);
  382. break;
  383. }
  384. r++;
  385. }
  386. return 1;
  387. }
  388. void
  389. print_stack()
  390. {
  391. int i= stack.top;
  392. while (i > -1) {
  393. printf("%d:%d %d\n", i, stack.rgstr[i].id, stack.rgstr[i].delta);
  394. i--;
  395. }
  396. return;
  397. }
  398. void
  399. insert_garbage()
  400. {
  401. int i;
  402. int o;
  403. o = stack.offset / 4 + ((stack.offset % 4) ? SIGN(stack.offset) : 0);
  404. if (stack.depth + o < 0) {
  405. for (i = 0; i > (stack.depth + o); i--) {
  406. HEX(0x55);
  407. push(&reg.ebp); /* push garbage into stack */
  408. }
  409. }
  410. fflush(stdout);
  411. return;
  412. }
  413. void
  414. save_register()
  415. {
  416. int i;
  417. for (i = 0; i < 8; i++) {
  418. if (!ISSET(reg.poisoned, 1 << i))
  419. continue; /* the i-th bitfield register is not poisoned */
  420. /* skip ESP */
  421. if ( i+1 == ESP)
  422. continue;
  423. /*
  424. * saving poisoned registers
  425. */
  426. HEX('P'+i);
  427. switch (i+1) {
  428. case EAX:
  429. push(&reg.eax);
  430. break;
  431. case ECX:
  432. push(&reg.ecx);
  433. break;
  434. case EDX:
  435. push(&reg.edx);
  436. break;
  437. case EBX:
  438. push(&reg.ebx);
  439. break;
  440. case EBP:
  441. push(&reg.ebp);
  442. break;
  443. case ESI:
  444. push(&reg.esi);
  445. break;
  446. case EDI:
  447. push(&reg.edi);
  448. break;
  449. }
  450. }
  451. fflush(stdout);
  452. return;
  453. }
  454. void
  455. load_register()
  456. {
  457. int i;
  458. for (i = 7; i > -1; i--) {
  459. if (!ISSET(reg.poisoned, 1 << i))
  460. continue; /* the i-th bitfield register is not poisoned */
  461. if (i == 4)
  462. continue; /* skip ESP */
  463. HEX('X' + i);
  464. switch (i + 1) {
  465. case EAX:
  466. pop(&reg.eax); break;
  467. case ECX:
  468. pop(&reg.ecx); break;
  469. case EDX:
  470. pop(&reg.edx); break;
  471. case EBX:
  472. pop(&reg.ebx); break;
  473. case EBP:
  474. pop(&reg.ebp); break;
  475. case ESI:
  476. pop(&reg.esi); break;
  477. case EDI:
  478. pop(&reg.edi); break;
  479. }
  480. }
  481. fflush(stdout);
  482. return;
  483. }
  484. void
  485. remove_remainder()
  486. {
  487. int i;
  488. i = stack.top + 1 - reg.dirty;
  489. if (i > 0) {
  490. HEX(0x83);
  491. HEX(0xc4);
  492. HEX(i*4 );
  493. }
  494. stack.top -= i;
  495. return;
  496. }
  497. void
  498. update_offset(dnt_reg_t * r, int regi)
  499. {
  500. int diff;
  501. if (r->id != regi) {
  502. printf("r->id:%d into register:%d\n", r->id, regi);
  503. fatal("Internal error! Please report the string \"%s\" to <bonelli@antifork.org>", std_in);
  504. }
  505. diff = r->offset - r->delta; /* diff */
  506. switch (diff) {
  507. case -1:
  508. DEC(regi);
  509. break;
  510. case -2:
  511. DEC(regi);
  512. DEC(regi);
  513. break;
  514. case 0:
  515. return;
  516. case 1:
  517. INC(regi);
  518. break;
  519. case 2:
  520. INC(regi);
  521. INC(regi);
  522. break;
  523. default:
  524. if (diff > 0) {
  525. if ( diff >= 255 )
  526. fatal("increment exceed the max value (255)");
  527. ADD(diff, regi)
  528. return;
  529. }
  530. /* diff < 0 */
  531. if ( diff <= -255 )
  532. fatal("decrement exceed the max value (255)");
  533. SUB(-diff, regi)
  534. }
  535. return;
  536. }
  537. void
  538. disasse_handler(int i)
  539. {
  540. unsigned char *s = (unsigned char *)std_code;
  541. if (s == NULL)
  542. return;
  543. printf("\nDump of assembler code for the current string:\n");
  544. while (*s) {
  545. int len;
  546. len = i386_len[(int) *s];
  547. switch (len) {
  548. case 0:
  549. if (i386_table_0[*s] == NULL)
  550. fatal("[\\x%.2x] unknown opcode", *s);
  551. printf("%s\t\t/* %c */\n", i386_table_0[*s], *s);
  552. s++;
  553. break;
  554. case 1:
  555. printf(i386_table_1[*s], *(s + 1));
  556. s += 2;
  557. break;
  558. case 2:
  559. if (i386_table_2[*(s + 1)] == NULL)
  560. fatal("[\\x%.2x\\x%.2x] unknown opcode", *s, *(s + 1));
  561. printf(i386_table_2[*(s + 1)], *(s + 2));
  562. s += 3;
  563. break;
  564. case 3:
  565. if (*(s + 1) != 0x83)
  566. fatal("[\\x%.2x\\x%.2x] unknown opcode", *s, *(s + 1));
  567. if (i386_table_3[*(s + 2)] == NULL)
  568. fatal("[\\x%.2x\\x%.2x\\x%.2x] unknown opcode", *s, *(s + 1), *(s + 2));
  569. printf(i386_table_3[*(s + 2)], *(s + 3));
  570. s += 4;
  571. break;
  572. }
  573. }
  574. }
  575. void
  576. objdump_handler(int i)
  577. {
  578. unsigned char *s = (unsigned char *)std_code;
  579. if (s == NULL)
  580. return;
  581. printf("\nDisassembly of the current string:\n");
  582. while (*s) {
  583. int len;
  584. len = i386_len[(int) *s];
  585. switch (len) {
  586. case 0:
  587. if (i386_table_0[*s] == NULL)
  588. fatal("[\\x%.2x] unknown opcode", *s);
  589. printf("%.2x\t%s\n", *s, i386_table_0[*s]);
  590. s++;
  591. break;
  592. case 1:
  593. printf("%.2x %.2x\t", *s, *(s + 1));
  594. printf(i386_table_1[*s], *(s + 1));
  595. s += 2;
  596. break;
  597. case 2:
  598. if (i386_table_2[*(s + 1)] == NULL)
  599. fatal("[\\x%.2x\\x%.2x] unknown opcode", *s, *(s + 1));
  600. printf("%.2x %.2x %.2x\t", *s, *(s + 1), *(s + 2));
  601. printf(i386_table_2[*(s + 1)], *(s + 2));
  602. s += 3;
  603. break;
  604. case 3:
  605. if (*(s + 1) != 0x83)
  606. fatal("[\\x%.2x\\x%.2x] unknown opcode", *s, *(s + 1));
  607. if (i386_table_3[*(s + 2)] == NULL)
  608. fatal("[\\x%.2x\\x%.2x\\x%.2x] unknown opcode", *s, *(s + 1), *(s + 2));
  609. printf("%.2x %.2x %.2x %.2x\t", *s, *(s + 1), *(s + 2), *(s + 3));
  610. printf(i386_table_3[*(s + 2)], *(s + 3));
  611. s += 4;
  612. break;
  613. }
  614. }
  615. }
  616. void
  617. reallign_esp()
  618. {
  619. int i;
  620. int j;
  621. i = stack.offset % 4;
  622. if (i == 0)
  623. return;
  624. if (i > 0) {
  625. for (j = 0; j < i; j++)
  626. HEX(0x44); /* inc %esp */
  627. return;
  628. }
  629. for (j = 0; j > i; j--)
  630. HEX(0x4c); /* dec %esp */
  631. return;
  632. }
  633. int
  634. main(int argc, char **argv)
  635. {
  636. int es;
  637. while ((es = getopt(argc, argv, "a:b:c:d:S:D:vh")) != EOF)
  638. switch (es) {
  639. case 'a':
  640. reg.eax.offset = strtol(optarg, (char **) NULL, 0);
  641. break;
  642. case 'b':
  643. reg.ebx.offset = strtol(optarg, (char **) NULL, 0);
  644. break;
  645. case 'c':
  646. reg.ecx.offset = strtol(optarg, (char **) NULL, 0);
  647. break;
  648. case 'd':
  649. reg.edx.offset = strtol(optarg, (char **) NULL, 0);
  650. break;
  651. case 'S':
  652. reg.esi.offset = strtol(optarg, (char **) NULL, 0);
  653. break;
  654. case 'D':
  655. reg.edi.offset = strtol(optarg, (char **) NULL, 0);
  656. break;
  657. case 'h':
  658. usage();
  659. break;
  660. case 'v':
  661. version();
  662. break;
  663. }
  664. argc -= optind;
  665. argv += optind;
  666. signal(SIGTSTP, objdump_handler); /* ignore SIGTSTP */
  667. signal(SIGINT, disasse_handler); /* ignore SIGINT */
  668. signal(SIGQUIT, SIG_IGN); /* ignore SIGQUIT */
  669. /* reading from stdin */
  670. MSG("Dante %s. (c) Bonelli Nicola <bonelli@antifork.org>\n", VERSION);
  671. MSG("\nwrite a plaintext string (^D exit | ^C disassemble | ^Z objdump ):\n");
  672. for (;;) {
  673. printf(">");
  674. fflush(stdout);
  675. std_in[0] = 0; /* reset */
  676. if (fgets(std_in, MAX_SIZE, stdin) == NULL)
  677. break;
  678. setup_registers(); /* clear registers */
  679. std_out [0]= 0;
  680. std_code[0]= 0;
  681. /* parsing */
  682. NCUT(std_in);
  683. SPACE(std_in);
  684. /* registers defaults */
  685. reg.poisoned = 0;
  686. reg.dirty= 0;
  687. /* setup stack */
  688. stack.top= -1;
  689. stack.top4= 0;
  690. stack.offset= 0;
  691. stack.depth= 0;
  692. if (scan_set((unsigned char *) std_in)) {
  693. /* save poisoned registers */
  694. save_register();
  695. /* insert garbage layer */
  696. insert_garbage();
  697. /* print plaintext code */
  698. TEXT(std_in);
  699. /* exec code */
  700. exec_code(std_in);
  701. /* reallign esp */
  702. reallign_esp();
  703. /* remove remainder */
  704. remove_remainder();
  705. /* load saved value */
  706. load_register();
  707. /* tune registers with offsets */
  708. update_offset(&reg.eax, EAX);
  709. update_offset(&reg.ebx, EBX);
  710. update_offset(&reg.ecx, ECX);
  711. update_offset(&reg.edx, EDX);
  712. update_offset(&reg.esi, ESI);
  713. update_offset(&reg.edi, EDI);
  714. update_offset(&reg.ebp, EBP);
  715. /* print the output */
  716. printf("\n\"%s\"\n", std_out);
  717. }
  718. }
  719. MSG("\nbye.\n");
  720. exit(0);
  721. }