void do_sib(int m) { int s, i, b; s = ss(sib()); i = indx(sib()); b = base(sib()); switch (b) { case 0: expand_out("%p:[EAX"); break; case 1: expand_out("%p:[ECX"); break; case 2: expand_out("%p:[EDX"); break; case 3: expand_out("%p:[EBX"); break; case 4: expand_out("%p:[ESP"); break; case 5: if (m == 0) { expand_out("%p:["); ohex('d', 4, 0, addrsize); } else expand_out("%p:[EBP"); break; case 6: expand_out("%p:[ESI"); break; case 7: expand_out("%p:[EDI"); break; } switch (i) { case 0: fprintf(out_fh,"+EAX"); break; case 1: fprintf(out_fh,"+ECX"); break; case 2: fprintf(out_fh,"+EDX"); break; case 3: fprintf(out_fh,"+EBX"); break; case 4: break; case 5: fprintf(out_fh,"+EBP"); break; case 6: fprintf(out_fh,"+ESI"); break; case 7: fprintf(out_fh,"+EDI"); break; } if (i != 4) switch (s) { case 0: break; case 1: fprintf(out_fh,"*2"); break; case 2: fprintf(out_fh,"*4"); break; case 3: fprintf(out_fh,"*8"); break; } }
void do_sib(int m) { int s, i, b; s = ss(sib()); i = indx(sib()); b = base(sib()); switch (b) { case 0: ua_str("%p:[eax"); break; case 1: ua_str("%p:[ecx"); break; case 2: ua_str("%p:[edx"); break; case 3: ua_str("%p:[ebx"); break; case 4: ua_str("%p:[esp"); break; case 5: if (m == 0) { ua_str("%p:["); ohex('d', 4, 0, addrsize); } else ua_str("%p:[ebp"); break; case 6: ua_str("%p:[esi"); break; case 7: ua_str("%p:[edi"); break; } switch (i) { case 0: uprintf("+eax"); break; case 1: uprintf("+ecx"); break; case 2: uprintf("+edx"); break; case 3: uprintf("+ebx"); break; case 4: break; case 5: uprintf("+ebp"); break; case 6: uprintf("+esi"); break; case 7: uprintf("+edi"); break; } if (i != 4) switch (s) { case 0: uprintf(""); break; case 1: uprintf("*2"); break; case 2: uprintf("*4"); break; case 3: uprintf("*8"); break; } }
static void percent(char c, char t) { word32 vofs; long l; int extend = (addrsize == 32) ? 4 : 2; switch (c) { case 'A': ohex(t, extend, 0, addrsize); break; case 'C': uprintf("C%d", reg(modrm())); break; case 'D': uprintf("D%d", reg(modrm())); break; case 'E': do_modrm(t); break; case 'G': if (t == 'F') reg_name(rm(modrm()), t); else reg_name(reg(modrm()), t); break; case 'I': ohex(t, 0, 0, opsize); break; case 'J': switch (bytes(t)) { case 1: vofs = (int8)getbyte(); break; case 2: vofs = getbyte(); vofs += getbyte()<<8; vofs = (int16)vofs; break; case 4: vofs = (word32)getbyte(); vofs |= (word32)getbyte() << 8; vofs |= (word32)getbyte() << 16; vofs |= (word32)getbyte() << 24; break; } l=vofs+codeoff; if(l<0x10000L) uprintf("%s%04lx%s %c", hex1, l, hex2, (vofs & 0x80000000L) ? 0x18 : 0x19); else uprintf("%s%08lX%s %c", hex1, l, hex2, (vofs & 0x80000000L) ? 0x18 : 0x19); break; case 'M': do_modrm(t); break; case 'O': ua_str("%p:["); ohex(t, extend, 0, addrsize); uprintf("%c",']'); break; case 'R': reg_name(reg(modrm()), t); //do_modrm(t); break; case 'S': uprintf("%c","ecsdfg"[reg(modrm())]); uprintf("%c",'s'); break; case 'T': uprintf("tr%d", reg(modrm())); break; case 'X': uprintf("ds:["); if (addrsize == 32) uprintf("%c",'e'); uprintf("si]"); break; case 'Y': uprintf("es:["); if (addrsize == 32) uprintf("%c",'e'); uprintf("di]"); break; case '2': ua_str(second[getbyte()]); break; case 'e': if (opsize == 32) { if (t == 'w') uprintf("%c",'d'); else { uprintf("%c",'e'); uprintf("%c",t); } } else uprintf("%c",t); break; case 'f': floating_point(t-'0'); break; case 'g': ua_str(groups[t-'0'][reg(modrm())]); break; case 'p': switch (t) { case 'c': case 'd': case 'e': case 'f': case 'g': case 's': prefix = t; ua_str(opmap1[getbyte()]); break; case ':': if (prefix) uprintf("%cs:", prefix); break; case ' ': ua_str(opmap1[getbyte()]); break; } break; case 's': switch (t) { case 'a': addrsize = 48 - addrsize; ua_str(opmap1[getbyte()]); break; case 'o': opsize = 48 - opsize; ua_str(opmap1[getbyte()]); break; } break; } }
void do_modrm(char t) { int m = mod(modrm()); int r = rm(modrm()); int extend = (addrsize == 32) ? 4 : 2; if (m == 3) { reg_name(r, t); return; } switch(bytes(t)) { case 1 : ua_str("byte ptr "); break; case 2 : ua_str("word ptr "); break; case 4 : ua_str("dword ptr "); break; default : ua_str("?word ptr "); break; } if ((m == 0) && (r == 5) && (addrsize == 32)) { ua_str("%p:["); ohex('d', extend, 0, addrsize); uprintf("%c",']'); return; } if ((m == 0) && (r == 6) && (addrsize == 16)) { ua_str("%p:["); ohex('w', extend, 0, addrsize); uprintf("%c",']'); return; } if ((addrsize != 32) || (r != 4)) ua_str("%p:["); if (addrsize == 16) { switch (r) { case 0: uprintf("bx+si"); break; case 1: uprintf("bx+di"); break; case 2: uprintf("bp+si"); break; case 3: uprintf("bp+di"); break; case 4: uprintf("si"); break; case 5: uprintf("di"); break; case 6: uprintf("bp"); break; case 7: uprintf("bx"); break; } } else { switch (r) { case 0: uprintf("eax"); break; case 1: uprintf("ecx"); break; case 2: uprintf("edx"); break; case 3: uprintf("ebx"); break; case 4: do_sib(m); break; case 5: uprintf("ebp"); break; case 6: uprintf("esi"); break; case 7: uprintf("edi"); break; } } switch (m) { case 1: ohex('b', extend, 1, addrsize); break; case 2: uprintf("+"); ohex('v', extend, 1, addrsize); break; } uprintf("%c",']'); }
/*------------------------------------------------------------------------*/ void do_modrm(char t) { int m; int r; int extend; m = mod(modrm()); r = rm(modrm()); extend = (addrsize == 32) ? 4 : 2; if (m == 3) { reg_name(r, t); return; } if ((m == 0) && (r == 5) && (addrsize == 32)) { expand_out("%p:["); ohex('d', extend, 0, addrsize); fprintf(out_fh,"]"); return; } if ((m == 0) && (r == 6) && (addrsize == 16)) { expand_out("%p:["); ohex('w', extend, 0, addrsize); fprintf(out_fh,"]"); return; } if ((addrsize != 32) || (r != 4)) expand_out("%p:["); if (addrsize == 16) { switch (r) { case 0: fprintf(out_fh,"BX+SI"); break; case 1: fprintf(out_fh,"BX+DI"); break; case 2: fprintf(out_fh,"BP+SI"); break; case 3: fprintf(out_fh,"BP+DI"); break; case 4: fprintf(out_fh,"SI"); break; case 5: fprintf(out_fh,"DI"); break; case 6: fprintf(out_fh,"BP"); break; case 7: fprintf(out_fh,"BX"); break; } } else { switch (r) { case 0: fprintf(out_fh,"EAX"); break; case 1: fprintf(out_fh,"ECX"); break; case 2: fprintf(out_fh,"EDX"); break; case 3: fprintf(out_fh,"EBX"); break; case 4: do_sib(m); break; case 5: fprintf(out_fh,"EBP"); break; case 6: fprintf(out_fh,"ESI"); break; case 7: fprintf(out_fh,"EDI"); break; } } switch (m) { case 1: ohex('b', extend, 0, addrsize); /* was 1 */ break; case 2: fprintf(out_fh,"+"); ohex('v', extend, 0, addrsize); /* was 1 */ break; } fprintf(out_fh,"]"); }
void escape(char c, char t) { U32 v; S32 delta, vofs, tmp; S8 vofsb; S16 vofsw; char *name; int extend; U8 b2, w; extend = (addrsize == 32) ? 4 : 2; switch (c) { case 'A': /* Direct Address */ ohex(t, extend, 0, addrsize); break; case 'C': /* Reg of R/M picks control reg */ fprintf(out_fh, "CR%d",reg(modrm())); break; case 'D': /* Reg of R/M pick debug reg */ fprintf(out_fh, "DR%d",modrm()); break; case 'E': /* R/M picks operand */ do_modrm(t); break; case 'G': /* Reg of R/M picks general reg */ if (t == 'F') reg_name(rm(modrm()), t); else reg_name(reg(modrm()), t); break; case 'I': /* Immediate data */ ohex(t, 0, 0, opsize); break; case 'J': /* Relative IP offset */ switch (bytes(t)) { case 1: vofsb = getbyte(); /* must remian signed! */ vofs = vofsb; break; case 2: vofsb = getbyte(); /*Must be Signed bytes/Words */ vofsw = getbyte()<<8; vofs = vofsw + vofsb; break; case 4: vofs = getbyte(); tmp = getbyte(); vofs |= tmp << 8; tmp = getbyte(); vofs |= tmp << 16; tmp = getbyte(); vofs |= tmp << 24; break; } delta = addrIn + vofs; fprintf(out_fh, "%08lX", delta); break; case 'M': /* R/M picks memory */ do_modrm(t); break; case 'O': /* NO R/M, Offset only */ expand_out("%p:["); ohex(t, extend, 0, addrsize); fprintf(out_fh,"]"); break; case 'R': /* Mod of R/M pick REG only */ do_modrm(t); break; case 'S': /* Reg of R/M picks seg reg */ fprintf(out_fh, "%s", seg_names[reg(modrm())]); break; case 'T': /* Reg of R/M picks test reg */ fprintf(out_fh, "TR%d",modrm()); break; case 'X': /* DS:ESI */ fprintf(out_fh,"DS:["); if (addrsize == 32) fprintf(out_fh,"E"); fprintf(out_fh,"SI]"); break; case 'Y': /* ES:EDI */ fprintf(out_fh,"ES:["); if (addrsize == 32) fprintf(out_fh,"E"); fprintf(out_fh,"DI]"); break; case '2': /* Prefix of 2 byte opcode */ b2 = getbyte(); if (b2 < 0x10) expand_out(SecOp00[b2]); else if ((b2 > 0x1F) && (b2 < 0x30)) expand_out(SecOp20[b2-0x20]); else if ((b2 > 0x7F) && (b2 < 0xC0)) expand_out(SecOp80[b2-0x80]); else fprintf(out_fh, "<invalid>"); break; case 'e': /* If "USE32" t is part of reg name */ if (opsize == 32) { if (t == 'w') /* put out "d" if t is "w" on USE32 segs*/ fprintf(out_fh,"D"); else { fprintf(out_fh,"E"); /* put out "E" if not t <> "w" then put t */ fputc(t, out_fh); } } else { fputc(t, out_fh); /* when USE16 just put out esc char */ } break; case 'f': /* floating point */ fprintf(out_fh,"<Float Op>"); /* floating_point(t-'0'); */ break; case 'g': /* do R/M group 'n' */ expand_out(groups[t-'0'][reg(modrm())]); break; case 'p': /* Segment prefix */ switch (t) { case 'C': /* CS */ case 'D': /* DS */ case 'E': /* ES */ case 'F': /* FS */ case 'G': /* GS */ case 'S': /* SS */ prefix = t; expand_out(opmap1[getbyte()]); break; case ':': if (prefix) { fputc(prefix, out_fh); fprintf(out_fh,"S:"); } break; case ' ': expand_out(opmap1[getbyte()]); break; } break; case 's': /* Size override */ switch (t) { case 'a': addrsize = 48 - addrsize; /* a is address */ expand_out(opmap1[getbyte()]); break; case 'o': /* o is operand */ opsize = 48 - opsize; expand_out(opmap1[getbyte()]); break; } break; } }