Пример #1
0
/*
op_t get_first_operand(FILE *f, ea_t addr)
{
	char buf[MAXSTR];
	char instr_clean[MAXSTR];
	// Store the disassembled text in buf
	ua_ana0(addr);
	generate_disasm_line(cmd.ea, buf, sizeof(buf)-1);
	// This will appear as colour-tagged text (which will
	// be mostly unreadable in IDA's
	tag_remove(buf, instr_clean, sizeof(instr_clean)-1);
	//qfprintf(f,"get_first_operand disasm instruction: %s\n", instr_clean);

	for(int i = 0; cmd.Operands[i].type != o_void; i++){
		qfprintf(f,"operand number %d, type %d, reg %d, phrase %d, value %a, addr %a\n", i, cmd.Operands[i].type,cmd.Operands[i].reg,
			cmd.Operands[i].phrase,cmd.Operands[i].value, cmd.Operands[i].addr);
		//if(cmd.Operands[i].type == o_reg) return cmd.Operands[i];
	}	
	return cmd.Operands[0];
	
}
*/
op_t get_first_operand_new(ea_t addr)
{
	ua_ana0(addr);

	return cmd.Operands[0];
	
}
Пример #2
0
//TODO: better algo of course!!!
//By now - it's full os shitty false positives
int assign_type(ea_t address, int *value)
{
	flags_t flags = getFlags(address);
	if (isHead(flags) && isCode(flags))
	{
		ua_ana0(address);

		if(cmd.itype == NN_mov)
			if(cmd.Operands[1].type == o_imm){
				*value = cmd.Operands[1].value;
				return CONSTVALUE;
			}
			else
				return VARVALUE;

		return VARVALUEVULN;

	}
	else{
		return UNDEFINED;
	}

	return UNDEFINED;

}
Пример #3
0
Register
parse_pointer (ea_t ea, int operand, ea_t &offset)
{
  ua_ana0(ea);
  if (cmd.Operands[operand].type != o_displ)
	  return REGISTER_UNSET;
  offset = cmd.Operands[operand].addr;
  return cmd.Operands[operand].reg;
}
Пример #4
0
//TODO: this is not a f*****g smart function! this is total crap!!!
//TODO: kill locating algo by function, Cause there a lot of places, where IDA f*****g sucks, and dont understand bounds of function!!!!
//replace by discovery up by the tree
ea_t find_instruction_that_changes_operand_backward_smart(ea_t start, op_t operand)
{
	func_t *f = get_func(start);
	char buf[MAXSTR];
	char instr_clean[MAXSTR];
	if(f)
	{
		ea_t addr = prev_head(start, f->startEA);
		while (addr != BADADDR)
		{
			flags_t flags = getFlags(addr);
			if (isHead(flags) && isCode(flags))
			{
				ua_ana0(addr);
				switch(cmd.itype){	
					case NN_lea:
					case NN_pop:
					case NN_shl:
					case NN_shr:					
					case NN_sal:
					case NN_sar:				
					case NN_imul:
					case NN_mul:
					case NN_idiv:
					case NN_div:
					case NN_xor:
					case NN_or:
					case NN_not:
					case NN_neg:
					case NN_inc:
					case NN_dec:
					case NN_add:
					case NN_sub:
					case NN_mov:
					case NN_movsx:
					case NN_movzx:{
						for(int i = 0; cmd.Operands[i].type != o_void; i++){
							if((cmd.Operands[i].type == operand.type) && (cmd.Operands[i].reg == operand.reg)){
								return addr;
							}

					}break;
					default:break;
				}
				}

			}
			addr = prev_head(addr, f->startEA);
		}
	}
	return BADADDR;
}
Пример #5
0
//--------------------------------------------------------------------------
void load_file(linput_t *li, ushort /*neflag*/, const char * /*fileformatname*/)
{
  header h;
  qlseek(li, 0);
  lread(li, &h, sizeof(h));
  h.swap();
  if ( ph.id != PLFM_HPPA ) set_processor_type("hppa", SETPROC_ALL|SETPROC_FATAL);
  inf.baseaddr = 0;

  load_aux_headers(li, h.aux_header_location, h.aux_header_size);
  load_spaces(li, h, h.space_location, h.space_total);
  load_subspaces(li, h, h.subspace_location, h.subspace_total);
  load_symbols(li, h, h.symbol_location, h.symbol_total);
  load_dl_header(li);
  create_filename_cmt();

  ulong dp = h.presumed_dp;
  if ( dp == 0 )
  {
//  23 61 28 00   ldil            ...., %dp
//  37 7B 01 60   ldo             0xB0(%dp), %dp
    if ( ua_ana0(inf.startIP) && cmd.Op1.type == o_imm && cmd.Op2.type == o_reg )
    {
      ulong v = cmd.Op1.value;
      if ( ua_ana0(cmd.ea+4) && cmd.Op1.type == o_displ )
        dp = v + cmd.Op1.addr;
    }
  }

  if ( dp != 0 )
  {
    netnode n;
    n.create("$ got");
    n.altset(0, dp+1);
  }

  add_til("hpux");

}
Пример #6
0
char get_byte_with_optimization(ea_t ea)
{
	switch (patchdiff_cpu)
	{
	case CPU_X8632:
	case CPU_X8664:
		return x86_get_byte(ea);
	case CPU_PPC:
		return ppc_get_byte(ea);
	default:
		{
			ua_ana0(ea);
			return (char)cmd.itype;
		}
	}
}
Пример #7
0
ea_t find_instruction_backward(ea_t start, uint16 itype)
{
	func_t *f = get_func(start);
	if(f)
	{
		ea_t addr = prev_head(start, f->startEA);
		while (addr != BADADDR)
		{
			flags_t flags = getFlags(addr);
			if (isHead(flags) && isCode(flags))
			{
				ua_ana0(addr);
				if(cmd.itype == itype)return addr;

			}
			addr = prev_head(addr, f->startEA);
		}
	}
	return BADADDR;
}
Пример #8
0
void pretty_printing_ex(FILE* f, TFuncMalloc func)
{

	func_t *callee_func;
	qstring name_of_malloc_callee_function;
	int func_name_set = 0;


	for(int i = 0; i < Malloc_calls.size(); i++){
		qfprintf(f,"\r\n");
		callee_func = get_func(Malloc_calls[i].address);
		func_name_set = 0;

		if(callee_func){
			func_name_set = 1;
			get_short_name(&name_of_malloc_callee_function, callee_func->startEA);
			//generate_disasm_line(callee_func->startEA, name_of_malloc_callee_function, sizeof(name_of_malloc_callee_function));
			//tag_remove(name_of_malloc_callee_function, name_of_malloc_callee_function, sizeof(name_of_malloc_callee_function));
		}

		if(func_name_set)
			qfprintf(f,"%s xref: at %a %s\n", func.alloc_func_name, Malloc_calls[i].address, name_of_malloc_callee_function.c_str());
		else
			qfprintf(f,"%s xref: at %a %s\n", func.alloc_func_name, Malloc_calls[i].address, "CISSRT_undefined_function");
		

		if(Malloc_calls[i].type == CONSTVALUE){
			qfprintf(f,"Type: CONST = %d Malloc bytes\n", Malloc_calls[i].value);
		}

		if(Malloc_calls[i].type == VARVALUE){
			char buffer[MAXSTR];
			//char instr_clean[MAXSTR];
			// Store the disassembled text in buf
			ua_ana0(Malloc_calls[i].address_of_last_size_object_modified);

			generate_disasm_line(cmd.ea, buffer, sizeof(buffer));
			tag_remove(buffer, buffer, sizeof(buffer));

			if(Malloc_calls[i].address_of_last_size_object_modified != BADADDR)
				qfprintf(f,"Type: VAR, last modif at %a %s\n", Malloc_calls[i].address_of_last_size_object_modified, buffer);
			else
				qfprintf(f,"Type: VAR, last modif lost :( \n");
			//qfprintf(f,"last modif: \n", instr_clean);			
		}

		if(Malloc_calls[i].type == VARVALUEVULN){
			char buffer[MAXSTR];
			//char instr_clean[MAXSTR];
			// Store the disassembled text in buf
			ua_ana0(Malloc_calls[i].address_of_last_size_object_modified);

			generate_disasm_line(cmd.ea, buffer, sizeof(buffer));
			tag_remove(buffer, buffer, sizeof(buffer));

			//qfprintf(f,"get_first_operand disasm instruction: %s\n", instr_clean);
			if(Malloc_calls[i].address_of_last_size_object_modified != BADADDR)
				qfprintf(f,"Type: VAR, Possible Integer Overflow %a %s\n", Malloc_calls[i].address_of_last_size_object_modified, buffer);
			else
				qfprintf(f,"Type: VAR, last modif lost :( \n");//shouldnt be here
		}

		if(Malloc_calls[i].type == UNDEFINED){
			char buffer[MAXSTR];
			// Store the disassembled text in buf
			ua_ana0(Malloc_calls[i].address_of_last_size_object_modified);

			generate_disasm_line(cmd.ea, buffer, sizeof(buffer));
			tag_remove(buffer, buffer, sizeof(buffer));

			//qfprintf(f,"get_first_operand disasm instruction: %s\n", instr_clean);
			if(Malloc_calls[i].address_of_last_size_object_modified != BADADDR)
				qfprintf(f,"Type: UNDEFINED, at %a %s", Malloc_calls[i].address_of_last_size_object_modified, buffer);//shouldnt be here
			else
				qfprintf(f,"Type: UNDEFINED, last modif lost :(");
		}
	}

}
Пример #9
0
void pretty_printing_ex(FILE* f, TFuncMallocWrapper func)
{
	func_t *callee_func;
	qstring name_of_malloc_callee_function;
	int func_name_set = 0;

	for(int i = 0; i < Malloc_calls.size(); i++){
		//qfprintf(f,"%s ----> %s xref: at %a \n", func.alloc_func_name, func.ancestor, Malloc_calls[i].address);
		qfprintf(f,"\r\n");
		callee_func = get_func(Malloc_calls[i].address);
		func_name_set = 0;

		if(callee_func){
			func_name_set = 1;
			get_short_name(&name_of_malloc_callee_function, callee_func->startEA);
			//generate_disasm_line(callee_func->startEA, name_of_malloc_callee_function, sizeof(name_of_malloc_callee_function));
			//tag_remove(name_of_malloc_callee_function, name_of_malloc_callee_function, sizeof(name_of_malloc_callee_function));
		}

		if(func_name_set)
			qfprintf(f,"%s argNumber = %d ----> %s xref: at %a %s\n", func.alloc_func_name, func.push_malloc_size_count, func.ancestor, Malloc_calls[i].address, name_of_malloc_callee_function.c_str());
		else
			qfprintf(f,"%s argNumber = %d ----> %s xref: at %a %s\n", func.alloc_func_name, func.push_malloc_size_count, func.ancestor, Malloc_calls[i].address, "CISSRT_undefined_function");
			//qfprintf(f,"%s xref: at %a %s\n", func.alloc_func_name, Malloc_calls[i].address, "CISSRT_undefined_function");


		if(Malloc_calls[i].type == CONSTVALUE){
			qfprintf(f,"Type: CONST = %d Malloc bytes\n", Malloc_calls[i].value);
		}
		else if(Malloc_calls[i].type == VARVALUE){
			char buf[MAXSTR];
			char instr_clean[MAXSTR];
			// Store the disassembled text in buf
			ua_ana0(Malloc_calls[i].address_of_last_size_object_modified);
			generate_disasm_line(cmd.ea, buf, sizeof(buf)-1);
			// This will appear as colour-tagged text (which will
			// be mostly unreadable in IDA's
			tag_remove(buf, instr_clean, sizeof(instr_clean)-1);
			if(Malloc_calls[i].address_of_last_size_object_modified != BADADDR)
				qfprintf(f,"Type: VAR, last modif at %a %s\n", Malloc_calls[i].address_of_last_size_object_modified, instr_clean);
			else
				qfprintf(f,"Type: VAR, last modif lost :(");
			//qfprintf(f,"last modif: %s\n", instr_clean);			
		}
		else if(Malloc_calls[i].type == VARVALUEVULN){
			char buf[MAXSTR];
			char instr_clean[MAXSTR];
			// Store the disassembled text in buf
			ua_ana0(Malloc_calls[i].address_of_last_size_object_modified);
			generate_disasm_line(cmd.ea, buf, sizeof(buf)-1);
			// This will appear as colour-tagged text (which will
			// be mostly unreadable in IDA's
			tag_remove(buf, instr_clean, sizeof(instr_clean)-1);
			//qfprintf(f,"get_first_operand disasm instruction: %s\n", instr_clean);
			if(Malloc_calls[i].address_of_last_size_object_modified != BADADDR)
				qfprintf(f,"Type: VAR, Possible Integer Overflow at %a %s\n", Malloc_calls[i].address_of_last_size_object_modified, instr_clean);
			else
				qfprintf(f,"Type: VAR, last modif lost :(");
		}
		else if(Malloc_calls[i].type == UNDEFINED){
			char buf[MAXSTR];
			char instr_clean[MAXSTR];
			// Store the disassembled text in buf
			ua_ana0(Malloc_calls[i].address_of_last_size_object_modified);
			generate_disasm_line(cmd.ea, buf, sizeof(buf)-1);
			// This will appear as colour-tagged text (which will
			// be mostly unreadable in IDA's
			tag_remove(buf, instr_clean, sizeof(instr_clean)-1);
			//qfprintf(f,"get_first_operand disasm instruction: %s\n", instr_clean);

			//qfprintf(f,"Type:var bytes, Possible Integer Overflow at %a %s\n", Malloc_calls[i].address_of_last_size_object_modified, instr_clean);
			if(Malloc_calls[i].address_of_last_size_object_modified != BADADDR)
				qfprintf(f,"Type: UNDEFINED, at %a %s", Malloc_calls[i].address_of_last_size_object_modified, instr_clean);//shouldnt be here
			else
				qfprintf(f,"Type: UNDEFINED, last modif lost :(");
		}
	}
}
Пример #10
0
int is_trampoline(ea_t address)
{
	ua_ana0(address);
	if(cmd.itype == NN_jmp)return 1;
	return 0;
}
Пример #11
0
int PPCHelper_ConvertFunction(func_t* pFunc)
{
	ea_t start = pFunc->startEA;
	ea_t end = pFunc->endEA;
//	struc_t* p_frame = get_frame(pFunc);
	
	const int MAX_REGS = 32;
	bool is_reg_saved[MAX_REGS];	// r0 - r31
	for(int i=0; i<MAX_REGS; i++)
		is_reg_saved[i] = false;
	bool is_arg_saved[MAX_REGS];	// r0 - r31
	for(int i=0; i<MAX_REGS; i++)
		is_arg_saved[i] = false;
	
	// process function from start to end
	for(ea_t ea=start; ea<end; ea+=4)
	{
		// get mnemonic
		char mnem[256];
		if( !ua_mnem(ea, mnem, sizeof(mnem)) )
			return false;
		tag_remove(mnem, mnem, sizeof(mnem));
		char* ptr = (char*)qstrstr(mnem, ".");
		if(ptr) *ptr = 0;
		// prepare cmd struct for this address
		ua_ana0(ea);
		// fix mnemonic for "bl"
		if( cmd.itype == 13 && (cmd.auxpref & 8) )
		{
			qstrncpy(mnem, "bl", sizeof(mnem));
		}
		// fix mnemonic for "blr"
		else if( cmd.itype == 320 && cmd.auxpref == 0x500 )
		{
			qstrncpy(mnem, "blr", sizeof(mnem));
		}
		

		// handle register saving
		if( (!qstrcmp(mnem, "stdu") || !qstrcmp(mnem, "std")) &&
			cmd.Op1.type == o_reg &&
			cmd.Op2.type == o_displ &&
			!is_reg_saved[cmd.Op1.reg] &&
			cmd.Op2.reg == 1 ) // 1 == "sp"
		{
			int src_reg = cmd.Op1.reg;
			int offset  = cmd.Op2.addr;
			int dst_reg = cmd.Op2.reg;
			char name[256];
			if( src_reg == 0 )
				qsnprintf(name, sizeof(name), "save_lr");
			else if( src_reg == 1 )
				qsnprintf(name, sizeof(name), "save_sp");
			else
				qsnprintf(name, sizeof(name), "save_r%d", src_reg);
			add_stkvar2(pFunc, name, offset, 0, NULL, 0);
			is_reg_saved[cmd.Op1.reg] = true;
			//msg("%08X : stdu %%r%d, %d(%%r%d)\n", (unsigned int)ea, src_reg, offset, dst_reg);
		}

		// handle arg saving
		else if( !qstrcmp(mnem, "mr") &&
			cmd.Op1.type == o_reg &&
			cmd.Op2.type == o_reg &&
			!is_arg_saved[cmd.Op2.reg] &&
			cmd.Op2.reg >= 3 )	// args begin at r3
		{
			int dst_reg = cmd.Op1.reg;
			int src_reg = cmd.Op2.reg;
			char canon[256];
			qsnprintf(canon, sizeof(canon), "%%r%d", dst_reg);
			char name[256];
			qsnprintf(name, sizeof(name), "arg%d", src_reg-3);
			add_regvar(pFunc, start, end, canon, name, NULL);
			is_arg_saved[cmd.Op2.reg] = true;
			//msg("%08X : mr   %%r%d, %%r%d\n", (unsigned int)ea, dst_reg, src_reg);
		}

		// if a function is called, then no more args can be saved
		else if( !qstrcmp(mnem, "bl") )
		{
			break;
		}
	}
	
	// process function from start to end
	msg("processing end to start (%08X to %08X)  -  %d\n", (unsigned int)end, (unsigned int)start, PPC_balways);
	bool is_in_return_point = false;
	for(ea_t ea=end-4; ea>start; ea-=4)
	{
		// get mnemonic
		char mnem[256];
		if( !ua_mnem(ea, mnem, sizeof(mnem)) )
			return false;
		tag_remove(mnem, mnem, sizeof(mnem));
		char* ptr = (char*)qstrstr(mnem, ".");
		if(ptr) *ptr = 0;
		// prepare cmd struct for this address
		ua_ana0(ea);
		// fix mnemonic for "bl"
		if( cmd.itype == 13 && (cmd.auxpref & 8) )
		{
			qstrncpy(mnem, "bl", sizeof(mnem));
		}
		// fix mnemonic for "blr"
		else if( cmd.itype == 320 && cmd.auxpref == 0x500 )
		{
			qstrncpy(mnem, "blr", sizeof(mnem));
		}
//			msg("%08X: %3s  inst_type = %d,  insgpref = %d,  segpref = %d,  auxpref = %d\n", (unsigned int)ea, mnem, cmd.itype, cmd.segpref, cmd.insnpref, cmd.auxpref);

			//qstrncpy(mnem, "bl", sizeof(mnem));
/*			msg("%08X: %s  %d %d %d (%d %d %d %d) (%d %d %d %d) (%d %d %d %d)  : %X %X %X  : %X %X %X  : %X %X %X  : %X %X %X  : %X %X %X  : %X %X %X\n",
			(unsigned int)ea, mnem, cmd.Op1.type, cmd.Op2.type, cmd.Op3.type,
			cmd.Op1.specflag1, cmd.Op1.specflag2, cmd.Op1.specflag3, cmd.Op1.specflag4,
			cmd.Op2.specflag1, cmd.Op2.specflag2, cmd.Op2.specflag3, cmd.Op2.specflag4,
			cmd.Op3.specflag1, cmd.Op3.specflag2, cmd.Op3.specflag3, cmd.Op3.specflag4,
			(unsigned int)cmd.Op1.specval, (unsigned int)cmd.Op2.specval, (unsigned int)cmd.Op3.specval,
			(unsigned int)cmd.Op1.addr, (unsigned int)cmd.Op2.addr, (unsigned int)cmd.Op3.addr,
			(unsigned int)cmd.Op1.value, (unsigned int)cmd.Op2.value, (unsigned int)cmd.Op3.value,
			(unsigned int)cmd.Op1.reg, (unsigned int)cmd.Op2.reg, (unsigned int)cmd.Op3.reg,
			(unsigned int)cmd.Op1.dtyp, (unsigned int)cmd.Op2.dtyp, (unsigned int)cmd.Op3.dtyp,
			(unsigned int)cmd.Op1.flags, (unsigned int)cmd.Op2.flags, (unsigned int)cmd.Op3.flags);
		}
*/		
		
		// if found a function return point, then look above for return register
		if( !qstrcmp(mnem, "blr") )
		{
			is_in_return_point = true;
			//msg("%08X return point end\n", (unsigned int)ea);
		}
		
		// if a function is called, thenit is no longer in the return point
		else if( !qstrcmp(mnem, "bl") )
		{
			is_in_return_point = false;
			//msg("%08X return point start\n", (unsigned int)ea);
		}

		// look for possible return register
		else if( is_in_return_point &&
			!qstrcmp(mnem, "mr") &&
			cmd.Op1.type == o_reg &&
			cmd.Op2.type == o_reg &&
			cmd.Op1.reg == 3 )	// return value is in r3
		{
			int dst_reg = cmd.Op1.reg;
			int src_reg = cmd.Op2.reg;
			char canon[256];
			qsnprintf(canon, sizeof(canon), "%%r%d", src_reg);
			add_regvar(pFunc, start, end, canon, "ret", NULL);
			//msg("%08X return register\n", (unsigned int)ea);
		}
	}

	// analyse area to refresh any changes
	analyze_area(start, end);
	return 0;
}
Пример #12
0
/* main workhorse */
void
process_PIC(ea_t from, ea_t to)
{
  int size;
  flags_t flag;
  dref_t dtype;
  bool has_PIC_init = false;
/***********************************************************\
 * Also we trace three special cases:
 * 1. Raw (not recognized ed by IDA) PIC prolog.
 *   call $+5
 *   pop ebx <-- fake_addr
 *   ... one or more non related with ebx instr
 *   add ebx, offset_to_GOT
 * 2. Switch stmt
 * a) with known size N
 *   cmp reg1, N
 *   ja ...
 *   mov reg2, ebx
 *   sub reg2, [ebx+reg1*4+offset]
 *   jmp reg2
 * b) more general but size is unknown
 *   mov reg1, ebx
 *   sub reg1, [ebx+regX*4+offset]
 *   jmp reg1
 * 3. On UnixWare 7 UDK C compiler produced prolog
 *  jmp end_of_function
 * main_function_body:
 *  ...
 * end_of_function:
 *  prolog like 1)
 *  jmp main_function_body
\***********************************************************/
  int first_case = 0;
  ea_t fake_addr = 0;
  ea_t pic_to = 0;
  int second_case = 0;
  int reg1 = pic_reg, reg2, N = 0, offset;
  int second_caseB = 0;

  int there_jump = 0, from_jump, to_jump;

#ifdef PIC_DEBUG
  RP_TRACE1("start %X\n", from);
  RP_TRACE1("end %X\n", to);
#endif
  for ( ea_t a = from; a < to; )
  {
     flag = getFlags(a);
     if ( !isCode(flag) )
     {
       a++;
       continue;
     }
     size = ua_ana0(a);
#define PIC_CONT	a += size; continue;
     if ( !size )
     {
       warning("Bad instruction at %X", a);
       a++;
       continue;
     }
#ifdef PIC_SHOW
 report_instr(a);
#endif
     if ( !has_PIC_init )
     {
        if ( !there_jump )
        {
          if ( cmd.itype == Ix86_jmp &&
	       ( cmd.Op1.type == o_near || cmd.Op1.type == o_far ) &&
	       cmd.Op1.addr < to &&
	       cmd.Op1.addr > a )
	  {
	    from_jump = a + size;
	    there_jump = 1;
	    to_jump = a = cmd.Op1.addr;
#ifdef PIC_DEBUG
 RP_TRACE2("from_jump %X, to_jump %X\n", from_jump, to_jump);
#endif
	    continue;
	  }
          there_jump = -1;
        }
        if ( !first_case && is_gotbase() )
        {
          first_case = 2;
          fake_addr = a + size;
          PIC_CONT;
        }
        if ( first_case )
          switch(first_case)
          {
             case 1:
               if ( cmd.itype == Ix86_pop &&
                    cmd.Op1.type == o_reg &&
                    cmd.Op1.reg == pic_reg )
               {
                 first_case = 2;
#ifdef PIC_DEBUG
 RP_TRACE("first case 2\n");
#endif
               } else
               {
                 if ( is_change_stack(&cmd) )
		 {
                   first_case = 0;
                 } else
	 	 {
		   PIC_CONT;
		 }
               }
                break;
             case 2:
               if ( cmd.itype == Ix86_add  &&
	            cmd.Op1.type == 1	   &&
		    cmd.Op1.reg == pic_reg &&
		    cmd.Op2.type == o_imm )
	       {
		  pic_to = fake_addr + cmd.Op2.value;
	          if ( (pic_to != got_addr) &&
                       (pic_to != got_plt_addr)
                     )
	            warning("Strange PIC prolog at %X, points to %X", a, pic_to);
#ifdef PIC_DEBUG
 RP_TRACE("PIC_init 1\n");
#endif
		  pic_add_dref(a, pic_to, dr_O, cmd.Op2.dtyp);
                  has_PIC_init = true;
                  first_case = 0;
	       }
	       if ( is_change_PIC_reg(&cmd) )
	       {
	          first_case = 0;
     	       }
                break;
          }
        if ( first_case || has_PIC_init )
        {
          PIC_CONT;
        }
        if ( cmd.itype == Ix86_mov	&&
             cmd.Op1.type == o_reg	&&
             cmd.Op1.reg == pic_reg	&&
             cmd.Op2.type == o_imm 	&&
             cmd.Op2.value == got_addr )
        {
          has_PIC_init = true;
#ifdef PIC_DEBUG
 RP_TRACE("PIC_init 2\n");
#endif
          PIC_CONT;
        }
        if ( cmd.itype == Ix86_call &&
             cmd.Op1.type == o_near &&
             cmd.Op1.addr == a + 5 )
        {
          first_case = 1;
          fake_addr = a + size;
#ifdef PIC_DEBUG
 RP_TRACE("first_case 1\n");
#endif
          PIC_CONT;
        }
       PIC_CONT;
     } /* not prolog yet */
     if ( there_jump == 1 &&
	  cmd.itype == Ix86_jmp &&
	  ( cmd.Op1.type == o_near || cmd.Op1.type == o_far ) &&
	  cmd.Op1.addr < to &&
	  cmd.Op1.addr < a  &&
	  cmd.Op1.addr >= from_jump )
     {
       there_jump = 2;
       a = from_jump;
       to = to_jump;
       continue;
     }
     if ( second_case )
       switch(second_case)
       {
         case 1:
          if ( cmd.itype == Ix86_ja &&
	       (cmd.Op1.type == o_far || cmd.Op1.type == o_near) )
	  {
#ifdef PIC_DEBUG
 RP_TRACE("second_case 2\n");
#endif
	    second_case = 2;
	  } else
	  {
	    second_case = 0;
	  }
           break;
         case 2:
          if ( cmd.itype == Ix86_mov	  &&
	       cmd.Op1.type == o_reg 	  &&
	       cmd.Op2.type == o_reg	  &&
	       cmd.Op2.reg == pic_reg )
	  {
	     reg2 = cmd.Op1.reg;
#ifdef PIC_DEBUG
 RP_TRACE("second_case 3\n");
#endif
	     second_case = 3;
	  } else
	  {
   	     second_case = 0;
	  }
	   break;
         case 3:
          if ( cmd.itype == Ix86_sub   &&
	       cmd.Op1.type == o_reg   &&
	       cmd.Op1.reg == reg2     &&
	       cmd.Op2.type == o_displ &&
	       cmd.Op2.specflag1 == 1  &&
	       get_SIB_base(cmd.Op2.specflag2) == pic_reg	&&
	       get_SIB_reg(cmd.Op2.specflag2) == reg1		&&
	       get_SIB_SS(cmd.Op2.specflag2) == 2 ) /* wow! sub reg2, [pic_reg+reg1*4+offset] */
	  {
	     offset = cmd.Op2.addr;
	     pic_add_dref(a, pic_to + offset, dr_O, cmd.Op2.dtyp);
#ifdef PIC_DEBUG
 RP_TRACE("second_case 4\n");
#endif
	     second_case = 4;
	  } else
	  {
#ifdef PIC_DEBUG
 RP_TRACE5("%d <-> %d, %d <-> %d, %d\n",
  get_SIB_base(cmd.Op2.specflag2), pic_reg,
  get_SIB_reg(cmd.Op2.specflag2), reg1,
  get_SIB_SS(cmd.Op2.specflag2) );
#endif
	     second_case = 0;
	  }
	   break;
         case 4:
          if ( cmd.itype == Ix86_jmpni &&
	       cmd.Op1.type == o_reg &&
	       cmd.Op1.reg == reg2 )
	  {
#ifdef PIC_DEBUG
 RP_TRACE2("second_case: %d from %X\n", N, (got_addr + offset) );
#endif
	     process_switchA(a+size, pic_to + offset, N);
	     second_case = 0;
	     PIC_CONT;
	  } else
	  {
	     second_case = 0;
	  }
	   break;
       }
       if ( second_case )
       {
         PIC_CONT;
       }
       if ( cmd.itype == Ix86_cmp &&
	    cmd.Op1.type == o_reg &&
	    cmd.Op2.type == o_imm )
       {
          second_case = 1;
          reg1 = cmd.Op1.reg;
          N = cmd.Op2.value;
          PIC_CONT;
       }
       /* check for 2b case */
       if ( second_caseB )
        switch(second_caseB)
        {
          case 1:
           if ( cmd.itype == Ix86_sub   &&
		cmd.Op1.type == o_reg   &&
		cmd.Op1.reg == reg1     &&
	 	cmd.Op2.type == o_displ	&&
                cmd.Op2.specflag1 == 1	&&
		get_SIB_base(cmd.Op2.specflag2) == pic_reg &&
		get_SIB_reg(cmd.Op2.specflag2) != pic_reg  &&
		get_SIB_SS(cmd.Op2.specflag2) == 2 )
	   {
	     offset = cmd.Op2.addr;
	     second_caseB = 2;
#ifdef PIC_DEBUG
 RP_TRACE("second_caseB is 2\n");
#endif
	   } else
	   {
#ifdef PIC_DEBUG
 RP_TRACE5("%d <-> %d, %d <-> %d, %d\n",
  get_SIB_base(cmd.Op2.specflag2), pic_reg,
  get_SIB_reg(cmd.Op2.specflag2), reg1,
  get_SIB_SS(cmd.Op2.specflag2) );
#endif
	     second_caseB = 0;
	   }
            break;
          case 2:
	   if ( cmd.itype == Ix86_jmpni &&
	        cmd.Op1.type == o_reg &&
	        cmd.Op1.reg == reg1 )
	   {
#ifdef PIC_DEBUG
 RP_TRACE1("second_caseB: from %X\n", (got_addr + offset) );
#endif
	     process_switchB(a+size, pic_to + offset, to);
	     second_caseB = 0;
	     PIC_CONT;
	   } else
	   {
	     second_caseB = 0;
	   }
            break;
        } /* second_caseB switch */
       if ( cmd.itype == Ix86_mov &&
            cmd.Op1.type == o_reg &&
            cmd.Op2.type == o_reg &&
            cmd.Op2.reg == pic_reg )
       {
          second_caseB = 1;
          reg1 = cmd.Op1.reg;
#ifdef PIC_DEBUG
 RP_TRACE("second_caseB is 1\n");
#endif
          PIC_CONT; /* ?? we anyway don`t deal with such instruction... */
       }
       /* no more special cases... */
       /* check for 1st operand for pic_reg */
       if ( cmd.Op1.type == o_displ )
       {
         if ( cmd.Op1.phrase == pic_reg  &&
	      ! cmd.Op1.specflag1 )
	 {
           fake_addr = 0;
           if ( exists_addr(&cmd.Op1) )
             fake_addr = cmd.Op1.addr;
	   dtype = get_dreftype_op1(&cmd);
	   pic_add_dref(a, pic_to + fake_addr, dtype, cmd.Op1.dtyp);
#ifdef PIC_DEBUG
 RP_TRACE1("PIC: %X\n", got_addr + fake_addr);
#endif
           PIC_CONT;
         }
         if ( cmd.Op1.specflag1 == 1 && (
             ( get_SIB_base(cmd.Op1.specflag2) == pic_reg  &&
               get_SIB_reg(cmd.Op1.specflag2) != pic_reg ) 	||
             ( get_SIB_base(cmd.Op1.specflag2) != pic_reg  &&
               get_SIB_reg(cmd.Op1.specflag2) == pic_reg   &&
               get_SIB_SS(cmd.Op1.specflag2) == 0 ) ) )
         {
            fake_addr = 0;
            if ( exists_addr(&cmd.Op1) )
              fake_addr = cmd.Op1.addr;
	    dtype = get_dreftype_op1(&cmd);
	    pic_add_dref(a, pic_to + fake_addr, dtype, cmd.Op1.dtyp);
#ifdef PIC_DEBUG
 RP_TRACE1("PIC: %X\n", got_addr + fake_addr);
#endif
            PIC_CONT;
         }
       }
       /* check for 2nd operand for pic_reg */
       if ( cmd.Op2.type == o_displ )
       {
         if ( cmd.Op2.phrase == pic_reg  &&
	      ! cmd.Op2.specflag1 )
	 {
           fake_addr = 0;
           if ( exists_addr(&cmd.Op2) )
             fake_addr = cmd.Op2.addr;
	   pic_add_dref(a, pic_to + fake_addr, get_dreftype_op2(&cmd), cmd.Op2.dtyp);
#ifdef PIC_DEBUG
 RP_TRACE1("PIC: %X\n", got_addr + fake_addr);
#endif
           PIC_CONT;
         }
         if ( cmd.Op2.specflag1 == 1 && (
             ( get_SIB_base(cmd.Op2.specflag2) == pic_reg  &&
               get_SIB_reg(cmd.Op2.specflag2) != pic_reg ) 	||
             ( get_SIB_base(cmd.Op2.specflag2) != pic_reg  &&
               get_SIB_reg(cmd.Op2.specflag2) == pic_reg   &&
               get_SIB_SS(cmd.Op2.specflag2) == 0 ) ) )
         {
            fake_addr = 0;
            if ( exists_addr(&cmd.Op2) )
              fake_addr = cmd.Op2.addr;
#ifdef PIC_DEBUG
 RP_TRACE1("PIC: %X\n", got_addr + fake_addr);
#endif      
	    pic_add_dref(a, pic_to + fake_addr, get_dreftype_op2(&cmd), cmd.Op2.dtyp);
            PIC_CONT;
         }
       }
     a += size;
  }
}
Пример #13
0
int dline_add(dline_t * dl, ea_t ea, char options)
{
	char buf[256];
	char tmp[256];
	char dis[256];
	char addr[30];
	char * dll;
	int len;
	flags_t f;

	buf[0] = '\0';

	f = getFlags(ea);
	generate_disasm_line(ea, dis, sizeof(dis));

	ua_ana0(ea);
	init_output_buffer(buf, sizeof(buf));

	// Adds block label
	if (has_dummy_name(f))
	{
		get_nice_colored_name(ea,tmp,sizeof(tmp),GNCN_NOSEG|GNCN_NOFUNC);
		out_snprintf("%s", tmp);
		out_line(":\n", COLOR_DATNAME);
	}

	if (options)
	{
		qsnprintf(addr, sizeof(addr), "%lu", (unsigned long)ea);
		out_snprintf("%s ", addr);
	}

	out_insert(get_output_ptr(), dis);
	term_output_buffer();

	len = strlen(buf);

	if (dl->available < (len+3))
	{
		dll = (char *)qrealloc(dl->lines, sizeof(char*) * (dl->num+len+256));
		if (!dll) return -1;

		dl->available = len+256;
		dl->lines = dll;
	}

	if (dl->num)
	{
		dl->lines[dl->num] = '\n';
		dl->num++;
	}

	memcpy(&dl->lines[dl->num], buf, len);

	dl->available -= len+1;
	dl->num += len;

	dl->lines[dl->num] = '\0';

	return 0;
}