Buenas, estoy modificando la clase que tengo creada para depurar aplicaciones y si creo el proceso a depurar con CreateProcess no tengo problemas pero al atachearme al proceso tengo el problema de que no puedo obtener la información de la estructura PROCESS_INFORMATION y cuando quiero terminar el proceso uso CloseHandle y ahí me explota en la cara. También uso TerminateProcess y tampoco funciona. Os adjunto la parte del código necesaria:
Código PHP:
void __fastcall THiloDebugger::Execute()
{
DEBUG_EVENT DebugEv;
HANDLE CurrentExceptionThread;
DWORD dwContinueStatus;
int Error;
TDll *ItemDLL;
bool salir=false;
ListaBPs = new TList;
ListaDlls = new TList;
ListaThreads = new TList;
Synchronize(OnInitLoopDebugThread); //Usaremos este evento para inizialización de variables en la clase usuario si se requiere.
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
// El proceso se tiene que crear en la misma función donde está el hilo del depurador sino no vale
if(Atached){
if(!AtachProcessByNameWindow(WindowName.c_str(),Error))
return;
}else{
CreateProcess(PathFile.c_str(),NULL, NULL, NULL, FALSE, DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &si, &pi);
}
InfoProcess.hProcess = pi.hProcess;
InfoProcess.ProcessID = pi.dwProcessId;
do{
if (WaitForDebugEvent(&DebugEv,1) == true)
{
if(TerminateDebugger == false){
// Paró por depuración
// Tomamos el contexto del hilo que generó el evento
CurrentExceptionThread = GetHandleThread(DebugEv.dwThreadId);
DWORD actual;
if(CurrentExceptionThread != NULL){
con.ContextFlags= CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS;
GetThreadContext(CurrentExceptionThread, &con);
}
switch(DebugEv.dwDebugEventCode)
{
case EXIT_PROCESS_DEBUG_EVENT:
// llamamos a funciones dentro del Hilo para evitar código espaqueti
// estas funciones no requieren del syncronice
dwContinueStatus = OnExitProcessDebugEventThread(&DebugEv.u.ExitProcess);
salir = true;
break;
case CREATE_PROCESS_DEBUG_EVENT:
// Carga del proceso en el depurador
CurrentExceptionThread = DebugEv.u.CreateProcessInfo.hThread;
con.ContextFlags= CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS;
GetThreadContext(CurrentExceptionThread, &con);
dwContinueStatus = OnCreateProcessDebugEventThread(&DebugEv.u.CreateProcessInfo, DebugEv.dwThreadId);
break;
case EXCEPTION_DEBUG_EVENT:
// Excepciones y BPs
LastExceptionAddress = (DWORD)DebugEv.u.Exception.ExceptionRecord.ExceptionAddress;
ExceptionCode = DebugEv.u.Exception.ExceptionRecord.ExceptionCode;
switch(ExceptionCode)
{
case EXCEPTION_BREAKPOINT:
dwContinueStatus = OnBreakpointDebugEventThread(LastExceptionAddress);
break;
case EXCEPTION_SINGLE_STEP: // Aqui se gestionan los HW hay que crear otro Callback
dwContinueStatus = OnSingleStepEventThread(&DebugEv.u.Exception);
break;
case EXCEPTION_GUARD_PAGE_VIOLATION:
dwContinueStatus = OnExceptionGuardPageEventThread(&DebugEv.u.Exception);
break;
case EXCEPTION_ACCESS_VIOLATION:
//Esto es para controlar los MemoryBPs
//primero tengo que ver como funciona este
//tipo de bps
dwContinueStatus = OnExceptionGuardPageEventThread(&DebugEv.u.Exception);
break;
case EXCEPTION_INVALID_HANDLE:
//Aqui gestiono cuando CloseHandle use un handle invalido
dwContinueStatus = OnExceptionInvalidHandleEventThread(&DebugEv.u.Exception);
break;
default:
dwContinueStatus = OnExceptionDefault(DebugEv.dwDebugEventCode,LastExceptionAddress);
}
break;
case CREATE_THREAD_DEBUG_EVENT:
// Parada por creacion de hilos
dwContinueStatus = OnCreateThreadDebugEventThread(&DebugEv.u.CreateThread,DebugEv.dwThreadId);
break;
case EXIT_THREAD_DEBUG_EVENT:
// Parada por destrucción de hilos
dwContinueStatus =OnExitThreadDebugEventThread(&DebugEv.u.ExitThread,(DWORD)DebugEv.dwThreadId);
break;
case LOAD_DLL_DEBUG_EVENT:
// Parada por carga de dll
dwContinueStatus =OnLoadDllDebugEventThread(&DebugEv.u.LoadDll);
break;
case UNLOAD_DLL_DEBUG_EVENT:
// liberación de dll
dwContinueStatus =OnUnloadDllDebugEventThread(&DebugEv.u.UnloadDll);
break;
case OUTPUT_DEBUG_STRING_EVENT:
// Envío de cadenas al depurador
dwContinueStatus = OnOutputDebugStringEventThread(&DebugEv.u.DebugString);
break;
case RIP_EVENT:
// system debugging error ?? ni idea que es esto
dwContinueStatus = OnRipEventThread(&DebugEv.u.RipInfo);
break;
default:
// evento desconocido
dwContinueStatus=DBG_EXCEPTION_NOT_HANDLED;
}
if(CurrentExceptionThread != NULL){
SetThreadContext(CurrentExceptionThread, &con);
}
ContinueDebugEvent(DebugEv.dwProcessId,DebugEv.dwThreadId,dwContinueStatus);
if(Detach_Debugger == true){
DebugActiveProcessStop(pi.dwProcessId);
salir = true;
}
}
else{ // TerminateDebugger == true
DebugActiveProcessStop(pi.dwProcessId);
TerminateProcess(pi.hProcess,0);
salir = true;
}
}
else
{
// Paro por tiempo
if(TerminateDebugger == true)
{
DebugActiveProcessStop(pi.dwProcessId);
TerminateProcess(pi.hProcess,0);
salir= true;
}
}
}while(salir == false);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
Synchronize(OnExitLoopDebugThread);
for(int x=0; x != ListaBPs->Count;)
{
delete ListaBPs->Items[x];
ListaBPs->Delete(x);
}
delete ListaBPs;
ListaBPs = NULL;
for(int x=0; x != ListaThreads->Count;)
{
delete ListaThreads->Items[x];
ListaThreads->Delete(x);
}
delete ListaThreads;
ListaThreads = NULL;
for(int x=0; x != ListaDlls->Count;)
{
ItemDLL = (TDll *)ListaDlls->Items[x];
for (int i = 0; i < ItemDLL->APIs->Count;) {
delete ItemDLL->APIs->Items[i];
ItemDLL->APIs->Delete(i);
}
delete ListaDlls->Items[x];
ListaDlls->Delete(x);
}
delete ListaDlls;
ListaDlls = NULL;
}
//---------------------------------------------------------------------------
bool THiloDebugger::AtachProcessByNameWindow(char *wName,int &Error)
{
HWND HParent;
DWORD ProcessId;
DWORD ThreadId;
int retval=false;
HParent=FindWindow(NULL,wName);
if(HParent){
ThreadId=GetWindowThreadProcessId(HParent,&ProcessId);
if(ThreadId){
if(DebugActiveProcess(ProcessId)){
pi.dwProcessId=ProcessId;
pi.dwThreadId=ThreadId;
pi.hProcess=HParent;
retval=true;
Error=0;
}else{
Error=-1;
}
}else{
Error=-2;
}
}else{
Error=-3;
}
return retval;
}
¿Alguien me puede ayudar?
Gracias por adelantado.