Beispiel #1
0
int run(struct emu *e, struct emu_env *env)
{
	int j=0;
	int ret; //= emu_cpu_run(emu_cpu_get(e));

	for( j=0;j< 1000000;j++ )
	{
		struct emu_env_hook *hook = NULL;
		hook = emu_env_w32_eip_check(env);

		if( hook != NULL )
		{
			if( strcmp(hook->hook.win->fnname,"ExitThread") == 0 )
				break;

			if( hook->hook.win->fnhook == NULL )
			{
				g_critical("unhooked call to %s", hook->hook.win->fnname);
				break;
			}
		} else
		{
			ret = emu_cpu_parse(emu_cpu_get(e));
			struct emu_env_hook *hook =NULL;
			if( ret != -1 )
			{
				hook = emu_env_linux_syscall_check(env);
				if( hook == NULL )
				{
					ret = emu_cpu_step(emu_cpu_get(e));
				} else
				{
					if( hook->hook.lin->fnhook != NULL )
						hook->hook.lin->fnhook(env, hook);
					else
						break;
				}
			}

			if( ret == -1 )
			{
				g_debug("cpu error %s", emu_strerror(e));
				break;
			}
		}
	}

	return 0;
}
Beispiel #2
0
void __cdecl main(void){
	
	e = emu_new();
	cpu = emu_cpu_get(e);
	mem = emu_memory_get(e);
	env = emu_env_new(e);
	
	//emu_log_level_set( emu_logging_get(e),  EMU_LOG_DEBUG);

	if ( env == 0 ){ printf("%s\n%s\n", emu_strerror(e), strerror(emu_errno(e))); exit(-1);}

	int i =  0;
	void* stack;
	int stacksz;

	//            0      1      2      3      4      5         6      7    
	int regs[] = {0,    0,      0,     0,  0x12fe00,0x12fff0  ,0,    0};
	//*regm[] = {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"};

	for (i=0;i<8;i++) cpu->reg[(emu_reg32)i] = regs[i];

	stacksz = regs[ebp] - regs[esp] + 500;
	stack = malloc(stacksz);
	memset(stack, 0, stacksz);
	
	//printf("writing initial stack space\n");
	emu_memory_write_block(mem, regs[esp] - 250, stack, stacksz);

	emu_env_w32_export_new_hook(env, "LoadLibraryA", new_user_hook_LoadLibraryA, NULL);

	/*	00436A32     B8 00000000    MOV EAX,0
		00436A37     40             INC EAX

		00436A3D     68 6C333200    PUSH 32336C
		00436A42     68 7368656C    PUSH 6C656873
		00436A47     54             PUSH ESP
		00436A48     68 771D807C    PUSH 7C801D77
		00436A4D     59             POP ECX
		00436A4E     FFD1           CALL ECX 

		686C333200687368656C5468771D807C59FFD1   */

	unsigned char shellcode[20] = {
		0x68, 0x6C, 0x33, 0x32, 0x00, 0x68, 0x73, 0x68, 0x65, 0x6C, 0x54, 0x68, 0x77, 0x1D, 0x80, 0x7C, 
		0x59, 0xFF, 0xD1, 0xCC
	};

	//write shellcode to memory
	emu_memory_write_block(mem, 0x401000, shellcode,  20);

	emu_cpu_eip_set(cpu, 0x401000);
	system("cls");

	int step=0;
	char* buf = (char*)malloc(100);

	while(1){
		
		struct emu_env_w32_dll_export *ex = NULL;
		ex = emu_env_w32_eip_check(env);

		if(ex != NULL){ 
			//eip was found to be the start address of some dll export
			if(ex->fnhook == NULL){ //if fnhook != 0 then handler was executed by library already
				printf("Unhooked call to api %s\n", ex->fnname); //can insert generic handler here
				break;
			}
		}
		else{
			
			emu_disasm_addr(cpu, cpu->eip, buf);
			printf("%x\t%s\n", cpu->eip, buf);

			if( emu_cpu_parse(cpu) == -1){
				printf("step %d  parse failed error: %s", step, emu_strerror(e));
				break;
			}
			
			if( emu_cpu_step(cpu) == -1){
				printf("step %d  step failed error: %s", step, emu_strerror(e));
				break;
			}
			step++;
		}
			
	}

	printf("Run complete step=%d eax is: %x\n\n", step, cpu->reg[eax]);
	getch();
	

}
Beispiel #3
0
void emulate_thread(gpointer data, gpointer user_data)
{
	struct emu_emulate_ctx *ctx = user_data;
	struct emu_config *conf = ctx->config;
	struct emu *e = ctx->emu;
	struct emu_env *env = ctx->env;
	int ret;

	g_mutex_lock(&ctx->mutex);

	if( ctx->state == waiting )
		ctx->state = running;


	if( ctx->time == NULL )
		ctx->time = g_timer_new();
	else
		g_timer_continue(ctx->time);

	while( ctx->state == running )
	{
		if( (ctx->steps % (1024*1024)) == 0 )
		{
			g_debug("steps %li", ctx->steps);
			if( ctx->steps > conf->limits.steps )
			{
				g_info("shellcode took too many steps ... (%li steps)",  ctx->steps);
				ctx->state = failed;
				break;
			}
			if( conf->limits.cpu > 0. )
			{
				double elapsed = g_timer_elapsed(ctx->time, NULL);
				if( elapsed > conf->limits.cpu )
				{
					g_info("shellcode took too long ... (%f seconds)",  elapsed);
					ctx->state = failed;
					break;
				}
			}
		}
		ctx->steps++;
		struct emu_env_hook *hook = NULL;
		hook = emu_env_w32_eip_check(env);

		if( hook != NULL )
		{
			if( hook->hook.win->fnhook == NULL )
			{
				g_critical("unhooked call to %s", hook->hook.win->fnname);
				break;
			} else
				if( ctx->state == waiting )
				/* for now, we stop!
				 * had a blocking io call
				 * callback from main will come at a given point
				 * and requeue us to the threadpool
				 */
				goto unlock_and_return;
		} else
		{
			ret = emu_cpu_parse(emu_cpu_get(e));
			struct emu_env_hook *hook =NULL;
			if( ret != -1 )
			{
				hook = emu_env_linux_syscall_check(env);
				if( hook == NULL )
				{
					ret = emu_cpu_step(emu_cpu_get(e));
				} else
				{
					if( hook->hook.lin->fnhook != NULL )
					{
						hook->hook.lin->fnhook(env, hook);
						if( ctx->state == waiting )
							/* stop 
							 * as mentioned previously
							 */
							goto unlock_and_return;
					}
				}
			}

			if( ret == -1 )
			{
				g_debug("cpu error %s", emu_strerror(e));
				break;
			}
		}
	}

	g_timer_stop(ctx->time);

	if( ctx->state == failed )
		g_debug("emulating shellcode failed");

	g_mutex_unlock(&ctx->mutex);

#ifdef DEBUG
	double elapsed = g_timer_elapsed(ctx->time, NULL);
	g_debug("shellcode took %f seconds on cpu, %li steps", elapsed, ctx->steps);
#endif

	GAsyncQueue *aq = g_async_queue_ref(g_dionaea->threads->cmds);
	g_async_queue_push(aq, async_cmd_new(emulate_ctx_free, ctx));
	g_async_queue_unref(aq);
	ev_async_send(g_dionaea->loop, &g_dionaea->threads->trigger);
	return;


	unlock_and_return:
	g_timer_stop(ctx->time);
	g_mutex_unlock(&ctx->mutex);
}