Ejemplo n.º 1
0
static unsigned patch_internal(int call, unsigned len, void *insnbuf,
			       unsigned long ip)
{
	u64 reloc;
	struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
	reloc = call_vrom_long_func(vmi_rom, get_reloc,	call);
	switch(rel->type) {
		case VMI_RELOCATION_CALL_REL:
			BUG_ON(len < 5);
			*(char *)insnbuf = MNEM_CALL;
			patch_offset(insnbuf, ip, (unsigned long)rel->eip);
			return 5;

		case VMI_RELOCATION_JUMP_REL:
			BUG_ON(len < 5);
			*(char *)insnbuf = MNEM_JMP;
			patch_offset(insnbuf, ip, (unsigned long)rel->eip);
			return 5;

		case VMI_RELOCATION_NOP:
			/* obliterate the whole thing */
			return 0;

		case VMI_RELOCATION_NONE:
			/* leave native code in place */
			break;

		default:
			BUG();
	}
	return len;
}
Ejemplo n.º 2
0
void patch_cmd(int argc, char **argv) {
  r_binfmt_s bin;

  patch_options_parse(argc, argv);

  r_binfmt_load(&bin, patch_options_filename, patch_options_arch);

  if(patch_options_offset != R_BINFMT_BAD_ADDR) {
    patch_offset(&bin,
		 patch_options_offset,
		 patch_options_bytes->bytes,
		 patch_options_bytes->len);

  } else {
    patch_address(&bin,
		  patch_options_address,
		  patch_options_bytes->bytes,
		  patch_options_bytes->len);
  }

  if(patch_options_output == NULL)
    patch_options_output = patch_options_filename;


  r_binfmt_write(&bin, patch_options_output);
  printf("[+] Patched %" PRIu64 " bytes (result saved in %s)\n", patch_options_bytes->len, patch_options_output);


  r_binfmt_free(&bin);
}
Ejemplo n.º 3
0
/*
 * Apply patch if appropriate, return length of new instruction
 * sequence.  The callee does nop padding for us.
 */
static unsigned vmi_patch(u8 type, u16 clobbers, void *insns, unsigned len)
{
	switch (type) {
		case PARAVIRT_IRQ_DISABLE:
			return patch_internal(VMI_CALL_DisableInterrupts, len, insns);
		case PARAVIRT_IRQ_ENABLE:
			return patch_internal(VMI_CALL_EnableInterrupts, len, insns);
		case PARAVIRT_RESTORE_FLAGS:
			return patch_internal(VMI_CALL_SetInterruptMask, len, insns);
		case PARAVIRT_SAVE_FLAGS:
			return patch_internal(VMI_CALL_GetInterruptMask, len, insns);
        	case PARAVIRT_SAVE_FLAGS_IRQ_DISABLE:
			if (len >= 10) {
				patch_internal(VMI_CALL_GetInterruptMask, len, insns);
				patch_internal(VMI_CALL_DisableInterrupts, len-5, insns+5);
				return 10;
			} else {
				/*
				 * You bastards didn't leave enough room to
				 * patch save_flags_irq_disable inline.  Patch
				 * to a helper
				 */
				BUG_ON(len < 5);
				*(char *)insns = MNEM_CALL;
				patch_offset(insns, irq_save_disable_callout);
				return 5;
			}
		case PARAVIRT_INTERRUPT_RETURN:
			return patch_internal(VMI_CALL_IRET, len, insns);
		case PARAVIRT_STI_SYSEXIT:
			return patch_internal(VMI_CALL_SYSEXIT, len, insns);
		default:
			break;
	}
	return len;
}