Example #1
0
void mterpBBCallback(DECAF_Callback_Params* params)
{
  if ( (mterpMap == NULL) || (params == NULL) )
  {
    return;
  }

  CPUState* env = params->bb.env;
  TranslationBlock* tb = params->bb.tb;
  Dalvik_Callback_Params dalvikparams;

  DEFENSIVE_CHECK0((env == NULL) || (tb == NULL));

  MterpInfo* pInfo = NULL;
  if (OpaqueHashmap_getVal(mterpMap, getCurrentPID(), (void**)&pInfo) != 0)
  {
    return;
  }

  //check to make sure that the BB is for the right iBaseRange first
  uint32_t opcode = mterpAddrToOpcode(pInfo->iBase, tb->pc);
  if (opcode != INV_ADDR)
  {
    if (RangeList_exist(pInfo->ranges, getDalvikPC(env)))
    {
      dalvikparams.ib.env = env;
      dalvikparams.ib.dalvik_pc = getDalvikPC(env);
      dalvikparams.ib.opcode = opcode;
      SimpleCallback_dispatch(&DS_Mterp_callbacks[DS_DALVIK_INSN_BEGIN_CB], &dalvikparams);
    }
  }
}
Example #2
0
void disableJitBBCallback(DECAF_Callback_Params* params)
{
  if ( (disableJitMap == NULL) || (params == NULL) )
  {
    return;
  }

  CPUState* env = params->bb.env;
  TranslationBlock* tb = params->bb.tb;
  Dalvik_Callback_Params dalvikparams;

  DEFENSIVE_CHECK0((env == NULL) || (tb == NULL));

  DisableJitInfo* pInfo = NULL;

  if (OpaqueHashmap_getVal(disableJitMap, getCurrentPID(), (void**)&pInfo) != 0)
  {
    return;
  }

  if (tb->pc == pInfo->getCodeAddr)
  {
    if (pInfo->retHandle != DECAF_NULL_HANDLE)
    {
      return;
    }

    if (RangeList_exist(pInfo->ranges, DECAF_getFirstParam(env)))
    {
      pInfo->retAddr = lp_strip(DECAF_getReturnAddr(env));
      pInfo->retHandle = DECAF_registerOptimizedBlockBeginCallback(&disableJitBBCallback, pInfo->retAddr, OCB_CONST);
    }

      /** TESTING SETTING THE TARGET ADDRESS TO 0 -- RESULTS: It doesn't make sense why the performance is so much lower
         than the original method of replacing the return value with 0. This is particularly true for the string tests
         in com.android.cm3 since most of the work is being done outside of the library. Also setting it to 0 makes
         gives in consistent results in the . and + in terms of the calls and returns. Before I made this change
         there seems to be two .s per + in linpack (which is weird in itself) but after this change there seems to be
         many .s per + like thousands more - it is just one single line change - perhaps it has something to do with
         the code itself where changing the address to 0 is NOT forcing a NULL to be returned**/
      //printf("%x\n", env->regs[0]);
      //env->regs[0] = 0;
      /** END TEST **/
  }
  else if ( (pInfo->retHandle != DECAF_NULL_HANDLE) && (lp_strip(tb->pc) == pInfo->retAddr) )
  {
#ifdef TARGET_ARM
    env->regs[0] = 0;
#elif defined(TARGET_I386)
    env->regs[R_EAX] = 0;
#endif
    
    DECAF_unregisterOptimizedBlockBeginCallback(pInfo->retHandle);
    pInfo->retHandle = DECAF_NULL_HANDLE;
    pInfo->retAddr = INV_ADDR;
    //printf("+");
  }
}
Example #3
0
//reg 0 is c2_base0 and 1 is c2_base1
void Context_PGDWriteCallback(DECAF_Callback_Params* params)
{
  struct timeval t;
  gettimeofday(&t, NULL);

  DEFENSIVE_CHECK0(params == NULL);

  //TODO: Keep a record of what the current PGD is and the new PGD is
  // so that we don't do unnecessary updates - this applies to the
  // skipupdates flag that is set when system calls are made as well
  if (!bSkipNextPGDUpdate)
  {
    updateProcessList(params->pgd.env, params->pgd.newPGD, UPDATE_PROCESSES | UPDATE_THREADS);
  }

  //reset this flag
  bSkipNextPGDUpdate = 0;
}
Example #4
0
//LOK: My tests have shown that do_fork -> then update on a PGD write is a perfect choice. Should change the logic to do that.
// it seems to cover many more cases than do_fork and schedule()
//TODO: have to fix the potential problem where this is called twice before the return is processed
// in which case the process name will not be updated properly
void contextBBCallback(DECAF_Callback_Params* params)
{
  static gva_t taskAddr = INV_ADDR;
  static int updateMask = 0;
  gpid_t pid = -1;
  TranslationBlock* tb = NULL;
  CPUState* env = NULL;

  DEFENSIVE_CHECK0(params == NULL);

  env = params->bb.env;
  tb = params->bb.tb;
  
  if (NULL == tb)
  {
    return;
  }

  if ( (tb->pc == SET_TASK_COMM_ADDR) || (tb->pc == DO_PRCTL_ADDR) )//set_task_comm
  {
    //In this case, we just update the name when the function returns
    //TODO: Fix i386 support 
    //TODO: Make sure this taskAddr is NOT the thread's task 
#ifdef TARGET_ARM
    taskAddr = env->regs[0];
    Context_retAddr = env->regs[14];
#elif TARGET_I386
    taskAddr = env->regs[R_EAX];
    DECAF_read_mem(env, env->regs[R_ESP], &Context_retAddr, sizeof(Context_retAddr));
#endif
  }
  else if ( (tb->pc == DO_EXECVE_ADDR) || (tb->pc == DO_CLONE_ADDR) )//do_execve
  {
    //we OR the update mask since its possible for the system call
    // to call another test - e.g. do_fork - and without declaring
    // the updateMask as static and using |= the flags will be
    // overwritten
    //TODO: Implement a STACK for the return addresses!!!
    //in this case we update the process, threads and module lists
    updateMask |= UPDATE_PROCESSES | UPDATE_THREADS | UPDATE_MODULES;
#ifdef TARGET_ARM
    Context_retAddr = env->regs[14];
#endif
  }
  else if (tb->pc == DO_FORK_ADDR) //do_fork
  {
    //In this case we just update the process and threads lists 
    updateMask |= UPDATE_PROCESSES | UPDATE_THREADS;
#ifdef TARGET_ARM
    Context_retAddr = env->regs[14];
#endif
  }

  if (tb->pc == Context_retAddr)
  {
    if (taskAddr != INV_ADDR)
    //if we need to update the names only
    {
      pid = DECAF_get_pid(env, taskAddr);
      if (pid != -1)
      {
        //if we found the PID then just read the names and update
        updateProcessListByTask(env, taskAddr, UPDATE_PROCESSES | UPDATE_THREADS | UPDATE_MODULES, 0);
      }
      taskAddr = INV_ADDR;
    } 
    else
    {
      updateProcessList(env, getCurrentPGD(), updateMask);
    }

    //since we updated the list already - lets skip the next PGD
    //write update
    bSkipNextPGDUpdate = 1;
    Context_retAddr = 0;
    DECAF_flushTranslationBlock_env(env, Context_retAddr);
  }

  if (Context_retAddr != 0)
  {
    //instead of registering for a new callback - we will just update our
    //conditions list and flush the entry for retAddr
   DECAF_flushTranslationBlock_env(env, Context_retAddr);
  }

  return;
}
Example #5
0
/**
 * Instruction Begin callback.
 */
void nd_instruction_begin_callback(DECAF_Callback_Params* params){
	DEFENSIVE_CHECK0(params == NULL);
	DEFENSIVE_CHECK0(getCurrentPID() != ND_GLOBAL_TRACING_PID);

	CPUState* env = params->ib.env;
	gva_t cur_pc = params->ib.cur_pc;
	//since for thumb instruction, the last bit is '1'	
	gva_t cur_pc_even = cur_pc & 0xfffffffe;


	if(!nd_in_blacklist(cur_pc_even)){
		return;
	}

	//ARM Instruction
	union _tmpARMInsn{
		target_ulong insn;
		char chars[4];
	} tmpARMInsn;
	//Thumb Instruction
	union _tmpThumbInsn{
		unsigned short insn;
		char chars[2];
	} tmpThumbInsn;
	//Thumb2 Instruction
	union _tmpThumb2Insn{
		target_ulong insn;
		char chars[4];
	} tmpThumb2Insn;

	//undefined instruction
	if(cur_pc == -1){
		return;
	}

	//the first instruction of target native method
	SourcePolicy* sourcePolicy = findSourcePolicy(cur_pc_even);
	if(sourcePolicy != NULL){
		DECAF_printf("Step into Native\n");
		sourcePolicy->handler(sourcePolicy, env);
	}

	//DECAF_printf("%x  %x\n", cur_pc_even, lastCallSysLibAddrRet);

	//return from JNI API calls/system library calls
	if(cur_pc_even == lastCallJNIAddrRet){
		if(lastJniHandler != NULL){
			lastJniHandler(env, 0);
			lastJniHandler = NULL;
			lastCallJNIAddrRet = -1;
		}
	}
	
	if(cur_pc_even == lastCallSysLibAddrRet){
		if(lastSysLibHandler != NULL){
			lastSysLibHandler(env, 0);
			lastSysLibHandler = NULL;
			lastCallSysLibAddrRet = -1;
		}
	}
	
	//Thumb instruction
	if(env->thumb == 1){
		if(DECAF_read_mem(env, cur_pc_even, tmpThumbInsn.chars, 2) != -1){
			darm_t d;
			//darm_str_t str;
    	// magic table constructed based on section A6.1 of the ARM manual
    	static uint8_t is_thumb2[0x20] = {
        [0x01d] = 1,
        [0x01e] = 1,
        [0x01f] = 1,
    	};

			if(is_thumb2[tmpThumbInsn.insn >> 11]){
				//Thumb2 instruction
				if(DECAF_read_mem(env, cur_pc_even, tmpThumb2Insn.chars, 4) != -1){
					if(darm_thumb2_disasm(&d, tmpThumb2Insn.insn & 0x0000ffff, 
								tmpThumb2Insn.insn >> 16, env) == 0){
						//if(darm_str(&d, &str, env) == 0){
							//DECAF_printf("T2  %x: %s\n", cur_pc, str.total);
						//}
					}
				}
			}else{
				//Thumb instruction
				if(darm_thumb_disasm(&d, tmpThumbInsn.insn, env) == 0){
					//if(darm_str(&d, &str, env) == 0){
						//DECAF_printf("T   %x: %s\n", cur_pc, str.total);
					//}
				}
			}
		}
Example #6
0
/**
 * Instruction Begin callback.
 */
void nd_instruction_begin_callback(DECAF_Callback_Params* params){
	DEFENSIVE_CHECK0(params == NULL);
	DEFENSIVE_CHECK0(getCurrentPID() != ND_GLOBAL_TRACING_PID);

	CPUState* env = params->ib.env;
	gva_t cur_pc = params->ib.cur_pc;
	//since for thumb instruction, the last bit is '1'	
	gva_t cur_pc_even = cur_pc & 0xfffffffe;

	//ARM Instruction
	union _tmpARMInsn{
		target_ulong insn;
		char chars[4];
	} tmpARMInsn;
	//Thumb Instruction
	union _tmpThumbInsn{
		unsigned short insn;
		char chars[2];
	} tmpThumbInsn;
	//Thumb2 Instruction
	union _tmpThumb2Insn{
		target_ulong insn;
		char chars[4];
	} tmpThumb2Insn;

	//undefined instruction
	if(cur_pc == -1){
		return;
	}

	//the first instruction of target native method
	SourcePolicy* sourcePolicy = findSourcePolicy(cur_pc_even);
	if(sourcePolicy != NULL){
		sourcePolicy->handler(sourcePolicy, env);
	}
	
	//Thumb instruction
	if(env->thumb == 1){
		if(DECAF_read_mem(env, cur_pc_even, tmpThumbInsn.chars, 2) != -1){
			darm_t d;
			darm_str_t str;
    	// magic table constructed based on section A6.1 of the ARM manual
    	static uint8_t is_thumb2[0x20] = {
        [0x01d] = 1,
        [0x01e] = 1,
        [0x01f] = 1,
    	};

			if(is_thumb2[tmpThumbInsn.insn >> 11]){
				//Thumb2 instruction
				if(DECAF_read_mem(env, cur_pc_even, tmpThumb2Insn.chars, 4) != -1){
					if(darm_thumb2_disasm(&d, tmpThumb2Insn.insn >> 16, tmpThumb2Insn.insn & 0x0000ffff) == 0){
						if(darm_str(&d, &str) == 0){
							//DECAF_printf("T2  %x: %s\n", cur_pc, str.total);
						}
					}
				}
			}else{
				//Thumb instruction
				if(darm_thumb_disasm(&d, tmpThumbInsn.insn) == 0){
					if(darm_str(&d, &str) == 0){
						//DECAF_printf("T   %x: %s\n", cur_pc, str.total);
					}
				}
			}
		}