Exemple #1
0
static void hijack_xor_sequences(reloc_seq_t *seq, hijacksection_t *hijacksection, pefile_t *pefile)
{
	reloc_seq_t *seq_ptr;

	assert(seq != NULL);
	assert(hijacksection != NULL);
	assert(pefile != NULL);

	for (seq_ptr = seq; seq_ptr != NULL; seq_ptr = seq_ptr->next) {
		reloc_insn_list_t *ilistptr;

		if (seq_ptr->relocated)
			continue;

		// See if there is a guaranteed ZF=1 instruction like xor eax, eax in the seq.
		for (ilistptr = seq_ptr->instructions; ilistptr != NULL; ilistptr = ilistptr->next) {
			disassembly_t *in = ilistptr->insn;
			armoring_swirly();
			if (in->Instruction.type == insn_xor) {
				if (operands_match(in)) {
					if (split_reloc_sequence(seq_ptr, in->MemoryAddress - seq_ptr->start) != FALSE) {
						hijack_xor_seq(seq_ptr->next, hijacksection, pefile);
						seq_ptr = seq_ptr->next;
					} else {
						hijack_xor_seq(seq_ptr, hijacksection, pefile);
					}
					break;
				}
			}
		}
	}
}
Exemple #2
0
static bool
instructions_match(fs_inst *a, fs_inst *b)
{
   return a->opcode == b->opcode &&
          a->saturate == b->saturate &&
          a->predicate == b->predicate &&
          a->predicate_inverse == b->predicate_inverse &&
          a->conditional_mod == b->conditional_mod &&
          a->dst.type == b->dst.type &&
          operands_match(a->opcode, a->src, b->src);
}
Exemple #3
0
static bool
instructions_match(fs_inst *a, fs_inst *b)
{
   return a->opcode == b->opcode &&
          a->saturate == b->saturate &&
          a->predicate == b->predicate &&
          a->predicate_inverse == b->predicate_inverse &&
          a->conditional_mod == b->conditional_mod &&
          a->dst.type == b->dst.type &&
          a->sources == b->sources &&
          (a->is_tex() ? (a->texture_offset == b->texture_offset &&
                          a->mlen == b->mlen &&
                          a->regs_written == b->regs_written &&
                          a->base_mrf == b->base_mrf &&
                          a->sampler == b->sampler &&
                          a->eot == b->eot &&
                          a->header_present == b->header_present &&
                          a->shadow_compare == b->shadow_compare)
                       : true) &&
          operands_match(a, b);
}
Exemple #4
0
bool
fs_visitor::opt_cse_local(bblock_t *block, exec_list *aeb)
{
   bool progress = false;

   void *mem_ctx = ralloc_context(this->mem_ctx);

   for (fs_inst *inst = (fs_inst *)block->start;
	inst != block->end->next;
	inst = (fs_inst *) inst->next) {

      /* Skip some cases. */
      if (is_expression(inst) && !inst->predicate && inst->mlen == 0 &&
          !inst->force_uncompressed && !inst->force_sechalf &&
          !inst->conditional_mod)
      {
	 bool found = false;

	 aeb_entry *entry;
	 foreach_list(entry_node, aeb) {
	    entry = (aeb_entry *) entry_node;

	    /* Match current instruction's expression against those in AEB. */
	    if (inst->opcode == entry->generator->opcode &&
		inst->saturate == entry->generator->saturate &&
		operands_match(entry->generator->src, inst->src)) {

	       found = true;
	       progress = true;
	       break;
	    }
	 }

	 if (!found) {
	    /* Our first sighting of this expression.  Create an entry. */
	    aeb_entry *entry = ralloc(mem_ctx, aeb_entry);
	    entry->tmp = reg_undef;
	    entry->generator = inst;
	    aeb->push_tail(entry);
	 } else {
	    /* This is at least our second sighting of this expression.
	     * If we don't have a temporary already, make one.
	     */
	    bool no_existing_temp = entry->tmp.file == BAD_FILE;
	    if (no_existing_temp) {
	       entry->tmp = fs_reg(this, glsl_type::float_type);
	       entry->tmp.type = inst->dst.type;

	       fs_inst *copy = new(ralloc_parent(inst))
		  fs_inst(BRW_OPCODE_MOV, entry->generator->dst, entry->tmp);
	       entry->generator->insert_after(copy);
	       entry->generator->dst = entry->tmp;
	    }

	    /* dest <- temp */
	    fs_inst *copy = new(ralloc_parent(inst))
	       fs_inst(BRW_OPCODE_MOV, inst->dst, entry->tmp);
	    inst->replace_with(copy);

	    /* Appending an instruction may have changed our bblock end. */
	    if (inst == block->end) {
	       block->end = copy;
	    }

	    /* Continue iteration with copy->next */
	    inst = copy;
	 }
      }
Exemple #5
0
bool
fs_visitor::opt_cse_local(bblock_t *block, exec_list *aeb)
{
   bool progress = false;

   void *mem_ctx = ralloc_context(this->mem_ctx);

   int ip = block->start_ip;
   for (fs_inst *inst = (fs_inst *)block->start;
	inst != block->end->next;
	inst = (fs_inst *) inst->next) {

      /* Skip some cases. */
      if (is_expression(inst) &&
          !inst->predicate &&
          !inst->is_partial_write() &&
          !inst->conditional_mod)
      {
	 bool found = false;

	 aeb_entry *entry;
	 foreach_list(entry_node, aeb) {
	    entry = (aeb_entry *) entry_node;

	    /* Match current instruction's expression against those in AEB. */
	    if (inst->opcode == entry->generator->opcode &&
		inst->saturate == entry->generator->saturate &&
                inst->dst.type == entry->generator->dst.type &&
                operands_match(entry->generator->src, inst->src)) {

	       found = true;
	       progress = true;
	       break;
	    }
	 }

	 if (!found) {
	    /* Our first sighting of this expression.  Create an entry. */
	    aeb_entry *entry = ralloc(mem_ctx, aeb_entry);
	    entry->tmp = reg_undef;
	    entry->generator = inst;
	    aeb->push_tail(entry);
	 } else {
	    /* This is at least our second sighting of this expression.
	     * If we don't have a temporary already, make one.
	     */
	    bool no_existing_temp = entry->tmp.file == BAD_FILE;
	    if (no_existing_temp) {
               int written = entry->generator->regs_written;

               fs_reg orig_dst = entry->generator->dst;
               fs_reg tmp = fs_reg(GRF, virtual_grf_alloc(written),
                                   orig_dst.type);
               entry->tmp = tmp;
               entry->generator->dst = tmp;

               for (int i = 0; i < written; i++) {
                  fs_inst *copy = MOV(orig_dst, tmp);
                  copy->force_writemask_all =
                     entry->generator->force_writemask_all;
                  entry->generator->insert_after(copy);

                  orig_dst.reg_offset++;
                  tmp.reg_offset++;
               }
	    }

	    /* dest <- temp */
            int written = inst->regs_written;
            assert(written == entry->generator->regs_written);
            assert(inst->dst.type == entry->tmp.type);
            fs_reg dst = inst->dst;
            fs_reg tmp = entry->tmp;
            fs_inst *copy = NULL;
            for (int i = 0; i < written; i++) {
               copy = MOV(dst, tmp);
               copy->force_writemask_all = inst->force_writemask_all;
               inst->insert_before(copy);

               dst.reg_offset++;
               tmp.reg_offset++;
            }
            inst->remove();

	    /* Appending an instruction may have changed our bblock end. */
	    if (inst == block->end) {
	       block->end = copy;
	    }

	    /* Continue iteration with copy->next */
	    inst = copy;
	 }
      }
Exemple #6
0
static void hijack_xor_seq(reloc_seq_t *seq, hijacksection_t *hijacksection, pefile_t *pefile)
{
	char *old_buf;
	char *new_buf;
	DWORD newMemoryAddress = 0;
	DWORD dwOperand = 0;
	DWORD xorInsnSize = 0;

	assert(seq != NULL);
	assert(hijacksection != NULL);
	assert(pefile != NULL);

	if (seq->relocated)
		return;

	if (seq->instructions->insn->Instruction.type != insn_xor
		|| !operands_match(seq->instructions->insn))
	{
		return;
	}

	xorInsnSize = seq->instructions->insn->InstructionSize;

    seq->instructions = seq->instructions->next;
    seq->length -= xorInsnSize;
    seq->start += xorInsnSize;

	// See if we have enough room to plant the 6 byte "JZ rel32" instruction
	if (seq->length < 6)
		return;

	old_buf = va_to_ptr(pefile, seq->start);

	if (old_buf == NULL) {
		old_buf = hijacksection_va_to_ptr(hijacksection, seq->start);
		if (old_buf == NULL)
			return;
	}

	new_buf = hijack_reserve(hijacksection, seq->length + 6, &newMemoryAddress);

	new_buf[0] = 0xEB;   // 8-bit relative JMP prefix

    newMemoryAddress++;  // lets bypass the fake 0xEB we put in for future reference.

    hijack(old_buf, seq->start, &new_buf[1], newMemoryAddress, seq);

	// finish off the new hijack area with a jmp back to the original.
	new_buf[seq->length + 1] = 0xE9;  // 32-bit JMP prefix
	dwOperand = (seq->start + seq->length) - (newMemoryAddress + seq->length + 5);
	memcpy(&new_buf[(seq->length) + 2], &dwOperand, sizeof dwOperand);

	// Put in a jz prefix to the new "real" code chunk
	old_buf[0] = 0x0F;
	old_buf[1] = 0x84;

	dwOperand = newMemoryAddress - (seq->start + 6);

	memcpy(&old_buf[2], &dwOperand, sizeof dwOperand);

	// if we have enough room left, put in a fake jmp or call to before the "real" code
	// This will throw off disassembly, especially if we put a valid instruction prefix there.
	if (seq->length >= xorInsnSize + 6 + 5) {  // call <offset> is 5 bytes
		old_buf[6] = 0xE8;   // 32-bit relative CALL prefix
		dwOperand = (newMemoryAddress - 1) - (seq->start + 6 + 5);
		memcpy(&old_buf[7], &dwOperand, sizeof dwOperand);
	}

	//printf("XOR Hijack: %d bytes from 0x%08X to 0x%08X\n", seq->length, seq->start, newMemoryAddress+1);
	//debug_print_insn_list(seq->instructions);
	//printf("\n");

	seq->relocated = TRUE;

	// make a new relocatable sequence out of what has been moved so that another algorithm
	// may play with it further... (evil laughter)
	//    ...This could turn out to be a dumb idea...
	
 //   if (seq->length > xorInsnSize) {
	//	reloc_seq_t *new_seq;
	//	DWORD dwSeqOffset = 0;
	//	reloc_insn_list_t *insn;

	//	new_seq = ecalloc(1, sizeof *new_seq);
	//	new_seq->instructions = seq->instructions;
	//	new_seq->length = seq->length;
	//	new_seq->start = newMemoryAddress + 1;  // Add 1 to bypass the fake prefix we added.
	//	
	//	// just in case it might bite us later on, lets adjust all the addresses for the instructions
	//	for (insn = new_seq->instructions; insn != NULL; insn = insn->next) {
	//		insn->insn->MemoryAddress = newMemoryAddress + dwSeqOffset + 1;
	//		dwSeqOffset += insn->insn->InstructionSize;
	//	}
	//	
	//	new_seq->next = seq->next;
	//	seq->next = new_seq;
	//}
}