Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > C++ Builder
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 07-05-2020
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Problemas con CloseHandle y atacheo de proceso

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(),NULLNULLNULLFALSEDEBUG_PROCESS DEBUG_ONLY_THIS_PROCESSNULLNULL, &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.ContextFlagsCONTEXT_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.ContextFlagsCONTEXT_FULL CONTEXT_FLOATING_POINT CONTEXT_DEBUG_REGISTERS;
                                        
GetThreadContext(CurrentExceptionThread, &con);
                                        
dwContinueStatus OnCreateProcessDebugEventThread(&DebugEv.u.CreateProcessInfoDebugEv.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);
                                
salirtrue;
                        }
                }
        }while(
salir == false);

        
CloseHandle(pi.hProcess);
        
CloseHandle(pi.hThread);

        
Synchronize(OnExitLoopDebugThread);

        for(
int x=0!= ListaBPs->Count;)
        {
                
delete ListaBPs->Items[x];
                
ListaBPs->Delete(x);
        }
        
delete ListaBPs;
        
ListaBPs NULL;


        for(
int x=0!= ListaThreads->Count;)
        {
                
delete ListaThreads->Items[x];
                
ListaThreads->Delete(x);
        }
        
delete ListaThreads;
        
ListaThreads NULL;

        for(
int x=0!= ListaDlls->Count;)
        {
                
ItemDLL = (TDll *)ListaDlls->Items[x];
                for (
int i 0ItemDLL->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.
Responder Con Cita
  #2  
Antiguo 07-05-2020
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Casi lo solucioné así pero no se si será la mejor solución:
Código PHP:
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.dwThreadId=ThreadId;
                    
pi.hProcess OpenProcessPROCESS_QUERY_INFORMATION PROCESS_VM_READ PROCESS_TERMINATEFALSEProcessId);
                    
pi.dwProcessId=ProcessId;
                    
retval=true;
                    
Error=0;

            }else{
                
Error=-1;
            }
        }else{
            
Error=-2;
        }
    }else{
        
Error=-3;
    }
    return 
retval;

Con esto ya obtengo el Handle del proceso atacheado pero me sigue faltando el pi.hThread. ¿como puedo obtenerlo? No da error pero estoy haciendo un CloseHandle(NULL) porque es lo que pale al salir del depurado porque pi.hThread no la he inicializado con el valor y vale NULL.
Responder Con Cita
  #3  
Antiguo 07-05-2020
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Lo he solucionado así:
Código PHP:
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.dwThreadId=ThreadId;
                    
pi.hProcess OpenProcessPROCESS_QUERY_INFORMATION PROCESS_VM_READ PROCESS_TERMINATEFALSEProcessId);
                    
pi.hThread OpenThreadTHREAD_QUERY_INFORMATION THREAD_TERMINATEFALSEThreadId);
                    
pi.dwProcessId=ProcessId;
                    
retval=true;
                    
Error=0;

            }else{
                
Error=-1;
            }
        }else{
            
Error=-2;
        }
    }else{
        
Error=-3;
    }
    return 
retval;

Con esto ya obtengo el Handle del proceso atacheado y el del thread y aparentemente funciona todo ok. ¿está bien la solución?
Responder Con Cita
  #4  
Antiguo 07-05-2020
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Amigos ahora estoy con una variante pero que en vez del nombre de la ventana trabaje con el pid del proceso y tengo esto:
Código PHP:
bool THiloDebugger::AtachProcessById(int id,int &Error)
{
    
DWORD ThreadId;
    
int retval=false;

    
//ThreadId=GetWindowThreadId(HParent,&ProcessId);
    
if(ThreadId)
    {
        if(
DebugActiveProcess(id)){
            
pi.dwThreadId=ThreadId;
            
pi.hProcess OpenProcessPROCESS_QUERY_INFORMATION PROCESS_VM_READ PROCESS_TERMINATEFALSEid);
            
pi.hThread OpenThreadTHREAD_QUERY_INFORMATION THREAD_TERMINATEFALSEThreadId);
            
pi.dwProcessId=id;
            
retval=true;
            
Error=0;
        }else{
            
Error=-1;
        }
    }else{
        
Error=-2;
    }
    return 
retval;

El problema es que para hacerlo así necesito el hwnd de la ventana y no puedo usar FindWindow porque se supone que no tengo el titulo de la ventana y que lo hago con el pid. ¿como podria solucionarlo?
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Cómo averiguar el PID de un proceso Ðαяισš Varios 20 01-01-2009 01:35:33
Abortar un proceso TONIAM Varios 10 31-05-2007 19:26:41
Terminar proceso torito Varios 15 20-04-2007 02:44:36
Matar proceso raugadel API de Windows 9 05-10-2006 19:23:49
Matar Proceso anitra_cattivo API de Windows 2 10-09-2003 19:10:55


La franja horaria es GMT +2. Ahora son las 23:52:39.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi