Beispiel #1
0
/*
 we want to call this gadget:
 FFFFFFF0071E1998 MSR #0, c0, c2, #2, X8 ; [>] MDSCR_EL1 (Monitor Debug System Control Register)
 FFFFFFF0071E199C ISB // this a workaround for some errata...
 FFFFFFF0071E19A0 B    loc_FFFFFFF0071E19F8
 ...
 FFFFFFF0071E19F8 BL   _ml_set_interrupts_enabled
 FFFFFFF0071E19FC ADD  SP, SP, #0x220
 FFFFFFF0071E1A00 LDP  X29, X30, [SP,#0x20+var_s0]
 FFFFFFF0071E1A04 LDP  X20, X19, [SP,#0x20+var_10]
 FFFFFFF0071E1A08 LDP  X28, X27, [SP+0x20+var_20],#0x30
 FFFFFFF0071E1A0C RET

 lets just use the ERET case to get full register control an run that on a little ROP stack which then
 returns to thread_exception_return
 
 */
void set_MDSCR_EL1_KDE(mach_port_t target_thread_port) {
  /* this state will be restored by an eret */
  arm_context_t eret_return_state = {0};
  
  // allocate a stack for the rop:
  //uint64_t rop_stack_kern_base = kmem_alloc_wired(0x4000);
  uint64_t rop_stack_kern_base = early_kalloc(0x1000);
  
  uint64_t rop_stack_kern_middle = rop_stack_kern_base + 0xc00;
  
  eret_return_state.ss.ss_64.sp = rop_stack_kern_middle;
  uint64_t rop_stack_kern_popped_base = rop_stack_kern_middle + 0x220;
  // x28, x27, x20, x19, fp, lr
  uint64_t popped_regs[] = {0, 0, 0, 0, 0x414243444546, ksym(KSYMBOL_THREAD_EXCEPTION_RETURN)}; // directly return back to userspace after this
  kmemcpy(rop_stack_kern_popped_base, (uint64_t)popped_regs, sizeof(popped_regs));

#define MDSCR_EL1_KDE (1<<13)
  eret_return_state.ss.ss_64.x[8] = MDSCR_EL1_KDE;
  
  // the target place to eret to
  eret_return_state.ss.ss_64.pc = ksym(KSYMBOL_SET_MDSCR_EL1_GADGET);
  
  // we want to return on to SP0 and to EL1
  // A,I,F should still be masked, D unmasked (here we could actually mask D?)
#define SPSR_A   (1<<8)
#define SPSR_I   (1<<7)
#define SPSR_F   (1<<6)
#define SPSR_EL1_SP0 (0x4)
  eret_return_state.ss.ss_64.cpsr = SPSR_A | SPSR_I | SPSR_F | SPSR_EL1_SP0;
  
  //uint64_t eret_return_state_kern = kmem_alloc_wired(sizeof(arm_context_t));
  uint64_t eret_return_state_kern = early_kalloc(sizeof(arm_context_t));
  kmemcpy(eret_return_state_kern, (uint64_t)&eret_return_state, sizeof(arm_context_t));
  
  // make the arbitrary call
  kcall(ksym(KSYMBOL_X21_JOP_GADGET), 2, eret_return_state_kern, ksym(KSYMBOL_EXCEPTION_RETURN));
  
  printf("returned from trying to set the KDE bit\n");
  
  // free the stack we used:
  //kmem_free(rop_stack_kern_base, 0x4000);
}
Beispiel #2
0
static inline  void forth_vm_execute_instruction(forth_context_type *fc, char cmd)
{
//	printf("%c\n",cmd);
//	getchar();
	switch(cmd)
	{
		case '0': push(fc,0);				break;
		case '1': push(fc,1);				break;
		case '2': push(fc,2);				break;
		case '3': push(fc,3);				break;
		case '4': push(fc,4);				break;
		case '5': push(fc,5);				break;
		case '6': push(fc,6);				break;
		case '7': push(fc,7);				break;
		case '8': push(fc,8);				break;
		case '9': push(fc,9);				break;
		case '@': at(fc);					break; //@
		case '!': to(fc);					break; //!
		case 'd': fc->SP+=fc->cell;			break; //drop
		case 'D': dup(fc);					break; //dup
		case 's': swap_(fc);					break; //swap
		case 'l': push(fc,next_cell(fc));	break; //lit
		case '+': add(fc);  				break; //+
		case '-': sub(fc);  				break; //-
		case '*': mul(fc);					break; //*
		case '/': div_(fc);					break; // /
		case '%': mod(fc);					break; //mod
		case '&': and(fc);  				break; // and
		case '|': or(fc);   				break; // or
		case '^': xor(fc);   				break; // xor
		case '>': more(fc);					break; // >
		case '<': less(fc);					break;  // <
		case '=': eq(fc);					break; // =
		case 'b': branch(fc);				break; // branch
		case '?': cbranch(fc);				break; // ?branch
		case 'c': call(fc);					break; // call
		case 'r': ret(fc);					break; // ret
		case 't': to_r(fc);					break; // >R
		case 'f': from_r(fc);				break; // R>
		case 'i': in(fc);					break; // in
		case 'o': out(fc);					break; // out
		case '_': fc->stop=1;				break; // stop
		case 'A': adr0(fc);					break; // @0
		case 1:	  push(fc,fc->SP);			break; // SP@
		case 2:	  fc->SP=pop(fc);			break; // SP!
		case 3:	  push(fc,fc->RP);			break; // RP@
		case 4:	  fc->RP=pop(fc);			break; // RP!
		case 5:	 shl(fc);					break; // <<
		case 6:	 shr(fc);					break; // >>
		case 7:  push(fc,*(size_t *)(fc->mem+fc->RP)); break; // i
		case 8:  cat(fc);					break; // c@
		case 9:  cto(fc);					break; // c!
		case 10: set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(1);				break; // nop
		case 11: in_ready(fc);				break; // ?in
		case 12: out_ready(fc);				break; // ?out
		case 16: umod(fc);					break; // umod
		case 17: udiv(fc);					break; // u/
// kernel
		case 'K': kalsym_lookup(fc);		break; // lookup kallsym address
		case 18:  kcall(fc);				break; // kcall
	}
}