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); }
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(); }
Emulator_LibEmu::Emulator_LibEmu() { e = emu_new(); cpu = emu_cpu_get(e); mem = emu_memory_get(e); im_base=0; }
void emulate(struct emu_config *conf, struct connection *con, void *data, unsigned int size, unsigned int offset) { struct emu_emulate_ctx *ctx = g_malloc0(sizeof(struct emu_emulate_ctx)); ctx->config = conf; ctx->sockets = g_hash_table_new(g_int_hash, g_int_equal); ctx->processes = g_hash_table_new(g_int_hash, g_int_equal); ctx->files = g_hash_table_new(g_int_hash, g_int_equal); ctx->ctxcon = con; if( con ) connection_ref(ctx->ctxcon); ctx->emu = emu_new(); ctx->env = emu_env_new(ctx->emu); struct emu_env * env = ctx->env; struct emu *e = ctx->emu; struct emu_cpu *cpu = emu_cpu_get(ctx->emu); ctx->env->userdata = ctx; g_mutex_init(&ctx->mutex); ctx->serial = 67; emu_env_w32_load_dll(env->env.win,"ws2_32.dll"); emu_ll_w32_export_hook(env, "accept", ll_win_hook_accept, NULL); emu_env_w32_export_hook(env, "bind", user_hook_bind, NULL); emu_env_w32_export_hook(env, "closesocket", user_hook_close, NULL); emu_env_w32_export_hook(env, "connect", user_hook_connect, NULL); emu_env_w32_export_hook(env, "listen", user_hook_listen, NULL); emu_ll_w32_export_hook(env, "recv", ll_win_hook_recv, NULL); emu_env_w32_export_hook(env, "send", user_hook_send, NULL); emu_env_w32_export_hook(env, "socket", user_hook_socket, NULL); emu_env_w32_export_hook(env, "WSASocketA", user_hook_WSASocket, NULL); emu_env_w32_export_hook(env, "CreateProcessA", user_hook_CreateProcess, NULL); emu_env_w32_export_hook(env, "WaitForSingleObject", user_hook_WaitForSingleObject, NULL); emu_env_w32_export_hook(env, "CreateFileA", user_hook_CreateFile, NULL); emu_env_w32_export_hook(env, "WriteFile", user_hook_WriteFile, NULL); emu_env_w32_export_hook(env, "CloseHandle", user_hook_CloseHandle, NULL); emu_env_w32_export_hook(env, "_lcreat", user_hook__lcreat, NULL); emu_env_w32_export_hook(env, "_lwrite", user_hook__lwrite, NULL); emu_env_w32_export_hook(env, "_lclose", user_hook__lclose, NULL); // emu_env_linux_syscall_hook(env, "exit", user_hook_exit, NULL); // emu_env_linux_syscall_hook(env, "socket", user_hook_socket, NULL); // emu_env_linux_syscall_hook(env, "bind", user_hook_bind, NULL); // emu_env_linux_syscall_hook(env, "listen", user_hook_listen, NULL); // emu_env_linux_syscall_hook(env, "accept", user_hook_accept, NULL); #define CODE_OFFSET 0x417000 int j; for( j=0; j<8; j++ ) emu_cpu_reg32_set(cpu,j , 0); // set flags emu_cpu_eflags_set(cpu, 0); // write code to offset emu_memory_write_block(emu_memory_get(ctx->emu), CODE_OFFSET, data, size); // set eip to code emu_cpu_eip_set(emu_cpu_get(e), CODE_OFFSET + offset); emu_cpu_reg32_set(emu_cpu_get(e), esp, 0x0012fe98); emulate_thread(NULL, ctx); }