static int format_att_mnemonic( x86_insn_t *insn, char *buf, int len) {
        int size = 0;
        char *suffix;

        if (! insn || ! buf || ! len )
                return(0);

        memset( buf, 0, len );

        /* do long jump/call prefix */
        if ( insn->type == insn_jmp || insn->type == insn_call ) {
                if (! is_imm_jmp( x86_operand_1st(insn) ) ||
                     (x86_operand_1st(insn))->datatype != op_byte ) {
                    /* far jump/call, use "l" prefix */
                    STRNCAT( buf, "l", len );
                }
                STRNCAT( buf, insn->mnemonic, len );

                return ( strlen( buf ) );
        }

        /* do mnemonic */
        STRNCAT( buf, insn->mnemonic, len );

        /* do suffixes for memory operands */
        if (!(insn->note & insn_note_nosuffix) &&
            (insn->group == insn_arithmetic ||
             insn->group == insn_logic ||
             insn->group == insn_move ||
             insn->group == insn_stack ||
             insn->group == insn_string ||
             insn->group == insn_comparison ||
             insn->type == insn_in ||
             insn->type == insn_out
            )) {
            if ( x86_operand_count( insn, op_explicit ) > 0 &&
                 is_memory_op( x86_operand_1st(insn) ) ){
                size = x86_operand_size( x86_operand_1st( insn ) );
            } else if ( x86_operand_count( insn, op_explicit ) > 1 &&
                        is_memory_op( x86_operand_2nd(insn) ) ){
                size = x86_operand_size( x86_operand_2nd( insn ) );
            }
        }

        if ( size == 1 ) suffix = "b";
        else if ( size == 2 ) suffix = "w";
        else if ( size == 4 ) suffix = "l";
        else if ( size == 8 ) suffix = "q";
        else suffix = "";

        STRNCAT( buf, suffix, len );
        return ( strlen( buf ) );
}
Esempio n. 2
0
static int format_att_mnemonic( x86_insn_t *insn, char *buf, int len) {
    int size = 0;
    char *suffix;

    if (! insn || ! buf || ! len )
        return(0);

    memset( buf, 0, len );

    /* intel callf/call far is always an lcall */
    if (! strcmp( "callf", insn->mnemonic ) ) {
        STRNCAT( buf, "lcall", len );
        return ( strlen( buf ) );
    }

    /* do long jump/call prefix */
    if ( insn->type == insn_jmp || insn->type == insn_call ) {
        if (! is_imm_jmp( x86_operand_1st(insn) ) ||
                (x86_operand_1st(insn))->datatype != op_byte ) {
            /* far jump/call, use "l" prefix */
            STRNCAT( buf, "l", len );
        }
        STRNCAT( buf, insn->mnemonic, len );

        return ( strlen( buf ) );
    }

    /* do mnemonic */
    STRNCAT( buf, insn->mnemonic, len );

    /* do suffixes for memory operands */
    if ( x86_operand_count( insn, op_explicit ) > 0 &&
            is_memory_op( x86_operand_1st(insn) ) ) {
        size = x86_operand_size( x86_operand_1st( insn ) );
    } else if ( x86_operand_count( insn, op_explicit ) > 1 &&
                is_memory_op( x86_operand_2nd(insn) ) ) {
        size = x86_operand_size( x86_operand_2nd( insn ) );
    }

    if ( size == 1 ) suffix = "b";
    else if ( size == 2 ) suffix = "w";
    else if ( size == 4 ) suffix = "l";
    else if ( size == 8 ) suffix = "q";
    else suffix = "";

    STRNCAT( buf, suffix, len );
    return ( strlen( buf ) );
}
Esempio n. 3
0
bool X86RTLGenerator::parseInsn(x86_insn_t &aInsn, RTLOp &aRTLOp)
{
	size_t uOpCount = x86_operand_count(&aInsn, op_explicit);
	unsigned uExpectedOpCount = 0xFFFFFFFF;

	switch(aInsn.type)
	{
		case insn_add:
			aRTLOp.setType(RTLOp::OP_ADD);
			uExpectedOpCount = 2;
			break;
		case insn_call:
			aRTLOp.setType(RTLOp::OP_CALL);
			break;	
		case insn_jcc:
			aRTLOp.setType(RTLOp::OP_JUMP);
			break;
		case insn_jmp:
			aRTLOp.setType(RTLOp::OP_JUMP);
			break;
		case insn_mov:
			aRTLOp.setType(RTLOp::OP_ASSIGN);
			break;
		case insn_return:
			aRTLOp.setType(RTLOp::OP_RETURN);
			break;
		case insn_sub:
			aRTLOp.setType(RTLOp::OP_SUBTRACT);
			break;
		case insn_test:
			aRTLOp.setType(RTLOp::OP_COMPARE);
			break;
		case insn_push:
		case insn_pop:
			aRTLOp.setType(RTLOp::OP_NOP);
			break;
		default:
			return false;
	}

	if((uOpCount >= 1) && (!parseArgument(x86_operand_1st(&aInsn), aRTLOp.getArg1())))
	{
		return false;
	}

	if((uOpCount >= 2) && (!parseArgument(x86_operand_2nd(&aInsn), aRTLOp.getArg2())))
	{
		return false;
	}

	if((uOpCount >= 3) && (!parseArgument(x86_operand_3rd(&aInsn), aRTLOp.getArg3())))
	{
		return false;
	}

	return true;
}
Esempio n. 4
0
void *decode_instructions(
    void *buf,
    void *buf_limit,
    void *(*putxml_fptr)(void *putxml_data, const char *element_format, void *element_data),
    void *putxml_data,
    void *(*printf_fptr)(void *printf_data, const char *format, ...),
    void *printf_data,
    const char *config_string)
{
#define PUTXML(efmt, edata)	(*putxml_fptr)(putxml_data, (const char*)(efmt), (void*)(edata))
#define PRINTF(fmt, x)		(*printf_fptr)(printf_data, (const char*)(fmt), x)
#define PRINTF2(fmt, x, y)	(*printf_fptr)(printf_data, (const char*)(fmt), x, y)

    size_t buf_size = (char*)buf_limit - (char*)buf;
    unsigned char *uc_buf = (unsigned char*) buf;
    int have_opnd, which;
    x86_insn_t insn;
    x86_op_t *opnd;
    intptr_t addr;
    char sbuf[MAX_OP_STRING * 2];
    size_t pos, size;

    if (!putxml_fptr) {
        putxml_fptr = empty_putxml;
    }
    if (!printf_fptr) {
        intptr_t stdio_fprintf_addr = (intptr_t) &fprintf;
        printf_fptr = (void * (*)(void *, const char *, ...)) stdio_fprintf_addr;
        if (!printf_data)  printf_data = stdout;
    }

    x86_init(0, 0, 0);
    PUTXML("insns", buf);
    PUTXML("mach name='%s'/", "i386(base-hsdis)");
    PUTXML("format bytes-per-line='%p'/", (intptr_t)FORMAT_BYTES_PER_LINE);

    for (pos = 0; pos < buf_size; pos += size) {
        size = x86_disasm(uc_buf, buf_size, (intptr_t) buf, pos, &insn);
        PUTXML("insn", (char*)buf + pos);
        if (size == 0) {
            PRINTF("invalid\t0x%02x", uc_buf[pos]);
            size = 1;  /* to make progress */
        } else {
            PRINTF2("%s%s", insn.prefix_string, insn.mnemonic);
            have_opnd = 0;
            for (which = 0; which < 3; which++) {
                /* dest comes first, then src and/or imm */
                switch (which) {
                case 0:
                    opnd = x86_operand_1st(&insn);
                    break;
                case 1:
                    opnd = x86_operand_2nd(&insn);
                    break;
                default:
                    opnd = x86_operand_3rd(&insn);
                    break;
                }
                if (!opnd)  continue;
                if (opnd->flags & op_implied)  continue;
                if (!have_opnd++)
                    PRINTF("\t", 0);
                else	PRINTF(", ", 0);
                addr = addr_from_operand(opnd);
                if (!(addr && PUTXML("addr/", addr))) {
                    x86_format_operand(opnd,
                                       sbuf, sizeof(sbuf),
                                       intel_syntax);
                    PRINTF("%s", sbuf);
                }
            }
        }
        PUTXML("/insn", (char*)buf + pos + size);
        PRINTF("\n", 0);
    }

    PUTXML("/insns", (char*)buf + pos);
    x86_cleanup();
    return (char*)buf + pos;
}
int x86_format_insn( x86_insn_t *insn, char *buf, int len,
                     enum x86_asm_format format ){
        char str[MAX_OP_STRING];
        x86_op_t *src, *dst;
        int i;

        memset(buf, 0, len);
        if ( format == intel_syntax ) {
                /* INTEL STYLE: mnemonic dest, src, imm */
                STRNCAT( buf, insn->prefix_string, len );
                STRNCAT( buf, insn->mnemonic, len );
                STRNCAT( buf, "\t", len );

                /* dest */
		if ( (dst = x86_operand_1st( insn )) && !(dst->flags & op_implied) ) {
        		x86_format_operand( dst, str, MAX_OP_STRING, format);
                	STRNCAT( buf, str, len );
                }

                /* src */
		if ( (src = x86_operand_2nd( insn )) ) {
                        if ( !(dst->flags & op_implied) ) {
                	        STRNCAT( buf, ", ", len );
                        }
        		x86_format_operand( src, str, MAX_OP_STRING, format);
                	STRNCAT( buf, str, len );
                }

                /* imm */
		if ( x86_operand_3rd( insn )) {
                	STRNCAT( buf, ", ", len );
        		x86_format_operand( x86_operand_3rd( insn ), 
				str, MAX_OP_STRING, format);
                	STRNCAT( buf, str, len );
		}

        } else if ( format == att_syntax ) {
                /* ATT STYLE: mnemonic src, dest, imm */
                STRNCAT( buf, insn->prefix_string, len );
                format_att_mnemonic(insn, str, MAX_OP_STRING);
                STRNCATF( buf, "%s\t", str, len);


		/* not sure which is correct? sometimes GNU as requires
		 * an imm as the first operand, sometimes as the third... */
                /* imm */
		if ( x86_operand_3rd( insn ) ) {
        		x86_format_operand(x86_operand_3rd( insn ), 
				str, MAX_OP_STRING, format);
                	STRNCAT( buf, str, len );
			/* there is always 'dest' operand if there is 'src' */
			STRNCAT( buf, ", ", len );
		}

                if ( (insn->note & insn_note_nonswap ) == 0 ) {
                        /* regular AT&T style swap */
                        src = x86_operand_2nd( insn );
                        dst = x86_operand_1st( insn );
                }
                else {
                        /* special-case instructions */
                        src = x86_operand_1st( insn );
                        dst = x86_operand_2nd( insn );
                }

                /* src */
                if ( src ) {
                        x86_format_operand(src, str, MAX_OP_STRING, format);
                        STRNCAT( buf, str, len );
                        /* there is always 'dest' operand if there is 'src' */
                        if ( dst && !(dst->flags & op_implied) ) {
                                STRNCAT( buf, ", ", len );
                        }
                }

                /* dest */
                if ( dst && !(dst->flags & op_implied) ) {
                        x86_format_operand( dst, str, MAX_OP_STRING, format);
                        STRNCAT( buf, str, len );
                }


        } else if ( format == raw_syntax ) {
                format_raw_insn( insn, buf, len );
        } else if ( format == xml_syntax ) {
                format_xml_insn( insn, buf, len );
        } else { /* default to native */
                /* NATIVE style: RVA\tBYTES\tMNEMONIC\tOPERANDS */
                /* print address */
                STRNCATF( buf, "%08X\t", insn->addr, len );

                /* print bytes */
                for ( i = 0; i < insn->size; i++ ) {
                        STRNCATF( buf, "%02X ", insn->bytes[i], len );
                }

                STRNCAT( buf, "\t", len );

                /* print mnemonic */
                STRNCAT( buf, insn->prefix_string, len );
                STRNCAT( buf, insn->mnemonic, len );
                STRNCAT( buf, "\t", len );

                /* print operands */
                /* dest */
		if ( x86_operand_1st( insn )  ) {
        		x86_format_operand( x86_operand_1st( insn ), 
				str, MAX_OP_STRING, format);
                	STRNCATF( buf, "%s\t", str, len );
		}

                /* src */
		if ( x86_operand_2nd( insn ) ) {
        		x86_format_operand(x86_operand_2nd( insn ), 
				str, MAX_OP_STRING, format);
                	STRNCATF( buf, "%s\t", str, len );
		}

                /* imm */
		if ( x86_operand_3rd( insn )) {
        		x86_format_operand( x86_operand_3rd( insn ), 
				str, MAX_OP_STRING, format);
                	STRNCAT( buf, str, len );
		}
        }

        return( strlen( buf ) );
}
static int format_xml_insn( x86_insn_t *insn, char *buf, int len ) {
        char str[MAX_OP_XML_STRING];
        int i;

        STRNCAT( buf, "<x86_insn>\n", len );

        STRNCATF( buf, "\t<address rva=\"0x%08X\" ", insn->addr, len );
        STRNCATF( buf, "offset=\"0x%08X\" ", insn->offset, len );
        STRNCATF( buf, "size=%d bytes=\"", insn->size, len );

        for ( i = 0; i < insn->size; i++ ) {
                STRNCATF( buf, "%02X ", insn->bytes[i], len );
        }
        STRNCAT( buf, "\"/>\n", len );

        STRNCAT( buf, "\t<prefix type=\"", len );
        len -= format_insn_prefix_str( insn->prefix, buf, len );
        STRNCATF( buf, "\" string=\"%s\"/>\n", insn->prefix_string, len );

        STRNCATF( buf, "\t<mnemonic group=\"%s\" ",
                  get_insn_group_str (insn->group), len );
        STRNCATF( buf, "type=\"%s\" ", get_insn_type_str (insn->type), len );
        STRNCATF( buf, "string=\"%s\"/>\n", insn->mnemonic, len );

        STRNCAT( buf, "\t<flags type=set>\n", len );
        STRNCAT( buf, "\t\t<flag name=\"", len );
        len -= format_insn_eflags_str( insn->flags_set, buf, len );
        STRNCAT( buf, "\"/>\n\t</flags>\n", len );


        STRNCAT( buf, "\t<flags type=tested>\n", len );
        STRNCAT( buf, "\t\t<flag name=\"", len );
        len -= format_insn_eflags_str( insn->flags_tested, buf, len );
        STRNCAT( buf, "\"/>\n\t</flags>\n", len );

	if ( x86_operand_1st( insn ) ) {
        	x86_format_operand( x86_operand_1st(insn), str,
                           sizeof str, xml_syntax);
        	STRNCAT( buf, "\t<operand name=dest>\n", len );
        	STRNCAT( buf, str, len );
        	STRNCAT( buf, "\t</operand>\n", len );
	}

	if ( x86_operand_2nd( insn ) ) {
        	x86_format_operand( x86_operand_2nd( insn ), str,
                           sizeof str, xml_syntax);
        	STRNCAT( buf, "\t<operand name=src>\n", len );
        	STRNCAT( buf, str, len );
        	STRNCAT( buf, "\t</operand>\n", len );
	}

	if ( x86_operand_3rd( insn ) ) {
        	x86_format_operand( x86_operand_3rd(insn), str,
                           sizeof str, xml_syntax);
        	STRNCAT( buf, "\t<operand name=imm>\n", len );
        	STRNCAT( buf, str, len );
        	STRNCAT( buf, "\t</operand>\n", len );
	}

        STRNCAT( buf, "</x86_insn>\n", len );

        return strlen (buf);
}
Esempio n. 7
0
int x86_format_insn( x86_insn_t *insn, char *buf, int len,
                     enum x86_asm_format format ) {
    char str[MAX_OP_STRING];
    int i;

    memset(buf, 0, len);
    if ( format == intel_syntax ) {
        /* INTEL STYLE: mnemonic dest, src, imm */
        STRNCAT( buf, insn->prefix_string, len );
        STRNCAT( buf, insn->mnemonic, len );
        STRNCAT( buf, "\t", len );

        /* dest */
        if ( x86_operand_1st( insn )  ) {
            x86_format_operand( x86_operand_1st( insn ),
                                insn, str, MAX_OP_STRING, format);
            STRNCAT( buf, str, len );
        }

        /* src */
        if ( x86_operand_2nd( insn ) ) {
            STRNCAT( buf, ", ", len );
            x86_format_operand(x86_operand_2nd( insn ),
                               insn, str, MAX_OP_STRING, format);
            STRNCAT( buf, str, len );
        }

        /* imm */
        if ( x86_operand_3rd( insn )) {
            STRNCAT( buf, ", ", len );
            x86_format_operand( x86_operand_3rd( insn ),
                                insn, str, MAX_OP_STRING, format);
            STRNCAT( buf, str, len );
        }

    } else if ( format == att_syntax ) {
        /* ATT STYLE: mnemonic src, dest, imm */
        STRNCAT( buf, insn->prefix_string, len );
        format_att_mnemonic(insn, str, MAX_OP_STRING);
        STRNCATF( buf, "%s\t", str, len);

        /* src */
        if ( x86_operand_2nd( insn ) ) {
            x86_format_operand(x86_operand_2nd( insn ),
                               insn, str, MAX_OP_STRING, format);
            STRNCAT( buf, str, len );
            /* there is always 'dest' operand if there is 'src' */
            STRNCAT( buf, ", ", len );
        }

        /* dest */
        if ( x86_operand_1st( insn )  ) {
            x86_format_operand( x86_operand_1st( insn ),
                                insn, str, MAX_OP_STRING, format);
            STRNCAT( buf, str, len );
        }


        /* imm */
        if ( x86_operand_3rd( insn ) ) {
            STRNCAT( buf, ", ", len );
            x86_format_operand(x86_operand_3rd( insn ),
                               insn, str, MAX_OP_STRING, format);
            STRNCAT( buf, str, len );
        }

    } else if ( format == raw_syntax ) {
        format_raw_insn( insn, buf, len );
    } else if ( format == xml_syntax ) {
        format_xml_insn( insn, buf, len );
    } else { /* default to native */
        /* NATIVE style: RVA\tBYTES\tMNEMONIC\tOPERANDS */
        /* print address */
        STRNCATF( buf, "%08lX\t", insn->addr, len );

        /* print bytes */
        for ( i = 0; i < insn->size; i++ ) {
            STRNCATF( buf, "%02X ", insn->bytes[i], len );
        }

        STRNCAT( buf, "\t", len );

        /* print mnemonic */
        STRNCAT( buf, insn->prefix_string, len );
        STRNCAT( buf, insn->mnemonic, len );
        STRNCAT( buf, "\t", len );

        /* print operands */
        /* dest */
        if ( x86_operand_1st( insn )  ) {
            x86_format_operand( x86_operand_1st( insn ),
                                insn, str, MAX_OP_STRING, format);
            STRNCATF( buf, "%s\t", str, len );
        }

        /* src */
        if ( x86_operand_2nd( insn ) ) {
            x86_format_operand(x86_operand_2nd( insn ),
                               insn, str, MAX_OP_STRING, format);
            STRNCATF( buf, "%s\t", str, len );
        }

        /* imm */
        if ( x86_operand_3rd( insn )) {
            x86_format_operand( x86_operand_3rd( insn ),
                                insn, str, MAX_OP_STRING, format);
            STRNCAT( buf, str, len );
        }
    }

    return( strlen( buf ) );
}