#include ".\print_file.h"
#include "windows.h"
#include "globals.h"

print_file::print_file(void)
{
}

print_file::~print_file(void)
{
}


void print_file::do_it(x86_insn_t *insn)
{
	
	/*
	char line[4096];
	x86_format_insn(insn, line, 4096, intel_syntax);
	printf("[%X] %s\n",insn->addr,line);
	*/
}

void print_file::finish()
{

	char payload[2];
	payload[0]=0x90;
	payload[1]=0xC3;
	memcpy((void *)(_current_off),payload,1);
	memcpy((void *)(_current_off+1),payload,1);
	memcpy((void *)(_current_off+2),payload,1);
	memcpy((void *)(_current_off+3),payload,1);
	memcpy((void *)(_current_off+4),payload+1,1);
    
}

void print_file::do_it2(instruction *ins)
{
	x86_insn_t * insn=ins->insn();
	instruction *next_ins;
	//printf(" | %X\n",ins->_new_offset);
	
	/*
	BUG HERE!!
	The first instruction has no offset!
	if(!ins->_new_offset)
		return; //Should not happend!
	*/

	memcpy((void *)(_base + 0x004BFA00 + ins->_new_offset),insn->bytes,insn->size);
	_current+=insn->size;
	_current_off+=insn->size;


	/*
		Fix next_flow (passage d'une fonction à l'autre)
	*/
	if(ins->next_flow)
	{
		//printf("fixing ^\n");
		next_ins=globals::instance()._map[ins->next_flow];
		int old_addr = next_ins->_new_offset ;
		int new_addr = ins->_new_offset + insn->size;

		*( (long *)( _base + 0x004BFA00 + ins->_new_offset + insn->size -4) ) = old_addr - new_addr;
	}

	/*
		Fix not added flow!
	*/
	if(insn->type == insn_call && !ins->next_flow)
	{
		int old_dis = insn->operands[0].op.data.relative_far;
		int new_dis = old_dis + insn->offset - ( ins->_new_offset + 0x004BFA00 - 0x1A00);
		//printf("fix 2^ | %X %X %X %X\n",old_dis,insn->offset,ins->_new_offset,new_dis);
		*( (long *)( _base + 0x004BFA00 + ins->_new_offset + insn->size -4) ) = new_dis;
	}

}

void print_file::init(long starthere,long basep)
{
	_current = starthere;
	_base=basep;
	_current_off = basep + 0x004BFA00;
}