void closer (t_Tracer_OpenTr *open) { Debugger *c; PROCESS_INFORMATION ProcInfo; char bla[30]; if (open->Definition->Name == "CreateProcessA") { printf("MAIN: Process created (CreateProcessA)\n"); if (!ReadProcessMemory(dbg.getProcessHandle(), (LPCVOID)(open->OutArgs[9].data.address), &ProcInfo, sizeof(ProcInfo), NULL)) { printf("Failed to read process memory at %08X\n", open->OutArgs[9].data.address); } else { c = new (Debugger); sprintf(bla,"Child %u",ProcInfo.dwProcessId); c->attach(ProcInfo.dwProcessId); c->log.Name= bla; Children.push_back(c); } } else if (open->Definition->Name == "CreateProcessAsUserA") { printf("MAIN: Process created (CreateProcessAsUserA)\n"); if (!ReadProcessMemory(dbg.getProcessHandle(), (LPCVOID)(open->OutArgs[10].data.address), &ProcInfo, sizeof(ProcInfo), NULL)) { printf("Failed to read process memory at %08X\n", open->OutArgs[10].data.address); } else { c = new (Debugger); sprintf(bla,"Child %u",ProcInfo.dwProcessId); c->attach(ProcInfo.dwProcessId); c->log.Name= bla; Children.push_back(c); } } }
// this function is called to process every breakpoint entry, so it should be as fast as possible. void normal_break (DEBUG_EVENT *db) { t_disassembly dis; DWORD address; HANDLE process; HANDLE thread; node *bp_node; bool stalking = false; DWORD tick_count; CONTEXT context; LDT_ENTRY selector_entry; DWORD fs_base; DWORD stack_top; DWORD stack_bottom; tick_count = GetTickCount(); address = (DWORD)(db->u.Exception.ExceptionRecord.ExceptionAddress); thread = dbg.FindThread((DWORD)db->dwThreadId)->hThread; process = dbg.getProcessHandle(); // bring the called function to the top of the list. //function_list = splay(address, function_list); // ensure the breakpoint lies in a module we are stalking. for (node *cursor = bp_modules; cursor != NULL; cursor = cursor->next) { if (address >= cursor->base && address <= cursor->base + cursor->size) { stalking = true; break; } } // if we're not stalking the current module, return now. if (!stalking) return; // // if we're recording, log the entry to the appropriate recorder file. // if (recorder_mode != NOT_RECORDING) { //function_list->recorded[recorder_mode]++; //printf("T:%04x [R%d] %08X %-25s [%5u] ", db->dwThreadId, recorder_mode, address, function_list->name, function_list->recorded[recorder_mode]); if (disassemble_flag) printf("%08x T:%08x [R%d] %08X ", tick_count, db->dwThreadId, recorder_mode, address); if ((bp_node = ps_node_find_by_address(address, bp_modules)) != NULL) fprintf(recorder, "%08x:%08x:%s:%08x:%08x\n", tick_count, db->dwThreadId, bp_node->name, bp_node->base, address - bp_node->base); } // else, not recording. else { if (disassemble_flag) printf("%08x T:%08x [bp] %08X ", tick_count, db->dwThreadId, address); } // if enabled, print the disassembly at the breakpoint address. if (disassemble_flag) { // XXX - wonder if there is any significant speed increase when we skip just the disassembly output. if (dbg.Disassemble(thread, address, &dis)) printf("%s\n", dis.mnemonic.c_str()); else printf("\n"); } // if we are recording and register enumeration / dereferencing is enabled, process the registers we are interested in. if (recorder_mode != NOT_RECORDING && reg_enum_flag) { context.ContextFlags = CONTEXT_FULL; // get the thread context (containing the register values). if (GetThreadContext(thread, &context) == 0) return; // get the thread selector entry and calculate the 32-bit address for the FS register. if (GetThreadSelectorEntry(thread, context.SegFs, &selector_entry) == 0) return; fs_base = selector_entry.BaseLow + (selector_entry.HighWord.Bits.BaseMid << 16) + (selector_entry.HighWord.Bits.BaseHi << 24); // determine the top/bottom of the debuggee's stack. ReadProcessMemory(process, (void *)(fs_base + 4), &stack_top, 4, NULL); ReadProcessMemory(process, (void *)(fs_base + 8), &stack_bottom, 4, NULL); ps_analyze_register(process, tick_count, address, bp_node, stack_top, stack_bottom, context.Eax, "EAX"); ps_analyze_register(process, tick_count, address, bp_node, stack_top, stack_bottom, context.Ebx, "EBX"); ps_analyze_register(process, tick_count, address, bp_node, stack_top, stack_bottom, context.Ecx, "ECX"); ps_analyze_register(process, tick_count, address, bp_node, stack_top, stack_bottom, context.Edx, "EDX"); ps_analyze_register(process, tick_count, address, bp_node, stack_top, stack_bottom, context.Esi, "ESI"); ps_analyze_register(process, tick_count, address, bp_node, stack_top, stack_bottom, context.Edi, "EDI"); } // to restore the break point we just processed: // - save the breakpoint address. // - enable single stepping. // - let the single step handler restore the breakpoint and disable single stepping. if (!dbg.one_time) { dbg.breakpoint_restore = address; dbg.breakpoint_restore_thread = thread; dbg.SetSingleStep(thread, true); } }