Exemple #1
0
static knh_xblock_t *knh_generateWrapper(CTX ctx, void *callee, int argc, knh_ffiparam_t *argv)
{
  knh_xblock_t *blk = get_unused_xblock(ctx);
  knh_xblock_t *function = blk->block;

  size_t fidx = 0;
  int i = 0;
  knh_ffiparam_t *t;
  // local ffiarguments;
  ffi_cif *cif = (ffi_cif*)KNH_MALLOC(ctx, sizeof(ffi_cif));
  ffi_type **args = (ffi_type**)KNH_MALLOC(ctx, sizeof(ffi_type) * argc);
  void *values[1];
  
  for (i = 0; i < argc; i++) {
	t = &argv[i];
	if (t->sfpidx != -1) {
	  // it means arguments	
	  switch(t->type) {
	  case CLASS_Tvoid:
		// do nothing
		break;
	  case CLASS_Int:
		args[i] = &ffi_type_uint64;
		break;
	  case CLASS_Float:
		args[i] = &ffi_type_double;
		break;
	  default:
		args[i] = &ffi_type_pointer;
		break;
	  }
	}
  }

  if (ffi_prep_cif(cif, FFI_DEFAULT_ABI, argc,
				   &ffi_type_void, args) == FFI_OK) {
	fprintf(stderr, "OKAY!\n");
  } else {
	fprintf(stderr, "this is not okay!\n");
  }

}
Exemple #2
0
static knh_xblock_t* knh_generateWrapper(CTX ctx, void* callee, int argc, knh_ffiparam_t *argv)
{
	//unsigned char *FUNCTION = (unsigned char*)knh_xmalloc(ctx, 1);
	knh_xblock_t *blk = get_unused_xblock(ctx);
	unsigned char *function = blk->block;
	
	size_t fidx = 0;

	// magick word
	WRITE_HEX(0x55); // push ebp 
	WRITE_HEX(0x89); // mov esp->ebp
	WRITE_ASM(MOD_IMD, _ESP, _EBP);

	// incase we use ebp, store it.
	WRITE_HEX(0x53); // push ebx

	// we need stack argc * 8bytes at most
	size_t stacksize = argc * 8;
	// allocate stack (sub esp 0x38)
	WRITE_HEX(0x83);
	WRITE_HEX(0xec);
	WRITE_HEX((unsigned char)(stacksize + 0x8));

	// before going, we need edx to be store;
	// mov edx --> -0x4(ebp)
	WRITE_HEX(0x89); // mov r+disp r
	WRITE_ASM(MOD_PLUS8, _EDX, _EBP);
    WRITE_HEX(0xfc);

	//now, process first argument;
	int i;
	knh_ffiparam_t *t;

	for (i = 0; i < argc; i++) {
		t = &(argv[i]);
		if (t->sfpidx != -1) {
			// if sfpidx == -1, its ret value;
			// prepare ebx (put sfp from edx);
			WRITE_HEX(0x89);
			WRITE_ASM(MOD_IMD, _EDX, _EBX);

			switch(t->type) {
			case CLASS_Tvoid:
				// do noting.
				break;
			case CLASS_Int:
				// its 64bit int
				//TODO: we need to call translater, but now, we ignore
				//TODO: assume we cast Int --> int;
				// add ebx[sfp] + sfpidx * 16;
				WRITE_HEX(0x83); //add
				WRITE_ASM(MOD_IMD,  _EAX , _EBX);
				WRITE_HEX((unsigned char)(t->sfpidx * 16));

				// move ivalue(offset is 8);
				WRITE_HEX(0x8b); // mov r+disp, r
				WRITE_ASM(MOD_PLUS8, _EAX, _EBX);
				WRITE_HEX(0x8);

				// move eax to local value
				//WRITE_HEX(0x89);
				//WRITE_ASM(MOD_IMD, _EBP, _EAX);
				//				WRITE_HEX(0xf4);
				break;
			case CLASS_Float:
				WRITE_HEX(0x83);
				WRITE_ASM(MOD_IMD, _EAX, _EBX);
				WRITE_HEX((unsigned char)(t->sfpidx * 16));

				// load fvalue;

				WRITE_HEX(0xdd);// fld 64bit
				WRITE_HEX(0x43);// eax
				WRITE_HEX(0x8); // offset

				// push it to eax;
				WRITE_HEX(0xdd); // fstp : store & pop 64
				WRITE_HEX(0x1c);
				WRITE_HEX(0x24);

				break;
			default:
				break;
			}
		} else continue; // if its ret value
	}

	// now, call foreign function
	// NOT SURE??? since konoha is using FASTCALL,
	// call convension is always Fastcall.

	unsigned char default_disp = 0x8;
	unsigned char disp = 0x0;

	// argc contains ret value. remeber...
	// TODO :only for a single argument...
	for (i = argc - 1; i > 0; i--) {
		// push aruguments on the stack;
		// mov argument to eax!
		// TODO : now, we only consider 32 bit values

		if (argv[i].type == CLASS_Int) {
			function[fidx++] = 0x89; // mov r+disp r
			function[fidx++] = 0x45; // 0xXX(ebp)
			disp = default_disp + i * 4;
			disp = 0x100 - disp;
			function[fidx++] = disp; // -0x8
			//move to esp
			function[fidx++] = 0x89;
			function[fidx++] = 0x04;
			function[fidx++] = 0x24;
		}

	}

	//now call.
	// call foreign function
	//	intptr_t ucallee = (intptr_t)callee;
	//	intptr_t next_addr = (intptr_t)function + (intptr_t)fidx + 5 /*for call instruction */;
	//intptr_t rel = (ucallee > next_addr) ? ucallee - next_addr : next_addr - ucallee;
	//rel = -rel;
	//unsigned char *src = (unsigned char*)&rel;

	// absolute call
	unsigned char *src = (unsigned char*)&callee;
	// mov this to eax;
	WRITE_HEX(0xb8); // mov to eax
	WRITE_HEX(src[0]);
	WRITE_HEX(src[1]);
	WRITE_HEX(src[2]);
	WRITE_HEX(src[3]);

	// now call
	WRITE_HEX(0xff);
	WRITE_HEX(0xd0);

	//  function[fidx++] = 0xcc;
	// after calling, restore edx;
	// restore edx;
	WRITE_HEX(0x8b);
	WRITE_ASM(MOD_PLUS8, _EDX, _EBP);
	WRITE_HEX(0xfc);

	if (argv[0].sfpidx == -1) {
		switch(argv[0].type) {
		case CLASS_Tvoid:
			goto STEP_OUT;
			break;
		case CLASS_Int:
			// get return value, and give it to Konoha
			// ret value is on eax;
			// push eax
			function[fidx++] = 0x50; // push eax
			break;
		case CLASS_Float:
			// it is on FPU. we need no concern.
			break;
		}
	}

	// get rix (at 0x8(ebp)) --> eax
	WRITE_HEX(0x8b);  // mov
	WRITE_ASM(MOD_PLUS8, _EAX, _EBP); // 0xXX(ebp) eax
	WRITE_HEX(0x8); // 8

	// get edx --> ebx
	WRITE_HEX(0x89);
	WRITE_ASM(MOD_IMD, _EDX, _EBX);

	// ebx[sfp] + 16 * rix
	// first, 16 * rix = 2^4 * rix
	WRITE_HEX(0xc1); // shl
	WRITE_ASM(MOD_IMD, _ESP, _EAX);
	WRITE_HEX(0x4);

	// second, add eax to ebx;
	WRITE_HEX(0x01); //add
	WRITE_ASM(MOD_IMD, _EAX, _EBX); // add eax -> ebx;

	// now at ebx is pointing to sfp[K_RIX];
	// copy retvalue to sfp[K_RIX].ivalue (offset is 0x8)
	// pop eax;


	// offset is different for each types
	if (argv[0].sfpidx == -1) {
		switch (argv[0].type) {
		case CLASS_Int:
			function[fidx++] = 0x58; // pop eax
			// mov eax --> 0x8(%ebx)
			function[fidx++] = 0x89; // mov r+disp r
			function[fidx++] = 0x43; // eax: ebx
			function[fidx++] = 0x8; // 0x8
			break;
		case CLASS_Float:
			//fstpl 0x8(ebx)
			WRITE_HEX(0xdd);
			WRITE_ASM(MOD_PLUS8, _EBX, _EBX);
			WRITE_HEX(0x8);
			break;
		}
	}

	// from here, closing this function
	// close stack; add 0xXX esp
 STEP_OUT:
	WRITE_HEX(0x83);
	WRITE_HEX(0xc4);
	WRITE_HEX((unsigned char)(stacksize + 0x8));

	// restore ebx
	WRITE_HEX(0x5b); // pop ebx
	WRITE_HEX(0x5d);	// pop ebp;

	// ret $0x4
	WRITE_HEX(0xc2); // ret
	WRITE_HEX(0x4);
	WRITE_HEX(0x0);

	//	return function;
	return blk;
}