void proc_emu_on_io_in(struct connection *con, struct processor_data *pd) { g_debug("%s con %p pd %p", __PRETTY_FUNCTION__, con, pd); struct emu_ctx *ctx = pd->ctx; int offset = MAX(ctx->offset-300, 0); void *streamdata = NULL; int32_t size = bistream_get_stream(pd->bistream, bistream_in, offset, -1, &streamdata); int ret = 0; if( size != -1 ) { struct emu *e = emu_new(); #if 0 emu_cpu_debugflag_set(emu_cpu_get(e), instruction_string); emu_log_level_set(emu_logging_get(e),EMU_LOG_DEBUG); #endif ret = emu_shellcode_test(e, streamdata, size); emu_free(e); ctx->offset += size; if( ret >= 0 ) { struct incident *ix = incident_new("dionaea.shellcode.detected"); GAsyncQueue *aq = g_async_queue_ref(g_dionaea->threads->cmds); g_async_queue_push(aq, async_cmd_new(async_incident_report, ix)); g_async_queue_unref(aq); ev_async_send(g_dionaea->loop, &g_dionaea->threads->trigger); g_debug("shellcode found offset %i", ret); profile(ctx->config, con, streamdata, size, ret); pd->state = processor_done; } g_free(streamdata); } }
int check_buffer(const unsigned char *bytes,uint32_t length) { //fprintf(stderr,"DEBUG:Checking buffer\n"); if (length > MAX_STR_LEN_TO_CHECK) { fprintf(stderr,"WARNING: Long string with more than %d bytes! return -1 in developing mode\n",MAX_STR_LEN_TO_CHECK); return -1; } struct emu * e; e = emu_new(); int result; result = emu_shellcode_test(e, (unsigned char *)bytes, length); emu_free(e); if (result >= 0) return result; e = emu_new(); result = emu_shellcode_test(e, (unsigned char *)bytes, length); emu_free(e); return result; }
void profile(struct emu_config *conf, struct connection *con, void *data, unsigned int size, unsigned int offset) { struct emu *e = emu_new(); struct emu_env *env = emu_env_new(e); env->profile = emu_profile_new(); // struct emu_cpu *cpu = emu_cpu_get(e); struct emu_memory *mem = emu_memory_get(e); emu_cpu_reg32_set(emu_cpu_get(e), esp, 0x0012fe98); emu_memory_write_block(mem, CODE_OFFSET, data, size); emu_cpu_eip_set(emu_cpu_get(e), CODE_OFFSET + offset); run(e, env); bool needemu = false; struct emu_profile_function *function; for( function = emu_profile_functions_first(env->profile->functions); !emu_profile_functions_istail(function); function = emu_profile_functions_next(function) ) { if( strcmp("recv", function->fnname) == 0 ) { g_message("Can not profile %s, emulating instead", function->fnname); needemu = true; } } if( needemu == true ) { emulate(conf, con, data, size, offset); } else { GString *str = g_string_new(NULL); json_profile_debug(env->profile, str); //printf("%s", str->str); struct incident *i = incident_new("dionaea.module.emu.profile"); incident_value_string_set(i, "profile", str); incident_value_con_set(i, "con", con); connection_ref(con); GAsyncQueue *aq = g_async_queue_ref(g_dionaea->threads->cmds); g_async_queue_push(aq, async_cmd_new(async_incident_report, i)); g_async_queue_unref(aq); ev_async_send(g_dionaea->loop, &g_dionaea->threads->trigger); } emu_env_free(env); emu_free(e); }
Emulator_LibEmu::~Emulator_LibEmu() { emu_free(e); }
void emulate_ctx_free(void *data) { struct emu_emulate_ctx *ctx = data; GHashTableIter iter; gpointer key, value; g_hash_table_iter_init (&iter, ctx->files); while( g_hash_table_iter_next (&iter, &key, &value) ) { g_debug("file key %p %i value %p \n", key, *(int *)key, value); struct tempfile *tf = value; if( tf->fh == NULL ) { /* file was closed by shellcode */ struct incident *i = incident_new("dionaea.download.complete"); incident_value_string_set(i, "path", g_string_new(tf->path)); if( ctx->ctxcon ) incident_value_con_set(i, "con", ctx->ctxcon); incident_value_string_set(i, "url", g_string_new("emulate://")); incident_report(i); incident_free(i); }else tempfile_close(tf); tempfile_unlink(tf); tempfile_free(tf); } g_hash_table_destroy(ctx->files); g_hash_table_iter_init (&iter, ctx->processes); while( g_hash_table_iter_next (&iter, &key, &value) ) { g_debug("process key %p %i value %p \n", key, *(int *)key, value); } g_hash_table_destroy(ctx->processes); g_hash_table_iter_init (&iter, ctx->sockets); while( g_hash_table_iter_next (&iter, &key, &value) ) { struct connection *con = value; g_debug("connection key %p %i value %p type %s state %s socket %i\n", key, *(int *)key, value, connection_type_to_string(con->type), connection_state_to_string(con->state), con->socket); if( con->socket != -1 ) {/* avoid callbacks from connection_close() */ close(con->socket); con->socket = -1; } g_free(key); con->protocol.ctx = NULL; con->events.free.repeat = .5; connection_free(con); } g_hash_table_destroy(ctx->sockets); if( ctx->time != NULL ) g_timer_destroy(ctx->time); emu_free(ctx->emu); emu_env_free(ctx->env); g_mutex_clear(&ctx->mutex); if( ctx->ctxcon != NULL ) connection_unref(ctx->ctxcon); g_free(ctx); }