示例#1
0
static int format_operand_att( x86_op_t *op, x86_insn_t *insn, char *buf,
                               int len) {

    char str[MAX_OP_STRING];

    memset (str, 0, sizeof str);

    switch ( op->type ) {
    case op_register:
        STRNCATF( buf, "%%%s", op->data.reg.name, len );
        break;

    case op_immediate:
        get_operand_data_str( op, str, sizeof str );
        STRNCATF( buf, "$%s", str, len );
        break;

    case op_relative_near:
        STRNCATF( buf, "0x%08X",
                  (unsigned int)(op->data.sbyte +
                                 insn->addr + insn->size), len );
        break;

    case op_relative_far:
        if (op->datatype == op_word) {
            STRNCATF( buf, "0x%08X",
                      (unsigned int)(op->data.sword +
                                     insn->addr + insn->size), len );
        } else {
            STRNCATF( buf, "0x%08X",
                      (unsigned int)(op->data.sdword +
                                     insn->addr + insn->size), len );
        }
        break;

    case op_absolute:
    case op_offset:
        /* ATT requires a '*' before absolute JMP/CALL ops */
        if (insn->type == insn_jmp || insn->type == insn_call)
            STRNCAT( buf, "*", len );

        len -= format_seg( op, buf, len, att_syntax );
        STRNCATF( buf, "0x%08lX", op->data.sdword, len );
        break;

    case op_expression:
        len -= format_seg( op, buf, len, att_syntax );
        len -= format_expr( &op->data.expression, buf, len,
                            att_syntax );
        break;
    case op_unused:
    case op_unknown:
        /* return 0-truncated buffer */
        break;
    }

    return ( strlen( buf ) );
}
static int format_operand_raw( x86_op_t *op, x86_insn_t *insn, char *buf,
                               int len){

        char str[MAX_OP_RAW_STRING];
	char *datatype = get_operand_datatype_str(op);

        switch (op->type) {
                case op_register:

                        get_operand_regtype_str( op->data.reg.type, str,
                                                 sizeof str );

                        STRNCAT( buf, "reg|", len );
                        STRNCATF( buf, "%s|", datatype, len );
                        STRNCATF( buf, "%s:", op->data.reg.name, len );
                        STRNCATF( buf, "%s:", str, len );
                        STRNCATF( buf, "%d|", op->data.reg.size, len );
                        break;

                case op_immediate:

                        get_operand_data_str( op, str, sizeof str );

                        STRNCAT( buf, "immediate|", len );
                        STRNCATF( buf, "%s|", datatype, len );
                        STRNCATF( buf, "%s|", str, len );
                        break;

                case op_relative_near:
			/* NOTE: in raw format, we print the
			 * relative offset, not the actual
			 * address of the jump target */

                        STRNCAT( buf, "relative|", len );
                        STRNCATF( buf, "%s|", datatype, len );
                        STRNCATF( buf, "%hhd|", op->data.sbyte, len );
                        break;

                case op_relative_far:

                        STRNCAT( buf, "relative|", len );
                        STRNCATF( buf, "%s|", datatype, len );

                        if (op->datatype == op_word) {
                                STRNCATF( buf, "%hd|", op->data.sword, len);
                                break;
                        } else {
                        	STRNCATF( buf, "%d|", op->data.sdword, len );
			}
                        break;

                case op_absolute:

                        STRNCAT( buf, "absolute_address|", len );
                        STRNCATF( buf, "%s|", datatype, len );

                        STRNCATF( buf, "$0x%04hX:", op->data.absolute.segment,
				len );
			if (op->datatype == op_descr16) {
                        	STRNCATF( buf, "0x%04hX|", 
					op->data.absolute.offset.off16, len );
			} else {
                        	STRNCATF( buf, "0x%08X|", 
					op->data.absolute.offset.off32, len );
			}

                        break;

                case op_expression:

                        STRNCAT( buf, "address_expression|", len );
                        STRNCATF( buf, "%s|", datatype, len );

                        len -= format_seg( op, buf, len, native_syntax );
                        len -= format_expr( &op->data.expression, buf, len,
                                     raw_syntax );

                        STRNCAT( buf, "|", len );
                        break;

                case op_offset:

                        STRNCAT( buf, "segment_offset|", len );
                        STRNCATF( buf, "%s|", datatype, len );

                        len -= format_seg( op, buf, len, xml_syntax );

                        STRNCATF( buf, "%08X|", op->data.sdword, len );
                        break;

                case op_unused:
                case op_unknown:
                        /* return 0-truncated buffer */
                        break;
        }

        return( strlen( buf ) );
}
static int format_operand_xml( x86_op_t *op, x86_insn_t *insn, char *buf,
                               int len){

        char str[MAX_OP_STRING] = "\0";

        switch (op->type) {
                case op_register:

                        get_operand_regtype_str( op->data.reg.type, str,
                                                 sizeof str );

                        STRNCAT( buf, "\t\t<register ", len );
                        STRNCATF( buf, "name=\"%s\" ", op->data.reg.name, len );
                        STRNCATF( buf, "type=\"%s\" ", str, len );
                        STRNCATF( buf, "size=%d/>\n", op->data.reg.size, len );
                        break;

                case op_immediate:

                        get_operand_data_str( op, str, sizeof str );

                        STRNCAT( buf, "\t\t<immediate ", len );
                        STRNCATF( buf, "type=\"%s\" ",
                                  get_operand_datatype_str (op), len );
                        STRNCATF( buf, "value=\"%s\"/>\n", str, len );
                        break;

                case op_relative_near:
                        STRNCAT( buf, "\t\t<relative_offset ", len );

                        STRNCATF( buf, "value=\"0x%08X\"/>\n",
                                  (unsigned int)(op->data.sbyte +
                                  insn->addr + insn->size), len );
                        break;

                case op_relative_far:
                        STRNCAT( buf, "\t\t<relative_offset ", len );

                        if (op->datatype == op_word) {
                                STRNCATF( buf, "value=\"0x%08X\"/>\n",
                                          (unsigned int)(op->data.sword +
                                          insn->addr + insn->size), len);
                                break;
                        } else {

                        	STRNCATF( buf, "value=\"0x%08X\"/>\n",
                                      op->data.sdword + insn->addr + insn->size,
                                      len );
			}
                        break;

                case op_absolute:

                        STRNCATF( buf, 
				"\t\t<absolute_address segment=\"0x%04hX\"",
                        	op->data.absolute.segment, len );

			if (op->datatype == op_descr16) {
                        	STRNCATF( buf, "offset=\"0x%04hX\">", 
					op->data.absolute.offset.off16, len );
			} else {
                        	STRNCATF( buf, "offset=\"0x%08X\">", 
					op->data.absolute.offset.off32, len );
			}

                        STRNCAT( buf, "\t\t</absolute_address>\n", len );
                        break;

                case op_expression:
			

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

                        len -= format_seg( op, buf, len, xml_syntax );
                        len -= format_expr( &op->data.expression, buf, len,
                                     xml_syntax );

                        STRNCAT( buf, "\t\t</address_expression>\n", len );
                        break;

                case op_offset:

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

                        len -= format_seg( op, buf, len, xml_syntax );

                        STRNCAT( buf, "\t\t\t<address ", len);
                        STRNCATF( buf, "value=\"0x%08X\"/>\n",
                                          op->data.sdword, len );
                        STRNCAT( buf, "\t\t</segment_offset>\n", len );
                        break;

                case op_unused:
                case op_unknown:
                        /* return 0-truncated buffer */
                        break;
        }

        return( strlen( buf ) );
}
static int format_operand_native( x86_op_t *op, x86_insn_t *insn, char *buf,
                                  int len){

        char str[MAX_OP_STRING];

        switch (op->type) {
                case op_register:
                        STRNCAT( buf, op->data.reg.name, len );
                        break;

                case op_immediate:
                        get_operand_data_str( op, str, sizeof str );
                        STRNCAT( buf, str, len );
                        break;

                case op_relative_near:
                        STRNCATF( buf, "0x%08X",
                                  (unsigned int)(op->data.sbyte +
                                  insn->addr + insn->size), len );
                        break;

                case op_relative_far:
                        if ( op->datatype == op_word ) {
                                STRNCATF( buf, "0x%08X",
                                          (unsigned int)(op->data.sword +
                                          insn->addr + insn->size), len );
                                break;
                        } else {
                        	STRNCATF( buf, "0x%08X", op->data.sdword +
                                	  insn->addr + insn->size, len );
			}
                        break;

                case op_absolute:
                        STRNCATF( buf, "$0x%04hX" ":", op->data.absolute.segment,
				len );
			if (op->datatype == op_descr16) {
                        	STRNCATF( buf, "0x%04hX", 
					op->data.absolute.offset.off16, len );
			} else {
                        	STRNCATF( buf, "0x%08X", 
					op->data.absolute.offset.off32, len );
			}
                        break;

                case op_offset:
                        len -= format_seg( op, buf, len, native_syntax );
                        STRNCATF( buf, "[0x%08X]", op->data.sdword, len );
                        break;

                case op_expression:
                        len -= format_seg( op, buf, len, native_syntax );
                        len -= format_expr( &op->data.expression, buf, len,
                                     native_syntax );
                        break;
                case op_unused:
                case op_unknown:
                        /* return 0-truncated buffer */
                        break;
        }

        return( strlen( buf ) );
}
static int format_expr( x86_ea_t *ea, char *buf, int len,
                        enum x86_asm_format format ) {
        char str[MAX_OP_STRING];

        if ( format == att_syntax ) {
		if (ea->base.name[0] || ea->index.name[0] || ea->scale) {
               		PRINT_DISPLACEMENT(ea);
	                STRNCAT( buf, "(", len );

	                if ( ea->base.name[0]) {
	                        STRNCATF( buf, "%%%s", ea->base.name, len );
	                }
	                if ( ea->index.name[0]) {
	                        STRNCATF( buf, ",%%%s", ea->index.name, len );
	                        if ( ea->scale > 1 ) {
	                                STRNCATF( buf, ",%d", ea->scale, len );
	                        }
	                }
	                /* handle the syntactic exception */
	                if ( ! ea->base.name[0] &&
	                     ! ea->index.name[0]   ) {
	                        STRNCATF( buf, ",%d", ea->scale, len );
	                }

	                STRNCAT( buf, ")", len );
		} else
			STRNCATF( buf, "0x%X", ea->disp, len );

        } else if ( format == xml_syntax ){

                if ( ea->base.name[0]) {
                        STRNCAT (buf, "\t\t\t<base>\n", len);

                        get_operand_regtype_str (ea->base.type, str,
                                                 sizeof str);
                        STRNCAT (buf, "\t\t\t\t<register ", len);
                        STRNCATF (buf, "name=\"%s\" ", ea->base.name, len);
                        STRNCATF (buf, "type=\"%s\" ", str, len);
                        STRNCATF (buf, "size=%d/>\n", ea->base.size, len);

                        STRNCAT (buf, "\t\t\t</base>\n", len);
                }

                if ( ea->index.name[0]) {
                        STRNCAT (buf, "\t\t\t<index>\n", len);

                        get_operand_regtype_str (ea->index.type, str,
                                                 sizeof str);

                        STRNCAT (buf, "\t\t\t\t<register ", len);
                        STRNCATF (buf, "name=\"%s\" ", ea->index.name, len);
                        STRNCATF (buf, "type=\"%s\" ", str, len);
                        STRNCATF (buf, "size=%d/>\n", ea->index.size, len);

                        STRNCAT (buf, "\t\t\t</index>\n", len);
                }

                //scale
                STRNCAT (buf, "\t\t\t<scale>\n", len);
                STRNCAT (buf, "\t\t\t\t<immediate ", len);
                STRNCATF (buf, "value=\"%d\"/>\n", ea->scale, len);
                STRNCAT (buf, "\t\t\t</scale>\n", len);

                if ( ea->disp_size ) {

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

                        if ( ea->disp_size > 1 && ! ea->disp_sign ) {
                                STRNCAT (buf, "\t\t\t\t<address ", len);
                                STRNCATF (buf, "value=\"0x%X" "\"/>\n", ea->disp,
                                          len);
                        } else {
                                STRNCAT (buf, "\t\t\t\t<immediate ", len);
                                STRNCATF (buf, "value=%d" "/>\n", ea->disp, len);
                        }

                        STRNCAT (buf, "\t\t\t</displacement>\n", len);
                }

        } else if ( format == raw_syntax ) {

                PRINT_DISPLACEMENT(ea);
                STRNCAT( buf, "(", len );

                STRNCATF( buf, "%s,", ea->base.name, len );
                STRNCATF( buf, "%s,", ea->index.name, len );
                STRNCATF( buf, "%d", ea->scale, len );
                STRNCAT( buf, ")", len );

        } else {

                STRNCAT( buf, "[", len );

                if ( ea->base.name[0] ) {
                        STRNCAT( buf, ea->base.name, len );
                        if ( ea->index.name[0] ||
                             (ea->disp_size && ! ea->disp_sign) ) {
                                STRNCAT( buf, "+", len );
                        }
                }
                if ( ea->index.name[0] ) {
                        STRNCAT( buf, ea->index.name, len );
                        if ( ea->scale > 1 )
                        {
                                STRNCATF( buf, "*%d", ea->scale, len );
                        }
                        if ( ea->disp_size && ! ea->disp_sign )
                        {
                                STRNCAT( buf, "+", len );
                        }
                }

                if ( ea->disp_size || (! ea->index.name[0] && 
					! ea->base.name[0] ) )
                {
                        PRINT_DISPLACEMENT(ea);
                }

                STRNCAT( buf, "]", len );
        }

        return( strlen(buf) );
}
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);
}
static int format_raw_insn( x86_insn_t *insn, char *buf, int len ){
	struct op_string opstr = { buf, len };
        int i;

        /* RAW style:
         * ADDRESS|OFFSET|SIZE|BYTES|
         * PREFIX|PREFIX_STRING|GROUP|TYPE|NOTES|
	 * MNEMONIC|CPU|ISA|FLAGS_SET|FLAGS_TESTED|
	 * STACK_MOD|STACK_MOD_VAL
	 * [|OP_TYPE|OP_DATATYPE|OP_ACCESS|OP_FLAGS|OP]*
         *
         * Register values are encoded as:
         * NAME:TYPE:SIZE
         *
         * Effective addresses are encoded as:
         * disp(base_reg,index_reg,scale)
         */
        STRNCATF( buf, "0x%08X|", insn->addr  , len );
        STRNCATF( buf, "0x%08X|", insn->offset, len );
        STRNCATF( buf, "%d|"    , insn->size  , len );

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

        len -= format_insn_prefix_str( insn->prefix, buf, len );
        STRNCATF( buf, "|%s|", insn->prefix_string             , len );
        STRNCATF( buf, "%s|", get_insn_group_str( insn->group ), len );
        STRNCATF( buf, "%s|", get_insn_type_str( insn->type )  , len );
        STRNCATF( buf, "%s|", insn->mnemonic                   , len );
        STRNCATF( buf, "%s|", get_insn_cpu_str( insn->cpu )  , len );
        STRNCATF( buf, "%s|", get_insn_isa_str( insn->isa )  , len );

	/* insn note */
	len -= format_insn_note( insn, buf, len );

        len -= format_insn_eflags_str( insn->flags_set, buf, len );
        STRNCAT( buf, "|", len );
        len -= format_insn_eflags_str( insn->flags_tested, buf, len );
        STRNCAT( buf, "|", len );
        STRNCATF( buf, "%d|", insn->stack_mod, len );
        STRNCATF( buf, "%d|", insn->stack_mod_val, len );

	opstr.len = len;
	x86_operand_foreach( insn, format_op_raw, &opstr, op_any );

        return( strlen (buf) );
}
示例#9
0
static int format_operand_raw( x86_op_t *op, x86_insn_t *insn, char *buf,
                               int len) {

    char str[MAX_OP_RAW_STRING];
    char *datatype = get_operand_datatype_str(op);

    switch (op->type) {
    case op_register:

        get_operand_regtype_str( op->data.reg.type, str,
                                 sizeof str );

        STRNCAT( buf, "reg|", len );
        STRNCATF( buf, "%s|", datatype, len );
        STRNCATF( buf, "%s:", op->data.reg.name, len );
        STRNCATF( buf, "%s:", str, len );
        STRNCATF( buf, "%d|", op->data.reg.size, len );
        break;

    case op_immediate:

        get_operand_data_str( op, str, sizeof str );

        STRNCAT( buf, "immediate|", len );
        STRNCATF( buf, "%s|", datatype, len );
        STRNCATF( buf, "%s|", str, len );
        break;

    case op_relative_near:

        STRNCAT( buf, "relative|", len );
        STRNCATF( buf, "%s|", datatype, len );
        STRNCATF( buf, "%08X|",
                  (unsigned int)(op->data.sbyte +
                                 insn->addr + insn->size), len );
        break;

    case op_relative_far:

        STRNCAT( buf, "relative|", len );
        STRNCATF( buf, "%s|", datatype, len );

        if (op->datatype == op_word) {
            STRNCATF( buf, "%08X",
                      (unsigned int)(op->data.sword +
                                     insn->addr + insn->size), len);
            break;
        } else {
            STRNCATF( buf, "%08lX|",
                      op->data.sdword + insn->addr + insn->size,
                      len );
        }
        break;

    case op_absolute:

        STRNCAT( buf, "absolute_address|", len );
        STRNCATF( buf, "%s|", datatype, len );

        len -= format_seg( op, buf, len, native_syntax );

        STRNCATF( buf, "%08lX|", op->data.sdword, len );

        break;

    case op_expression:

        STRNCAT( buf, "address_expression|", len );
        STRNCATF( buf, "%s|", datatype, len );

        len -= format_seg( op, buf, len, native_syntax );
        len -= format_expr( &op->data.expression, buf, len,
                            raw_syntax );

        STRNCAT( buf, "|", len );
        break;

    case op_offset:

        STRNCAT( buf, "segment_offset|", len );
        STRNCATF( buf, "%s|", datatype, len );

        len -= format_seg( op, buf, len, xml_syntax );

        STRNCATF( buf, "%08lX|", op->data.sdword, len );
        break;

    case op_unused:
    case op_unknown:
        /* return 0-truncated buffer */
        break;
    }

    return( strlen( buf ) );
}
示例#10
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 ) );
}